AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting (https://forums.alliedmods.net/forumdisplay.php?f=107)
-   -   Solved Get players medigun TF2 (https://forums.alliedmods.net/showthread.php?t=334321)

Cieniu97 09-15-2021 19:26

Get players medigun TF2
 
Intro:
Hello, I'm new here :>
Recently I started working on plugin for TF2 that logs events. I am completely new to sourcemod. Could use some help.

Context:
There is an event in TF2 called "player_chargedeployed".
It launches as it states when uber charge is deployed. It provides us with two values userid and targetid.

Question:
I would like to know if one could get type of uber used based on that information. Stock, kritz, quick-fix, vax.

My attempt:

PHP Code:

public Action Event_ChargeDeployed(Event event, const char[] namebool dontBroadcast)
{
        
    
char userid[64];
    
userid getSteam64(event.GetInt("userid"));
    
    
int clientIndex GetClientOfUserId(event.GetInt("userid"));
    
char typeOfUber[32];
    
GetClientWeapon(clientIndextypeOfUbersizeof(typeOfUber));
    
    
char targetid[64];
    
targetid getSteam64(event.GetInt("targetid"));
        
    
PrintToChatAll("player_chargedeployed,userid:%s,targetid:%s,typeofuber:%s"useridtargetidtypeOfUber);    


My output: tf_weapon_medigun
Expected output: name of specific medicgun for exampl tf_weapon_vaccinator

Outro:
If I broke any of your forum standards plz let me know, happy to improve!

PC Gamer 09-16-2021 01:55

Re: Get players medigun TF2
 
Welcome Cieniu97! You posted in the correct place for a scripting question.

Here's what I came up with for you. I tested it and it works. Maybe someone more experienced than I can chime in if there is a better way to do it. The stocks at the bottom of the code originated from Chdata. They're very useful:
PHP Code:

#include <sourcemod>
#include <tf2_stocks>

#pragma semicolon 1
#pragma newdecls required

#define PLUGIN_VERSION "1.0"

public Plugin myinfo =
{
    
name "[TF2] Display Medigun Usage",
    
author "Cieniu97",
    
description "Display Medigun type in chat when ubercharging",
    
version PLUGIN_VERSION,
    
url "www.sourcemod.net"
}

public 
void OnPluginStart()
{
    
HookEvent("player_chargedeployed"Event_ChargeDeployed);    
}

public 
Action Event_ChargeDeployed(Event event, const char[] namebool dontBroadcast)
{
    
int medic GetClientOfUserId(GetEventInt(event"userid"));
    if (
IsValidClient(medic) && TF2_GetPlayerClass(medic) == TFClass_Medic)
    {        
        
int patient GetClientOfUserId(GetEventInt(event"targetid"));
        
        
int weaponid GetIndexOfWeaponSlot(medic1);

        
char weapon[64];
        
        switch (
weaponid)
        {
        case 
29:
            {
                
weapon "Stock Medi Gun";
            }
        case 
211:
            {
                
weapon "Strange/Renamed Medi Gun";
            }            
        case 
35:
            {
                
weapon "The Kritzkrieg";
            }
        case 
411:
            {
                
weapon "The Quick-Fix";
            }
        case 
663:
            {
                
weapon "Festive Medi Gun";
            }
        case 
796:
            {
                
weapon "Silver Botkiller Medi Gun Mk.I";
            }
        case 
805:
            {
                
weapon "Gold Botkiller Medi Gun Mk.I";
            }
        case 
885:
            {
                
weapon "Rust Botkiller Medi Gun Mk.I";
            }
        case 
894:
            {
                
weapon "Blood Botkiller Medi Gun Mk.I";
            }
        case 
903:
            {
                
weapon "Carbonado Botkiller Medi Gun Mk.I";
            }
        case 
912:
            {
                
weapon "Diamond Botkiller Medi Gun Mk.I";
            }
        case 
961:
            {
                
weapon "Silver Botkiller Medi Gun Mk.II";
            }
        case 
970:
            {
                
weapon "Gold Botkiller Medi Gun Mk.II";
            }            
        case 
998:
            {
                
weapon "The Vaccinator";
            }
        case 
15008:
            {
                
weapon "Masked Mender";
            }
        case 
15010:
            {
                
weapon "Wrapped Reviver";
            }
        case 
15025:
            {
                
weapon "Reclaimed Reanimator";
            }
        case 
15039:
            {
                
weapon "Civil Servant";
            }
        case 
15050:
            {
                
weapon "Spark of Life";
            }
        case 
15078:
            {
                
weapon "Wildwood";
            }
        case 
15097:
            {
                
weapon "Flower Power";
            }
        case 
15121:
            {
                
weapon "Dressed To Kill";
            }
        case 
15122:
            {
                
weapon "High Roller's";
            }
        case 
15123:
            {
                
weapon "Coffin Nail";
            }            
        case 
15145:
            {
                
weapon "Blitzkrieg";
            }
        case 
15146:
            {
                
weapon "Corsair";
            }
        default:
            {
                
weapon "Unknown Medi Gun";
            }
        }
        
        
PrintToChatAll("Medic %N Ubercharged %N Using %s"medicpatientweapon);
    }
}  

stock bool IsValidClient(int clientbool nobots true)

    if (
client <= || client MaxClients)
    {
        return 
false
    }
    return 
IsClientInGame(client); 
}  

stock int GetIndexOfWeaponSlot(int iClientint iSlot)
{
    return 
GetWeaponIndex(GetPlayerWeaponSlot(iClientiSlot));
}

stock int GetClientCloakIndex(int iClient)
{
    return 
GetWeaponIndex(GetPlayerWeaponSlot(iClientTFWeaponSlot_Watch));
}

stock int GetWeaponIndex(int iWeapon)
{
    return 
IsValidEnt(iWeapon) ? GetEntProp(iWeaponProp_Send"m_iItemDefinitionIndex"):-1;
}

stock int GetActiveIndex(int iClient)
{
    return 
GetWeaponIndex(GetEntPropEnt(iClientProp_Send"m_hActiveWeapon"));
}

stock bool IsWeaponSlotActive(int iClientint iSlot)
{
    return 
GetPlayerWeaponSlot(iClientiSlot) == GetEntPropEnt(iClientProp_Send"m_hActiveWeapon");
}

stock bool IsIndexActive(int iClientint iIndex)
{
    return 
iIndex == GetWeaponIndex(GetEntPropEnt(iClientProp_Send"m_hActiveWeapon"));
}

stock bool IsSlotIndex(int iClientint iSlotint iIndex)
{
    return 
iIndex == GetIndexOfWeaponSlot(iClientiSlot);
}

stock bool IsValidEnt(int iEnt)
{
    return 
iEnt MaxClients && IsValidEntity(iEnt);
}

stock int GetSlotFromPlayerWeapon(int iClientint iWeapon)
{
    for (new 
0<= 5i++)
    {
        if (
iWeapon == GetPlayerWeaponSlot(iClienti))
        {
            return 
i;
        }
    }
    return -
1;



Cieniu97 09-16-2021 07:24

Re: Get players medigun TF2
 
Thanks! That works excellent. You are awesome.
I just have few fallow up questions while we are on it.

Are there some advantages of using this
PHP Code:

GetEventInt(event"userid"

over this
PHP Code:

event.GetInt("userid"


And is that a crime over humanity if I simplify the whole thing to this?

PHP Code:

int weaponid GetEntProp(GetPlayerWeaponSlot(medic1), Prop_Send"m_iItemDefinitionIndex"); 

It just seems like a massive overkill to validate it on every possible step.
Plugin gonna be used in very specific environment. Competitive matches to be precise.
And when event happens we know that medic used this, so for example why verify if that was medic who called it?

heavyisgps 09-16-2021 18:16

Re: Get players medigun TF2
 
PHP Code:


#define KRITZKRIEG 35
#define QUICKFIX 411
#define VACCINATOR 998
#define VACCINATOR_POINT_NUMBER 4 //Offset with 1 since count starts at 0, 4 vaccinators gives 1 point
public Action:Event_Charge_Deployed(Handle:event, const String:name[], bool:dontBroadcast)
{
    new 
client GetClientOfUserId(GetEventInt(event"userid"));
    
//LogPlayerEvent(client, "triggered", "a charge was deployed");
    
    
switch(playerLoadout[client][1][0])
        {
        case 
VACCINATOR:
            {
                if(
vacStorage[client] == VACCINATOR_POINT_NUMBER)
                {
                
LogPlayerEvent(client"triggered""vaccinator");
                
vacStorage[client] = 0;
                }else
                
vacStorage[client]++;
                
            }
        case 
KRITZKRIEG:
            {
                
LogPlayerEvent(client"triggered""kritz");
            }
        case 
QUICKFIX:
            {
                
LogPlayerEvent(client"triggered""quickfix");
            }
        default:
            {
                
LogPlayerEvent(client"triggered""uber");
            }
    }



This is a snippet from the superlogs tf2, uses old syntax, but it's failr short and you can use what others have posted here to make it work

The reason for vaccinator is that every vaccination provides 1 charge deployed, but after 4 vaccination deploys, a player is awarded 1 point.

The LogPlayerEvent requires loghelper.inc include file to compile.

PC Gamer 09-17-2021 15:10

Re: Get players medigun TF2
 
Cieniu97, you are correct on all counts. I updated and shared the weapon stocks from Chdata because you may find them useful.

Good luck with your project. It sounds interesting.

Naydef 09-18-2021 06:58

Re: Get players medigun TF2
 
So far the answers above depend on the item definition index and don't take into account that serve mods (ex. Freak Fortress 2) can change the charge type or a game update could add more weapon skins.

The following example code gets the charge type by reading attributes and it's shorter (depends on nosoop's TF2Attributes):
PHP Code:

#include <sourcemod>
#include <sdktools>
#include <tf2attributes>
#include <tf2_stocks>

#pragma semicolon 1
#pragma newdecls required

public Plugin myinfo = {
    
name        "Get Uber Type on Deploy",
    
version     "0.0.0"
};

public 
void OnPluginStart()
{
    
HookEvent("player_chargedeployed"Event_ChargeDeployed);    
}

enum
{
    
UBER,
    
CRITS,
    
QUICKFIX,
    
VAX
}

public 
Action Event_ChargeDeployed(Event event, const char[] namebool dontBroadcast)
{
    
int client GetClientOfUserId(GetEventInt(event"userid"));
    if(
IsValidClient(client))
    {
        
int weapon GetPlayerWeaponSlot(clientTFWeaponSlot_Secondary);
        if(
IsValidEntity(weapon))
        {
            switch(
TF2Attrib_HookValueInt(0"set_charge_type"weapon))
            {
                case 
UBER:
                {
                    
PrintToChatAll("%n deployed UBER"client);
                }
                
                case 
CRITS:
                {
                    
PrintToChatAll("%n deployed CRITS"client);
                }
                
                case 
QUICKFIX:
                {
                    
PrintToChatAll("%n deployed QUICKFIX"client);
                }
                
                case 
VAX:
                {
                    
PrintToChatAll("%n deployed VAX"client);
                }
            }
        }
    }
}

stock bool IsValidClient(int clientbool nobots true)

    if (
client <= || client MaxClients)
    {
        return 
false
    }
    return 
IsClientInGame(client); 


This response answers the original question.

Cieniu97 10-01-2021 11:19

Re: Get players medigun TF2
 
I ended up using PC Gamer suggestion.

As for heavyisgps answer. The old syntax doesnt seem to work in spEdit compiler.

Naydef, your code looks super slick! But I dont understand why it works ;) and using that without knowledge would be risky for me. I still struggle with understanding enums.
For example in PC Gamer solution there is switch statment that takes from tf2stocks.inc.
Idk why wouldn't I be able to just get the name from that data structure. In other languages its easy. Just tf2weapons[x] would return the name. Do I have to make switch statments for each enum in tf2 hahah?

PS: How do I mark it as solved?

PC Gamer 10-01-2021 15:56

Re: Get players medigun TF2
 
I'm glad we were able to help, and I'm glad other people added their code. That's how we all get better at coding.

Part of reason for different answers in this thread is that you asked for two different things. In the text of your original post you asked for the type of uber used, which is what Naydef brilliantly provided. You also stated that your expected output was the name of the specific medigun used, which is what I provided.

In the end, I also learned something new from this thread so I thank people for sharing.

To mark a post as 'solved', as stated by Maxximou5 in a post somewhere:

At the beginning of the thread:
1. Click the edit button (top right of post, next to quote)
2. Click on "go advanced" (bottom right of edited post)
3. At the top, under reason for editing, select TITLE you will see "no prefix", select [Solved]


All times are GMT -4. The time now is 11:55.

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