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
// let's reset the view back to normal for the end
R_SetView(VF_MIN, '0 0 0');
R_SetView(VF_SIZE, '1 0 0' * w + '0 1 0' * h);
-
- // be safe against triggerbots until everyone has the fixed engine
- // this call is meant to overwrite the trace globals by something
- // unsuspicious
- traceline('0 0 0', '0 0 0', MOVE_WORLDONLY, world);
}
#define spider_h "gfx/vehicles/hud_bg.tga"
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
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;
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)
}
// this draws the triangles of a model DIRECTLY. Don't expect high performance, really...
-void PolyDrawModel(entity e)
+float PolyDrawModelSurface(entity e, float i_s)
{
- float i_s, i_t;
+ float i_t;
float n_t;
vector tri;
string tex;
- for(i_s = 0; ; ++i_s)
+ tex = getsurfacetexture(e, i_s);
+ if not(tex)
+ return 0; // this is beyond the last one
+ n_t = getsurfacenumtriangles(e, i_s);
+ for(i_t = 0; i_t < n_t; ++i_t)
{
- tex = getsurfacetexture(e, i_s);
- if not(tex)
- break; // this is beyond the last one
- n_t = getsurfacenumtriangles(e, i_s);
- for(i_t = 0; i_t < n_t; ++i_t)
- {
- tri = getsurfacetriangle(e, i_s, i_t);
- R_BeginPolygon(tex, 0);
- R_PolygonVertex(getsurfacepoint(e, i_s, tri_x), getsurfacepointattribute(e, i_s, tri_x, SPA_TEXCOORDS0), '1 1 1', 1);
- R_PolygonVertex(getsurfacepoint(e, i_s, tri_y), getsurfacepointattribute(e, i_s, tri_y, SPA_TEXCOORDS0), '1 1 1', 1);
- R_PolygonVertex(getsurfacepoint(e, i_s, tri_z), getsurfacepointattribute(e, i_s, tri_z, SPA_TEXCOORDS0), '1 1 1', 1);
- R_EndPolygon();
- }
+ tri = getsurfacetriangle(e, i_s, i_t);
+ R_BeginPolygon(tex, 0);
+ R_PolygonVertex(getsurfacepoint(e, i_s, tri_x), getsurfacepointattribute(e, i_s, tri_x, SPA_TEXCOORDS0), '1 1 1', 1);
+ R_PolygonVertex(getsurfacepoint(e, i_s, tri_y), getsurfacepointattribute(e, i_s, tri_y, SPA_TEXCOORDS0), '1 1 1', 1);
+ R_PolygonVertex(getsurfacepoint(e, i_s, tri_z), getsurfacepointattribute(e, i_s, tri_z, SPA_TEXCOORDS0), '1 1 1', 1);
+ R_EndPolygon();
}
+ return 1;
+}
+void PolyDrawModel(entity e)
+{
+ float i_s;
+ for(i_s = 0; ; ++i_s)
+ if(!PolyDrawModelSurface(e, i_s))
+ break;
}
void DrawCircleClippedPic(vector centre, float radius, string pic, float f, vector rgb, float a, float drawflag)
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;
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;
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
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;
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);
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;
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) {
}
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
*/
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;
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);
}
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 CTS_ClientKill_Think (void)
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
}
//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;
.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)
if(deathtype & HITTYPE_HEADSHOT)
headshot = 1;
}
+ if(g_ca)
+ PlayerScore_Add(attacker, SP_SCORE, damage * cvar("g_ca_damage2score_multiplier"));
}
}
else
compressShortVector_init();
+ allowed_to_spawn = TRUE;
+
local entity head;
head = nextent(world);
maxclients = 0;
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);