RebornKyle Posted December 3, 2024 Posted December 3, 2024 Was wondering if its possible to prevent an NPC from using ragdoll upon being killed. Preferably it would be a scripted behavior that I could assign to any NPC, but I didn't see any that sounded like that when I perused Behaved.
RebornKyle Posted December 21, 2024 Author Posted December 21, 2024 2 hours ago, Linken said: Type "broadsword 0" Possible to make this scriptable? Only want it to occur in a specific situation. Even just toggling this on/off would work, but I'm not looking for cheats
Linken Posted December 21, 2024 Posted December 21, 2024 Are you looking for it to be global or only impact specific npcs?
RebornKyle Posted December 21, 2024 Author Posted December 21, 2024 2 minutes ago, Linken said: Are you looking for it to be global or only impact specific npcs? In this case either would be fine, it would be during a duel and going back to what it was after the duel
Linken Posted December 21, 2024 Posted December 21, 2024 11 hours ago, RebornKyle said: In this case either would be fine, it would be during a duel and going back to what it was after the duel Alright, I'll leave it up to you on how to implement or how to call it. So I'll write some simple tutorials. I'm going light on the details since I know you have a coding background, but let me know if you need screenshots. 1. In Q3_Interface.h, declare your new script command. 2. In Q3_Interface.cpp, add your command to the Enum2String and the Set method in the appropriate spot (would recommend making it a Boolean) 3. IF Making Global: have it change the value of the "g_broadsword" cvar to 0 (turned off) or 1 (turned on) depending if set to true or false. You can stop here. 4. IF Making NPC Specific, declare a new NPC scriptFlag (in b_public.h). In this example I'll just call it SCF_NO_RAGDOLL, make sure its Hexadecimal value is correct. An unmodified OpenJK source code should probably be 0x100000000. 5. To apply to an NPC, create a new function somewhere called by your script command and write something like this: static void Q3_SetRagdoll(int entID, qboolean ragDoll) { gentity_t *ent = &g_entities[entID]; if ( !ent ) { Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetRagdoll: invalid entID %d\n", entID); return; } if(ragDoll) ent->NPC->scriptFlags |= SCF_NO_RAGDOLL; else ent->NPC->scriptFlags &= ~SCF_NO_RAGDOLL; } 6. Lastly go to the function G_RagDoll (in g_main.cpp) and add a check near the beginning of the function to verify if the NPC has this scriptFlag applied, and if they do, return qfalse. DISCLAIMER: I wrote this code on the fly and didn't personally test.
RebornKyle Posted December 22, 2024 Author Posted December 22, 2024 On 12/21/2024 at 12:41 PM, Linken said: Alright, I'll leave it up to you on how to implement or how to call it. So I'll write some simple tutorials. I'm going light on the details since I know you have a coding background, but let me know if you need screenshots. 1. In Q3_Interface.h, declare your new script command. 2. In Q3_Interface.cpp, add your command to the Enum2String and the Set method in the appropriate spot (would recommend making it a Boolean) 3. IF Making Global: have it change the value of the "g_broadsword" cvar to 0 (turned off) or 1 (turned on) depending if set to true or false. You can stop here. 4. IF Making NPC Specific, declare a new NPC scriptFlag (in b_public.h). In this example I'll just call it SCF_NO_RAGDOLL, make sure its Hexadecimal value is correct. An unmodified OpenJK source code should probably be 0x100000000. 5. To apply to an NPC, create a new function somewhere called by your script command and write something like this: static void Q3_SetRagdoll(int entID, qboolean ragDoll) { gentity_t *ent = &g_entities[entID]; if ( !ent ) { Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetRagdoll: invalid entID %d\n", entID); return; } if(ragDoll) ent->NPC->scriptFlags |= SCF_NO_RAGDOLL; else ent->NPC->scriptFlags &= ~SCF_NO_RAGDOLL; } 6. Lastly go to the function G_RagDoll (in g_main.cpp) and add a check near the beginning of the function to verify if the NPC has this scriptFlag applied, and if they do, return qfalse. DISCLAIMER: I wrote this code on the fly and didn't personally test. Well hey I greatly appreciate this! I'll be sure to give this a go when I have some time soonish. I'll probably opt for the specific NPC one since setting it globally would probably get messy if other users prefer it differently and having to change it back afterwards could alter those preferences. Happy Holidays! Linken likes this
RebornKyle Posted December 28, 2024 Author Posted December 28, 2024 On 12/21/2024 at 12:41 PM, Linken said: 4. IF Making NPC Specific, declare a new NPC scriptFlag (in b_public.h). In this example I'll just call it SCF_NO_RAGDOLL, make sure its Hexadecimal value is correct. An unmodified OpenJK source code should probably be 0x100000000. 5. To apply to an NPC, create a new function somewhere called by your script command and write something like this: static void Q3_SetRagdoll(int entID, qboolean ragDoll) { gentity_t *ent = &g_entities[entID]; if ( !ent ) { Quake3Game()->DebugPrint( IGameInterface::WL_WARNING, "Q3_SetRagdoll: invalid entID %d\n", entID); return; } if(ragDoll) ent->NPC->scriptFlags |= SCF_NO_RAGDOLL; else ent->NPC->scriptFlags &= ~SCF_NO_RAGDOLL; } 6. Lastly go to the function G_RagDoll (in g_main.cpp) and add a check near the beginning of the function to verify if the NPC has this scriptFlag applied, and if they do, return qfalse. DISCLAIMER: I wrote this code on the fly and didn't personally test. I managed to accomplish the global change, but just like I thought it would affect later sessions if you didn't reset it. I haven't managed to figure out the scriptflag for specific NPCs unfortunately though. Here's the relevant parts of what I wrote: Q3_Interface: ____________________________________________________________________ ENUM2STRING(SET_NO_RAGDOLL), ----------------------------------------------------------------- /* ============ Q3_SetNoRagdoll Description : Return type : static void Argument : int entID Argument : qboolean ragdoll ============ */ static void Q3_SetNoRagdoll(int entID, qboolean ragdoll) { gentity_t *ent = &g_entities[entID]; if (!ent) { Quake3Game()->DebugPrint(IGameInterface::WL_WARNING, "Q3_SetNoRagdoll: entID %d not a client\n", entID); return; } if (ragdoll) { ent->NPC->scriptFlags |= SCF_NO_RAGDOLL; } else { ent->NPC->scriptFlags &= ~SCF_NO_RAGDOLL; } } -------------------------------------------------------------------------------- case SET_NO_RAGDOLL://## %t="BOOL_TYPES" # NPCs won't ragdoll on death if (ent->NPC == NULL) { DebugPrint(WL_WARNING, "GetFloat: SET_NO_RAGDOLL, %s not an NPC\n", ent->targetname); return false; } *value = (ent->NPC->scriptFlags&SCF_NO_RAGDOLL); break; g_main: ____________________________________________________________________ //rww - game interface for the ragdoll stuff. //Returns qtrue if the entity is now in a ragdoll state, otherwise qfalse. //(ported from MP's CG version) qboolean G_RagDoll(gentity_t *ent, vec3_t forcedAngles) { vec3_t G2Angles; vec3_t usedOrg; qboolean inSomething = qfalse; int ragAnim; //int ragVar = gi.Cvar_VariableIntegerValue("broadsword"); int ragVar = g_broadsword->integer; if (!ragVar) { return qfalse; } if (!ent || !ent->inuse || !ent->client || ent->health > 0 || ent->client->noRagTime >= level.time || ent->client->noRagTime==-1 || (ent->s.powerups & (1 << PW_DISRUPTION)) || !ent->e_DieFunc || ent->playerModel < 0 || !ent->ghoul2.size() || !G_RagWantsHumanoidsOnly(&ent->ghoul2[ent->playerModel]) ) { return qfalse; } if (ent->NPC->scriptFlags & SCF_NO_RAGDOLL) { return qfalse; } So not sure if something I did here is off or not. Oh and of course I declared the SCF_NO_RAGDOLL in b_public.h and the SET_NO_RAGDOLL in Q3_Interface.h. I noticed that, for g_main, any level won't start if I put the last if statement I created before the previous if block Linken likes this
Linken Posted December 29, 2024 Posted December 29, 2024 The way you wrote it is not the global change, it's the NPC change. Global change would only impact the cvar. Looking at your code I don't see any issues. What does your script look like for calling this?
RebornKyle Posted December 29, 2024 Author Posted December 29, 2024 2 minutes ago, Linken said: The way you wrote it is not the global change, it's the NPC change. Global change would only impact the cvar. Looking at your code I don't see any issues. What does your script look like for calling this? Yes sorry I should have clarified, this is for the NPC change. I accomplished the global change, but it wasn't satisfactory for me. And my script is called when the NPC is spawned, along with the other behaviors its spawned with, which are all base game and work fine as they did before this addition. Here's the script call. set ( /*@SET_TYPES*/ "SET_NO_RAGDOLL", /*@BOOL_TYPES*/ "true" );
Linken Posted December 29, 2024 Posted December 29, 2024 52 minutes ago, RebornKyle said: Yes sorry I should have clarified, this is for the NPC change. I accomplished the global change, but it wasn't satisfactory for me. And my script is called when the NPC is spawned, along with the other behaviors its spawned with, which are all base game and work fine as they did before this addition. Here's the script call. set ( /*@SET_TYPES*/ "SET_NO_RAGDOLL", /*@BOOL_TYPES*/ "true" ); Does the global change work through the script?
RebornKyle Posted December 29, 2024 Author Posted December 29, 2024 9 minutes ago, Linken said: Does the global change work through the script? Yes, but for that it would be set as ( /*@SET_TYPES*/ "SET_NO_RAGDOLL", 0); Since my solution for that involves directly changing the cvar for broadsword, as you suggested.
Linken Posted December 29, 2024 Posted December 29, 2024 . 34 minutes ago, RebornKyle said: Yes, but for that it would be set as ( /*@SET_TYPES*/ "SET_NO_RAGDOLL", 0); Since my solution for that involves directly changing the cvar for broadsword, as you suggested. Check the script command in debug mode, there might be something missing
RebornKyle Posted yesterday at 03:27 AM Author Posted yesterday at 03:27 AM On 12/29/2024 at 1:07 AM, Linken said: . Check the script command in debug mode, there might be something missing Maybe there could be a different area to implement this? I've gotten nothing checking the script. Since ragdoll only applies to humanoid npcs, maybe there's a point in the code where that is laid out, and I can do the check there?
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now