From: Rudolf Polzer Date: Sun, 24 Oct 2010 12:14:49 +0000 (+0200) Subject: Merge remote branch 'refs/remotes/origin/fruitiex/ca_nodmg_after_round' X-Git-Tag: xonotic-v0.1.0preview~245^2~8 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=commitdiff_plain;h=1430d30ddc3e83966012a69c4caf17f220a53c52;hp=a83b99f70b5e102960fd6a8acb48c40f07d43b43 Merge remote branch 'refs/remotes/origin/fruitiex/ca_nodmg_after_round' --- diff --git a/defaultXonotic.cfg b/defaultXonotic.cfg index 3ac447e864..0ba520e135 100644 --- a/defaultXonotic.cfg +++ b/defaultXonotic.cfg @@ -615,6 +615,8 @@ set g_arena_respawn_delay 0 set g_arena_respawn_waves 0 set g_ca_respawn_delay 0 set g_ca_respawn_waves 0 +set g_ca_damage2score_multiplier 0.01 +set g_ca_round_timelimit 180 set g_nexball_respawn_delay 0 set g_nexball_respawn_waves 0 set g_as_respawn_delay 0 diff --git a/gfx/hud/default/player_blue.tga b/gfx/hud/default/player_blue.tga new file mode 100644 index 0000000000..cf10bc5fe4 Binary files /dev/null and b/gfx/hud/default/player_blue.tga differ diff --git a/gfx/hud/default/player_red.tga b/gfx/hud/default/player_red.tga new file mode 100644 index 0000000000..aea0ed85b7 Binary files /dev/null and b/gfx/hud/default/player_red.tga differ diff --git a/qcsrc/client/hud.qc b/qcsrc/client/hud.qc index 357f8a0e35..7ce1a202d6 100644 --- a/qcsrc/client/hud.qc +++ b/qcsrc/client/hud.qc @@ -3859,6 +3859,37 @@ void HUD_VoteWindow(void) float mod_active; // is there any active mod icon? +// Clan Arena HUD modicons +void HUD_Mod_CA(vector pos, vector mySize) +{ + mod_active = 1; // CA should never hide the mod icons panel + float redalive, bluealive; + redalive = getstati(STAT_REDALIVE); + bluealive = getstati(STAT_BLUEALIVE); + + drawfont = hud_bigfont; + vector redpos, bluepos; + if(mySize_x > mySize_y) + { + redpos = pos; + bluepos = pos + eY * 0.5 * mySize_y; + drawpic_aspect_skin(redpos, "player_red.tga", 0.5 * mySize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); + drawstring_aspect(redpos + eX * 0.5 * mySize_x, ftos(redalive), 0.5 * mySize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); + drawpic_aspect_skin(bluepos, "player_blue.tga", 0.5 * mySize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); + drawstring_aspect(bluepos + eX * 0.5 * mySize_x, ftos(bluealive), 0.5 * mySize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); + } + else + { + redpos = pos; + bluepos = pos + eY * 0.5 * mySize_y; + drawpic_aspect_skin(redpos, "player_red.tga", eX * mySize_x + eY * 0.3 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); + drawstring_aspect(redpos + eY * 0.3 * mySize_y, ftos(redalive), eX * mySize_x + eY * 0.2 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); + drawpic_aspect_skin(bluepos, "player_blue.tga", eX * mySize_x + eY * 0.3 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); + drawstring_aspect(bluepos + eY * 0.3 * mySize_y, ftos(bluealive), eX * mySize_x + eY * 0.2 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); + } + drawfont = hud_font; +} + // CTF HUD modicon section float redflag_prevframe, blueflag_prevframe; // status during previous frame float redflag_prevstatus, blueflag_prevstatus; // last remembered status @@ -4355,7 +4386,7 @@ void HUD_ModIcons(void) if(!autocvar_hud_panel_modicons && !autocvar__hud_configure) return; - if (gametype != GAME_KEYHUNT && gametype != GAME_CTF && gametype != GAME_NEXBALL && gametype != GAME_CTS && gametype != GAME_RACE && !autocvar__hud_configure) + if (gametype != GAME_KEYHUNT && gametype != GAME_CTF && gametype != GAME_NEXBALL && gametype != GAME_CTS && gametype != GAME_RACE && gametype != GAME_CA && !autocvar__hud_configure) return; active_panel = HUD_PANEL_MODICONS; @@ -4392,6 +4423,8 @@ void HUD_ModIcons(void) HUD_Mod_NexBall(pos, mySize); else if(gametype == GAME_CTS || gametype == GAME_RACE) HUD_Mod_Race(pos, mySize); + else if(gametype == GAME_CA) + HUD_Mod_CA(pos, mySize); } // Draw pressed keys (#11) diff --git a/qcsrc/common/constants.qh b/qcsrc/common/constants.qh index 6f0eccfafb..b4b92ff8bd 100644 --- a/qcsrc/common/constants.qh +++ b/qcsrc/common/constants.qh @@ -310,6 +310,7 @@ const float STAT_SHOTORG = 46; // compressShotOrigin const float STAT_LEADLIMIT = 47; const float STAT_BULLETS_LOADED = 48; const float STAT_NEX_CHARGE = 49; +const float STAT_HUD = 50; // see DP source, quakedef.h const float STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW = 222; @@ -320,7 +321,6 @@ const float CTF_STATE_ATTACK = 1; const float CTF_STATE_DEFEND = 2; const float CTF_STATE_COMMANDER = 3; -const float STAT_HUD = 50; const float HUD_NORMAL = 0; const float HUD_SPIDERBOT = 10; const float HUD_WAKIZASHI = 11; @@ -337,6 +337,10 @@ const float STAT_VEHICLESTAT_RELOAD1 = 64; const float STAT_VEHICLESTAT_AMMO2 = 65; const float STAT_VEHICLESTAT_RELOAD2 = 66; +// mod stats (1xx) +const float STAT_REDALIVE = 100; +const float STAT_BLUEALIVE = 101; + //const float STAT_SPIDERBOT_AIM 53 // compressShotOrigin //const float STAT_SPIDERBOT_TARGET 54 // compressShotOrigin diff --git a/qcsrc/server/arena.qc b/qcsrc/server/arena.qc index ee4ce1b87e..046743151d 100644 --- a/qcsrc/server/arena.qc +++ b/qcsrc/server/arena.qc @@ -8,8 +8,8 @@ float arena_roundbased; entity spawnqueue_first; entity spawnqueue_last; entity champion; +string champion_name; float warmup; -float allowed_to_spawn; float ca_players; float required_ca_players; .float caplayer; @@ -122,7 +122,7 @@ void reset_map(float dorespawn) if(g_keyhunt) kh_Controller_SetThink(cvar("g_balance_keyhunt_delay_round")+(game_starttime - time), "", kh_StartRound); - if(g_arena || g_ca) + if(g_arena) if(champion && champion.classname == "player" && player_count > 1) UpdateFrags(champion, +1); @@ -195,11 +195,15 @@ void Arena_Warmup() if((!g_arena && !g_ca) || (g_arena && !arena_roundbased) || (time < game_starttime)) return; - f = floor(warmup - time + 1); + f = ceil(warmup - time); + if(f > 0) + champion = world; // this is done because a if(champion) will not execute if champion = world allowed_to_spawn = 0; - if(g_ca && (ca_players < required_ca_players || inWarmupStage)) + if(inWarmupStage) + allowed_to_spawn = 1; + if(ca_players < required_ca_players) allowed_to_spawn = 1; msg = NEWLINES; @@ -208,7 +212,7 @@ void Arena_Warmup() if (g_ca) allowed_to_spawn = 1; if(champion && g_arena) - msg = strcat("The Champion is ", champion.netname, "^7\n"); + msg = strcat("The Champion is ", champion_name, "^7\n"); //centerprint(self, strcat(msg, "The Champion is ", champion.netname, "^7\n")); if(f != roundStartTime_prev) { @@ -257,6 +261,9 @@ void Arena_Warmup() } float next_round; +float stopalivecheck; +float redalive, bluealive; +.float redalive_stat, bluealive_stat; /** * This function finds out whether an arena round is over 1 player is left. * It determines the last player who's still alive and saves it's entity reference @@ -266,6 +273,22 @@ float next_round; */ void Spawnqueue_Check() { + if(g_ca) // we want to perform this before the return block below... + { + // this is STUPID to perform again, but has to be done so that we can give instant feedback when a round ends + // and so the code won't start searching for a champion using find() before all players are actually REMOVED + redalive = 0; bluealive = 0; + FOR_EACH_PLAYER(self) { + if (self.team == COLOR_TEAM1 && self.health >= 1) redalive += 1; + else if (self.team == COLOR_TEAM2 && self.health >= 1) bluealive += 1; + } + // as if the above stuff wasn't stupid enough, let's run it a third time! :D + // (so that we can send redalive/bluealive as a stat) + FOR_EACH_PLAYER(self) { + self.redalive_stat = redalive; + self.bluealive_stat = bluealive; + } + } if(time < warmup + 1 || inWarmupStage) return; @@ -285,34 +308,43 @@ void Spawnqueue_Check() else if(ca_players < required_ca_players) { FOR_EACH_PLAYER(self) centerprint(self, strcat("^1Need at least 1 player in each team to play CA", "^7\n")); - - allowed_to_spawn = 1; return; } else if(!next_round) { if((redspawned && !bluespawned) || (bluespawned && !redspawned)) { next_round = time + 5; - champion = find(world, classname, "player"); - string champion_team; - if(champion.team == COLOR_TEAM1) { - champion_team = "^1Red team"; - play2all("ctf/red_capture.wav"); - } - else if(champion.team == COLOR_TEAM2) { - champion_team = "^4Blue team"; - play2all("ctf/blue_capture.wav"); - } - FOR_EACH_CLIENT(self) centerprint(self, strcat(champion_team, "^7 wins the round.", "^7\n")); + if(champion_name) + strunzone(champion_name); + champion_name = strzone(champion.netname); } - else if(!redspawned && !bluespawned) { + else if((!redspawned && !bluespawned) || time - warmup > cvar("g_ca_round_timelimit")) { FOR_EACH_CLIENT(self) centerprint(self, strcat("^7Round tied.", "^7\n")); next_round = time + 5; } + + } + if(!stopalivecheck) + { + if(redalive && !bluealive) + { + play2all("ctf/red_capture.wav"); + FOR_EACH_CLIENT(self) centerprint(self, "^1 RED ^7team wins the round.\n"); + TeamScore_AddToTeam(COLOR_TEAM1, ST_SCORE, +1); + stopalivecheck = TRUE; + } + else if(bluealive && !redalive) + { + play2all("ctf/blue_capture.wav"); + FOR_EACH_CLIENT(self) centerprint(self, "^4 BLUE ^7team wins the round.\n"); + TeamScore_AddToTeam(COLOR_TEAM2, ST_SCORE, +1); + stopalivecheck = TRUE; + } } if((next_round && next_round < time)) { + stopalivecheck = FALSE; next_round = 0; reset_map(TRUE); } diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index df6c8d4b2a..bb2b753b84 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -1305,7 +1305,12 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto void ClientKill (void) { - ClientKill_TeamChange(0); + if((g_arena || g_ca) && ((champion && champion.classname == "player" && player_count > 1) || player_count == 1)) // don't allow a kill in this case either + { + // do nothing + } + else + ClientKill_TeamChange(0); } void DoTeamChange(float destteam) diff --git a/qcsrc/server/clientcommands.qc b/qcsrc/server/clientcommands.qc index a9fd886bfe..b705e9c09c 100644 --- a/qcsrc/server/clientcommands.qc +++ b/qcsrc/server/clientcommands.qc @@ -430,7 +430,7 @@ void ReadyRestartForce() readyrestart_happened = 1; game_starttime = time; - if(!g_ca) + if(!g_ca && !g_arena) game_starttime += RESTART_COUNTDOWN; restart_mapalreadyrestarted = 0; //reset this var, needed when cvar sv_ready_restart_repeatable is in use @@ -448,7 +448,7 @@ void ReadyRestartForce() } //initiate the restart-countdown-announcer entity - if(cvar("sv_ready_restart_after_countdown")) + if(cvar("sv_ready_restart_after_countdown") && !g_ca && !g_arena) { restartTimer = spawn(); restartTimer.think = restartTimer_Think; diff --git a/qcsrc/server/defs.qh b/qcsrc/server/defs.qh index d1d86ed79a..745a6e0b2a 100644 --- a/qcsrc/server/defs.qh +++ b/qcsrc/server/defs.qh @@ -651,3 +651,5 @@ string deathmessage; .entity realowner; .float nex_charge; + +float allowed_to_spawn; // boolean variable used by the clan arena code to determine if a player can spawn (after the round has ended) diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index c7336356ca..ab0638387e 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -753,6 +753,8 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float if(deathtype & HITTYPE_HEADSHOT) headshot = 1; } + if(g_ca) + PlayerScore_Add(attacker, SP_SCORE, damage * cvar("g_ca_damage2score_multiplier")); } } else diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index 08329a29d7..6260d7e86d 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -440,6 +440,8 @@ void spawnfunc_worldspawn (void) compressShortVector_init(); + allowed_to_spawn = TRUE; + local entity head; head = nextent(world); maxclients = 0; @@ -642,6 +644,11 @@ void spawnfunc_worldspawn (void) addstat(STAT_NEX_CHARGE, AS_FLOAT, nex_charge); + if(g_ca) + { + addstat(STAT_REDALIVE, AS_INT, redalive_stat); + addstat(STAT_BLUEALIVE, AS_INT, bluealive_stat); + } // g_movementspeed hack addstat(STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW, AS_FLOAT, stat_sv_airspeedlimit_nonqw); addstat(STAT_MOVEVARS_AIRACCEL_QW, AS_FLOAT, stat_sv_airaccel_qw);