AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting (https://forums.alliedmods.net/forumdisplay.php?f=107)
-   -   Custom Minigun Property (https://forums.alliedmods.net/showthread.php?t=310011)

dacisco 08-15-2018 16:17

Custom Minigun Property
 
Hi, I want to create a simple script that applies the "TFCond_SpeedBuffAlly" (Disciplinary Action) buff to Miniguns immediately when they begin to wind down. The code below passes the compiler but nothing happens in-game, despite it being properly loaded and reloaded. Any advice would be greatly appreciated, thank you.


Code:

#include <sourcemod>
#include <tf2>

public Plugin myinfo =
{
        name = "Custom Property",
        author = "dacisco",
        description = "Adds Speed Boost",
        version = "1.0",
        url = "NA"
};

public void OnPluginStart()
{
        HookEvent("localplayer_winddown", Event_LocalPlayerWindDown);
}

public void Event_LocalPlayerWindDown(Event event, const char[] name, bool dontBroadcast)
{
        int target_id = event.GetInt("userid");
        int target = GetClientOfUserId(target_id);
        TF2_AddCondition(target, TFCond_SpeedBuffAlly, 2.0, 0);
}


nosoop 08-15-2018 20:47

Re: Custom Minigun Property
 
As the event name suggests, localplayer_winddown is only fired on the client side (if it even is; can't seem to get it to show up on my listen server). If you want to observe the events that are fired, set net_showevents to 2 on the server and watch the server console.

Anyways, since it's not fired on the server, SourceMod has no way to detect such an event.

Off the top of my head, you'll likely either have to track changes on the IN_ATTACK2 button with OnPlayerRunCmdPost or SDKHook_PostThinkPost, or directly hook CTFMinigun::WindDown() with DHooks.

dacisco 08-15-2018 23:39

Re: Custom Minigun Property
 
So I went ahead and confirmed what you are saying by testing it myself. You're right, I can't find that event being used in any circumstance. It looks like valve isn't using the event at all. Is there any way to make local events global, or to implement those that aren't being used?

Edit: I installed DHooks2 and scoured the code but in all honesty I have no idea where to begin. I feel like what I'm trying to do is simple but I can't find a relevant function to use. You mentioned "CTFMinigun::WindDown()": how would I implement this?

nosoop 08-16-2018 01:36

Re: Custom Minigun Property
 
Implementing the event would just about require the same steps, since you'd need to detect when the wind down occurs anyways.

Admittedly, DHooks is a bit more advanced (since you're going to be directly working with game functions, it'll be about as difficult as setting up SDKCalls). It's kind of a DIY-version of SDKHooks; the main difference is you'll also be declaring your own hooks instead of using some predefined ones.

For this I hope you have access to a Linux server, just because getting hooks to Windows functions takes a bit more work (rather, getting the signatures you'll need will be a massive pain point -- even I can't do it easily for this specific function).
  1. Download and install the version of the extension with detour support. I neglected to check earlier, but the original version of DHooks does not have the capabilities to hook what we need to hook (specifically, CTFMinigun::WindDown() is not a virtual function).
  2. Get the function signature of what you need to hook. You can do this in IDA or various other tools. There's better info on that topic elsewhere, but for now, the signature on Linux binaries is @_ZN10CTFMinigun8WindDownEv. Add that into a gamedata file under the "Signatures" section. I'm naming it CTFMinigun::WindDown() in this example.
  3. Hook the function and enable your detour. In your plugin, load the gamedata file, include dhooks, then refer to the sample code below in creating the detour:
    Code:

    // in OnPluginStart()
    // Create a detour for minigun winddown (the function has no return and no arguments, and an entity is calling this function)
    g_DHookMinigunWindDown = DHookCreateDetour(Address_Null, CallConv_THISCALL, ReturnType_Void, ThisPointer_CBaseEntity);

    // Load the address of the function from gamedata
    DHookSetFromConf(g_DHookMinigunWindDown, hGameData, SDKConf_Signature, "CTFMinigun::WindDown()");

    // Detour the function, handling it in a OnMinigunWindDownPost callback you define -- there you can pull the owner from the weapon and apply your effects
    DHookEnableDetour(g_DHookMinigunWindDown, true, OnMinigunWindDownPost);


----

Edit: For fun, I decided to write it as an example plugin for my pre-alpha Custom Attributes framework. Other than removing the native calls to the custom attribute library, you can basically use the code in scripting/sample_attributes/attr_minigun_boost_on_winddown.sp as-is.

dacisco 08-16-2018 19:10

Re: Custom Minigun Property
 
I went ahead and tried to get this going: no luck. First off, this is some good stuff so thank you. Here is what I did: I installed DHooks v2.2.0 w/ Detour support and TF2Attributes v1.2.1. I went ahead and installed your tf_custom_attributes library as well, so I kept the calls. Everything compiled just fine but I am unable to notice any difference in-game. The tf2.custattr.sample.txt is installed as well.

nosoop 08-16-2018 19:37

Re: Custom Minigun Property
 
I'd recommend stripping out the library calls to keep things simple (basically everything past TF2CustAttr_GetAttributeKeyValues minus keeping TF2_AddCondition intact and removing the include reference). Every minigun will work then.

But if you're keeping the calls and using my library, you'll also likely want to install tf_custom_attributes_manager, which is what actually reads the config and applies the attribute. The configuration is also set to only apply this effect to the Huo-Long Heater; add a section as appropriate for your preferred minigun (based on defindex), and reload and reequip with tf2custattrman_reload.

dacisco 08-16-2018 20:19

Re: Custom Minigun Property
 
Okay so I made the omissions that you suggested, that is, if I did it right:

Code:

/**
 * Sourcemod 1.7 Plugin Template
 */
#pragma semicolon 1
#include <sourcemod>

#include <tf2_stocks>
#include <dhooks>

#pragma newdecls required

//#include <tf_custom_attributes>

Handle g_DHookMinigunWindDown;

public void OnPluginStart() {
        Handle hGameConf = LoadGameConfigFile("tf2.custattr.sample");
        if (!hGameConf) {
                SetFailState("Missing weapon overhaul gamedata tf2.custattr.sample.txt).");
        }
       
        g_DHookMinigunWindDown = DHookCreateDetour(Address_Null, CallConv_THISCALL, ReturnType_Void,
                        ThisPointer_CBaseEntity);
        DHookSetFromConf(g_DHookMinigunWindDown, hGameConf, SDKConf_Signature,
                        "CTFMinigun::WindDown()");
        DHookEnableDetour(g_DHookMinigunWindDown, true, OnMinigunWindDownPost);
       
        delete hGameConf;
}

public MRESReturn OnMinigunWindDownPost(int minigun) {
        int owner = GetEntPropEnt(minigun, Prop_Send, "m_hOwnerEntity");
        if (owner < 1 || owner > MaxClients) {
                return MRES_Ignored;
        }
       
        /*KeyValues kv = TF2CustAttr_GetAttributeKeyValues(minigun);
        if (!kv) {
                return MRES_Ignored;
        }
       
        float flBoostDuration = kv.GetFloat("minigun winddown boost duration");
        */
        //if (flBoostDuration) {
                TF2_AddCondition(owner, TFCond_SpeedBuffAlly, 2.0, owner);
        /*}
        delete kv;*/
        return MRES_Ignored;
}


If this is in fact correct, I still didn't get any luck. I looked in tf2.custattr.sample.txt and realized that you are using:

Code:

"linux"                "@_ZN10CTFMinigun8WindDownEv"
What would be the alternative format for Windows (if this is an issue)?

nosoop 08-16-2018 20:54

Re: Custom Minigun Property
 
Seems correct to me.
Missing the Windows signature would definitely be an issue if you're testing the plugin out on a Windows server. DHooks should throw an error on it on startup, which you'll see using sm plugins list in the server console.

Windows doesn't have debugging symbols, so it'll take much more work to hook functions there. Will have to recommend Linux to save on the effort for that.

DHooks seems to be crashing on Windows for me, but here's the signature (the only reason I could find it was because I partially annotated a disassembly of the Windows server binary):

Code:

"windows"        "\x55\x8B\xEC\x83\xEC\x08\x56\x57\x8B\xF9\xE8\x2A\x2A\x2A\x2A\x8B\xF0\x85\xF6\x0F\x84\x2A\x2A\x2A\x2A\x8B\x16\x8B\xCE\x8B\x92\x40\x01\x00\x00\xFF\xD2\x84\xC0\x0F\x84\x2A\x2A\x2A\x2A\x8B\x07\x8B\xCF\x53"


All times are GMT -4. The time now is 20:19.

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