Facepunch / garrysmod-requests

Feature requests for Garry's Mod
85 stars 24 forks source link

Implement ClearOutputs(string)/ClearAllOutputs for all entities #1984

Closed TIMONz1535 closed 2 years ago

TIMONz1535 commented 2 years ago

Details

I found that npc_playercompanion has the ability to delete all outputs from the entity. YES, it is real! https://github.com/ValveSoftware/source-sdk-2013/blob/master/mp/src/game/server/hl2/npc_playercompanion.cpp#L127-L129 https://github.com/ValveSoftware/source-sdk-2013/blob/master/mp/src/game/server/hl2/npc_playercompanion.cpp#L3526-L3556 There is a typo in the method name haha - InputClearAllOuputs

In the end, it calls a method that deletes all CEventAction's - CBaseEntityOutput::DeleteAllElements https://github.com/ValveSoftware/source-sdk-2013/blob/master/mp/src/game/server/cbase.cpp#L459-L475

You can fire input ClearAllOutputs and it deletes all the entity's outputs, as far as I can tell. https://developer.valvesoftware.com/wiki/Npc_alyx https://developer.valvesoftware.com/wiki/Npc_vortigaunt

ClearAllOutputs  (only in Half-Life 2: Episode One Half-Life 2: Episode Two)
    Clears every output that this NPC has.

I propose to make this method shared for ALL entities. (see below for a universal solution) This will at least allow you to do something that was never possible - remove outputs on the map.

p.s.

By the way, I will say more. Indeed, it is possible to delete one selected output. This is the part of code that removes outputs that have triggered a set number of times max times to fire https://github.com/ValveSoftware/source-sdk-2013/blob/master/mp/src/game/server/cbase.cpp#L324-L361 However, I haven't come up with a way how we can "specify the output that we need".

TIMONz1535 commented 2 years ago

I found an interesting implementation in Mapbase - Source 2013 mod https://github.com/mapbase-source/source-sdk-2013/wiki/Base-Entity#inputs

RemoveOutput <string> - Removes all instances of the named output on this entity. Wildcards are supported, meaning you could just pass '*' to wipe all outputs from this entity.

https://github.com/mapbase-source/source-sdk-2013/blob/fca05c8be92ae0b68fb63ea46f24662e6b6af91a/sp/src/game/server/baseentity.cpp#L8051-L8074

//-----------------------------------------------------------------------------
// Purpose: Removes all outputs of the specified name.
//-----------------------------------------------------------------------------
void CBaseEntity::InputRemoveOutput( inputdata_t& inputdata )
{
    const char *szOutput = inputdata.value.String();
    datamap_t *dmap = GetDataDescMap();
    while ( dmap )
    {
        int fields = dmap->dataNumFields;
        for ( int i = 0; i < fields; i++ )
        {
            typedescription_t *dataDesc = &dmap->dataDesc[i];
            if ( ( dataDesc->fieldType == FIELD_CUSTOM ) && ( dataDesc->flags & FTYPEDESC_OUTPUT ) )
            {
                // If our names match, remove
                if (Matcher_NamesMatch(szOutput, dataDesc->externalName))
                {
                    CBaseEntityOutput *pOutput = (CBaseEntityOutput *)((int)this + (int)dataDesc->fieldOffset[0]);
                    pOutput->DeleteAllElements();
                }
            }
        }

        dmap = dmap->baseMap;
    }
}

Due to the fact that we want to have an outputs on the Lua side https://github.com/Facepunch/garrysmod-requests/issues/1911, the input name input RemoveOutput(string) is not suitable. I suggest input ClearOutputs(string) and also make a method on Lua

Entity:ClearOutputs(string name) -- the name supports wildcards

It is not necessary to add an input input ClearAllOutputs(void) in this case, since it is completely covered by the input above. However, it should be faster, this is the only one reason for adding it.

robotboy655 commented 2 years ago

Added ClearAllOutputs input to all entities Added Entity.ClearAllOutputs( str )

Accepts no argument as "delete everything".

Kefta commented 2 years ago

I think it should be named "ClearOutput" if an argument causes it to not clear all outputs but only one.

TIMONz1535 commented 2 years ago

POG it was done so quickly 🤪

I think it should be named "ClearOutput" if an argument causes it to not clear all outputs but only one.

In my opinion, ClearAllOutputs is correct. Since in most cases there are several outputs under one output name. But its still a several outputs, not inputs.

изображение

TIMONz1535 commented 2 years ago

@robotboy655 It looks like the CNPC_PlayerCompanion are still calling their own input, which clear everything (tested with alyx:Fire("ClearAllOutputs", "OnHearCombat"). Lua method works fine).

Also it remained in .fgd PlayerCompanion input ClearAllOutputs(void) : "Obliterate every output that this NPC has."

robotboy655 commented 2 years ago

Removed the original now.