Raised This Month: $51 Target: $400
 12% 

[RESOLU] ExecuteHamB( Ham_TraceAttack ... ) à partir d'un npc ? Pas de dommages :S


  
 
 
Thread Tools Display Modes
Author Message
micapat
Veteran Member
Join Date: Feb 2010
Location: Nyuu, nyuu (France).
Old 11-29-2011 , 14:40   [RESOLU] ExecuteHamB( Ham_TraceAttack ... ) à partir d'un npc ? Pas de dommages :S
#1

Bonsoir !

Donc voila j'ai un petit NPC qui peut tirer, le ciblage est ok, mais au niveau des dommages ils ne se réalisent pas c'est vraiment bizarre.

-> Quand le NPC me tire dessus j'ai bien le sang qui gicle, le viseur dévie si je prend une tête, mais je ne reçoit aucun dommages.

J'ai pris pas mal d'info de ce tutoriel : http://forums.alliedmods.net/showpos...3&postcount=42 .

Voila le call de la fonction :

PHP Code:
ptr create_tr2( );
engfuncEngFunc_TraceLineoriginShootoriginTargetDONT_IGNORE_MONSTERSnpcSentryptr );
entityHit get_tr2ptrTR_pHit );
get_tr2ptrTR_vecEndPosoriginEndShoot );
    
if( 
entityHit )
{
    
ExecuteHamBHam_TraceAttackentityHitnpcSentrydamagedirectionptrdamagebits ); // BUG !
    
free_tr2ptr );

Bien entendu la variable damage est supérieur à 0 ( 5.0 pour être précis ). J'ai même tenté en passant directement cet argument sans passer par la variable damage.

Evenement très très bizarre, le NPC me tire dessus, je ne prends aucun dommages. Puis le NPC se met à tirer sur une autre entité ( Un autre joueur par exemple ) et là BIM, je prends tous les dommages que j'aurais du me prendre ( Je meurt en somme ).

Logiquement Ham_TraceAttack appelle derrière Ham_TakeDamage nan ? Sinon je devrais alors appeller ExecuteHamB( Ham_TakeDamage ... ) derrière l'appel de Ham_TraceAttack ( Quel est l'utilité d'avoir un argument damage alors à part faire de jolies éclaboussures ? ).
__________________
micapat is offline
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
Old 11-29-2011 , 16:25   Re: ExecuteHamB( Ham_TraceAttack ... ) à partir d'un npc ? Pas de dommages :S
#2

Voici le code de TraceAttack :

PHP Code:
void CBasePlayer::TraceAttackentvars_t *pevAttackerfloat flDamageVector vecDirTraceResult *ptrint bitsDamageType )
{
    
BOOL shouldBleed TRUE;
    
BOOL shouldSpark FALSE;
    
BOOL hitShield   IsHittingShieldvecDirptr );

    
CBasePlayer *pAttacker = (CBasePlayer *)CBaseEntity::InstancepevAttacker );

    if( 
m_iTeam == pAttacker->m_iTeam && CVAR_GET_FLOAT"mp_friendlyfire" ) )
    {
        
shouldBleed FALSE;
    }

    if( !
pev->takedamage )
    {
        return;
    }

    
m_LastHitGroup ptr->iHitgroup;

    if( 
hitShield )
    {
        
flDamage 0.0;
        
shouldBleed FALSE;

        if( 
RANDOM_LONG0) )
            
EMIT_SOUNDENTpev ), CHAN_VOICE"weapons/ric_metal-1.wav"VOL_NORMATTN_NORM );
        else
            
EMIT_SOUNDENTpev ), CHAN_VOICE"weapons/ric_metal-2.wav"VOL_NORMATTN_NORM );

        
UTIL_Sparksptr->vecEndPos );

        
pev->punchangle.flDamage RANDOM_FLOAT( -0.150.15 );
        
pev->punchangle.flDamage RANDOM_FLOAT( -0.150.15 );

        if( 
pev->punchangle.)
            
pev->punchangle.= -4;

        if( 
pev->punchangle.< -)
            
pev->punchangle.= -5;

        else if( 
pev->punchangle.)
            
pev->punchangle.5;
    }
    else
    {
        switch( 
ptr->iHitgroup )
        {
            case 
HITGROUP_HEAD :
            {
                if( 
m_iKevlar == )
                {
                    
shouldBleed FALSE;
                    
shouldSpark TRUE;
                }

                
flDamage *= 4;

                if( 
shouldBleed )
                {
                    
pev->punchangle.flDamage * -0.5;

                    if( 
pev->punchangle.< -12 )
                        
pev->punchangle.= -12;

                    
pev->punchangle.flDamage RANDOM_FLOAT( -1.01.0 );

                    if( 
pev->punchangle.< -)
                        
pev->punchangle.= -9;

                    else if( 
pev->punchangle.)
                        
pev->punchangle.9;
                }

                break;
            }
            case 
HITGROUP_CHEST :
            {
                if( 
m_iKevlar )
                {
                    
shouldBleed FALSE;
                }

                if( 
shouldBleed )
                {
                    
pev->punchangle.flDamage * -0.1;

                    if( 
pev->punchangle.< -)
                        
pev->punchangle.= -4;
                }

                break;
            }
            case 
HITGROUP_STOMACH :
            {
                if( 
m_iKevlar )
                {
                    
shouldBleed FALSE;
                }

                
flDamage *= 1.25;

                if( 
shouldBleed )
                {
                    
pev->punchangle.flDamage * -0.1;

                    if( 
pev->punchangle.< -)
                        
pev->punchangle.= -4;
                }

                break;
            }
            case 
HITGROUP_LEFTARM  :
            case 
HITGROUP_RIGHTARM :
            {
                if( 
m_iKevlar )
                {
                    
shouldBleed FALSE;
                }

                break;
            }
            case 
HITGROUP_LEFTLEG  :
            case 
HITGROUP_RIGHTLEG :
            {
                
flDamage *= 0.75;
                break;
            }
        }
    }

    if( 
shouldBleed )
    {
        
BloodSplatptr->vecEndPosvecDirptr->iHitgroup, (int)( flDamage ) );
        
SpawnBloodptr->vecEndPosBloodColor(), flDamage );
        
TraceBleedflDamagevecDirptrbitsDamageType );
    }
    else if( 
ptr->iHitgroup == HITGROUP_HEAD && shouldSpark )
    {
        
MESSAGE_BEGINMSG_PVSSVC_TEMPENTITYptr->vecEndPos );
        
WRITE_BYTETE_STREAK_SPLASH );
        
WRITE_COORDptr->vecEndPos.);
        
WRITE_COORDptr->vecEndPos.);
        
WRITE_COORDptr->vecEndPos.);
        
WRITE_COORDptr->vecPlaneNormal.);
        
WRITE_COORDptr->vecPlaneNormal.);
        
WRITE_COORDptr->vecPlaneNormal.);
        
WRITE_BYTE);
        
WRITE_SHORT22 );
        
WRITE_SHORT25 );
        
WRITE_SHORT65 );
        
MESSAGE_END();
    }

    
AddMultiDamagepevAttackerthisflDamagebitsDamageType );

Ca n'appelle pas directement TakeDamage et tu vois à la place AddMultiDamage.

PHP Code:
//
// ClearMultiDamage - resets the global multi damage accumulator
//
void ClearMultiDamage(void)
{
    
gMultiDamage.pEntity NULL;
    
gMultiDamage.amount    0;
    
gMultiDamage.type 0;
}

//
// ApplyMultiDamage - inflicts contents of global multi damage register on gMultiDamage.pEntity
//
// GLOBALS USED:
//        gMultiDamage

void ApplyMultiDamage(entvars_t *pevInflictorentvars_t *pevAttacker )
{
    
Vector        vecSpot1;//where blood comes from
    
Vector        vecDir;//direction blood should go
    
TraceResult    tr;
    
    if ( !
gMultiDamage.pEntity )
        return;

    
gMultiDamage.pEntity->TakeDamage(pevInflictorpevAttackergMultiDamage.amountgMultiDamage.type );
}


// GLOBALS USED:
//        gMultiDamage

void AddMultiDamageentvars_t *pevInflictorCBaseEntity *pEntityfloat flDamageint bitsDamageType)
{
    if ( !
pEntity )
        return;
    
    
gMultiDamage.type |= bitsDamageType;

    if ( 
pEntity != gMultiDamage.pEntity )
    {
        
ApplyMultiDamage(pevInflictor,pevInflictor); // UNDONE: wrong attacker!
        
gMultiDamage.pEntity    pEntity;
        
gMultiDamage.amount        0;
    }

    
gMultiDamage.amount += flDamage;

Le but de AddMultiDamage, c'est de cumuler les dégâts subits, pour un même joueur, de n'importe quel attaqueur, le temps d'une frame. Et après, ApplyMultiDamage est appelé pour envoyer TakeDamage.

C'est là ton problème.

Normalement quand TraceAttack est appelé, ApplyMultiDamage doit être appelé immédiatement après dans ton code. Tu peux voir des exemples dans HLSDK, c'est toujours appelé. Ca permet comme tu l'auras compris de donner les dégâts accumélés.
En ne le faisant pas et en se basant que sur AddMultiDamage, ApplyMultiDamage va se déclencher que quand l'entité (victime) enregistré la première fois ne sera plus le même, et du coup TakeDamage se executé sur l'entité enregistré auparavant.

Pour résoudre ton souci, soit tu zappes TraceAttack, soit tu utilises Orpheu pour appeler ApplyMultiDamage après ton TraceAttack. La deuxième option est plus cool tout de même. Si t'as besoin d'aide sur orpheu, dis le moi.
__________________
Arkshine is offline
micapat
Veteran Member
Join Date: Feb 2010
Location: Nyuu, nyuu (France).
Old 11-29-2011 , 17:05   Re: ExecuteHamB( Ham_TraceAttack ... ) à partir d'un npc ? Pas de dommages :S
#3

Ouai je viens de regarder le SDK de HL et ils appellent bien ApplyMultiDamage à chaque fois ...

Le truc c'est que j'y connais rien à Orpheu ... Quand je vois les tutos j'ai l'impression que ça ressemble même pas à du code. Mais bon après je suis pas réfractaire à m'y pencher si ça peut être utile.

Mais imaginons un instant que je développe un module, il n'est pas possible que j'appelle cette fonction ( en C++ du coup ) ?

Ou sinon est-ce que ne je pourrais pas tricher en appelant une deuxième fois à la suite ExecuteHamB( TraceAttack .. ) mais avec par exemple le npc qui inflige 0 dégats sur une entité fixe qui est crée dans un coin de la map ? C'est crade mais je pense que ça pourrait marcher.

Merci
__________________
micapat is offline
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
Old 11-29-2011 , 17:11   Re: ExecuteHamB( Ham_TraceAttack ... ) à partir d'un npc ? Pas de dommages :S
#4

Je me doutais bien que tu allais être peaumé. Ce n'est pas facile.
Donc, je t'ai fais le fichier.

Copier le contenu dans un fichier nommé ApplyMultiDamage (pas d'extension) dans orpheu/functions/.

Code:
{
    "name"      : "ApplyMultiDamage",
    "library"   : "mod",
    "arguments" :
    [
        {
            "type"  : "entvars_s *",
            "info"  : "pevInflictor"
        },
        {
            "type"  : "entvars_s *",
            "info"  : "pevAttacker"
        }
    ],
    "identifiers":
    [
        {
            "os"    : "windows",
            "mod"   : "cstrike",
            "value" : [0x90,0x8B,0x0D,"*","*","*","*",0x85,0xC9,0x74,"*",0x8B,0x15,"*","*","*","*",0x8B],
            "displacement" : 1
        },
        {
            "os"    : "linux",
            "mod"   : "cstrike",
            "value" : "ApplyMultiDamage__FP9entvars_sT0"
        }
    ]
}
Et voici un exemple d'utilisation :

Code:
new OrpheuFunction:HandeFuncApplyMultiDamage; public plugin_init() {     HandeFuncApplyMultiDamage = OrpheuGetFunction( "ApplyMultiDamage" ); } public RandomFunction() {     // TraceAttack()     OrpheuCallSuper( HandeFuncApplyMultiDamage, inflictorIndex, attackerIndex ); }

Bien sûr, oublies pas d'installer Orpheu, hein !

Pour ce qui est du module, tu seras obligés de faire la même chose que Orpheu, c'est à dire fouiller la mémoire avec une signature/nom du symbole pour trouver la fonction. Ca revient au même.

En passant, ton free_tr2 ca devrait se situer hors du check, au risque d'avoir des surprises de ne pas avoir libéré la mémoire.
__________________

Last edited by Arkshine; 11-30-2011 at 06:04.
Arkshine is offline
micapat
Veteran Member
Join Date: Feb 2010
Location: Nyuu, nyuu (France).
Old 11-29-2011 , 17:44   Re: ExecuteHamB( Ham_TraceAttack ... ) à partir d'un npc ? Pas de dommages :S
#5

Merci beaucoup

Pour info la méthode "crade" marche bien, je me demande si elle n'est pas plus rapide que passer par Orpheu ? Je connais pas le fonctionnement d'Orpheu donc je peux pas dire.

Pour le free_tr2 en fait y a un else que je n'ai pas posté, bon ca fait laid parce que du coup ya free_tr2 deux fois é_é.

( PS : Le fonctionnement du fichier ça va il est pas dur à comprendre, mais bon personnellement j'aurais trouvé ça plus "propre" que tout soit géré via des fonctions du genre OrpheuInitName( ), OrpheuInitArguments( ) ... ). Là on a des fichiers externes qui se baladent ).
__________________
micapat is offline
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
Old 11-29-2011 , 18:00   Re: ExecuteHamB( Ham_TraceAttack ... ) à partir d'un npc ? Pas de dommages :S
#6

Je vois pas l'intérêt d'utiliser une méthode "crade" quand on peut faire "propre"... Créer une entité, ça engendre beaucoup de codes et a plein de répercussions, sans parler que tu exécutes du code pour rien. Orpheu est rapide. Et puis même, de manière générale je ne vois pas pourquoi tu t'autorises à utiliser une méthode crade sous prétexte que tu ne connais pas bien orpheu. C'est un peu dommage de penser comme ça.

Je comprends ta remarque, mais faut comprendre aussi que Orpheu est multi-mod et que pour des raisons pratiques, un fichier externe est bien plus simple. Ca se partage plus facilement, ca se modifie plus facilement, c'est plus clair, on peut y mettre plusieurs mods dans un même fichier, se parse avant l'initialisation des plugins et j'en passe. En utilisant ta façon, on utilise plus de natives, donc bouffe plus de CPU, on a plus de code. Au final, c'est moche et ingérable, alourdissant considérablement le code. Ca ne convient pas du tout pour les fonctionnalités du module.
__________________

Last edited by Arkshine; 11-29-2011 at 18:03.
Arkshine is offline
micapat
Veteran Member
Join Date: Feb 2010
Location: Nyuu, nyuu (France).
Old 11-29-2011 , 18:12   Re: ExecuteHamB( Ham_TraceAttack ... ) à partir d'un npc ? Pas de dommages :S
#7

C'est la première fois que je requiers et manipule Orpheu surtout. Mais bon là je vois qu'il n'y a pas le choix. La méthode "crade" c'était juste du test, et je n'ai même pas eu besoin de créer une autre entité, j'ai simplement retourné l'attaque sur l'attaquant.

Merci

EDIT : Pas si résolu que ça en faite, ça plante dès que le npc attaque une autre personne après moi, où après mon respawn. Connor m'a parlé de ClearMultiDamage( ), je pense que je dois l’appeler aussi nan ?

J'ai trouvé ceci dans HLSDK, donc je pense que oui :

PHP Code:
ClearMultiDamage( );
pEntity->TraceAttackpevInflictorflAdjustedDamage, (tr.vecEndPos vecSrc).Normalize( ), &trbitsDamageType );
ApplyMultiDamagepevInflictorpevAttacker ); 
EDIT 2 :

Je crois que j'ai réussi à faire le fichier mais uniquement coté Linux :S Windows c'est monstrueux !

Code:
{
    "name"      : "ClearMultiDamage",
    "library"   : "mod",
    "identifiers":
    [
        {
            "os"    : "linux",
            "mod"   : "cstrike",
            "value" : "ClearMultiDamage__Fv"
        }
    ]
}
EDIT 3 ( Ouai ça en fait beaucoup ! ) :

Ok, ça roxx J'ai testé sur mon serveur Linux et ça fonctionne bien, ma sentry me dégomme et dégomme les autres npcs sans problèmes ! Mais je ne sais vraiment pas par contre comment trouver l'équivalent Windaube Windows . Peux tu me donner la technique secrète, j'ai essayé de comprendre avec http://forums.alliedmods.net/showthread.php?t=118934 mais il conseille en recherchant grâce aux chaines de caractères, ce qu'il n'y a pas dans cet fonction ! ( Je n'arrive pas à avoir le joli code en C qu'il a en plus ).

J'avoue que Orpheu claque Tu m'a converti maintenant c'pas bien
Attached Thumbnails
Click image for larger version

Name:	Sans titre.png
Views:	88
Size:	33.6 KB
ID:	96054  
__________________

Last edited by micapat; 11-29-2011 at 20:24.
micapat is offline
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
Old 11-30-2011 , 06:03   Re: [PRESQUE] ExecuteHamB( Ham_TraceAttack ... ) à partir d'un npc ? Pas de dommages
#8

Y'a certaines fonctions qui ne sont pas facile à trouver sous windows. Il faut en général trouver sous linux voir où cette fonction est appelée et sous windows trouver cette fonction et remonter jusqu'à cette fonction voulue. Dans ce cas, c'est relativement facile. Tu vois que ClearMultiDamage est utilisé par exemple dans CKnife::Swing sous linux, qui est appelé de CKnife::SwingAgain et est en passant une fonction exportée. Sous Windows, tu cherches CKnife::SwingAgain, vu que c'est exportée tu vois le nom du symbole, puis dedans tu vois une fonction non nommée, qui ne peut être que CKnife::Swing. Puis dans le code, tu cherches un point de repère qui indique où était utilisée la fonction recherchée, me suis servi du code just au dessus et j'ai trouvé facilement. J'aurais pu aussi chercher directement via une chaîne de caractères pour trouver la fonction CKnife::Swing. Tu vois en gros, tout est une question de trouver un point de repère et de remonter jusqu'à la source via des indices (string, references).

Bref : ClearMultiDamage

Code:
{
    "name"        : "ClearMultiDamage",
    "library"     : "mod",
    "identifiers" :
    [
        {
            "os"    : "windows",
            "mod"   : "cstrike",
            "value" : [0x90,0x33,0xC0,0xA3,"*","*","*","*",0xA3,"*","*","*","*",0xA3],
            "displacement" : 1
        },
        {
            "os"    : "linux",
            "mod"   : "cstrike",
            "value" : "ClearMultiDamage__Fv"
        }
    ]
}

Important : J'ai rectifié le contenu de ApplyMultiDamage dans mon précédent message. J'ai oublié displacement : 1. Je ne sais pas trop pourquoi ça fonctionne encore, mais ce n'est pas correct quoi qu'il en soit, donc modifie.
__________________

Last edited by Arkshine; 11-30-2011 at 06:13.
Arkshine is offline
micapat
Veteran Member
Join Date: Feb 2010
Location: Nyuu, nyuu (France).
Old 11-30-2011 , 06:18   Re: [RESOLU] ExecuteHamB( Ham_TraceAttack ... ) à partir d'un npc ? Pas de dommages :
#9

Ok, merci de ton aide

J'ai testé et ça fonctionne désormais sous Windows aussi -> Résolu
__________________

Last edited by micapat; 11-30-2011 at 06:19.
micapat is offline
 



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 07:17.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode