From 0b6c73beffcfe00002f999f776a51318715337b3 Mon Sep 17 00:00:00 2001 From: Walter Julius Hennecke Date: Wed, 25 Jul 2012 23:57:38 +0200 Subject: [PATCH] Fixes to selfdestruct Some fixes to selfdestruct .... not done yet still needs lots of debugging ... --- game/g_cmds.c | 54 ++++++++++++++++++++++++------------------------ game/g_target.c | 35 +++++++++++++++++-------------- stefgame.suo | Bin 235008 -> 235008 bytes 3 files changed, 46 insertions(+), 43 deletions(-) diff --git a/game/g_cmds.c b/game/g_cmds.c index 6f61479..801931f 100644 --- a/game/g_cmds.c +++ b/game/g_cmds.c @@ -6312,16 +6312,16 @@ static void Cmd_selfdestruct_f(gentity_t *ent) { // Setup command-Execution if(trap_Argc() < 1 ) { - G_PrintfClient(ent, "Usage: selfdestruct start duration intervall intervall-60 intervall-10 audio [target]\n"); - G_PrintfClient(ent, "duration: total countdown-duration in seconds.\n"); - G_PrintfClient(ent, "intervall: intervall of audio warnings up to T-60 seconds in seconds.\n"); - G_PrintfClient(ent, "intervall-60: intervall of audio warnings within T-60 seconds in seconds.\n"); - G_PrintfClient(ent, "intervall-10: intervall of audio warnings within T-10 seconds in seconds.\n"); - G_PrintfClient(ent, "audio: set this 0 if you do want a muted countdown, else set this 1.\n"); - G_PrintfClient(ent, "target: Optional Argument. This will be fired once the countdown hits 0. If not set the entity will kill all clients.\n"); - G_PrintfClient(ent, "\nUsage: selfdestruct remaining\n"); - G_PrintfClient(ent, "This will give out the remaining countdown-time even if the count is muted.\n"); - G_PrintfClient(ent, "\nUsage: selfdestruct abort\n"); + G_PrintfClient(ent, "Usage: selfdestruct start duration intervall intervall-60 intervall-10 audio [target]"); + G_PrintfClient(ent, "duration: total countdown-duration in seconds."); + G_PrintfClient(ent, "intervall: intervall of audio warnings up to T-60 seconds in seconds."); + G_PrintfClient(ent, "intervall-60: intervall of audio warnings within T-60 seconds in seconds."); + G_PrintfClient(ent, "intervall-10: intervall of audio warnings within T-10 seconds in seconds."); + G_PrintfClient(ent, "audio: set this 0 if you do want a muted countdown, else set this 1."); + G_PrintfClient(ent, "target: Optional Argument. This will be fired once the countdown hits 0. If not set the entity will kill all clients."); + G_PrintfClient(ent, "\nUsage: selfdestruct remaining"); + G_PrintfClient(ent, "This will give out the remaining countdown-time even if the count is muted."); + G_PrintfClient(ent, "\nUsage: selfdestruct abort"); G_PrintfClient(ent, "This will abort any self destruct running"); return; } @@ -6331,7 +6331,7 @@ static void Cmd_selfdestruct_f(gentity_t *ent) { //Is there sth running alrerady? destructEnt = G_Find(NULL, FOFS(classname), "target_selfdestruct"); if(destructEnt) { - G_PrintfClient(ent, "There's already a self destruct in progress, aborting setup.\n"); + G_PrintfClient(ent, "There's already a self destruct in progress, aborting setup."); return; } @@ -6350,7 +6350,7 @@ static void Cmd_selfdestruct_f(gentity_t *ent) { destructEnt->flags = atoi(arg6); if(trap_Argc() == 7) { trap_Argv(7, arg7, sizeof(arg7)); - destructEnt->target = arg7; + destructEnt->target = G_NewString(arg7); } destructEnt->spawnflags = 1; //tells ent to free once aborted. G_CallSpawn(destructEnt); //Spawn-Function will also manage init, so we need to call that. @@ -6358,36 +6358,36 @@ static void Cmd_selfdestruct_f(gentity_t *ent) { //Is there sth running alrerady? destructEnt = G_Find(NULL, FOFS(classname), "target_selfdestruct"); if(!destructEnt) { - G_PrintfClient(ent, "There's no self destruct in progress, aborting call.\n"); + G_PrintfClient(ent, "There's no self destruct in progress, aborting call."); return; } //we need the remaining time in minutes and seconds from taht entity. Just ask them off and have the command do the math. ETAsec = floor(modf(((destructEnt->damage - level.time)/60000), &ETAmin)*60); //break it apart, put off the minutes and return the floored secs if (ETAsec > 0) //If we don't have secs we don't need to state that. Need to do a language-switch here... - trap_SendServerCommand( -1, va("servermsg \"Self Destruct in %s minutes and %s seconds.\"", ETAmin, ETAsec)); + trap_SendServerCommand( -1, va("servermsg \"Self Destruct in %.0f minutes and %s.0f seconds.\"", ETAmin, ETAsec)); else - trap_SendServerCommand( -1, va("servermsg \"Self Destruct in %s minutes.\"", ETAmin)); + trap_SendServerCommand( -1, va("servermsg \"Self Destruct in %.0f minutes.\"", ETAmin)); } else if (!Q_stricmp(arg, "abort")) { //Is there sth running alrerady? destructEnt = G_Find(NULL, FOFS(classname), "target_selfdestruct"); if(!destructEnt) { - G_PrintfClient(ent, "There's no self destruct in progress, aborting call.\n"); + G_PrintfClient(ent, "There's no self destruct in progress, aborting call."); return; } destructEnt->use(destructEnt, NULL, NULL); // Use-Function will simply manage the abort } else { - G_PrintfClient(ent, "Error: Invalid command-Argument. Arguments are start, remaining and abort\n"); - G_PrintfClient(ent, "Usage: selfdestruct start duration intervall intervall-60 intervall-10 audio [target]\n"); - G_PrintfClient(ent, "duration: total countdown-duration in seconds.\n"); - G_PrintfClient(ent, "intervall: intervall of audio warnings up to T-60 seconds in seconds.\n"); - G_PrintfClient(ent, "intervall-60: intervall of audio warnings within T-60 seconds in seconds.\n"); - G_PrintfClient(ent, "intervall-10: intervall of audio warnings within T-10 seconds in seconds.\n"); - G_PrintfClient(ent, "audio: set this 0 if you do want a muted countdown, else set this 1.\n"); - G_PrintfClient(ent, "target: Optional Argument. This will be fired once the countdown hits 0. If not set the entity will kill all clients.\n\n"); - G_PrintfClient(ent, "Usage: selfdestruct remaining\n"); - G_PrintfClient(ent, "This will give out the remaining countdown-time even if the count is muted.\n\n"); - G_PrintfClient(ent, "Usage: selfdestruct abort\n"); + G_PrintfClient(ent, "Error: Invalid command-Argument. Arguments are start, remaining and abort"); + G_PrintfClient(ent, "Usage: selfdestruct start duration intervall intervall-60 intervall-10 audio [target]"); + G_PrintfClient(ent, "duration: total countdown-duration in seconds."); + G_PrintfClient(ent, "intervall: intervall of audio warnings up to T-60 seconds in seconds."); + G_PrintfClient(ent, "intervall-60: intervall of audio warnings within T-60 seconds in seconds."); + G_PrintfClient(ent, "intervall-10: intervall of audio warnings within T-10 seconds in seconds."); + G_PrintfClient(ent, "audio: set this 0 if you do want a muted countdown, else set this 1."); + G_PrintfClient(ent, "target: Optional Argument. This will be fired once the countdown hits 0. If not set the entity will kill all clients."); + G_PrintfClient(ent, "\nUsage: selfdestruct remaining"); + G_PrintfClient(ent, "This will give out the remaining countdown-time even if the count is muted."); + G_PrintfClient(ent, "\nUsage: selfdestruct abort"); G_PrintfClient(ent, "This will abort any self destruct running"); return; } diff --git a/game/g_target.c b/game/g_target.c index 9fe9923..0c28cba 100644 --- a/game/g_target.c +++ b/game/g_target.c @@ -2578,7 +2578,7 @@ spawnflags: 1 tells ent to free once aborted void target_selfdestruct_use(gentity_t *ent, gentity_t *other, gentity_t *activator) { //with the use-function we're going to init aborts in a fairly simple manner: Fire warning notes... trap_SendServerCommand( -1, va("servermsg \"Self Destruct sequence aborted.\"")); - trap_SendServerCommand( -1, va("playSnd sound/voice/selfdestruct/abort.mp3\n" ) ); + G_AddEvent(ent, EV_GLOBAL_SOUND, G_SoundIndex("sound/voice/selfdestruct/abort.mp3")); //set wait to -1... ent->wait = -1; //and arrange for a think in a sec @@ -2611,9 +2611,9 @@ void target_selfdestruct_think(gentity_t *ent) { ETAsec = floor(modf((ent->wait / 60000), &ETAmin)*60); if (ent->flags == 1) { if (ETAsec > 0) //If we don't have secs we don't need to state that. - trap_SendServerCommand( -1, va("servermsg \"Self Destruct in %s minutes and %s seconds.\"", ETAmin, ETAsec)); + trap_SendServerCommand( -1, va("servermsg \"Self Destruct in %.0f minutes and %.0f seconds.\"", ETAmin, ETAsec)); else - trap_SendServerCommand( -1, va("servermsg \"Self Destruct in %s minutes.\"", ETAmin)); + trap_SendServerCommand( -1, va("servermsg \"Self Destruct in %.0f minutes.\"", ETAmin)); } // with that out of the way let's set the next think @@ -2640,7 +2640,7 @@ void target_selfdestruct_think(gentity_t *ent) { G_Damage (NULL, NULL, NULL, NULL, NULL, 999999, 0, MOD_TRIGGER_HURT); //maybe a new message ala "[Charname] did not abandon ship." //} //let's hear it - trap_SendServerCommand( -1, va("playSnd sound/weapons/explosions/explode2.wav\n" ) ); + G_AddEvent(ent, EV_GLOBAL_SOUND, G_SoundIndex("sound/weapons/explosions/explode2.wav")); //let's be shakey for a sec... I hope lol ^^ trap_SetConfigstring( CS_CAMERA_SHAKE, va( "%f %i", 999999, (level.time + 1000) ) ); } @@ -2688,36 +2688,39 @@ void SP_target_selfdestruct(gentity_t *ent) { ETAsec = floor(modf((ent->wait / 60000), &ETAmin)*60); if (ent->flags == 1) { if (ETAsec > 0) //If we don't have secs we don't need to state that. - trap_SendServerCommand( -1, va("servermsg \"Self Destruct in %s minutes and %s seconds.\"", ETAmin, ETAsec)); + trap_SendServerCommand( -1, va("servermsg \"Self Destruct in %.0f minutes and %.0f seconds.\"", ETAmin, ETAsec)); else - trap_SendServerCommand( -1, va("servermsg \"Self Destruct in %s minutes.\"", ETAmin)); + trap_SendServerCommand( -1, va("servermsg \"Self Destruct in %.0f minutes.\"", ETAmin)); } else { if (ETAsec > 0) //If we don't have secs we don't need to state that. - trap_SendServerCommand( -1, va("servermsg \"Self Destruct in %s minutes and %s seconds. There will be no further audio warnings.\"", ETAmin, ETAsec)); + trap_SendServerCommand( -1, va("servermsg \"Self Destruct in %.0f minutes and %0.f seconds. There will be no further audio warnings.\"", ETAmin, ETAsec)); else - trap_SendServerCommand( -1, va("servermsg \"Self Destruct in %s minutes. There will be no further audio warnings.\"", ETAmin)); + trap_SendServerCommand( -1, va("servermsg \"Self Destruct in %.0f minutes. There will be no further audio warnings.\"", ETAmin)); } + ent->r.svFlags |= SVF_BROADCAST; + trap_LinkEntity(ent); + //Additionally we have some audio files ready to go in english with automatic german counterparts. Play them as well. if (ent->wait == 1200000) { - trap_SendServerCommand( -1, va("playSnd sound/voice/selfdestruct/20-a1.mp3\n" ) ); + G_AddEvent(ent, EV_GLOBAL_SOUND, G_SoundIndex("sound/voice/selfdestruct/20-a1.mp3")); } else if (ent->wait == 900000) { if (ent->flags == 1) - trap_SendServerCommand( -1, va("playSnd sound/voice/selfdestruct/15-a1.mp3\n" ) ); + G_AddEvent(ent, EV_GLOBAL_SOUND, G_SoundIndex("sound/voice/selfdestruct/15-a1.mp3")); else - trap_SendServerCommand( -1, va("playSnd sound/voice/selfdestruct/15-a0.mp3\n" ) ); + G_AddEvent(ent, EV_GLOBAL_SOUND, G_SoundIndex("sound/voice/selfdestruct/15-a0.mp3")); } else if (ent->wait == 600000) { - trap_SendServerCommand( -1, va("playSnd sound/voice/selfdestruct/10-a1.mp3\n" ) ); + G_AddEvent(ent, EV_GLOBAL_SOUND, G_SoundIndex("sound/voice/selfdestruct/10-a1.mp3")); } else if (ent->wait == 300000) { if (ent->flags == 1) - trap_SendServerCommand( -1, va("playSnd sound/voice/selfdestruct/5-a1.mp3\n" ) ); + G_AddEvent(ent, EV_GLOBAL_SOUND, G_SoundIndex("sound/voice/selfdestruct/5-a1.mp3")); else - trap_SendServerCommand( -1, va("playSnd sound/voice/selfdestruct/5-a0.mp3\n" ) ); + G_AddEvent(ent, EV_GLOBAL_SOUND, G_SoundIndex("sound/voice/selfdestruct/5-a0.mp3")); } else { if (ent->flags == 1) - trap_SendServerCommand( -1, va("playSnd sound/voice/selfdestruct/X-a1.mp3\n" ) ); + G_AddEvent(ent, EV_GLOBAL_SOUND, G_SoundIndex("sound/voice/selfdestruct/X-a1.mp3")); else - trap_SendServerCommand( -1, va("playSnd sound/voice/selfdestruct/X-a0.mp3\n" ) ); + G_AddEvent(ent, EV_GLOBAL_SOUND, G_SoundIndex("sound/voice/selfdestruct/X-a0.mp3")); } // Now all that's left is to plan the next think. diff --git a/stefgame.suo b/stefgame.suo index 7252be8cdb6b8792f811548d3b93cff1de401268..2ce0ecc90a5720733f17742f8113ff4a2119592a 100644 GIT binary patch delta 5583 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 delta 5459 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