TF2-DMB / CBaseNPC

Provides a friendly interface for plugins to use in order to create custom NPCs on the game Team Fortress 2
37 stars 6 forks source link

Model Updating Parented Particle Issue #56

Closed artvin01 closed 3 months ago

artvin01 commented 3 months ago

Step 1: Make an NPC with basenpc Step 2: Parent a particle to the NPC onto ANY specific attachment Mainly Via:

AcceptEntityInput(iChild, "SetParentAttachment", iParent, iChild); Or AcceptEntityInput(iChild, "SetParentAttachmentMaintainOffset", iParent, iChild);

Step 3: Animate the NPC (attack animation, or taunt), if it doesnt turn or move, the parented particle doesnt get updated to the new position and stays in place

Hint: Bonemerged works as intended.

artvin01 commented 3 months ago

image Picture to showcase

image How it should be

ill investigate this issue further, just know that this issue didnt happen when i still used base_boss

artvin01 commented 3 months ago

This also only seems to happen if the NPC moves, it might be related to updating animations, or updating its gestures. image in specific, it is this function, changing this causes major issues, primarily the netprop. image it looks like it doesnt support it. layers are forced!

artvin01 commented 3 months ago

Setting Playbackrate to extreamly low numbers (< 0.01) causes this issue.

Kenzzer commented 3 months ago

Hello, I finally got some free time and took a look at this issue. I don't believe what you describe over those posts is a bug inherent with CBaseNPC, and more so source engine shenanigans, which unfortunately you will have to figure out on your own, much like I suggested you over Discord last year for this same issue.

Here's a video demonstration where I showcase a model (HHH) with two parented particles, one through SetParentAttachment one through SetParentAttachmentMaintainOffset, with the model alternating between a low and high playback rate, with no showcase of the bug described. First entity is a plain, unmodified CBaseNPC, second entity is a simple prop_dynamic

https://github.com/user-attachments/assets/21af5a14-66f3-40e0-adb5-23777d90b0f8

And here's the plugin code to generate this video :

#include <sourcemod>
#include <sdktools>
#include <cbasenpc>

#define MODEL "models/bots/headless_hatman.mdl"

public void OnPluginStart() {
    RegConsoleCmd("npc_test_cbasenpc", Command_NpcTest);
    RegConsoleCmd("npc_test_prop", Command_PropTest)
}

public void OnMapStart() {
    PrecacheModel(MODEL);
}

static Action Command_NpcTest(int client, int args) {
    CBaseNPC npc = CBaseNPC();
    if (npc != INVALID_NPC) {   
        int entity = npc.GetEntity();

        float origin[3];
        GetEntPropVector(client, Prop_Send, "m_vecOrigin", origin);

        Begin(entity, origin);
    }
    return Plugin_Continue;
}

static Action Command_PropTest(int client, int args) {
    int entity = CreateEntityByName("prop_dynamic");
    if (entity != -1) {

        float origin[3];
        GetEntPropVector(client, Prop_Send, "m_vecOrigin", origin);

        Begin(entity, origin);
    }
    return Plugin_Continue;
}

static void Begin(int entity, float tp[3]) {
    CBaseAnimating animating = CBaseAnimating(entity);

    animating.SetModel(MODEL);
    animating.Spawn();
    animating.SetLocalOrigin(tp);

    CBaseEntity eyeEffetR = CBaseEntity(CreateEntityByName("info_particle_system"));

    SetVariantString("!activator");
    AcceptEntityInput(eyeEffetR.index, "SetParent", entity);

    eyeEffetR.SetLocalOrigin({0.0, 0.0, 20.0});
    SetVariantString("righteye");
    AcceptEntityInput(eyeEffetR.index, "SetParentAttachmentMaintainOffset");

    DispatchKeyValue(eyeEffetR.index, "effect_name", "halloween_boss_eye_glow");

    DispatchSpawn(eyeEffetR.index);
    ActivateEntity(eyeEffetR.index);
    AcceptEntityInput(eyeEffetR.index, "Start");

    int eyeEffetL = CreateEntityByName("info_particle_system");

    SetVariantString("!activator");
    AcceptEntityInput(eyeEffetL, "SetParent", entity);
    SetVariantString("lefteye");
    AcceptEntityInput(eyeEffetL, "SetParentAttachment");

    DispatchKeyValue(eyeEffetL, "effect_name", "halloween_boss_eye_glow");

    DispatchSpawn(eyeEffetL);
    ActivateEntity(eyeEffetL);
    AcceptEntityInput(eyeEffetL, "Start");

    int sequence = animating.LookupSequence("stand_ITEM1");
    animating.ResetSequence(sequence);

    CreateTimer(3.0, Update, EntIndexToEntRef(entity), TIMER_REPEAT);

    PrintToChatAll("Begun the test prop!");
}

static Action Update(Handle timer, int ref) {
    int entity = EntRefToEntIndex(ref);
    if (entity == -1) {
        return Plugin_Stop;
    }

    if (GetEntPropFloat(entity, Prop_Send, "m_flPlaybackRate") < 0.5) {
        SetEntPropFloat(entity, Prop_Send, "m_flPlaybackRate", 1.0);
    } else {
        SetEntPropFloat(entity, Prop_Send, "m_flPlaybackRate", 0.005);
    }
}

I highly encourage you to create a minimal reproduction case plugin if you truly believe this is a bug with the extension, otherwise I will never be able to pinpoint your problem. When you do, please make another github issue with everything summarised as simple as possible, with the least amount of code as possible. Thank you, and good luck investigating this issue !