000
06.07.2008, 15:07
Reaver_D
|
Hallo!
Also, ich bin relativ neu und versuche mich an einem Metamod-Plugin (ist ja vom Aufbau ähnlich wie HL Mods) und nun habe ich mehrere Fragen/Probleme:
// Überprüfen, ob ich getroffen bin if ((pThis->v.dmg_take != 0) && !(pThis->v.health < 1)) { // bin ich tot? if (pThis->v.health < pThis->v.dmg_take) { // ja, ich bin tot
// Player-Pointer vom Feind holen CPlayer *pAtt = CPlayer::GetPlayerFromArray(pThis->v.dmg_inflictor);
if (!FNullEnt(pAtt->m_pEdict)) // das ist nötig, wegen der Granaten... { // dem Angreifer einen Punkt geben pAtt->m_frags++; pAtt->m_fragsSinceLastDeath++; // Bekommt der Angreifer irgendwas Ranking-mäßiges? if (pAtt->m_fragsSinceLastDeath == 3) EMIT_SOUND(pAtt->m_pEdict, CHAN_AUTO, "misc/monsterkill.wav", 1.0, ATTN_NONE);
//if (pAtt->m_fragsSinceLastDeath == 6) // EMIT_SOUND(pAtt->m_pEdict, CHAN_AUTO, "misc/monsterkill.wav", 1.0, ATTN_NONE); }
// meine "Kills seit dem letzten Tod" zurücksetzen" m_fragsSinceLastDeath = 0;
// Und eine Nachricht senden UTIL_SendTextMsg(pThis, HUD_PRINTTALK, UTIL_VarArgs("Getoetet von %s (%.0f HP)",STRING(pAtt->m_pEdict->v.netname), pAtt->m_pEdict->v.health));//, )); } Ich hab ewig gebraucht, um das herauszufinden und jetzt funktioniert das leider nicht immer. Diese Abfrage habe ich in CmdStart reingeschrieben (richtig?). Leider Habe ich jetzt das Problem, dass er mir anzeigt, dass ich, wenn ich z.B. nur noch 13 HP habe und mich der Bot dann angreift, dass ich von ihm getötet wurde (obwohl ich noch lebe!). Und wenn jmd. einen Headshot macht, dann funktioniert das ganze auch nicht. Warum?
Das nächste ist: Ich wollte die Funktion TraceLine hooken, aber sie wird nicht aufgerufen:
C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion) { enginefuncs_t meta_engfuncs_post;
memset(&meta_engfuncs_post, 0, sizeof(enginefuncs_t));
meta_engfuncs_post.pfnTraceLine = TraceLine_Post;
memcpy(pengfuncsFromEngine, &meta_engfuncs_post, sizeof(enginefuncs_t));
return 1; } Ich hoffe, dass ihr mir helfen könnt!
Liebe Grüße Reaver4D54
--
Dieser Beitrag wurde am 06.07.2008 um 15:08 von Reaver_D bearbeitet.
|
|
Profil || Suche
|
001
06.07.2008, 18:47
luckerking
|
Ich habe noch nie einen Mod erstellt und mir auch noch nie den Code von HL angeguckt. Aber, vielleicht kann ich dir ja trotzdem helfen.
Ich nehme an v.health beinhaltet die aktuellen Hp von dem Spieler und v.dmg_take den Schaden den er nimmt.
Warum überprüfst du bei der ersten Abfrage ob "Health" nicht kleiner als 1 ist? In der zweiten Abfrage überprüfst du, ob Health < dmg_take, theoretisch reicht es doch auch aus, wenn Health <= dmg_take
--
|
|
Profil || Suche
|
002
06.07.2008, 19:08
Reaver_D
|
Das habe ich gemacht, weil ich mir evtl. den else-Teil noch vorbehalten wollte. Ich weiß, dass es insgesamt kürzer gehen würde, aber ich werde es vielleicht noch brauchen. Trotzdem schonmal Danke für deine Antwort!
Kann jmd. helfen?
Liebe Grüße Reaver4D54
--
|
|
Profil || Suche
|
003
06.07.2008, 19:21
luckerking
|
Ach, sorry, war mein Gedankenfehler. Ist klar, dass, wenn man weniger als 1 hab hat, nicht mehr sterben kann :)
In der zweiten Abfrage überprüfst du, ob Health < dmg_take, theoretisch reicht es doch auch aus, wenn Health <= dmg_take
Was sagst du den dazu?
--
|
|
Profil || Suche
|
004
06.07.2008, 20:00
Reaver_D
|
Jo, das stimmt. Änder ich gleich mal. Aber das wird ja nichts an den Fehlern ändern... :'-(
--
|
|
Profil || Suche
|
005
06.07.2008, 20:12
luckerking
|
Ich dachte an den Headshot.
100 hp und 100 schaden.
--
|
|
Profil || Suche
|
006
06.07.2008, 20:55
Reaver_D
|
Hat nichts geändert...
zusätzlich habe ich das Problem festgestellt, dass er mir schon anzeigt, dass ich tot wäre, wenn ich noch z.B. 10 HP habe, warum?
--
|
|
Profil || Suche
|
007
06.07.2008, 21:32
Bluthund
|
Steht in dmg_take der Damagewert vor oder nach Einbeziehung des Hitbox- und/oder Armormultiplikators? Sprich: Ist es der Waffenschaden oder der real genommene Schaden nach sämtlichen Einflüssen von außen. Ich nehme mal stark an, dass an der Stelle nämlich das Problem liegt. Evtl solltest du auch versuchen im Sinne der Wartbarkeit solche Konstrukte:!(pThis->v.health < 1) in sowas hier pThis->v.health >= 1 umzuwandeln.
@luckerking: Ein Headshot macht im allgemeinen in CS um einiges mehr als 100dp.
--
The C language combines all the power of assembly language with all the ease-of-use of assembly language. "humorig is n blödwort :>" by -CarniGGeLjumpR-
|
|
Profil || Suche
|
008
07.07.2008, 00:59
Reaver_D
|
Das ist eine gute Frage. Wie kann ich das herausfinden? Oder wo könnte ich gucken, wie ich die "äußeren Einflüsse" mit einbeziehe? Eigentlich müsste CS das ja auch berechnen...
Okay, und Danke für den Tipp! Auf solche "Kleinigkeiten" achte ich nie und irgendwann, wenn ich mich später dran setzte, packe ich mich immer am Kopf und frage mich, warum ich das denn so gemacht habe =)
Wenn noch jmd. was zu den Problemen (z.B. auch TraceLine) weiß, wäre nett, wenn er mir helfen könnte...
Gute Nacht und liebe Grüße Reaver4D54
--
|
|
Profil || Suche
|
009
07.07.2008, 01:27
Bluthund
|
2 Möglichkeiten: 1. Du schaust nach wo du deine Damage-Werte herholst. 2. Wenn du das nicht kannst (aus welchem Grund auch immer), baust du dir ein paar Debugausgaben zusammen. Dann gehst du ins Spiel und nimmst ein paar Testreihen auf. Wenn der Schaden egal auf welche Hitbox (und egal ob Armor oder nicht) einer bestimmten Waffe immer gleich (im Rahmen der definierten Schwankungen) ist, wird es wohl der Waffenschaden sein.
Zu deinem Traceline-Problem: Ich hab selbst noch nix mit Metamod gemacht aber was du da tust sieht suspekt aus: Du baust dir eine Variable vom enginefuncs-Type zusammen und machst sie erstmal leer. Dann schreibst du den Funktionspointer für deine Funktion an die jeweilige Stelle in der Struktur. Soweit kann ich das alles nachvollziehen. Und dann bügelst du die Eingabestruktur mit deiner Struktur, welche nur einen fp enthält, über. Ich kann mir nicht wirklich vorstellen, dass das gewollt ist. Falls doch will ich nichts gesagt haben. Wie gesagt kenne ich die Vor-/Nachbedingungen der Funktion da nicht und weiß auch nicht was du da an E/A-Parametern hast (die Typen sind mir geläufig, aber die Herkunft der Daten in deinem Fall nicht).
--
The C language combines all the power of assembly language with all the ease-of-use of assembly language. "humorig is n blödwort :>" by -CarniGGeLjumpR-
|
|
Profil || Suche
|
010
07.07.2008, 09:24
hausi
|
@Traceline: Ich würde mal die folgenden 2 Zeilen vertauschen:
meta_engfuncs_post.pfnTraceLine = TraceLine_Post; memcpy(pengfuncsFromEngine, &meta_engfuncs_post, sizeof(enginefuncs_t)); Denn mit der ersten Zeile schreibst du deine Funktion rein und mit der zweiten (und die hat Bluthund wohl übersehen) kopierst du gleich wieder den Pointer der Originalfunktion drüber.
--
|
|
Profil || Suche
|
011
07.07.2008, 13:22
Reaver_D
|
?
void * memcpy ( void * destination, const void * source, size_t num ); Mit der zweiten Zeile schreibe ich doch meine Funktionen (welche in meta_engfuncs_post drin sind) an pengfuncsFromEngine, oder nicht?
Wenn ichs finde, dann poste ich mal, wie amx das macht. Ich meine nur, dass das ähnlich war.
--
|
|
Profil || Suche
|
012
07.07.2008, 13:28
Bluthund
|
@hausi: Hab ich nich übersehen :) Aber das war genau der Punkt, der mich stutzig macht. mem*() nehmen zuerst Ziel und anschließend Quelle, von daher schreibt er seine Struktur in den Speicher auf den pengfuncsFromEngine zeigt. Das macht von der Reihenfolge schon Sinn aber ist halt dahingehend komisch, da in seiner Struktur nur ein Pointer steht (und wie der Name des Eingabeparameters andeutet dort initial alle FPs der Engine drin sind).
@Reaver: Ja du kopierst deine lokale Variable in den Speicher auf den pengfuncsFromEngine zeigt.
Mehr Sinn würde imho sowat hier machen
memcpy(&meta_engfuncs_post, pengfuncsFromEngine, sizeof(enginefuncs_t)); // alle Funtionspointer der Engine holen meta_engfuncs_post.pfnTraceLine = TraceLine_Post; // FP für TraceLine schreiben memcpy(pengfuncsFromEngine, &meta_engfuncs_post, sizeof(enginefuncs_t)); // Zurückspeichern wobei man hier auch einfach
pengfuncsFromEngine->pfnTraceLine = TraceLine_Post machen könnte... Wie gesagt ich hab noch nie was mit MM gemacht aber das da oben sieht von der Semantik her sehr sehr komisch aus. Wobei halt zu klären wäre, was nach dem Aufruf dieser Funktion mit dem Pointer pengfuncsFromEngine noch alles passiert. Zeigt er schon auf die engfuncs_t, welche direkt an die Gamelogic-DLLs übergeben werden? Wird er noch über irgendne MetaMod-Funktion umgefriemelt oder in das System "eingeschoben"?
--
The C language combines all the power of assembly language with all the ease-of-use of assembly language. "humorig is n blödwort :>" by -CarniGGeLjumpR-
Dieser Beitrag wurde am 07.07.2008 um 13:39 von Bluthund bearbeitet.
|
|
Profil || Suche
|
013
07.07.2008, 13:31
Tuboatse-Harald
|
a) Was sagt uns das `_Post'? Dass es schon zu spät ist. b) Einfach den entsprechenden Pointer in der Enginefungs Struct überschreiben, nichts nullen. c) return HANDLED;
--
Twisted and Brainfire. Das Fleisch ist willig und der Club ist eine Fleischerei!
|
|
Profil || Suche
|
014
07.07.2008, 14:24
Reaver_D
|
Ja, logisch ist das auch. Ich verstehe selber nicht, warum das nicht geht...
Ich hab jetzt beim amx-mod danach gesucht und folgende 2 Sachen gefunden
enginefuncs_t meta_engfuncs_post; C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion) { memset(&meta_engfuncs_post, 0, sizeof(enginefuncs_t));
meta_engfuncs_post.pfnMessageBegin = C_MessageBegin_Post; meta_engfuncs_post.pfnMessageEnd = C_MessageEnd_Post; meta_engfuncs_post.pfnWriteByte = C_WriteByte_Post; meta_engfuncs_post.pfnWriteChar = C_WriteChar_Post; meta_engfuncs_post.pfnWriteShort = C_WriteShort_Post; meta_engfuncs_post.pfnWriteLong = C_WriteLong_Post; meta_engfuncs_post.pfnWriteAngle = C_WriteAngle_Post; meta_engfuncs_post.pfnWriteCoord = C_WriteCoord_Post; meta_engfuncs_post.pfnWriteString = C_WriteString_Post; meta_engfuncs_post.pfnWriteEntity = C_WriteEntity_Post; meta_engfuncs_post.pfnRegUserMsg = C_RegUserMsg_Post;
memcpy(pengfuncsFromEngine, &meta_engfuncs_post, sizeof(enginefuncs_t));
return 1; } C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion) { LOG_DEVELOPER(PLID, "called: GetEngineFunctions_Post; version=%d", *interfaceVersion); if(!pengfuncsFromEngine) { LOG_ERROR(PLID, "GetEngineFunctions_Post called with null pengfuncsFromEngine"); return(FALSE); } else if(*interfaceVersion != ENGINE_INTERFACE_VERSION) { LOG_ERROR(PLID, "GetEngineFunctions_Post version mismatch; requested=%d ours=%d", *interfaceVersion, ENGINE_INTERFACE_VERSION); // Tell metamod what version we had, so it can figure out who is out of date. *interfaceVersion = ENGINE_INTERFACE_VERSION; return(FALSE); } memcpy(pengfuncsFromEngine, &g_EngineFuncs_Post_Table, sizeof(enginefuncs_t)); g_pengfuncsTable_Post=pengfuncsFromEngine; return TRUE;
} Der erste Teil stammt aus der meta_api.cpp
Habs auch mit return MRES_HANDLED ausprobiert. Geht auch nicht...
Liebe Grüße Reaver4D54
--
|
|
Profil || Suche
|
015
07.07.2008, 14:59
luckerking
|
Bluthund postete @luckerking: Ein Headshot macht im allgemeinen in CS um einiges mehr als 100dp. Weiß ich doch, kann ja sein, dass er die dmg verändert hat. (Oder ein Usp headshot :) )
Mal so nebenbei, gibt es ein Tutorial für erstellen eines Metamod-Plugin?
Um die Variable gleich im Spiel auszugeben kannst du das ja hier gleich ausgeben, wie du das schon mit den HP(von dem Gegner?) gemacht hast.
// Und eine Nachricht senden UTIL_SendTextMsg(pThis, HUD_PRINTTALK, UTIL_VarArgs("Getoetet von %s (%.0f HP)",STRING(pAtt->m_pEdict->v.netname), pAtt->m_pEdict->v.health));//, ));
--
|
|
Profil || Suche
|