Willkommen ~Gast!
Registrieren || Einloggen || Hilfe/FAQ || Staff
Probleme mit der Registrierung im Forum? Melde dich unter registerEin Bild.
Autor Beitrag
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:

Quellcode:// Ü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:

Quellcode: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.
zum Seitenanfang zum Seitenende 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

--

zum Seitenanfang zum Seitenende 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

--

zum Seitenanfang zum Seitenende 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 :)

Zitat:
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?

--

zum Seitenanfang zum Seitenende 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... :'-(

--

zum Seitenanfang zum Seitenende Profil || Suche
005
06.07.2008, 20:12
luckerking



Ich dachte an den Headshot.

100 hp und 100 schaden.

--

zum Seitenanfang zum Seitenende 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?

--

zum Seitenanfang zum Seitenende 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:Quellcode:!(pThis->v.health < 1) in sowas hier Quellcode: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-

zum Seitenanfang zum Seitenende 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

--

zum Seitenanfang zum Seitenende 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-

zum Seitenanfang zum Seitenende Profil || Suche
010
07.07.2008, 09:24
hausi



@Traceline:
Ich würde mal die folgenden 2 Zeilen vertauschen:
Quellcode: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.

--

zum Seitenanfang zum Seitenende Profil || Suche
011
07.07.2008, 13:22
Reaver_D



?

Quellcode: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.

--

zum Seitenanfang zum Seitenende 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
Quellcode: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
Quellcode: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.
zum Seitenanfang zum Seitenende 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!

zum Seitenanfang zum Seitenende 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

Quellcode: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;
}
Quellcode: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

--

zum Seitenanfang zum Seitenende Profil || Suche
015
07.07.2008, 14:59
luckerking



Zitat:
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.
Quellcode:// 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));//, ));

--

zum Seitenanfang zum Seitenende Profil || Suche