AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting Help (https://forums.alliedmods.net/forumdisplay.php?f=11)
-   -   Solved Store Attacker damage in dinamic array for every victim (https://forums.alliedmods.net/showthread.php?t=333461)

Shadows Adi 07-13-2021 13:43

Store Attacker damage in dinamic array for every victim
 
Hello,
I am trying to store a player's damage dealt to another player in an dinamic array. Down below I tried to find Attacker's name in array to get an index:
  • if it's returning a valid index, it loops through all Array items to get all the attacker's victims. Afterwards, it checks if the current victim's name is same as the one found ( if there is already the victim's name in the array ) and then it adds the current damage dealt to the victim in the same index in Array. If there is no equality between victim's name and all the entries found in the array, then it pushes another entry with the Attacker's name but other Victim name.
  • if it's returning a negative value, then pushes a new entry in array, a first one, with Attacker's name and his Victim's name with current damage dealt.

I found this after I added debug messages to code ( you can see down below ):

The problem is when it search for attacker's victim name and it finds one in array, instead of creating a new entry with Attacker's name and the new victim's name, it creates an entry with first victim name from array.

Code:
PHP Code:

enum _:PlayerStats
{
    
AttackerName[MAX_NAME_LENGTH],
    
VictimName[MAX_NAME_LENGTH],
    
DamageGiven,
    
DamageReceived
}

    new 
item ArrayFindString(g_aPlayerStatsg_szName[iAttacker])
    new 
index

    
new iData[PlayerStats]

    if(
item != -1)
    {
        
client_print(iAttackerprint_chat"if 1")
        for(new 
iArraySize(g_aPlayerStats); i++)
        {
            
ArrayGetArray(g_aPlayerStatsiiData)

            
index containi(iData[AttackerName], g_szName[iAttacker])

            if(
index != -1)
            {
                
client_print(iAttackerprint_chat"if 2")
                if(
equali(iData[VictimName], g_szName[iVictim]))
                {
                    
client_print(iAttackerprint_chat"if 3")
                    
iData[DamageGiven] += floatround(flDamage)

                    
ArraySetArray(g_aPlayerStatsiiData)

                    continue
                }
                else
                {
                    
client_print(iAttackerprint_chat"else 1")
                    
copy(iData[VictimName], charsmax(iData[VictimName]), g_szName[iVictim])
                    
iData[DamageGiven] = floatround(flDamage)

                    
ArrayPushArray(g_aPlayerStatsiData)

                    break
                }
            }
        }
    }

    
client_print(iAttackerprint_chat"else 2")
    
copy(iData[AttackerName], charsmax(iData[AttackerName]), g_szName[iAttacker])
    
copy(iData[VictimName], charsmax(iData[VictimName]), g_szName[iVictim])
    
iData[DamageGiven] = floatround(flDamage)

    
ArrayPushArray(g_aPlayerStatsiData

Debug messages order and informations:
PHP Code:

First shot to a victim:
To: [19] ~ LKtRN

called

else 
2

Second shot to the first victim
:
To: [43] ~ LKtRN
To
: [24] ~ LKtRN

called
:
if 
1
if 2LKtRN LKtRN
if 3
else 2

Third shot to other victim
:
To: [43] ~ LKtRN
To
: [24] ~ LKtRN
To
: [38] ~ FnRQavErAKxInEhrfp
To
: [38] ~ FnRQavErAKxInEhrfp

called
:
if 
1
if 2LKtRN FnRQavErAKxInEhrfp
else 1
else 


Natsheh 07-13-2021 13:51

Re: Store Attacker damage in dinamic array for every victim
 
use tries it will make your life much easiers than dynamic arrays for this kind purpose since you're seeking using strings.

also if you're using an array for a limited size such as max players you can make a 3d array it will be better.

PHP Code:

enum _:PlayerStats
{
    
AttackerName[MAX_NAME_LENGTH],
    
DamageGiven,
    
DamageReceived
}

new 
g_victim_stats[33][33][PlayerStats]

g_victim_statsVICTIM_ID ] [ ATTACKER_ID ] [ PlayerStats 


Shadows Adi 07-14-2021 03:09

Re: Store Attacker damage in dinamic array for every victim
 
I will try and tries way.

Quote:

Originally Posted by Natsheh (Post 2752744)
PHP Code:

new g_victim_stats[33][33][PlayerStats]

g_victim_statsVICTIM_ID ] [ ATTACKER_ID ] [ PlayerStats 


This won't work, because i need to know the victim's ID too, and i can't retrieve that using a loop through players using get_players() native.

Bugsy 07-14-2021 07:45

Re: Store Attacker damage in dinamic array for every victim
 
I don't understand why the 3d array approach wouldn't work. You would always pass the victim, attacker, and damage amount, so you will have all data. Please better explain where your hiccup is so we can help with that.

Player id 3 attacks player id 5 with 20 dmg
g_victim_stats[ 5 ][ 3 ][ DamageReceived ] = 20
g_victim_stats[ 3 ][ 5 ][ DamageGiven ] = 20

Natsheh 07-15-2021 09:01

Re: Store Attacker damage in dinamic array for every victim
 
Why it won't work ?

What do you mean you need to know the victims id, what is the function are you using?

Also it would be better if youve explained what are you trying to do.

+ARUKARI- 07-15-2021 20:31

Re: Store Attacker damage in dinamic array for every victim
 
Does this work?
My understanding is that -1 is always returned.
Code:
 new item = ArrayFindString(g_aPlayerStats, g_szName[iAttacker])

Bugsy 07-15-2021 22:31

Re: Store Attacker damage in dinamic array for every victim
 
Again, I think the 3d array solution is fine. Why do you want the data stored in the array and then to find said data based on the player name that you search.

Please explain what you are trying to accomplish, I'm pretty sure you are overthinking it, or just thinking about it the wrong way. PM if you want.

Shadows Adi 07-16-2021 03:39

Re: Store Attacker damage in dinamic array for every victim
 
I will try later the 3D array too, thank you.

I need the Victim's ID, because this function will used in Round End Event, so I need to loop through player entities to get valid indexes.

Quote:

Originally Posted by +ARUKARI- (Post 2752909)
Does this work?
My understanding is that -1 is always returned.
Code:
 new item = ArrayFindString(g_aPlayerStats, g_szName[iAttacker])

Yes, it works somehow, because I push the attacker's name too, which is a string:
Code:
 copy(iData[AttackerName], charsmax(iData[AttackerName]), g_szName[iAttacker])

Bugsy 07-16-2021 10:35

Re: Store Attacker damage in dinamic array for every victim
 
Is this what you're trying to do?
PHP Code:


#include <amxmodx>
#include <hamsandwich>
#include <fakemeta>

new const Version[] = "0.1";

#define MAX_PLAYERS 32
#define MAX_NAME_LENGTH 32

enum PlayerStats
{
    
DamageGiven,
    
DamageReceived
}

new 
g_szNameMAX_PLAYERS ][ MAX_NAME_LENGTH ];
new 
g_pzStatsMAX_PLAYERS ][ MAX_PLAYERS ][ PlayerStats ];

public 
plugin_init() 
{
    
register_plugin"Round Damage" Version "bugsy" );
    
    
RegisterHamHam_TakeDamage "player" "HamTakeDamage" true );
    
register_logevent"RoundEnd" "1=Round_End" ); 
}

public 
client_putinserverid )
{
    
get_user_nameid g_szNameid ] , charsmaxg_szName[] ) );
}

public 
HamTakeDamagevictim inflictor attacker Float:fDamage bitDamage 
{     
    new 
iActualDamage pevvictim pev_dmg_take ); 
    
    
g_pzStatsvictim ][ attacker ][ DamageReceived ] += iActualDamage;
    
g_pzStatsattacker ][ victim ][ DamageGiven ] += iActualDamage;
}

public 
RoundEnd()
{
    new 
iPlayers32 ] , iNum iAttackerPlayer iVictimPlayer iTotalDamage iSingleDamage;
    new 
szHUD512 ] , iPos;
    
    
get_playersiPlayers iNum );
    
    for ( new 
iNum i++ )
    {
        
iAttackerPlayer iPlayers];
        
        
iPos 0;
        
iTotalDamage 0;
        
        for ( new 
iNum p++ )
        {
            
iVictimPlayer iPlayers];
            
            if ( 
!= )
            {
                
iSingleDamage g_pzStatsiAttackerPlayer ][ iVictimPlayer ][ DamageGiven ];
                
                if ( 
iSingleDamage )
                {
                    
iTotalDamage += iSingleDamage;
                    
iPos += formatexszHUDiPos ] , charsmaxszHUD ) - iPos "%s - %d damage^n" g_szNameiVictimPlayer ] , iSingleDamage );
                }
            }
        }

        if ( 
iTotalDamage )
        {
            
iPos += formatexszHUDiPos ] , charsmaxszHUD ) - iPos "^n^nTotal Damage - %d" iTotalDamage );
            
set_hudmessage255 0.050.35 0.0 5.0 );
            
show_hudmessageiAttackerPlayer szHUD );
        }    
    }

    
ClearArray();
}

ClearArray()
{
    for ( new 
<= MAX_PLAYERS i++ )
    {
        for ( new 
<= MAX_PLAYERS p++ )
        {
            
g_pzStats][ ][ DamageGiven ] = 0;
            
g_pzStats][ ][ DamageReceived ] = 0;
        }
    }



Shadows Adi 07-17-2021 03:46

Re: Store Attacker damage in dinamic array for every victim
 
Quote:

Originally Posted by Bugsy (Post 2752933)
Is this what you're trying to do?
Code:
#include <amxmodx> #include <hamsandwich> #include <fakemeta> new const Version[] = "0.1"; #define MAX_PLAYERS 32 #define MAX_NAME_LENGTH 32 enum PlayerStats {     DamageGiven,     DamageReceived } new g_szName[ MAX_PLAYERS + 1 ][ MAX_NAME_LENGTH ]; new g_pzStats[ MAX_PLAYERS + 1 ][ MAX_PLAYERS + 1 ][ PlayerStats ]; public plugin_init() {     register_plugin( "Round Damage" , Version , "bugsy" );         RegisterHam( Ham_TakeDamage , "player" , "HamTakeDamage" , true );     register_logevent( "RoundEnd" , 2 , "1=Round_End" ); } public client_putinserver( id ) {     get_user_name( id , g_szName[ id ] , charsmax( g_szName[] ) ); } public HamTakeDamage( victim , inflictor , attacker , Float:fDamage , bitDamage ) {         new iActualDamage = pev( victim , pev_dmg_take );         g_pzStats[ victim ][ attacker ][ DamageReceived ] += iActualDamage;     g_pzStats[ attacker ][ victim ][ DamageGiven ] += iActualDamage; } public RoundEnd() {     new iPlayers[ 32 ] , iNum , iAttackerPlayer , iVictimPlayer , iTotalDamage , iSingleDamage;     new szHUD[ 512 ] , iPos;         get_players( iPlayers , iNum );         for ( new i = 0 ; i < iNum ; i++ )     {         iAttackerPlayer = iPlayers[ i ];                 iPos = 0;         iTotalDamage = 0;                 for ( new p = 0 ; p < iNum ; p++ )         {             iVictimPlayer = iPlayers[ p ];                         if ( i != p )             {                 iSingleDamage = g_pzStats[ iAttackerPlayer ][ iVictimPlayer ][ DamageGiven ];                                 if ( iSingleDamage > 0 )                 {                     iTotalDamage += iSingleDamage;                     iPos += formatex( szHUD[ iPos ] , charsmax( szHUD ) - iPos , "%s - %d damage^n" , g_szName[ iVictimPlayer ] , iSingleDamage );                 }             }         }                 if ( iTotalDamage > 0 )         {             iPos += formatex( szHUD[ iPos ] , charsmax( szHUD ) - iPos , "^n^nTotal Damage - %d" , iTotalDamage );             set_hudmessage( 0 , 255 , 0 , 0.05, 0.35 , 0 , 0.0 , 5.0 );             show_hudmessage( iAttackerPlayer , szHUD );         }       } }

Yes, something like that.
So it will loop through all entries from "p" loop first, then will continue the "i" loop, isn't that?


All times are GMT -4. The time now is 02:30.

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