# HG changeset patch # User Adam Kaminski # Date 1637687694 18000 # Tue Nov 23 12:14:54 2021 -0500 # Node ID 0cace8154daa9e142f4b71e542363f28ff2fa31a # Parent 58fc4cac9954d2feaafa0c7e67249bf151bac755 Changing the result value of GAMEEVENT_CHAT and GAMEEVENT_ACTOR_DAMAGED scripts now determines whether or not the chat message gets printed, or how much damage the target actor receives. diff -r 58fc4cac9954 -r 0cace8154daa src/chat.cpp --- a/src/chat.cpp Mon Nov 22 10:36:19 2021 -0500 +++ b/src/chat.cpp Tue Nov 23 12:14:54 2021 -0500 @@ -1038,6 +1038,34 @@ } } + // [AK] Only save chat messages for non-private chat messages. + if (( ulMode != CHATMODE_PRIVATE_SEND ) && ( ulMode != CHATMODE_PRIVATE_RECEIVE )) + { + BOTCMD_SetLastChatString( pszString ); + BOTCMD_SetLastChatPlayer( PLAYER_IsValidPlayer( ulPlayer ) ? players[ulPlayer].userinfo.GetName() : "" ); + + for ( ULONG ulIdx = 0; ulIdx < MAXPLAYERS; ulIdx++ ) + { + if ( playeringame[ulIdx] == false ) + continue; + + // Don't tell the bot someone talked if it was it who talked. + if ( ulIdx == ulPlayer ) + continue; + + // If this is a bot, tell it a player said something. + if ( players[ulIdx].pSkullBot ) + players[ulIdx].pSkullBot->PostEvent( BOTEVENT_PLAYER_SAY ); + } + + g_SavedChatMessages[ulPlayer].put( pszString ); + + // [AK] Trigger an event script indicating that a chat message was received. + // If the event returns 0, then don't print the message. + if ( GAMEMODE_HandleEvent( GAMEEVENT_CHAT, NULL, ulPlayer != MAXPLAYERS ? ulPlayer : -1, ulMode - CHATMODE_GLOBAL ) == 0 ) + return; + } + ChatString = pszString; // [BB] Remove invalid color codes, those can confuse the printing and create new lines. @@ -1072,32 +1100,6 @@ else if ( sound == 3 ) // Doom 2 S_Sound( CHAN_VOICE | CHAN_UI, "misc/chat", 1, ATTN_NONE ); } - - // [AK] Only save chat messages for non-private chat messages. - if (( ulMode != CHATMODE_PRIVATE_SEND ) && ( ulMode != CHATMODE_PRIVATE_RECEIVE )) - { - g_SavedChatMessages[ulPlayer].put( pszString ); - - // [AK] Trigger an event script indicating that a chat message was received. - GAMEMODE_HandleEvent( GAMEEVENT_CHAT, 0, ulPlayer != MAXPLAYERS ? ulPlayer : -1, ulMode - CHATMODE_GLOBAL ); - - BOTCMD_SetLastChatString( pszString ); - BOTCMD_SetLastChatPlayer( PLAYER_IsValidPlayer( ulPlayer ) ? players[ulPlayer].userinfo.GetName() : "" ); - - for ( ULONG ulIdx = 0; ulIdx < MAXPLAYERS; ulIdx++ ) - { - if ( playeringame[ulIdx] == false ) - continue; - - // Don't tell the bot someone talked if it was it who talked. - if ( ulIdx == ulPlayer ) - continue; - - // If this is a bot, tell it a player said something. - if ( players[ulIdx].pSkullBot ) - players[ulIdx].pSkullBot->PostEvent( BOTEVENT_PLAYER_SAY ); - } - } } //***************************************************************************** diff -r 58fc4cac9954 -r 0cace8154daa src/gamemode.cpp --- a/src/gamemode.cpp Mon Nov 22 10:36:19 2021 -0500 +++ b/src/gamemode.cpp Tue Nov 23 12:14:54 2021 -0500 @@ -89,6 +89,9 @@ // Our current game mode. static GAMEMODE_e g_CurrentGameMode; +// [AK] The result value of the current event being executed. +static LONG g_lEventResult = 1; + // [BB] Implement the string table and the conversion functions for the GMF and GAMEMODE enums. #define GENERATE_ENUM_STRINGS // Start string generation #include "gamemode_enums.h" @@ -1079,37 +1082,45 @@ //***************************************************************************** // -void GAMEMODE_HandleEvent ( const GAMEEVENT_e Event, AActor *pActivator, const int DataOne, const int DataTwo ) +LONG GAMEMODE_HandleEvent ( const GAMEEVENT_e Event, AActor *pActivator, const int DataOne, const int DataTwo ) { // [BB] Clients don't start scripts. if ( NETWORK_InClientMode() ) - return; + return 1; // [AK] Allow events that are triggered by an actor spawning or // taking damage to be executed immediately, in case any of the // actor pointers that were responsible for calling the event // become NULL after one tic. - bool bRunNow = ( Event == GAMEEVENT_ACTOR_SPAWNED || Event == GAMEEVENT_ACTOR_DAMAGED ); + // Also allow chat events to be executed immediately. + bool bRunNow = ( Event == GAMEEVENT_ACTOR_SPAWNED || Event == GAMEEVENT_ACTOR_DAMAGED || Event == GAMEEVENT_CHAT ); // [BB] The activator of the event activates the event script. // The first argument is the type, e.g. GAMEEVENT_PLAYERFRAGS, // the second and third are specific to the event, e.g. the second is the number of the fragged player. // The third argument will be zero if it isn't used in the script. FBehavior::StaticStartTypedScripts( SCRIPT_Event, pActivator, true, Event, bRunNow, false, DataOne, DataTwo ); + + // [AK] Get the result value of the event, then reset it back to the default value. + LONG lResult = GAMEMODE_GetEventResult( ); + GAMEMODE_SetEventResult( 1 ); + + // [AK] Return the result value of the event. + return lResult; } //***************************************************************************** // -void GAMEMODE_HandleDamageEvent ( AActor *target, AActor *inflictor, AActor *source, int damage, FName mod ) +bool GAMEMODE_HandleDamageEvent ( AActor *target, AActor *inflictor, AActor *source, int &damage, FName mod ) { // [AK] Don't run any scripts if the target doesn't allow executing GAMEEVENT_ACTOR_DAMAGED. if ( target->STFlags & STFL_NODAMAGEEVENTSCRIPT ) - return; + return true; // [AK] Don't run any scripts if the target can't execute GAMEEVENT_ACTOR_DAMAGED unless // all actors are forced to execute it. if ((( target->STFlags & STFL_USEDAMAGEEVENTSCRIPT ) == false ) && ( gameinfo.bForceDamageEventScripts == false )) - return; + return true; // [AK] We somehow need to pass all the actor pointers into the script itself. A simple way // to do this is temporarily spawn a temporary actor and change its actor pointers to the target, @@ -1121,10 +1132,28 @@ temp->master = source; temp->tracer = inflictor; - GAMEMODE_HandleEvent( GAMEEVENT_ACTOR_DAMAGED, temp, damage, GlobalACSStrings.AddString( mod )); + GAMEMODE_SetEventResult( damage ); + damage = GAMEMODE_HandleEvent( GAMEEVENT_ACTOR_DAMAGED, temp, damage, GlobalACSStrings.AddString( mod )); // [AK] Destroy the temporary actor after executing all event scripts. temp->Destroy( ); + + // [AK] If the new damage is zero, that means the target shouldn't take damage in P_DamageMobj. + return ( damage != 0 ); +} + +//***************************************************************************** +// +LONG GAMEMODE_GetEventResult( ) +{ + return g_lEventResult; +} + +//***************************************************************************** +// +void GAMEMODE_SetEventResult( LONG lResult ) +{ + g_lEventResult = lResult; } //***************************************************************************** diff -r 58fc4cac9954 -r 0cace8154daa src/gamemode.h --- a/src/gamemode.h Mon Nov 22 10:36:19 2021 -0500 +++ b/src/gamemode.h Tue Nov 23 12:14:54 2021 -0500 @@ -212,8 +212,10 @@ bool GAMEMODE_IsHandledSpecial ( AActor *Activator, int Special ); GAMESTATE_e GAMEMODE_GetState ( void ); void GAMEMODE_SetState ( GAMESTATE_e GameState ); -void GAMEMODE_HandleEvent ( const GAMEEVENT_e Event, AActor *pActivator = NULL, const int DataOne = 0, const int DataTwo = 0 ); -void GAMEMODE_HandleDamageEvent ( AActor *target, AActor *inflictor, AActor *source, int damage, FName mod ); +LONG GAMEMODE_HandleEvent ( const GAMEEVENT_e Event, AActor *pActivator = NULL, const int DataOne = 0, const int DataTwo = 0 ); +bool GAMEMODE_HandleDamageEvent ( AActor *target, AActor *inflictor, AActor *source, int &damage, FName mod ); +LONG GAMEMODE_GetEventResult ( void ); +void GAMEMODE_SetEventResult ( LONG lResult ); // [BB] This function doesn't really belong here. Find a better place for it. void GAMEMODE_DisplayStandardMessage( const char *pszMessage, const bool bInformClients = false ); diff -r 58fc4cac9954 -r 0cace8154daa src/p_acs.cpp --- a/src/p_acs.cpp Mon Nov 22 10:36:19 2021 -0500 +++ b/src/p_acs.cpp Tue Nov 23 12:14:54 2021 -0500 @@ -7800,6 +7800,13 @@ switch (state) { + // [AK] If this is the first tic of an event script, initialize the result value to whatever the current + // event's result value is supposed to be at this moment. + case SCRIPT_Running: + if ( ACS_IsEventScript( script )) + resultValue = GAMEMODE_GetEventResult( ); + break; + case SCRIPT_Delayed: // Decrement the delay counter and enter state running // if it hits 0 @@ -11654,6 +11661,10 @@ // [AK] We're done running this script so any action or line specials activated now aren't done in ACS. g_pCurrentScript = NULL; + // [AK] If this is an event script and the result value differs from the event's result value, update it. + if (( ACS_IsEventScript( script )) && ( resultValue != GAMEMODE_GetEventResult( ))) + GAMEMODE_SetEventResult( resultValue ); + // [BB] Stop the net traffic measurement and add the result to this script's traffic. NETTRAFFIC_AddACSScriptTraffic ( script, NETWORK_StopTrafficMeasurement ( ) ); @@ -12263,6 +12274,19 @@ //***************************************************************************** // +bool ACS_IsEventScript( int script ) +{ + FBehavior *pModule = NULL; + const ScriptPtr *pScriptData = FBehavior::StaticFindScript( script, pModule ); + + if ( pScriptData == NULL ) + return ( false ); + + return ( pScriptData->Type == SCRIPT_Event ); +} + +//***************************************************************************** +// bool ACS_IsScriptClientSide( int script ) { FBehavior *pModule = NULL; diff -r 58fc4cac9954 -r 0cace8154daa src/p_acs.h --- a/src/p_acs.h Mon Nov 22 10:36:19 2021 -0500 +++ b/src/p_acs.h Tue Nov 23 12:14:54 2021 -0500 @@ -1176,6 +1176,7 @@ // PROTOTYPES bool ACS_IsCalledFromConsoleCommand( void ); +bool ACS_IsEventScript( int script ); // [AK] bool ACS_IsCalledFromScript( void ); // [AK] bool ACS_IsScriptClientSide( int script ); bool ACS_IsScriptClientSide( const ScriptPtr *pScriptData ); diff -r 58fc4cac9954 -r 0cace8154daa src/p_interaction.cpp --- a/src/p_interaction.cpp Mon Nov 22 10:36:19 2021 -0500 +++ b/src/p_interaction.cpp Tue Nov 23 12:14:54 2021 -0500 @@ -1573,7 +1573,10 @@ } // [AK] Trigger an event script indicating that the player has taken damage, if we can. - GAMEMODE_HandleDamageEvent( target, inflictor, source, damage, mod ); + // If the event returns 0, then the target doesn't take damage and we do nothing. + if ( GAMEMODE_HandleDamageEvent( target, inflictor, source, damage, mod ) == false ) + return -1; + bDamageEventHandled = true; if (damage >= player->health @@ -1585,8 +1588,9 @@ } // [AK] If we haven't done so already, trigger an event script indicating that the player has taken damage. - if ( bDamageEventHandled == false ) - GAMEMODE_HandleDamageEvent( target, inflictor, source, damage, mod ); + // If the event returns 0, then the target doesn't take damage and we do nothing. + if (( bDamageEventHandled == false ) && ( GAMEMODE_HandleDamageEvent( target, inflictor, source, damage, mod ) == false )) + return -1; player->health -= damage; // mirror mobj health here for Dave // [RH] Make voodoo dolls and real players record the same health @@ -1653,7 +1657,9 @@ } // [AK] Trigger an event script indicating that the target actor has taken damage, if we can. - GAMEMODE_HandleDamageEvent( target, inflictor, source, damage, mod ); + // If the event returns 0, then the target doesn't take damage and we do nothing. + if ( GAMEMODE_HandleDamageEvent( target, inflictor, source, damage, mod ) == false ) + return -1; target->health -= damage; } diff -r 58fc4cac9954 -r 0cace8154daa src/sv_main.cpp --- a/src/sv_main.cpp Mon Nov 22 10:36:19 2021 -0500 +++ b/src/sv_main.cpp Tue Nov 23 12:14:54 2021 -0500 @@ -1230,11 +1230,14 @@ } else { - SERVERCOMMANDS_PlayerSay( ulPlayer, pszString, ulMode, bForbidChatToPlayers ); CHAT_AddChatMessage( ulPlayer, pszString ); // [AK] Trigger an event script indicating that a chat message was received. - GAMEMODE_HandleEvent( GAMEEVENT_CHAT, 0, ulPlayer != MAXPLAYERS ? ulPlayer : -1, ulMode - CHATMODE_GLOBAL ); + // If the event returns 0, then don't print the message or send it to the clients. + if ( GAMEMODE_HandleEvent( GAMEEVENT_CHAT, NULL, ulPlayer != MAXPLAYERS ? ulPlayer : -1, ulMode - CHATMODE_GLOBAL ) == 0 ) + return; + + SERVERCOMMANDS_PlayerSay( ulPlayer, pszString, ulMode, bForbidChatToPlayers ); } if ( ulMode == CHATMODE_PRIVATE_SEND )