From 93c2c1a5b4efbea4e009e65fbdbf5148cd68771c Mon Sep 17 00:00:00 2001 From: tayst Date: Wed, 15 May 2024 14:27:08 +0800 Subject: [PATCH] Japro update (#201) * proper one flag CTF with g_neutralflag 6 in ctf (cherry picked from commit 34fa19f822c637fef44d48730391e77efc419976) * warning fixes (cherry picked from commit 79a98a34b2caf90162872f946b42b6c0c758cb35) --------- Co-authored-by: videoP --- codemp/game/g_cvar.c | 6 +- codemp/game/g_items.c | 18 +++++- codemp/game/g_main.c | 138 ++++++++++++++++++++++++++++++++-------- codemp/game/g_svcmds.c | 10 +++ codemp/game/g_team.c | 91 ++++++++++++++++++++++---- codemp/game/g_trigger.c | 40 +++++++++++- 6 files changed, 257 insertions(+), 46 deletions(-) diff --git a/codemp/game/g_cvar.c b/codemp/game/g_cvar.c index 04f73c7111..a41080d712 100644 --- a/codemp/game/g_cvar.c +++ b/codemp/game/g_cvar.c @@ -247,7 +247,7 @@ static void CVU_Grapple(void) { } */ -static void RemoveRabbit(void) { +void RemoveRabbit(void) { int i; gclient_t *cl; gentity_t *ent; @@ -470,7 +470,7 @@ void CVU_Rabbit( void ) { if (!G_CallSpawn(ent)) G_FreeEntity( ent ); } - else if (((g_neutralFlag.integer == 4 || g_neutralFlag.integer == 5) && (level.gametype == GT_CTF))) { //One Flag CTF + else if (((g_neutralFlag.integer == 4 || g_neutralFlag.integer == 5 || g_neutralFlag.integer == 6) && (level.gametype == GT_CTF))) { //One Flag CTF //Remove and spawn neutral flag. Remove CTF flags RemoveRabbit(); //Delete the current flag first @@ -483,7 +483,7 @@ void CVU_Rabbit( void ) { if (!G_CallSpawn(ent)) G_FreeEntity(ent); } - else if (((g_neutralFlag.integer != 4 && g_neutralFlag.integer != 5) && (level.gametype == GT_CTF))) { //turned off neutral flag in CTF gametype + else if (((g_neutralFlag.integer != 4 && g_neutralFlag.integer != 5 && g_neutralFlag.integer != 6) && (level.gametype == GT_CTF))) { //turned off neutral flag in standard CTF gametype //Remove neutral flag. Remove and add CTF flags. RemoveRabbit(); //Delete the current flag first RemoveRedBlueFlags(); diff --git a/codemp/game/g_items.c b/codemp/game/g_items.c index 04fb49ea36..4cd6a5024c 100644 --- a/codemp/game/g_items.c +++ b/codemp/game/g_items.c @@ -3176,10 +3176,17 @@ void FinishSpawningItem( gentity_t *ent ) { G_FreeEntity( ent ); return; } - if (level.gametype == GT_CTF && g_neutralFlag.integer >= 4) { + if (level.gametype == GT_CTF && (g_neutralFlag.integer == 4 || g_neutralFlag.integer == 5)) { G_FreeEntity(ent); return; } + if (level.gametype == GT_CTF && g_neutralFlag.integer == 6) { + //Get rid of it...only if neutralflag is at base... what am i doing + if (!level.redCapturing) { + G_FreeEntity(ent); + return; + } + } } else if (ent->item->giTag == PW_BLUEFLAG) { VectorCopy(ent->s.origin, level.blueFlagOrigin); @@ -3188,10 +3195,17 @@ void FinishSpawningItem( gentity_t *ent ) { G_FreeEntity( ent ); return; } - if (level.gametype == GT_CTF && g_neutralFlag.integer >= 4) { + if (level.gametype == GT_CTF && (g_neutralFlag.integer == 4 || g_neutralFlag.integer == 5)) { G_FreeEntity(ent); return; } + if (level.gametype == GT_CTF && g_neutralFlag.integer == 6) { + //Get rid of it...only if neutralflag is at base... what am i doing + if (!level.blueCapturing) { + G_FreeEntity(ent); + return; + } + } } } diff --git a/codemp/game/g_main.c b/codemp/game/g_main.c index 8d1e794f66..4c411c3e11 100644 --- a/codemp/game/g_main.c +++ b/codemp/game/g_main.c @@ -3382,42 +3382,128 @@ int BG_GetTime(void) return level.time; } -void OneFlagCTFChecKTimers() { +qboolean G_CallSpawn(gentity_t *ent); +void Team_SetFlagStatus(int team, flagStatus_t status); +void OneFlagCTFCapture(int team) { + //Remvoe team flag, add neutral flag + gentity_t *ent = NULL; + gentity_t *newEnt = NULL; + char *classname; + + if (team == TEAM_RED) { + classname = "team_CTF_redflag"; + level.redCapturing = qfalse; + } + else { + classname = "team_CTF_blueflag"; + level.blueCapturing = qfalse; + } + + trap->SendServerCommand(-1, "cp \""); + trap->SendServerCommand(-1, va("print \"^5The %s^5 team has captured the flag!\n\"", team == 1 ? "^1red" : "^4blue")); + + while ((ent = G_Find(ent, FOFS(classname), classname)) != NULL) { + G_FreeEntity(ent); + } + + newEnt = G_Spawn(qtrue); + newEnt->classname = "team_CTF_neutralflag"; + VectorCopy(level.neutralFlagOrigin, newEnt->s.origin); + if (!G_CallSpawn(newEnt)) + G_FreeEntity(newEnt); + + Team_SetFlagStatus(TEAM_FREE, FLAG_ATBASE); + + AddTeamScore(level.neutralFlagOrigin, team, 1, qfalse); + CalculateRanks(); +} + +void OneFlagCTFCheckTimers() { if (level.gametype != GT_CTF) return; if (g_neutralFlag.integer < 4) return; - if (level.time > level.flagCapturingDebounce) { - int timer = g_neutralFlagTimer.integer; - if (timer < 0) - timer = 0; - if (level.redCapturing) { - if (level.redCaptureTime > 0) - trap->SendServerCommand(-1, va("cp \"^1Red team is capturing! %.0f\n\n\n\n\n\n\n\n\n\n\n\n\"", (timer - level.redCaptureTime) * 0.001f)); //Debounce this print? Or find a better way to visualize it (sound as well?) - level.redCaptureTime += 250; - } - else - level.redCaptureTime -= 250; + if (g_neutralFlag.integer == 5 || g_neutralFlag.integer == 5) { + if (level.time > level.flagCapturingDebounce) { + int timer = g_neutralFlagTimer.integer; + if (timer < 0) + timer = 0; + if (level.redCapturing) { + if (level.redCaptureTime > 0) + trap->SendServerCommand(-1, va("cp \"^1Red team is capturing! %.0f\n\n\n\n\n\n\n\n\n\n\n\n\"", (timer - level.redCaptureTime) * 0.001f)); //Debounce this print? Or find a better way to visualize it (sound as well?) + level.redCaptureTime += 250; + } + else + level.redCaptureTime -= 250; + + if (level.blueCapturing) { + if (level.blueCaptureTime > 0) + trap->SendServerCommand(-1, va("cp \"^4Blue team is capturing! %.0f\n\n\n\n\n\n\n\n\n\n\n\n\"", (timer - level.blueCaptureTime) * 0.001f)); + level.blueCaptureTime += 250; + } + else + level.blueCaptureTime -= 250; - if (level.blueCapturing) { - if (level.blueCaptureTime > 0) - trap->SendServerCommand(-1, va("cp \"^4Blue team is capturing! %.0f\n\n\n\n\n\n\n\n\n\n\n\n\"", (timer - level.blueCaptureTime) * 0.001f)); - level.blueCaptureTime += 250; + if (level.redCaptureTime < 0) + level.redCaptureTime = 0; + if (level.blueCaptureTime < 0) + level.blueCaptureTime = 0; + + + level.redCapturing = qfalse; + level.blueCapturing = qfalse; + + level.flagCapturingDebounce = level.time + 250; } - else - level.blueCaptureTime -= 250; + } + else if (g_neutralFlag.integer == 6) { + if (level.time > level.flagCapturingDebounce) { - if (level.redCaptureTime < 0) - level.redCaptureTime = 0; - if (level.blueCaptureTime < 0) - level.blueCaptureTime = 0; + int timer = g_neutralFlagTimer.integer; + if (timer < 0) + timer = 0; + if (level.redCapturing) { + if (level.redCaptureTime > timer) { + OneFlagCTFCapture(TEAM_RED); + } + else if (level.redCaptureTime > 0) + trap->SendServerCommand(-1, va("cp \"^1Red team is capturing! %.0f\n\n\n\n\n\n\n\n\n\n\n\n\"", (timer - level.redCaptureTime) * 0.001f)); //Debounce this print? Or find a better way to visualize it (sound as well?) - level.redCapturing = qfalse; - level.blueCapturing = qfalse; - level.flagCapturingDebounce = level.time + 250; + + level.redCaptureTime += 250; + } + else { + level.redCaptureTime -= 500; + } + + if (level.blueCapturing) { + if (level.blueCaptureTime > timer) { + OneFlagCTFCapture(TEAM_BLUE); + } + else if (level.blueCaptureTime > 0) + trap->SendServerCommand(-1, va("cp \"^4Blue team is capturing! %.0f\n\n\n\n\n\n\n\n\n\n\n\n\"", (timer - level.blueCaptureTime) * 0.001f)); + + level.blueCaptureTime += 250; + } + else { + level.blueCaptureTime -= 500; + } + + if (level.redCaptureTime < 0) + level.redCaptureTime = 0; + if (level.blueCaptureTime < 0) + level.blueCaptureTime = 0; + + level.flagCapturingDebounce = level.time + 250; + } + + //loda todo real 1flag capture system. + //e.g. + //if level.redcapturing, inc redcapture timer. if redcapture timer >30s or w/e, add point and get rid of red flag, print msg, re spawn neutralflag + //elsewhere, if red flag is taken, need to delete it and instead give person neutralflag. then turn off redcapturing (when flag capture prints? "grabbed the red" } } @@ -4252,7 +4338,7 @@ void G_RunFrame( int levelTime ) { SiegeCheckTimers(); - OneFlagCTFChecKTimers(); + OneFlagCTFCheckTimers(); #ifdef _G_FRAME_PERFANAL trap->PrecisionTimer_Start(&timer_ROFF); diff --git a/codemp/game/g_svcmds.c b/codemp/game/g_svcmds.c index d8ae883792..d8924c607d 100644 --- a/codemp/game/g_svcmds.c +++ b/codemp/game/g_svcmds.c @@ -627,6 +627,7 @@ static void RemoveCTFFlags(void) { } } +void RemoveRabbit(void); void SetGametypeFuncSolids( void ); void G_CacheGametype( void ); qboolean G_CallSpawn( gentity_t *ent ); @@ -662,6 +663,7 @@ void Svcmd_ChangeGametype_f (void) { //because of "variable change -- restarting gentity_t *ent; RemoveCTFFlags(); //Delete the current flag first + RemoveRabbit(); if (level.redFlag) { ent = G_Spawn(qtrue); @@ -677,6 +679,14 @@ void Svcmd_ChangeGametype_f (void) { //because of "variable change -- restarting if (!G_CallSpawn(ent)) G_FreeEntity( ent ); } + + if (level.neutralFlag) { + ent = G_Spawn(qtrue); + ent->classname = "team_CTF_neutralflag"; + VectorCopy(level.neutralFlagOrigin, ent->s.origin); + if (!G_CallSpawn(ent)) + G_FreeEntity(ent); + } } else { RemoveCTFFlags(); diff --git a/codemp/game/g_team.c b/codemp/game/g_team.c index e9e913f552..5504cb539e 100644 --- a/codemp/game/g_team.c +++ b/codemp/game/g_team.c @@ -560,6 +560,37 @@ void Team_CheckHurtCarrier(gentity_t *targ, gentity_t *attacker) } +qboolean G_CallSpawn(gentity_t *ent); +void Team_StartOneFlagCapture(gentity_t *player, int team) { + gentity_t *ent = NULL; + gentity_t *newEnt = NULL; + gitem_t *item; + + while ((ent = G_Find(ent, FOFS(classname), "team_CTF_neutralflag")) != NULL) { + G_FreeEntity(ent); + } + + item = BG_FindItemForPowerup(PW_NEUTRALFLAG); + player->client->ps.powerups[PW_NEUTRALFLAG] = 0; + + newEnt = G_Spawn(qtrue); + if (team == TEAM_RED) { + level.redCapturing = qtrue; + newEnt->classname = "team_CTF_redflag"; + VectorCopy(level.redFlagOrigin, newEnt->s.origin); + } + else if (team == TEAM_BLUE) { + level.blueCapturing = qtrue; + newEnt->classname = "team_CTF_blueflag"; + VectorCopy(level.blueFlagOrigin, newEnt->s.origin); + } + + if (!G_CallSpawn(newEnt)) + G_FreeEntity(newEnt); + + Team_SetFlagStatus(team, FLAG_ATBASE); +} + gentity_t *Team_ResetFlag( int team ) { char *c; gentity_t *ent, *rent = NULL; @@ -1155,17 +1186,31 @@ int Team_TouchEnemyFlag( gentity_t *ent, gentity_t *other, int team ) { } } else { + if (g_neutralFlag.integer == 6) { + if (team == TEAM_RED) { + level.redCapturing = qfalse; + } + else if (team == TEAM_BLUE) { + level.blueCapturing = qfalse; + } + } + if (g_fixCTFScores.integer) { float speed = VectorLength(other->client->ps.velocity); - int points = 0; - if (speed > 1000) - points = 1; if (speed > 2000) points = 2; + else if (speed > 1000) + points = 1; if (team == TEAM_RED) { - if (teamgame.blueStatus == FLAG_ATBASE && teamgame.redStatus == FLAG_ATBASE) - trap->SendServerCommand(-1, va("print \"%s ^5grabbed the ^1red^5 flag at ^3%.0f^5 ups (+^3%i^5)\n\"", other->client->pers.netname, speed, points)); + if (teamgame.blueStatus == FLAG_ATBASE && teamgame.redStatus == FLAG_ATBASE) { + if (g_neutralFlag.integer == 6) { + points += 3; + trap->SendServerCommand(-1, va("print \"%s ^5denied the flag at ^1red^5 base at ^3%.0f^5 ups (+^3%i^5)\n\"", other->client->pers.netname, speed, points)); + } + else + trap->SendServerCommand(-1, va("print \"%s ^5grabbed the ^1red^5 flag at ^3%.0f^5 ups (+^3%i^5)\n\"", other->client->pers.netname, speed, points)); + } else if (teamgame.blueStatus != FLAG_ATBASE) { points += 1; trap->SendServerCommand(-1, va("print \"%s ^5e-grabbed the ^1red^5 flag at ^3%.0f^5 ups (+^3%i^5)\n\"", other->client->pers.netname, speed, points)); @@ -1174,8 +1219,14 @@ int Team_TouchEnemyFlag( gentity_t *ent, gentity_t *other, int team ) { trap->SendServerCommand(-1, va("print \"%s ^5grabbed the ^1red^5 flag\n\"", other->client->pers.netname)); } else if (team == TEAM_BLUE) { - if (teamgame.redStatus == FLAG_ATBASE && teamgame.blueStatus == FLAG_ATBASE) - trap->SendServerCommand(-1, va("print \"%s ^5grabbed the ^4blue^5 flag at ^3%.0f^5 ups (+^3%i^5)\n\"", other->client->pers.netname, speed, points)); + if (teamgame.redStatus == FLAG_ATBASE && teamgame.blueStatus == FLAG_ATBASE) { + if (g_neutralFlag.integer == 6) { + points += 3; + trap->SendServerCommand(-1, va("print \"%s ^5denied the flag at ^4blue^5 base at ^3%.0f^5 ups (+^3%i^5)\n\"", other->client->pers.netname, speed, points)); + } + else + trap->SendServerCommand(-1, va("print \"%s ^5grabbed the ^4blue^5 flag at ^3%.0f^5 ups (+^3%i^5)\n\"", other->client->pers.netname, speed, points)); + } else if (teamgame.redStatus != FLAG_ATBASE) { points += 1; trap->SendServerCommand(-1, va("print \"%s ^5e-grabbed the ^4blue^5 flag at ^3%.0f^5 ups (+^3%i^5)\n\"", other->client->pers.netname, speed, points)); @@ -1184,19 +1235,33 @@ int Team_TouchEnemyFlag( gentity_t *ent, gentity_t *other, int team ) { trap->SendServerCommand(-1, va("print \"%s ^5grabbed the ^4blue^5 flag\n\"", other->client->pers.netname)); } else { - PrintCTFMessage(other->s.number, team, CTFMESSAGE_PLAYER_GOT_FLAG); + if (teamgame.flagStatus == FLAG_ATBASE) { + points += 1; + trap->SendServerCommand(-1, va("print \"%s ^5grabbed the flag at ^3%.0f^5 ups (+^3%i^5)\n\"", other->client->pers.netname, speed, points)); + } + else if (teamgame.flagStatus != FLAG_ATBASE) { + trap->SendServerCommand(-1, va("print \"%s ^5fielded the flag at ^3%.0f^5 ups (+^3%i^5)\n\"", other->client->pers.netname, speed, points)); + } + else + trap->SendServerCommand(-1, va("print \"%s ^5grabbed the flag\n\"", other->client->pers.netname)); } } else { PrintCTFMessage(other->s.number, team, CTFMESSAGE_PLAYER_GOT_FLAG); } } - if (team == TEAM_RED) - cl->ps.powerups[PW_REDFLAG] = INT_MAX; // flags never expire - else if (team == TEAM_BLUE) - cl->ps.powerups[PW_BLUEFLAG] = INT_MAX; // flags never expire - else//Rabbit + + if (level.gametype == GT_CTF && g_neutralFlag.integer == 6) { cl->ps.powerups[PW_NEUTRALFLAG] = INT_MAX; // flags never expire + } + else { + if (team == TEAM_RED) + cl->ps.powerups[PW_REDFLAG] = INT_MAX; // flags never expire + else if (team == TEAM_BLUE) + cl->ps.powerups[PW_BLUEFLAG] = INT_MAX; // flags never expire + else//Rabbit + cl->ps.powerups[PW_NEUTRALFLAG] = INT_MAX; // flags never expire + } if ((team == TEAM_RED && teamgame.redStatus == FLAG_ATBASE) || (team == TEAM_BLUE && teamgame.blueStatus == FLAG_ATBASE)) {//JAPRO SHITTY FLAG TIMER cl->pers.stats.startTimeFlag = level.time; diff --git a/codemp/game/g_trigger.c b/codemp/game/g_trigger.c index 176f274d67..8d8b8abce9 100644 --- a/codemp/game/g_trigger.c +++ b/codemp/game/g_trigger.c @@ -158,6 +158,8 @@ qboolean G_NameInTriggerClassList(char *list, char *str) return qfalse; } +void PrintCTFMessage(int plIndex, int teamIndex, int ctfMessage); +void Team_StartOneFlagCapture(gentity_t *player, int team); int Team_TouchOneFlagBase(gentity_t *ent, gentity_t *other, int team); extern qboolean gSiegeRoundBegun; void SiegeItemRemoveOwner(gentity_t *ent, gentity_t *carrier); @@ -205,9 +207,8 @@ void multi_trigger( gentity_t *ent, gentity_t *activator ) return; } - if (level.gametype == GT_CTF && (ent->spawnflags & 16384) && activator && activator->client) { + if (level.gametype == GT_CTF && (ent->spawnflags & 16384) && activator && activator->client && g_neutralFlag.integer < 6) { if (activator->client->ps.powerups[PW_NEUTRALFLAG]) { - if (g_neutralFlag.integer == 4 && activator->client->sess.sessionTeam != ent->alliedTeam) return; if (g_neutralFlag.integer == 5 && activator->client->sess.sessionTeam == ent->alliedTeam) @@ -230,6 +231,41 @@ void multi_trigger( gentity_t *ent, gentity_t *activator ) } } + if (level.gametype == GT_CTF && (ent->spawnflags & 32768) && activator && activator->client && g_neutralFlag.integer == 6) { + if (activator->client->ps.powerups[PW_NEUTRALFLAG]) { + if (ent->alliedTeam == TEAM_RED) { + Team_StartOneFlagCapture(activator, ent->alliedTeam); + } + else if (ent->alliedTeam == TEAM_BLUE) { + Team_StartOneFlagCapture(activator, ent->alliedTeam); + } + + AddScore(activator, ent->r.currentOrigin, 3); + + if (activator->client->pers.stats.startTimeFlag) {//JAPRO SHITTY FLAG TIMER + const float time = (level.time - activator->client->pers.stats.startTimeFlag) / 1000.0f; + //int average = floorf(cl->pers.stats.displacementFlag / time) + 0.5f; + int average; + if (activator->client->pers.stats.displacementFlagSamples) + average = floorf(((activator->client->pers.stats.displacementFlag * sv_fps.value) / activator->client->pers.stats.displacementFlagSamples) + 0.5f); + else + average = activator->client->pers.stats.topSpeedFlag; + + trap->SendServerCommand(-1, va("print \"%s^5 has placed the flag at %s^5 base in ^3%.2f^5 seconds with max of ^3%i^5 ups and average ^3%i^5 ups (^3%i^5)\n\"", activator->client->pers.netname, ent->alliedTeam == 1 ? "^1red" : "^4blue", time, (int)floorf(activator->client->pers.stats.topSpeedFlag + 0.5f), average, 3)); + activator->client->pers.stats.startTimeFlag = 0; + activator->client->pers.stats.topSpeedFlag = 0; + activator->client->pers.stats.displacementFlag = 0; + activator->client->pers.stats.displacementFlagSamples = 0; + } + else if (g_fixCTFScores.integer) { + trap->SendServerCommand(-1, va("print \"%s^5 has placed the flat at %s^5 base (+^33^5)\n\"", activator->client->pers.netname, ent->alliedTeam == 1 ? "^1red" : "^4blue")); + } + else + PrintCTFMessage(activator->s.number, ent->alliedTeam, CTFMESSAGE_PLAYER_CAPTURED_FLAG); + + } + } + if (level.gametype == GT_SIEGE && ent->genericValue1) { haltTrigger = qtrue;