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

Solved [L4D] Count witch entities


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Omixsat
Member
Join Date: Jul 2022
Old 09-06-2022 , 15:14   [L4D] Count witch entities
Reply With Quote #1

I've been trying to place currently spawned witch entities in an index so I can count them on the fly. It's supposed to be for a specific purpose other than counting that I won't disclose yet. I'm just not sure if my code is correct or optimal. Please let me know if there's an issue.

PHP Code:
#include <sourcemod>
#define MAXEDICTS 2048
#define DEBUG 1

public Plugin myinfo 
{
    
name "[L4D] Witch Counter",
    
author "Omixsat",
    
description "Count witch entities",
    
version "1.0",
    
url ""
}

int TotalWitchEntCount[MAXEDICTS+1] = 0;
int WitchesStartledCount 0;
int WitchID 0;

public 
void OnPluginStart()
{
    
HookEvent("player_death"Event_PlayerDeathEventHookMode_PostNoCopy);
    
HookEvent("witch_harasser_set"Event_WitchStartledEventHookMode_PostNoCopy);
    
HookEvent("witch_spawn"Event_WitchSpawnEventHookMode_PostNoCopy);
}

public 
void OnMapStart()
{
    
WitchesStartledCount 0;
    
TotalWitchEntCount 0;
}

public 
void OnMapEnd()
{
    
WitchesStartledCount 0;
    
TotalWitchEntCount 0;
}

public 
void OnEntityDestroyed(int entity)
{
    
int DestroyedEntity EntIndexToEntRef(entity);
    
char EntityClass[32];
    
GetEdictClassname(DestroyedEntityEntityClasssizeof(EntityClass));
    if(
StrEqual(EntityClass"witch"))
    {
        
int EntIndex 0;
    
        for(
int eWitch 1eWitch <= WitchesStartledCounteWitch++)
        {
            
EntIndex TotalWitchEntCount[eWitch]; //EntIndex is referring to a specific witch ID
            
if (EntIndex == DestroyedEntity)
            {
                
WitchesStartledCount--;
                
RebuildWitchIndex(); // Check for witches
                #if DEBUG
                    
PrintToChat("Witch ID %i has despawned"DestroyedEntity);
                
#endif
            
}
        }
    }
}

public 
Action Event_PlayerDeath(Event event, const char[] namebool dontBroadcast)
{
    
int DeadWitch GetClientOfUserId(event.GetInt("entityid"));
    
    
char classname[32];
    
GetEdictClassname(DeadWitchclassnamesizeof(classname));
    if(
StrEqual(classname"witch"))
    {
        
int EntIndex 0;
    
        for(
int eWitch 1eWitch <= WitchesStartledCounteWitch++)
        {
            
EntIndex TotalWitchEntCount[eWitch]; //EntIndex is referring to a specific witch ID
            
if (EntIndex == DeadWitch)
            {
                
WitchesStartledCount--;
                
RebuildWitchIndex(); // Check for witches
            
}
        }
    }
}


public 
Action Event_WitchSpawn(Event eventchar event_name[], bool dontBroadcast)
{
    
RebuildWitchIndex();
}

public 
Action Event_WitchStartled(Event eventchar event_name[], bool dontBroadcast)
{
    
int WitchIndex GetEventInt(event"witchid");  
    
WitchID EntIndexToEntRef(WitchIndex);
    for(
int i 0<= MAXEDICTSi++)
    {
        if(
IsValidEdict(i) && IsValidEntity(i))
        {
            
char classname[32];
            
GetEdictClassname(iclassnamesizeof(classname));
            if(
StrEqual(classname"witch"))
            {
                
//TotalWitchEntCount++;
                
WitchesStartledCount++;
                
TotalWitchEntCount[WitchesStartledCount] = WitchID;
            }
        }
    }
    
    
#if DEBUG
        
PrintToChat("Witch ID %i has been startled"WitchID);
        
PrintToChat("Total number of witch entities %i "TotalWitchEntCount);
        
PrintToChat("Total number of startled witches at this time %i "WitchesStartledCount);
    
#endif
}

stock RebuildWitchIndex()
{
    
TotalWitchEntCount 0;
    for(
int i 0<= MAXEDICTSi++)
    {
        if(
IsValidEdict(i) && IsValidEntity(i))
        {
            
char classname[32];
            
GetEdictClassname(iclassnamesizeof(classname));
            if(
StrEqual(classname"witch"))
            {
                
TotalWitchEntCount++;
            }
        }
    }

There might be an issue where if any player fails to kill a startled witch and she retreats until eventually she despawns then I'm supposed to remove that specific entity from the startled witch count.

I still get an error on lines 84 and 89

Code:
Error 183: brackets after variable name indicates a fixed-size array, but size is missing or not constant
Attached Files
File Type: sp Get Plugin or Get Source (l4d_witchcounter.sp - 21 views - 3.6 KB)
__________________
My Plug-Ins
Plug-in lookup
My Forks
[1] [2]

Last edited by Omixsat; 09-13-2022 at 08:23. Reason: Attached the file
Omixsat is offline
alasfourom
Senior Member
Join Date: Feb 2022
Location: Saudi Arabia
Old 09-06-2022 , 18:49   Re: [L4D] Count witch entities
Reply With Quote #2

I'm not sure if that similar to what u need,
basically it will count spawned witches > sm_witch_counts
you can also type > sm_witch_stats > this will display to you total witches spawned + all players who killed a witch + who startled a witch

Not all witches who are killed means they startled, cuz u can crawn them

PHP Code:
#include <sourcemod>
#include <sdktools>

#pragma semicolon 1
#pragma newdecls required
#define PLUGIN_VERSION "1.0"

int iWitch_KillCount [MAXPLAYERS+1];
int iWitch_StartledCount [MAXPLAYERS+1];
int iWitch_SpawnCount;

public 
void OnPluginStart() 
{
    
HookEvent("round_start"Event_RoundStart);
    
HookEvent("witch_killed"Event_OnWitchDeath);
    
HookEvent("witch_spawn"Event_OnWitchSpawn);
    
HookEvent("witch_harasser_set"Event_OnWitchStartled);
    
    
RegConsoleCmd("sm_witch_stats"Command_Witch_Stats"Display Witch Info");
    
RegConsoleCmd("sm_witch_counts"Command_Witch_Counts"Display Witch Info");
}

void Event_RoundStart(Event event, const char[] namebool dontBroadcast)
{
    for (
int i 1<= MaxClientsi++)
    {
        
iWitch_KillCount [i] = 0;
        
iWitch_StartledCount [i] = 0;
    }
    
    
iWitch_SpawnCount 0;
}

public 
Action Command_Witch_Stats(int clientint args)
{
    
WitchStats_Display();
    return 
Plugin_Handled;
}

public 
Action Command_Witch_Counts(int clientint args)
{
    
PrintToChat(client"\x04Total Witches Spawned: \x05%d"iWitch_SpawnCount);
    return 
Plugin_Handled;
}

void Event_OnWitchDeath(Event event, const char[] namebool dontBroadcast)
{
    
int client GetClientOfUserId(event.GetInt("userid"));
    if (!
client || !IsClientInGame(client)) return;
    
    if(
GetClientTeam(client) == 2)
    {
        
iWitch_KillCount[client]++;
        if (
iWitch_KillCount[client] > 0PrintHintText(client"Witch Killed: %d"iWitch_KillCount[client]);
    }
}

void Event_OnWitchSpawn(Event event, const char[] namebool dontBroadcast)
{
    
iWitch_SpawnCount++;
    if (
iWitch_SpawnCount 0PrintHintTextToAll("Witch Spawned: %d"iWitch_SpawnCount);
}

void Event_OnWitchStartled(Event event, const char[] namebool dontBroadcast)
{
    
int client GetClientOfUserId(event.GetInt("userid"));
    if (!
client || !IsClientInGame(client)) return;
    
    if(
GetClientTeam(client) == 2)
    {
        
iWitch_StartledCount[client]++;
        if (
iWitch_StartledCount[client] > 0PrintHintText(client"Witch Startled: %d"iWitch_StartledCount[client]);
    }
}

void WitchStats_Display()
{
    
int client;
    
int players 0;
    
int[] players_clients = new int[MaxClients+1];
    
int iWitch_KillCount_MVPiWitch_StartledCount_MVP;
    
    
PrintToChatAll("\x04Total Witches Spawned: \x05%d"iWitch_SpawnCount);
    
    for (
client 1client <= MaxClientsclient++)
    {
        if (!
IsClientInGame(client) || GetClientTeam(client) == 3) continue;
        
players_clients[players] = client;
        
players++;
    }
    
    for (
int i 0playersi++)
    {
        
client players_clients [i];
        
iWitch_KillCount_MVP iWitch_KillCount    [client];
        
iWitch_StartledCount_MVP iWitch_StartledCount[client];
        
        
PrintToChatAll("\x03%N: \x04Witch Kills \x01%d | \x04Witch Startled \x01%d"clientiWitch_KillCount_MVPiWitch_StartledCount_MVP);
    }

__________________

Last edited by alasfourom; 09-06-2022 at 19:06. Reason: simple mistake
alasfourom is offline
Omixsat
Member
Join Date: Jul 2022
Old 09-06-2022 , 19:08   Re: [L4D] Count witch entities
Reply With Quote #3

Quote:
Originally Posted by alasfourom View Post
Not all witches who are killed means they startled, cuz u can crawn them
That's a good point about the witch being crowned, but the primary concern is to get all the ID's of the active(not crowned) startled witches hence the reason why I had to place them in an index. If that specific entity is destroyed(despawned) then I'd have to remove that specific entity from the list.

I also didn't know the ff. exists:
Code:
sm_witch_counts
sm_witch_stats
Thanks for the interesting info though
__________________
My Plug-Ins
Plug-in lookup
My Forks
[1] [2]

Last edited by Omixsat; 09-06-2022 at 19:12.
Omixsat is offline
alasfourom
Senior Member
Join Date: Feb 2022
Location: Saudi Arabia
Old 09-06-2022 , 19:16   Re: [L4D] Count witch entities
Reply With Quote #4

I tried to help you based on the snippet you shared

Maybe other ppl can help you more

Good luck
__________________

Last edited by alasfourom; 09-06-2022 at 19:21.
alasfourom is offline
Bacardi
Veteran Member
Join Date: Jan 2010
Location: mom's basement
Old 09-07-2022 , 12:00   Re: [L4D] Count witch entities
Reply With Quote #5

witch entities not exist on map until those spawn.
- Or I have missed something ?

You can use FindEntityByClassname to get witch entity if it exist.

You could try use dynamic array for store entities ref ids.
And store lot of other things, example using array.


Here test plugin.
It store witches which have spawned, woked and killed.
It store some extra info also.

to quick check array, use command sm_test and read console
to clear array, sm_test clear
example
__________________
Do not Private Message @me

Last edited by Bacardi; 09-07-2022 at 12:03. Reason: forget use "oneshot" parameter
Bacardi is offline
Omixsat
Member
Join Date: Jul 2022
Old 09-07-2022 , 16:15   Re: [L4D] Count witch entities
Reply With Quote #6

@Bacardi: That's actually close to what I'm trying to achieve. Thank you for the test script I'll study it along with another plugin which also does something similar.
__________________
My Plug-Ins
Plug-in lookup
My Forks
[1] [2]
Omixsat is offline
Omixsat
Member
Join Date: Jul 2022
Old 09-13-2022 , 05:07   Re: [L4D] Count witch entities
Reply With Quote #7

Okay... I'm ALMOST there. I'm now having issues with the argument type mismatch.

Lines 108, 145, and 146 are having errors.

Code:
error 035: argument type mismatch (argument 1)
PHP Code:
/*
    "witch_harasser_set"
    {
        "userid"    "short"        // Player who woke up the witch
        "witchid"    "long"        // Entindex of witch woken up
        "first"        "bool"        // First time the witch set a harasser
    }
    
    "witch_spawn"
    {
        "witchid"    "long"        // Entindex of witch spawning right now.
    }

    "witch_killed"
    {
        "userid"    "short"        // Player who killed the witch
        "witchid"    "long"        // Entindex of witch that was killed.
        "oneshot"    "bool"      // TRUE if the Witch was killed with one shot
    }
    "zombie_ignited"
    {
        "userid"        "short"  // player who caused ignition
        "gender"        "short"     // gender (type) of the infected
        "entityid"        "long"     // entity ID of Tank
        "victimname"    "string" // "Witch", "Tank", "Hunter", "Smoker", or "Infected"
        "fire_ammo"        "bool"     // true if incendiary ammo was used
    }
*/

#pragma semicolon 1
#pragma newdecls required
#include <sourcemod>
#include <sdktools>
#define PLUGIN_VERSION "0.2"
#define DEBUG 1

enum struct WitchInfo
{
    
int entref//block 0
    
bool IsRage//block 1
    
bool oneshot;
}

char witcheventnames[][] = {
    
"witch_harasser_set",
    
"witch_spawn",
    
"witch_killed"
};

ConVar hWitchDangerDistance;
ArrayList ListOWitches;

public 
Plugin myinfo 
{
    
name "[L4D] Witch Counter",
    
author "Omixsat,Bacardi",
    
description "Count witch entities and print their information",
    
version "1.0",
    
url ""
}

public 
void OnPluginStart()
{
    for(
int x 0sizeof(witcheventnames); x++)
        
HookEventEx(witcheventnames[x], witchevents);

    
ListOWitches = new ArrayList(3);

    
// if plugin is loaded manually, look all spawned witch entities on map
    
    
int ent = -1;
    
WitchInfo witch// sugar coated array

    
while((ent FindEntityByClassname(ent"witch")) != -1)
    {
        
witch.entref EntIndexToEntRef(ent);
        
ListOWitches.PushArray(witch);
    }

}

public 
void OnPluginEnd()
{

    
ListOWitches.Clear();
}

public 
void OnMapEnd()
{
    
ListOWitches.Clear();
}

public 
void OnEntityDestroyed(int entity)
{
    if(!
IsValidEntity(entity))
        return;
    
char classname[8];
    
GetEntityClassname(entity,classname,sizeof(classname));
    if(
StrEqual(classname"witch"))
    {
        
int WitchList ListOWitches.Length;

        for(
int w 0WitchListw++)
        {
            
int ent EntRefToEntIndex(ListOWitches.Get(w,0));
            if(
IsValidEntity(ent))
            {
                
PrintToChat("Witch ID %i has been removed from WitchList"ent);
                
ListOWitches.Erase(w); // = remove witch from list
            
}
        }
    }
}

public 
void witchevents(Event event, const char[] namebool dontBroadcast)
{
    
int entref EntIndexToEntRef(event.GetInt("witchid"0));
    
//int userid = event.GetInt("userid", 0);

    // Try find entref value from block 0, "entref"
    
int index ListOWitches.FindValue(entref0);


    if(
StrEqual(name"witch_spawn"))
    {
        
// This should not happen, same entity spawn twice
        
if(index != -1)
            return;

        
WitchInfo witch// sugar coated array

        
witch.entref EntIndexToEntRef(event.GetInt("witchid"));

        
ListOWitches.PushArray(witch);
    }
    else if(
StrEqual(name"witch_harasser_set"))
    {
        if(
index != -1)
        {
            
// store userid value to block 2, "harasser"
            //ListOWitches.Set(index, userid, 2); //no need

            // woked block 1
            
ListOWitches.Set(indextrue1);
            
PrintToChat("Witch ID %i Rage status: %i",EntRefToEntIndex(index),ListOWitches.Get(index,1));
            
PrintToChat("Witch ID via ArrayList is %i"EntRefToEntIndex(index));
            
//No need to look for m_rage or m_wanderrage 
        
}
    }
    else if(
StrEqual(name"witch_killed"))
    {
        if(
index != -1)
        {
            
//ListOWitches.Set(index, userid, 3); //killer
            
ListOWitches.Set(indexevent.GetBool("oneshot"), 2); //oneshot
        
}
    }

Attached Files
File Type: sp Get Plugin or Get Source (l4d_witchcounter.sp - 16 views - 3.6 KB)
__________________
My Plug-Ins
Plug-in lookup
My Forks
[1] [2]

Last edited by Omixsat; 09-13-2022 at 05:20. Reason: updated with code
Omixsat is offline
Silvers
SourceMod Plugin Approver
Join Date: Aug 2010
Location: SpaceX
Old 09-13-2022 , 06:20   Re: [L4D] Count witch entities
Reply With Quote #8

PrintToChat wants a client index to print to a specific person. You probably want PrintToChatAll instead. Replace PrintToChat with PrintToChatAll.

I think the events counting using "witch_spawn" and "witch_killed" for this is a bad idea since you could delete a Witch without it ever being killed, so the numbers would then be incorrect. I think you should just use FindEntityByClassname and count it that way, that method is fast enough.
__________________
Silvers is offline
Omixsat
Member
Join Date: Jul 2022
Old 09-13-2022 , 08:23   Re: [L4D] Count witch entities
Reply With Quote #9

Quote:
Originally Posted by Silvers View Post
PrintToChat wants a client index to print to a specific person. You probably want PrintToChatAll instead. Replace PrintToChat with PrintToChatAll.

I think the events counting using "witch_spawn" and "witch_killed" for this is a bad idea since you could delete a Witch without it ever being killed, so the numbers would then be incorrect. I think you should just use FindEntityByClassname and count it that way, that method is fast enough.
Thanks for the tip, Silvers . I might need to set a timer if that's the case. A check has to be implemented on OnEntityDestroyed
__________________
My Plug-Ins
Plug-in lookup
My Forks
[1] [2]
Omixsat is offline
Reply



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


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