From: Mario Date: Mon, 2 Feb 2015 20:13:37 +0000 (+1100) Subject: Merge branch 'master' into Mario/ctf_updates X-Git-Tag: xonotic-v0.8.1~29^2~17 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=530e06120a7b41f6175b1144fedf6903da8c13b0;p=xonotic%2Fxonotic-data.pk3dir.git Merge branch 'master' into Mario/ctf_updates Conflicts: qcsrc/client/hud.qc qcsrc/client/progs.src qcsrc/common/notifications.qh qcsrc/common/stats.qh qcsrc/server/mutators/gamemode_ctf.qc qcsrc/server/mutators/gamemode_ctf.qh --- 530e06120a7b41f6175b1144fedf6903da8c13b0 diff --cc qcsrc/client/hud.qc index 136b77361,e33b9b020..d22459af7 --- a/qcsrc/client/hud.qc +++ b/qcsrc/client/hud.qc @@@ -1,3 -1,11 +1,12 @@@ + #include "scoreboard.qh" + #include "teamradar.qh" + #include "../common/buffs.qh" + #include "../common/counting.qh" + #include "../common/mapinfo.qh" + #include "../common/nades.qh" + #include "../server/t_items.qh" ++#include "../server/mutators/gamemode_ctf.qh" + /* ================== Misc HUD functions @@@ -2759,9 -2767,9 +2768,9 @@@ void HUD_Mod_CA(vector myPos, vector my } // CTF HUD modicon section - float redflag_prevframe, blueflag_prevframe, yellowflag_prevframe, pinkflag_prevframe, neutralflag_prevframe; // status during previous frame - float redflag_prevstatus, blueflag_prevstatus, yellowflag_prevstatus, pinkflag_prevstatus, neutralflag_prevstatus; // last remembered status - float redflag_statuschange_time, blueflag_statuschange_time, yellowflag_statuschange_time, pinkflag_statuschange_time, neutralflag_statuschange_time; // time when the status changed -float redflag_prevframe, blueflag_prevframe; // status during previous frame -float redflag_prevstatus, blueflag_prevstatus; // last remembered status -float redflag_statuschange_time, blueflag_statuschange_time; // time when the status changed ++int redflag_prevframe, blueflag_prevframe, yellowflag_prevframe, pinkflag_prevframe, neutralflag_prevframe; // status during previous frame ++int redflag_prevstatus, blueflag_prevstatus, yellowflag_prevstatus, pinkflag_prevstatus, neutralflag_prevstatus; // last remembered status ++int redflag_statuschange_time, blueflag_statuschange_time, yellowflag_statuschange_time, pinkflag_statuschange_time, neutralflag_statuschange_time; // time when the status changed void HUD_Mod_CTF_Reset(void) { @@@ -2776,22 -2782,15 +2785,22 @@@ void HUD_Mod_CTF(vector pos, vector myS vector flag_size; float f; // every function should have that - float redflag, blueflag, yellowflag, pinkflag, neutralflag; // current status - float redflag, blueflag; // current status - float redflag_statuschange_elapsedtime, blueflag_statuschange_elapsedtime; // time since the status changed - float stat_items; - - stat_items = getstati(STAT_ITEMS, 0, 24); - redflag = (stat_items/IT_RED_FLAG_TAKEN) & 3; - blueflag = (stat_items/IT_BLUE_FLAG_TAKEN) & 3; - - if(redflag || blueflag) ++ int redflag, blueflag, yellowflag, pinkflag, neutralflag; // current status + float redflag_statuschange_elapsedtime, blueflag_statuschange_elapsedtime, yellowflag_statuschange_elapsedtime, pinkflag_statuschange_elapsedtime, neutralflag_statuschange_elapsedtime; // time since the status changed - float ctf_oneflag; // one-flag CTF mode enabled/disabled - float stat_items = getstati(STAT_CTF_FLAGSTATUS, 0, 24); ++ bool ctf_oneflag; // one-flag CTF mode enabled/disabled ++ int stat_items = getstati(STAT_CTF_FLAGSTATUS, 0, 24); + float fs, fs2, fs3, size1, size2; + vector e1, e2; + + redflag = (stat_items/CTF_RED_FLAG_TAKEN) & 3; + blueflag = (stat_items/CTF_BLUE_FLAG_TAKEN) & 3; + yellowflag = (stat_items/CTF_YELLOW_FLAG_TAKEN) & 3; + pinkflag = (stat_items/CTF_PINK_FLAG_TAKEN) & 3; + neutralflag = (stat_items/CTF_NEUTRAL_FLAG_TAKEN) & 3; + + ctf_oneflag = (stat_items & CTF_FLAG_NEUTRAL); + + if(redflag || blueflag || yellowflag || pinkflag || neutralflag) mod_active = 1; else mod_active = 0; @@@ -2822,46 -2816,22 +2831,47 @@@ blueflag_prevframe = blueflag; } + if (yellowflag != yellowflag_prevframe) + { + yellowflag_statuschange_time = time; + yellowflag_prevstatus = yellowflag_prevframe; + yellowflag_prevframe = yellowflag; + } + + if (pinkflag != pinkflag_prevframe) + { + pinkflag_statuschange_time = time; + pinkflag_prevstatus = pinkflag_prevframe; + pinkflag_prevframe = pinkflag; + } + + if (neutralflag != neutralflag_prevframe) + { + neutralflag_statuschange_time = time; + neutralflag_prevstatus = neutralflag_prevframe; + neutralflag_prevframe = neutralflag; + } + redflag_statuschange_elapsedtime = time - redflag_statuschange_time; blueflag_statuschange_elapsedtime = time - blueflag_statuschange_time; + yellowflag_statuschange_elapsedtime = time - yellowflag_statuschange_time; + pinkflag_statuschange_elapsedtime = time - pinkflag_statuschange_time; + neutralflag_statuschange_elapsedtime = time - neutralflag_statuschange_time; -- float BLINK_FACTOR = 0.15; -- float BLINK_BASE = 0.85; ++ const float BLINK_FACTOR = 0.15; ++ const float BLINK_BASE = 0.85; // note: // RMS = sqrt(BLINK_BASE^2 + 0.5 * BLINK_FACTOR^2) // thus // BLINK_BASE = sqrt(RMS^2 - 0.5 * BLINK_FACTOR^2) // ensure RMS == 1 -- float BLINK_FREQ = 5; // circle frequency, = 2*pi*frequency in hertz ++ const float BLINK_FREQ = 5; // circle frequency, = 2*pi*frequency in hertz string red_icon, red_icon_prevstatus; -- float red_alpha, red_alpha_prevstatus; ++ int red_alpha, red_alpha_prevstatus; red_alpha = red_alpha_prevstatus = 1; -- switch(redflag) { ++ switch(redflag) ++ { case 1: red_icon = "flag_red_taken"; break; case 2: red_icon = "flag_red_lost"; break; case 3: red_icon = "flag_red_carrying"; red_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break; @@@ -2872,7 -2842,7 +2882,8 @@@ red_icon = string_null; break; } -- switch(redflag_prevstatus) { ++ switch(redflag_prevstatus) ++ { case 1: red_icon_prevstatus = "flag_red_taken"; break; case 2: red_icon_prevstatus = "flag_red_lost"; break; case 3: red_icon_prevstatus = "flag_red_carrying"; red_alpha_prevstatus = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break; @@@ -2887,9 -2857,9 +2898,10 @@@ } string blue_icon, blue_icon_prevstatus; -- float blue_alpha, blue_alpha_prevstatus; ++ int blue_alpha, blue_alpha_prevstatus; blue_alpha = blue_alpha_prevstatus = 1; -- switch(blueflag) { ++ switch(blueflag) ++ { case 1: blue_icon = "flag_blue_taken"; break; case 2: blue_icon = "flag_blue_lost"; break; case 3: blue_icon = "flag_blue_carrying"; blue_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break; @@@ -2900,7 -2870,7 +2912,8 @@@ blue_icon = string_null; break; } -- switch(blueflag_prevstatus) { ++ switch(blueflag_prevstatus) ++ { case 1: blue_icon_prevstatus = "flag_blue_taken"; break; case 2: blue_icon_prevstatus = "flag_blue_lost"; break; case 3: blue_icon_prevstatus = "flag_blue_carrying"; blue_alpha_prevstatus = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break; @@@ -2914,157 -2884,25 +2927,163 @@@ break; } - if(mySize.x > mySize.y) { - if (myteam == NUM_TEAM_1) { // always draw own flag on left + string yellow_icon, yellow_icon_prevstatus; - float yellow_alpha, yellow_alpha_prevstatus; ++ int yellow_alpha, yellow_alpha_prevstatus; + yellow_alpha = yellow_alpha_prevstatus = 1; - switch(yellowflag) { ++ switch(yellowflag) ++ { + case 1: yellow_icon = "flag_yellow_taken"; break; + case 2: yellow_icon = "flag_yellow_lost"; break; + case 3: yellow_icon = "flag_yellow_carrying"; yellow_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break; + default: + if((stat_items & CTF_SHIELDED) && (myteam != NUM_TEAM_3)) + yellow_icon = "flag_yellow_shielded"; + else + yellow_icon = string_null; + break; + } - switch(yellowflag_prevstatus) { ++ switch(yellowflag_prevstatus) ++ { + case 1: yellow_icon_prevstatus = "flag_yellow_taken"; break; + case 2: yellow_icon_prevstatus = "flag_yellow_lost"; break; + case 3: yellow_icon_prevstatus = "flag_yellow_carrying"; yellow_alpha_prevstatus = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break; + default: + if(yellowflag == 3) + yellow_icon_prevstatus = "flag_yellow_carrying"; // make it more visible + else if((stat_items & CTF_SHIELDED) && (myteam != NUM_TEAM_3)) + yellow_icon_prevstatus = "flag_yellow_shielded"; + else + yellow_icon_prevstatus = string_null; + break; + } + + string pink_icon, pink_icon_prevstatus; - float pink_alpha, pink_alpha_prevstatus; ++ int pink_alpha, pink_alpha_prevstatus; + pink_alpha = pink_alpha_prevstatus = 1; - switch(pinkflag) { ++ switch(pinkflag) ++ { + case 1: pink_icon = "flag_pink_taken"; break; + case 2: pink_icon = "flag_pink_lost"; break; + case 3: pink_icon = "flag_pink_carrying"; pink_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break; + default: + if((stat_items & CTF_SHIELDED) && (myteam != NUM_TEAM_4)) + pink_icon = "flag_pink_shielded"; + else + pink_icon = string_null; + break; + } - switch(pinkflag_prevstatus) { ++ switch(pinkflag_prevstatus) ++ { + case 1: pink_icon_prevstatus = "flag_pink_taken"; break; + case 2: pink_icon_prevstatus = "flag_pink_lost"; break; + case 3: pink_icon_prevstatus = "flag_pink_carrying"; pink_alpha_prevstatus = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break; + default: + if(pinkflag == 3) + pink_icon_prevstatus = "flag_pink_carrying"; // make it more visible + else if((stat_items & CTF_SHIELDED) && (myteam != NUM_TEAM_4)) + pink_icon_prevstatus = "flag_pink_shielded"; + else + pink_icon_prevstatus = string_null; + break; + } + + string neutral_icon, neutral_icon_prevstatus; - float neutral_alpha, neutral_alpha_prevstatus; ++ int neutral_alpha, neutral_alpha_prevstatus; + neutral_alpha = neutral_alpha_prevstatus = 1; - switch(neutralflag) { ++ switch(neutralflag) ++ { + case 1: neutral_icon = "flag_neutral_taken"; break; + case 2: neutral_icon = "flag_neutral_lost"; break; + case 3: neutral_icon = "flag_neutral_carrying"; neutral_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break; + default: + if((stat_items & CTF_SHIELDED)) + neutral_icon = "flag_neutral_shielded"; + else + neutral_icon = string_null; + break; + } - switch(neutralflag_prevstatus) { ++ switch(neutralflag_prevstatus) ++ { + case 1: neutral_icon_prevstatus = "flag_neutral_taken"; break; + case 2: neutral_icon_prevstatus = "flag_neutral_lost"; break; + case 3: neutral_icon_prevstatus = "flag_neutral_carrying"; neutral_alpha_prevstatus = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break; + default: + if(neutralflag == 3) + neutral_icon_prevstatus = "flag_neutral_carrying"; // make it more visible + else if((stat_items & CTF_SHIELDED)) + neutral_icon_prevstatus = "flag_neutral_shielded"; + else + neutral_icon_prevstatus = string_null; + break; + } + + if(ctf_oneflag) + { + // hacky, but these aren't needed + red_icon = red_icon_prevstatus = blue_icon = blue_icon_prevstatus = yellow_icon = yellow_icon_prevstatus = pink_icon = pink_icon_prevstatus = string_null; + fs = fs2 = fs3 = 1; + } + else switch(team_count) + { + default: + case 2: fs = 0.5; fs2 = 0.5; fs3 = 0.5; break; + case 3: fs = 1; fs2 = 0.35; fs3 = 0.35; break; + case 4: fs = 0.75; fs2 = 0.25; fs3 = 0.5; break; + } + + if(mySize_x > mySize_y) + { + size1 = mySize_x; + size2 = mySize_y; + e1 = eX; + e2 = eY; + } + else + { + size1 = mySize_y; + size2 = mySize_x; + e1 = eY; + e2 = eX; + } + + switch(myteam) + { + default: + case NUM_TEAM_1: + { redflag_pos = pos; - blueflag_pos = pos + eX * 0.5 * mySize.x; - } else { - blueflag_pos = pos; - redflag_pos = pos + eX * 0.5 * mySize.x; + blueflag_pos = pos + eX * fs2 * size1; + yellowflag_pos = pos - eX * fs2 * size1; + pinkflag_pos = pos + eX * fs3 * size1; + break; } - flag_size = eX * 0.5 * mySize.x + eY * mySize.y; - } else { - if (myteam == NUM_TEAM_1) { // always draw own flag on left - redflag_pos = pos; - blueflag_pos = pos + eY * 0.5 * mySize.y; - } else { + case NUM_TEAM_2: + { + redflag_pos = pos + eX * fs2 * size1; blueflag_pos = pos; - redflag_pos = pos + eY * 0.5 * mySize.y; + yellowflag_pos = pos - eX * fs2 * size1; + pinkflag_pos = pos + eX * fs3 * size1; + break; + } + case NUM_TEAM_3: + { + redflag_pos = pos + eX * fs3 * size1; + blueflag_pos = pos - eX * fs2 * size1; + yellowflag_pos = pos; + pinkflag_pos = pos + eX * fs2 * size1; + break; + } + case NUM_TEAM_4: + { + redflag_pos = pos - eX * fs2 * size1; + blueflag_pos = pos + eX * fs3 * size1; + yellowflag_pos = pos + eX * fs2 * size1; + pinkflag_pos = pos; + break; } - flag_size = eY * 0.5 * mySize.y + eX * mySize.x; } + neutralflag_pos = pos; + flag_size = e1 * fs * size1 + e2 * size2; f = bound(0, redflag_statuschange_elapsedtime*2, 1); if(red_icon_prevstatus && f < 1) diff --cc qcsrc/common/notifications.qh index 445a95131,1cb1adf51..9580f5692 --- a/qcsrc/common/notifications.qh +++ b/qcsrc/common/notifications.qh @@@ -1302,14 -1316,13 +1342,13 @@@ float NOTIF_INFO_COUNT float NOTIF_CENTER_COUNT; float NOTIF_MULTI_COUNT; float NOTIF_CHOICE_COUNT; - float NOTIF_CPID_COUNT; // notification limits -- INCREASE AS NECESSARY - #define NOTIF_ANNCE_MAX 100 - #define NOTIF_INFO_MAX 300 - #define NOTIF_CENTER_MAX 200 - #define NOTIF_MULTI_MAX 200 - #define NOTIF_CHOICE_MAX 30 + const float NOTIF_ANNCE_MAX = 100; + const float NOTIF_INFO_MAX = 300; + const float NOTIF_CENTER_MAX = 200; + const float NOTIF_MULTI_MAX = 200; -const float NOTIF_CHOICE_MAX = 20; ++const float NOTIF_CHOICE_MAX = 30; // notification entities entity msg_annce_notifs[NOTIF_ANNCE_MAX]; diff --cc qcsrc/common/stats.qh index f08c6b56d,481713cc9..28ec85e30 --- a/qcsrc/common/stats.qh +++ b/qcsrc/common/stats.qh @@@ -34,62 -37,62 +37,62 @@@ const int STAT_VIEWZOOM // 29 empty? // 30 empty? // 31 empty? - const float STAT_KH_KEYS = 32; - const float STAT_CTF_STATE = 33; + const int STAT_KH_KEYS = 32; + const int STAT_CTF_STATE = 33; // 34 empty? - const float STAT_WEAPONS = 35; - const float STAT_SWITCHWEAPON = 36; - const float STAT_GAMESTARTTIME = 37; - const float STAT_STRENGTH_FINISHED = 38; - const float STAT_INVINCIBLE_FINISHED = 39; + const int STAT_WEAPONS = 35; + const int STAT_SWITCHWEAPON = 36; + const int STAT_GAMESTARTTIME = 37; + const int STAT_STRENGTH_FINISHED = 38; + const int STAT_INVINCIBLE_FINISHED = 39; // 40 empty? - const float STAT_ARC_HEAT = 41; - const float STAT_PRESSED_KEYS = 42; - const float STAT_ALLOW_OLDVORTEXBEAM = 43; // this stat could later contain some other bits of info, like, more server-side particle config - const float STAT_FUEL = 44; - const float STAT_NB_METERSTART = 45; - const float STAT_SHOTORG = 46; // compressShotOrigin - const float STAT_LEADLIMIT = 47; - const float STAT_WEAPON_CLIPLOAD = 48; - const float STAT_WEAPON_CLIPSIZE = 49; - const float STAT_VORTEX_CHARGE = 50; - const float STAT_LAST_PICKUP = 51; - const float STAT_HUD = 52; - const float STAT_VORTEX_CHARGEPOOL = 53; - const float STAT_HIT_TIME = 54; - const float STAT_DAMAGE_DEALT_TOTAL = 55; - const float STAT_TYPEHIT_TIME = 56; - const float STAT_LAYED_MINES = 57; - const float STAT_HAGAR_LOAD = 58; - const float STAT_SWITCHINGWEAPON = 59; - const float STAT_SUPERWEAPONS_FINISHED = 60; - const float STAT_VEHICLESTAT_HEALTH = 61; - const float STAT_VEHICLESTAT_SHIELD = 62; - const float STAT_VEHICLESTAT_ENERGY = 63; - const float STAT_VEHICLESTAT_AMMO1 = 64; - const float STAT_VEHICLESTAT_RELOAD1 = 65; - const float STAT_VEHICLESTAT_AMMO2 = 66; - const float STAT_VEHICLESTAT_RELOAD2 = 67; - const float STAT_VEHICLESTAT_W2MODE = 68; - const float STAT_NADE_TIMER = 69; - const float STAT_SECRETS_TOTAL = 70; - const float STAT_SECRETS_FOUND = 71; - const float STAT_RESPAWN_TIME = 72; - const float STAT_ROUNDSTARTTIME = 73; - const float STAT_WEAPONS2 = 74; - const float STAT_WEAPONS3 = 75; - const float STAT_MONSTERS_TOTAL = 76; - const float STAT_MONSTERS_KILLED = 77; - const float STAT_BUFFS = 78; - const float STAT_NADE_BONUS = 79; - const float STAT_NADE_BONUS_TYPE = 80; - const float STAT_NADE_BONUS_SCORE = 81; - const float STAT_HEALING_ORB = 82; - const float STAT_HEALING_ORB_ALPHA = 83; - const float STAT_PLASMA = 84; - const float STAT_OK_AMMO_CHARGE = 85; - const float STAT_OK_AMMO_CHARGEPOOL = 86; - const float STAT_CTF_FLAGSTATUS = 87; + const int STAT_ARC_HEAT = 41; + const int STAT_PRESSED_KEYS = 42; + const int STAT_ALLOW_OLDVORTEXBEAM = 43; // this stat could later contain some other bits of info, like, more server-side particle config + const int STAT_FUEL = 44; + const int STAT_NB_METERSTART = 45; + const int STAT_SHOTORG = 46; // compressShotOrigin + const int STAT_LEADLIMIT = 47; + const int STAT_WEAPON_CLIPLOAD = 48; + const int STAT_WEAPON_CLIPSIZE = 49; + const int STAT_VORTEX_CHARGE = 50; + const int STAT_LAST_PICKUP = 51; + const int STAT_HUD = 52; + const int STAT_VORTEX_CHARGEPOOL = 53; + const int STAT_HIT_TIME = 54; + const int STAT_DAMAGE_DEALT_TOTAL = 55; + const int STAT_TYPEHIT_TIME = 56; + const int STAT_LAYED_MINES = 57; + const int STAT_HAGAR_LOAD = 58; + const int STAT_SWITCHINGWEAPON = 59; + const int STAT_SUPERWEAPONS_FINISHED = 60; + const int STAT_VEHICLESTAT_HEALTH = 61; + const int STAT_VEHICLESTAT_SHIELD = 62; + const int STAT_VEHICLESTAT_ENERGY = 63; + const int STAT_VEHICLESTAT_AMMO1 = 64; + const int STAT_VEHICLESTAT_RELOAD1 = 65; + const int STAT_VEHICLESTAT_AMMO2 = 66; + const int STAT_VEHICLESTAT_RELOAD2 = 67; + const int STAT_VEHICLESTAT_W2MODE = 68; + const int STAT_NADE_TIMER = 69; + const int STAT_SECRETS_TOTAL = 70; + const int STAT_SECRETS_FOUND = 71; + const int STAT_RESPAWN_TIME = 72; + const int STAT_ROUNDSTARTTIME = 73; + const int STAT_WEAPONS2 = 74; + const int STAT_WEAPONS3 = 75; + const int STAT_MONSTERS_TOTAL = 76; + const int STAT_MONSTERS_KILLED = 77; + const int STAT_BUFFS = 78; + const int STAT_NADE_BONUS = 79; + const int STAT_NADE_BONUS_TYPE = 80; + const int STAT_NADE_BONUS_SCORE = 81; + const int STAT_HEALING_ORB = 82; + const int STAT_HEALING_ORB_ALPHA = 83; + const int STAT_PLASMA = 84; + const int STAT_OK_AMMO_CHARGE = 85; + const int STAT_OK_AMMO_CHARGEPOOL = 86; -// 87 empty? ++const int STAT_CTF_FLAGSTATUS = 87; // 88 empty? // 89 empty? // 90 empty? diff --cc qcsrc/server/autocvars.qh index 611564da2,bcb9d28d7..89f7caf78 --- a/qcsrc/server/autocvars.qh +++ b/qcsrc/server/autocvars.qh @@@ -221,13 -224,13 +224,13 @@@ float autocvar_g_chat_flood_spl_tell float autocvar_g_chat_nospectators; float autocvar_g_chat_teamcolors; float autocvar_g_chat_tellprivacy; --float autocvar_g_ctf_allow_vehicle_carry; --float autocvar_g_ctf_allow_vehicle_touch; --float autocvar_g_ctf_allow_monster_touch; --float autocvar_g_ctf_throw; ++bool autocvar_g_ctf_allow_vehicle_carry; ++bool autocvar_g_ctf_allow_vehicle_touch; ++bool autocvar_g_ctf_allow_monster_touch; ++bool autocvar_g_ctf_throw; float autocvar_g_ctf_throw_angle_max; float autocvar_g_ctf_throw_angle_min; --float autocvar_g_ctf_throw_punish_count; ++int autocvar_g_ctf_throw_punish_count; float autocvar_g_ctf_throw_punish_delay; float autocvar_g_ctf_throw_punish_time; float autocvar_g_ctf_throw_strengthmultiplier; @@@ -235,9 -238,8 +238,9 @@@ float autocvar_g_ctf_throw_velocity_for float autocvar_g_ctf_throw_velocity_up; float autocvar_g_ctf_drop_velocity_up; float autocvar_g_ctf_drop_velocity_side; - float autocvar_g_ctf_oneflag_reverse; ++bool autocvar_g_ctf_oneflag_reverse; float autocvar_g_ctf_portalteleport; --float autocvar_g_ctf_pass; ++bool autocvar_g_ctf_pass; float autocvar_g_ctf_pass_arc; float autocvar_g_ctf_pass_arc_max; float autocvar_g_ctf_pass_directional_max; @@@ -248,30 -250,21 +251,30 @@@ float autocvar_g_ctf_pass_request float autocvar_g_ctf_pass_turnrate; float autocvar_g_ctf_pass_timelimit; float autocvar_g_ctf_pass_velocity; --float autocvar_g_ctf_dynamiclights; ++bool autocvar_g_ctf_dynamiclights; string autocvar_g_ctf_flag_blue_model; --float autocvar_g_ctf_flag_blue_skin; ++int autocvar_g_ctf_flag_blue_skin; float autocvar_g_ctf_flag_collect_delay; float autocvar_g_ctf_flag_damageforcescale; --float autocvar_g_ctf_flag_dropped_waypoint; --float autocvar_g_ctf_flag_dropped_floatinwater; --float autocvar_g_ctf_flag_glowtrails; --float autocvar_g_ctf_flag_health; ++bool autocvar_g_ctf_flag_dropped_waypoint; ++bool autocvar_g_ctf_flag_dropped_floatinwater; ++bool autocvar_g_ctf_flag_glowtrails; ++int autocvar_g_ctf_flag_health; +string autocvar_g_ctf_flag_neutral_model; - float autocvar_g_ctf_flag_neutral_skin; ++int autocvar_g_ctf_flag_neutral_skin; +string autocvar_g_ctf_flag_pink_model; - float autocvar_g_ctf_flag_pink_skin; ++int autocvar_g_ctf_flag_pink_skin; string autocvar_g_ctf_flag_red_model; --float autocvar_g_ctf_flag_red_skin; - float autocvar_g_ctf_flag_return; ++int autocvar_g_ctf_flag_red_skin; ++bool autocvar_g_ctf_flag_return; +float autocvar_g_ctf_flag_return_carried_radius; float autocvar_g_ctf_flag_return_time; float autocvar_g_ctf_flag_return_when_unreachable; float autocvar_g_ctf_flag_return_damage; +float autocvar_g_ctf_flag_return_damage_delay; float autocvar_g_ctf_flag_return_dropped; +string autocvar_g_ctf_flag_yellow_model; - float autocvar_g_ctf_flag_yellow_skin; ++int autocvar_g_ctf_flag_yellow_skin; float autocvar_g_ctf_flagcarrier_auto_helpme_damage; float autocvar_g_ctf_flagcarrier_auto_helpme_time; float autocvar_g_ctf_flagcarrier_selfdamagefactor; @@@ -279,25 -272,25 +282,25 @@@ float autocvar_g_ctf_flagcarrier_selffo float autocvar_g_ctf_flagcarrier_damagefactor; float autocvar_g_ctf_flagcarrier_forcefactor; //float autocvar_g_ctf_flagcarrier_waypointforenemy_spotting; --float autocvar_g_ctf_fullbrightflags; --float autocvar_g_ctf_ignore_frags; --float autocvar_g_ctf_score_capture; --float autocvar_g_ctf_score_capture_assist; --float autocvar_g_ctf_score_kill; --float autocvar_g_ctf_score_penalty_drop; ++bool autocvar_g_ctf_fullbrightflags; ++bool autocvar_g_ctf_ignore_frags; ++int autocvar_g_ctf_score_capture; ++int autocvar_g_ctf_score_capture_assist; ++int autocvar_g_ctf_score_kill; ++int autocvar_g_ctf_score_penalty_drop; //float autocvar_g_ctf_score_penalty_suicidedrop; --float autocvar_g_ctf_score_penalty_returned; --float autocvar_g_ctf_score_pickup_base; --float autocvar_g_ctf_score_pickup_dropped_early; --float autocvar_g_ctf_score_pickup_dropped_late; --float autocvar_g_ctf_score_return; ++int autocvar_g_ctf_score_penalty_returned; ++int autocvar_g_ctf_score_pickup_base; ++int autocvar_g_ctf_score_pickup_dropped_early; ++int autocvar_g_ctf_score_pickup_dropped_late; ++int autocvar_g_ctf_score_return; float autocvar_g_ctf_shield_force; float autocvar_g_ctf_shield_max_ratio; float autocvar_g_ctf_shield_min_negscore; --float autocvar_g_ctf_stalemate; --float autocvar_g_ctf_stalemate_endcondition; ++bool autocvar_g_ctf_stalemate; ++int autocvar_g_ctf_stalemate_endcondition; float autocvar_g_ctf_stalemate_time; --float autocvar_g_ctf_reverse; ++bool autocvar_g_ctf_reverse; float autocvar_g_ctf_dropped_capture_delay; float autocvar_g_ctf_dropped_capture_radius; float autocvar_g_cts_finish_kill_delay; diff --cc qcsrc/server/mutators/gamemode_ctf.qc index ae657b4c6,2e6eb4ff7..bb09d734a --- a/qcsrc/server/mutators/gamemode_ctf.qc +++ b/qcsrc/server/mutators/gamemode_ctf.qc @@@ -14,11 -14,10 +14,11 @@@ void ctf_FakeTimeLimit(entity e, float WriteCoord(MSG_ONE, (t + 1) / 60); } --void ctf_EventLog(string mode, float flagteam, entity actor) // use an alias for easy changing and quick editing later ++void ctf_EventLog(string mode, int flagteam, entity actor) // use an alias for easy changing and quick editing later { if(autocvar_sv_eventlog) - GameLogEcho(strcat(":ctf:", mode, ":", ftos(flagteam), ((actor != world) ? (strcat(":", ftos(actor.playerid))) : ""))); + GameLogEcho(sprintf(":ctf:%s:%d:%d:%s", mode, flagteam, actor.team, ((actor != world) ? ftos(actor.playerid) : ""))); + //GameLogEcho(strcat(":ctf:", mode, ":", ftos(flagteam), ((actor != world) ? (strcat(":", ftos(actor.playerid))) : ""))); } void ctf_CaptureRecord(entity flag, entity player) @@@ -83,7 -80,7 +83,7 @@@ void ctf_CalculatePassVelocity(entity f else { flag.velocity = (desired_direction * autocvar_g_ctf_pass_velocity); } } --float ctf_CheckPassDirection(vector head_center, vector passer_center, vector passer_angle, vector nearest_to_passer) ++bool ctf_CheckPassDirection(vector head_center, vector passer_center, vector passer_angle, vector nearest_to_passer) { if(autocvar_g_ctf_pass_directional_max || autocvar_g_ctf_pass_directional_min) { @@@ -119,24 -116,18 +119,24 @@@ // CaptureShield Functions // ======================= --float ctf_CaptureShield_CheckStatus(entity p) ++bool ctf_CaptureShield_CheckStatus(entity p) { - float s, se; + float s, s2, s3, s4, se, se2, se3, se4, sr, ser; entity e; float players_worseeq, players_total; if(ctf_captureshield_max_ratio <= 0) - return FALSE; + return false; - s = PlayerScore_Add(p, SP_SCORE, 0); - if(s >= -ctf_captureshield_min_negscore) + s = PlayerScore_Add(p, SP_CTF_CAPS, 0); + s2 = PlayerScore_Add(p, SP_CTF_PICKUPS, 0); + s3 = PlayerScore_Add(p, SP_CTF_RETURNS, 0); + s4 = PlayerScore_Add(p, SP_CTF_FCKILLS, 0); + + sr = ((s - s2) + (s3 + s4)); + + if(sr >= -ctf_captureshield_min_negscore) - return FALSE; + return false; players_total = players_worseeq = 0; FOR_EACH_PLAYER(e) @@@ -159,14 -144,14 +159,14 @@@ // use this rule here if(players_worseeq >= players_total * ctf_captureshield_max_ratio) - return FALSE; + return false; - return TRUE; + return true; } --void ctf_CaptureShield_Update(entity player, float wanted_status) ++void ctf_CaptureShield_Update(entity player, bool wanted_status) { -- float updated_status = ctf_CaptureShield_CheckStatus(player); ++ bool updated_status = ctf_CaptureShield_CheckStatus(player); if((wanted_status == player.ctf_captureshielded) && (updated_status != wanted_status)) // 0: shield only, 1: unshield only { Send_Notification(NOTIF_ONE, player, MSG_CENTER, ((updated_status) ? CENTER_CTF_CAPTURESHIELD_SHIELDED : CENTER_CTF_CAPTURESHIELD_FREE)); @@@ -174,13 -159,12 +174,13 @@@ } } --float ctf_CaptureShield_Customize() ++bool ctf_CaptureShield_Customize() { - if(self.enemy.active != ACTIVE_ACTIVE) { return TRUE; } - if(!other.ctf_captureshielded) { return FALSE; } - if(CTF_SAMETEAM(self, other)) { return FALSE; } ++ if(self.enemy.active != ACTIVE_ACTIVE) { return true; } + if(!other.ctf_captureshielded) { return false; } - if(SAME_TEAM(self, other)) { return false; } ++ if(CTF_SAMETEAM(self, other)) { return false; } - return TRUE; + return true; } void ctf_CaptureShield_Touch() @@@ -231,7 -204,7 +231,7 @@@ void ctf_CaptureShield_Spawn(entity fla // Drop/Pass/Throw Code // ==================== --void ctf_Handle_Drop(entity flag, entity player, float droptype) ++void ctf_Handle_Drop(entity flag, entity player, int droptype) { // declarations player = (player ? player : flag.pass_sender); @@@ -326,7 -299,7 +326,7 @@@ void ctf_Handle_Retrieve(entity flag, e flag.pass_target = world; } --void ctf_Handle_Throw(entity player, entity receiver, float droptype) ++void ctf_Handle_Throw(entity player, entity receiver, int droptype) { entity flag = player.flagcarried; vector targ_origin, flag_velocity; @@@ -416,7 -389,7 +416,7 @@@ // Event Handlers // ============== --void ctf_Handle_Capture(entity flag, entity toucher, float capturetype) ++void ctf_Handle_Capture(entity flag, entity toucher, int capturetype) { entity enemy_flag = ((capturetype == CAPTURE_NORMAL) ? toucher.flagcarried : toucher); entity player = ((capturetype == CAPTURE_NORMAL) ? toucher : enemy_flag.ctf_dropper); @@@ -520,7 -476,7 +520,7 @@@ void ctf_Handle_Return(entity flag, ent ctf_RespawnFlag(flag); } --void ctf_Handle_Pickup(entity flag, entity player, float pickuptype) ++void ctf_Handle_Pickup(entity flag, entity player, int pickuptype) { // declarations float pickup_dropped_score; // used to calculate dropped pickup score @@@ -628,7 -567,7 +628,7 @@@ // Main Flag Functions // =================== --void ctf_CheckFlagReturn(entity flag, float returntype) ++void ctf_CheckFlagReturn(entity flag, int returntype) { if((flag.ctf_status == FLAG_DROPPED) || (flag.ctf_status == FLAG_PASSING)) { @@@ -654,25 -593,10 +654,25 @@@ } } - float ctf_Stalemate_Customize() ++bool ctf_Stalemate_Customize() +{ + // make spectators see what the player would see + entity e, wp_owner; + e = WaypointSprite_getviewentity(other); + wp_owner = self.owner; + + // team waypoints - if(CTF_SAMETEAM(wp_owner.flagcarried, wp_owner)) { return FALSE; } - if(SAME_TEAM(wp_owner, e)) { return FALSE; } - if(!IS_PLAYER(e)) { return FALSE; } ++ if(CTF_SAMETEAM(wp_owner.flagcarried, wp_owner)) { return false; } ++ if(SAME_TEAM(wp_owner, e)) { return false; } ++ if(!IS_PLAYER(e)) { return false; } + - return TRUE; ++ return true; +} + void ctf_CheckStalemate(void) { // declarations - float stale_flags = 0, stale_red_flags = 0, stale_blue_flags = 0, stale_yellow_flags = 0, stale_pink_flags = 0, stale_neutral_flags = 0; - float stale_red_flags = 0, stale_blue_flags = 0; ++ int stale_flags = 0, stale_red_flags = 0, stale_blue_flags = 0, stale_yellow_flags = 0, stale_pink_flags = 0, stale_neutral_flags = 0; entity tmp_entity; entity ctf_staleflaglist = world; // reset the list, we need to build the list each time this function runs @@@ -698,19 -619,12 +698,19 @@@ } } - if(stale_red_flags && stale_blue_flags) + if(ctf_oneflag) + stale_flags = (stale_neutral_flags >= 1); + else + stale_flags = (stale_red_flags >= 1) + (stale_blue_flags >= 1) + (stale_yellow_flags >= 1) + (stale_pink_flags >= 1); + + if(ctf_oneflag && stale_flags == 1) - ctf_stalemate = TRUE; ++ ctf_stalemate = true; + else if(stale_flags == ctf_teams) - ctf_stalemate = TRUE; + ctf_stalemate = true; - else if((!stale_red_flags && !stale_blue_flags) && autocvar_g_ctf_stalemate_endcondition == 2) + else if(stale_flags == 0 && autocvar_g_ctf_stalemate_endcondition == 2) - { ctf_stalemate = FALSE; wpforenemy_announced = FALSE; } + { ctf_stalemate = false; wpforenemy_announced = false; } - else if((!stale_red_flags || !stale_blue_flags) && autocvar_g_ctf_stalemate_endcondition == 1) + else if(stale_flags < ctf_teams && autocvar_g_ctf_stalemate_endcondition == 1) - { ctf_stalemate = FALSE; wpforenemy_announced = FALSE; } + { ctf_stalemate = false; wpforenemy_announced = false; } // if sufficient stalemate, then set up the waypointsprite and announce the stalemate if necessary if(ctf_stalemate) @@@ -718,10 -632,7 +718,10 @@@ for(tmp_entity = ctf_staleflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_staleflagnext) { if((tmp_entity.owner) && (!tmp_entity.owner.wps_enemyflagcarrier)) - WaypointSprite_Spawn("enemyflagcarrier", 0, 0, tmp_entity.owner, FLAG_WAYPOINT_OFFSET, world, tmp_entity.team, tmp_entity.owner, wps_enemyflagcarrier, true, RADARICON_FLAG, WPCOLOR_ENEMYFC(tmp_entity.owner.team)); + { - WaypointSprite_Spawn(((ctf_oneflag) ? "flagcarrier" : "enemyflagcarrier"), 0, 0, tmp_entity.owner, FLAG_WAYPOINT_OFFSET, world, 0, tmp_entity.owner, wps_enemyflagcarrier, TRUE, RADARICON_FLAG, WPCOLOR_ENEMYFC(tmp_entity.owner.team)); ++ WaypointSprite_Spawn(((ctf_oneflag) ? "flagcarrier" : "enemyflagcarrier"), 0, 0, tmp_entity.owner, FLAG_WAYPOINT_OFFSET, world, 0, tmp_entity.owner, wps_enemyflagcarrier, true, RADARICON_FLAG, WPCOLOR_ENEMYFC(tmp_entity.owner.team)); + tmp_entity.owner.wps_enemyflagcarrier.customizeentityforclient = ctf_Stalemate_Customize; + } } if (!wpforenemy_announced) @@@ -738,15 -649,9 +738,15 @@@ void ctf_FlagDamage(entity inflictor, e { if(ITEM_DAMAGE_NEEDKILL(deathtype)) { - // automatically kill the flag and return it - self.health = 0; - ctf_CheckFlagReturn(self, RETURN_NEEDKILL); + if(autocvar_g_ctf_flag_return_damage_delay) + { - self.ctf_flagdamaged = TRUE; ++ self.ctf_flagdamaged = true; + } + else + { + self.health = 0; + ctf_CheckFlagReturn(self, RETURN_NEEDKILL); + } return; } if(autocvar_g_ctf_flag_return_damage) @@@ -910,11 -802,10 +910,11 @@@ void ctf_FlagThink( void ctf_FlagTouch() { if(gameover) { return; } + if(self.active != ACTIVE_ACTIVE) { return; } if(trace_dphitcontents & (DPCONTENTS_PLAYERCLIP | DPCONTENTS_MONSTERCLIP)) { return; } - entity toucher = other; - float is_not_monster = (!(toucher.flags & FL_MONSTER)); + entity toucher = other, tmp_entity; - float is_not_monster = (!(toucher.flags & FL_MONSTER)), num_perteam = 0; ++ bool is_not_monster = (!(toucher.flags & FL_MONSTER)), num_perteam = 0; // automatically kill the flag and return it if it touched lava/slime/nodrop surfaces if(ITEM_TOUCH_NEEDKILL()) @@@ -1063,22 -943,6 +1063,22 @@@ void ctf_Reset( ctf_RespawnFlag(self); } +void ctf_Use() +{ + if(self.ctf_status != FLAG_BASE) { return; } + + self.active = ((self.active) ? ACTIVE_NOT : ACTIVE_ACTIVE); + + if(self.active == ACTIVE_ACTIVE) + WaypointSprite_Ping(self.wps_flagbase); +} + - float ctf_FlagWaypoint_Customize() ++bool ctf_FlagWaypoint_Customize() +{ - if(self.owner.active != ACTIVE_ACTIVE) { return FALSE; } - return TRUE; ++ if(self.owner.active != ACTIVE_ACTIVE) { return false; } ++ return true; +} + void ctf_DelayedFlagSetup(void) // called after a flag is placed on a map by ctf_FlagSetup() { // bot waypoints @@@ -1087,28 -951,17 +1087,28 @@@ self.bot_basewaypoint = self.nearestwaypoint; // waypointsprites - WaypointSprite_SpawnFixed(((self.team == NUM_TEAM_1) ? "redbase" : "bluebase"), self.origin + FLAG_WAYPOINT_OFFSET, self, wps_flagbase, RADARICON_FLAG, colormapPaletteColor(self.team - 1, false)); - WaypointSprite_UpdateTeamRadar(self.wps_flagbase, RADARICON_FLAG, colormapPaletteColor(self.team - 1, false)); + string basename = "base"; + + switch(self.team) + { + case NUM_TEAM_1: basename = "redbase"; break; + case NUM_TEAM_2: basename = "bluebase"; break; + case NUM_TEAM_3: basename = "yellowbase"; break; + case NUM_TEAM_4: basename = "pinkbase"; break; + default: basename = "neutralbase"; break; + } + + WaypointSprite_SpawnFixed(basename, self.origin + FLAG_WAYPOINT_OFFSET, self, wps_flagbase, RADARICON_FLAG, ((self.team) ? Team_ColorRGB(self.team) : '1 1 1')); - WaypointSprite_UpdateTeamRadar(self.wps_flagbase, RADARICON_FLAG, ((self.team) ? colormapPaletteColor(self.team - 1, FALSE) : '1 1 1')); ++ WaypointSprite_UpdateTeamRadar(self.wps_flagbase, RADARICON_FLAG, ((self.team) ? colormapPaletteColor(self.team - 1, false) : '1 1 1')); + self.wps_flagbase.customizeentityforclient = ctf_FlagWaypoint_Customize; // captureshield setup ctf_CaptureShield_Spawn(self); } --void ctf_FlagSetup(float teamnumber, entity flag) // called when spawning a flag entity on the map as a spawnfunc ++void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag entity on the map as a spawnfunc { // declarations - teamnumber = fabs(teamnumber - bound(0, autocvar_g_ctf_reverse, 1)); // if we were originally 1, this will become 0. If we were originally 0, this will become 1. self = flag; // for later usage with droptofloor() // main setup @@@ -1128,9 -982,8 +1128,9 @@@ flag.max_flag_health = ((autocvar_g_ctf_flag_return_damage && autocvar_g_ctf_flag_health) ? autocvar_g_ctf_flag_health : 100); flag.health = flag.max_flag_health; flag.event_damage = ctf_FlagDamage; - flag.pushable = TRUE; + flag.pushable = true; flag.teleportable = TELEPORT_NORMAL; + flag.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP; flag.damagedbytriggers = autocvar_g_ctf_flag_return_when_unreachable; flag.damagedbycontents = autocvar_g_ctf_flag_return_when_unreachable; flag.velocity = '0 0 0'; @@@ -1283,12 -1111,12 +1283,12 @@@ entity havocbot_ctf_find_enemy_flag(ent return world; } --float havocbot_ctf_teamcount(entity bot, vector org, float tc_radius) ++int havocbot_ctf_teamcount(entity bot, vector org, float tc_radius) { if (!teamplay) return 0; -- float c = 0; ++ int c = 0; entity head; FOR_EACH_PLAYER(head) @@@ -1910,16 -1722,10 +1910,15 @@@ void havocbot_role_ctf_setrole(entity b MUTATOR_HOOKFUNCTION(ctf_PlayerPreThink) { entity flag; - - float t = 0, t2 = 0, t3 = 0; ++ int t = 0, t2 = 0, t3 = 0; // initially clear items so they can be set as necessary later. - self.items &= ~(IT_RED_FLAG_CARRYING | IT_RED_FLAG_TAKEN | IT_RED_FLAG_LOST - | IT_BLUE_FLAG_CARRYING | IT_BLUE_FLAG_TAKEN | IT_BLUE_FLAG_LOST | IT_CTF_SHIELDED); + self.ctf_flagstatus &= ~(CTF_RED_FLAG_CARRYING | CTF_RED_FLAG_TAKEN | CTF_RED_FLAG_LOST + | CTF_BLUE_FLAG_CARRYING | CTF_BLUE_FLAG_TAKEN | CTF_BLUE_FLAG_LOST + | CTF_YELLOW_FLAG_CARRYING | CTF_YELLOW_FLAG_TAKEN | CTF_YELLOW_FLAG_LOST + | CTF_PINK_FLAG_CARRYING | CTF_PINK_FLAG_TAKEN | CTF_PINK_FLAG_LOST + | CTF_NEUTRAL_FLAG_CARRYING | CTF_NEUTRAL_FLAG_TAKEN | CTF_NEUTRAL_FLAG_LOST + | CTF_FLAG_NEUTRAL | CTF_SHIELDED); // scan through all the flags and notify the client about them for(flag = ctf_worldflaglist; flag; flag = flag.ctf_worldflagnext) @@@ -1997,13 -1797,9 +1996,13 @@@ MUTATOR_HOOKFUNCTION(ctf_PlayerDies } if(frag_target.flagcarried) - { ctf_Handle_Throw(frag_target, world, DROP_NORMAL); } + { + entity tmp_entity = frag_target.flagcarried; + ctf_Handle_Throw(frag_target, world, DROP_NORMAL); + tmp_entity.ctf_dropper = world; + } - return FALSE; + return false; } MUTATOR_HOOKFUNCTION(ctf_GiveFragsForKill) @@@ -2186,12 -1982,12 +2185,12 @@@ MUTATOR_HOOKFUNCTION(ctf_AbortSpeedrun { if(self.flagcarried) { - Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_2(self.flagcarried, INFO_CTF_FLAGRETURN_ABORTRUN_)); + Send_Notification(NOTIF_ALL, world, MSG_INFO, ((self.flagcarried.team) ? APP_TEAM_ENT_4(self.flagcarried, INFO_CTF_FLAGRETURN_ABORTRUN_) : INFO_CTF_FLAGRETURN_ABORTRUN_NEUTRAL)); ctf_RespawnFlag(self.flagcarried); - return TRUE; + return true; } - return FALSE; + return false; } MUTATOR_HOOKFUNCTION(ctf_MatchEnd) @@@ -2231,22 -2027,9 +2230,22 @@@ MUTATOR_HOOKFUNCTION(ctf_BotRoles) { havocbot_ctf_reset_role(self); - return TRUE; + return true; } +MUTATOR_HOOKFUNCTION(ctf_GetTeamCount) +{ + //ret_float = ctf_teams; + ret_string = "ctf_team"; - return TRUE; ++ return true; +} + +MUTATOR_HOOKFUNCTION(ctf_SpectateCopy) +{ + self.ctf_flagstatus = other.ctf_flagstatus; - return FALSE; ++ return false; +} + // ========== // Spawnfuncs @@@ -2417,10 -2145,9 +2416,10 @@@ void spawnfunc_team_CTF_bluespawn() { // ============== // scoreboard setup -void ctf_ScoreRules() +void ctf_ScoreRules(float teams) { - ScoreRules_basics(2, SFL_SORT_PRIO_PRIMARY, 0, true); + CheckAllowedTeams(world); - ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, 0, TRUE); ++ ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, 0, true); ScoreInfo_SetLabel_TeamScore (ST_CTF_CAPS, "caps", SFL_SORT_PRIO_PRIMARY); ScoreInfo_SetLabel_PlayerScore(SP_CTF_CAPS, "caps", SFL_SORT_PRIO_SECONDARY); ScoreInfo_SetLabel_PlayerScore(SP_CTF_CAPTIME, "captime", SFL_LOWER_IS_BETTER | SFL_TIME); @@@ -2448,18 -2175,6 +2447,18 @@@ void ctf_SpawnTeam (string teamname, fl void ctf_DelayedInit() // Do this check with a delay so we can wait for teams to be set up. { + ctf_teams = 2; + + entity tmp_entity; + for(tmp_entity = ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext) + { + if(tmp_entity.team == NUM_TEAM_3) { ctf_teams = max(3, ctf_teams); } + if(tmp_entity.team == NUM_TEAM_4) { ctf_teams = max(4, ctf_teams); } - if(tmp_entity.team == 0) { ctf_oneflag = TRUE; } ++ if(tmp_entity.team == 0) { ctf_oneflag = true; } + } + + ctf_teams = bound(2, ctf_teams, 4); + // if no teams are found, spawn defaults if(find(world, classname, "ctf_team") == world) { diff --cc qcsrc/server/mutators/gamemode_ctf.qh index bb76aa9e1,0e5930db2..d2572bc45 --- a/qcsrc/server/mutators/gamemode_ctf.qh +++ b/qcsrc/server/mutators/gamemode_ctf.qh @@@ -5,38 -7,38 +7,41 @@@ void ctf_RespawnFlag(entity flag); // score rule declarations - #define ST_CTF_CAPS 1 - #define SP_CTF_CAPS 4 - #define SP_CTF_CAPTIME 5 - #define SP_CTF_PICKUPS 6 - #define SP_CTF_DROPS 7 - #define SP_CTF_FCKILLS 8 - #define SP_CTF_RETURNS 9 -const float ST_CTF_CAPS = 1; -const float SP_CTF_CAPS = 4; -const float SP_CTF_CAPTIME = 5; -const float SP_CTF_PICKUPS = 6; -const float SP_CTF_DROPS = 7; -const float SP_CTF_FCKILLS = 8; -const float SP_CTF_RETURNS = 9; ++const int ST_CTF_CAPS = 1; ++const int SP_CTF_CAPS = 4; ++const int SP_CTF_CAPTIME = 5; ++const int SP_CTF_PICKUPS = 6; ++const int SP_CTF_DROPS = 7; ++const int SP_CTF_FCKILLS = 8; ++const int SP_CTF_RETURNS = 9; // flag constants // for most of these, there is just one question to be asked: WHYYYYY? #define FLAG_MIN (PL_MIN + '0 0 -13') #define FLAG_MAX (PL_MAX + '0 0 -13') - #define FLAG_SCALE 0.6 + const float FLAG_SCALE = 0.6; - #define FLAG_THINKRATE 0.2 - #define FLAG_TOUCHRATE 0.5 - #define WPFE_THINKRATE 0.5 + const float FLAG_THINKRATE = 0.2; + const float FLAG_TOUCHRATE = 0.5; + const float WPFE_THINKRATE = 0.5; --#define FLAG_DROP_OFFSET ('0 0 32') --#define FLAG_CARRY_OFFSET ('-16 0 8') ++const vector FLAG_DROP_OFFSET = ('0 0 32'); ++const vector FLAG_CARRY_OFFSET = ('-16 0 8'); #define FLAG_SPAWN_OFFSET ('0 0 1' * (PL_MAX_z - 13)) --#define FLAG_WAYPOINT_OFFSET ('0 0 64') --#define FLAG_FLOAT_OFFSET ('0 0 32') --#define FLAG_PASS_ARC_OFFSET ('0 0 -10') ++const vector FLAG_WAYPOINT_OFFSET = ('0 0 64'); ++const vector FLAG_FLOAT_OFFSET = ('0 0 32'); ++const vector FLAG_PASS_ARC_OFFSET = ('0 0 -10'); + - #define VEHICLE_FLAG_OFFSET ('0 0 96') - #define VEHICLE_FLAG_SCALE 1.0 ++const vector VEHICLE_FLAG_OFFSET = ('0 0 90'); ++ ++ + -#define VEHICLE_FLAG_OFFSET ('0 0 96') + const float VEHICLE_FLAG_SCALE = 1.0; // waypoint colors - #define WPCOLOR_ENEMYFC(t) ((t) ? colormapPaletteColor(t - 1, FALSE) * 0.75 : '1 1 1') -#define WPCOLOR_ENEMYFC(t) (colormapPaletteColor(t - 1, false) * 0.75) ++#define WPCOLOR_ENEMYFC(t) ((t) ? colormapPaletteColor(t - 1, false) * 0.75 : '1 1 1') #define WPCOLOR_FLAGCARRIER(t) ('0.8 0.8 0') - #define WPCOLOR_DROPPEDFLAG(t) ((t) ? ('0.25 0.25 0.25' + colormapPaletteColor(t - 1, FALSE)) * 0.5 : '1 1 1') -#define WPCOLOR_DROPPEDFLAG(t) (('0.25 0.25 0.25' + colormapPaletteColor(t - 1, false)) * 0.5) ++#define WPCOLOR_DROPPEDFLAG(t) ((t) ? ('0.25 0.25 0.25' + colormapPaletteColor(t - 1, false)) * 0.5 : '1 1 1') // sounds #define snd_flag_taken noise @@@ -65,44 -67,42 +70,44 @@@ entity ctf_worldflaglist .entity wps_flagdropped; .entity wps_enemyflagcarrier; .float wps_helpme_time; --float wpforenemy_announced; ++bool wpforenemy_announced; float wpforenemy_nextthink; // statuses - #define FLAG_BASE 1 - #define FLAG_DROPPED 2 - #define FLAG_CARRY 3 - #define FLAG_PASSING 4 -const float FLAG_BASE = 1; -const float FLAG_DROPPED = 2; -const float FLAG_CARRY = 3; -const float FLAG_PASSING = 4; ++const int FLAG_BASE = 1; ++const int FLAG_DROPPED = 2; ++const int FLAG_CARRY = 3; ++const int FLAG_PASSING = 4; - #define DROP_NORMAL 1 - #define DROP_THROW 2 - #define DROP_PASS 3 - #define DROP_RESET 4 -const float DROP_NORMAL = 1; -const float DROP_THROW = 2; -const float DROP_PASS = 3; -const float DROP_RESET = 4; ++const int DROP_NORMAL = 1; ++const int DROP_THROW = 2; ++const int DROP_PASS = 3; ++const int DROP_RESET = 4; - #define PICKUP_BASE 1 - #define PICKUP_DROPPED 2 -const float PICKUP_BASE = 1; -const float PICKUP_DROPPED = 2; ++const int PICKUP_BASE = 1; ++const int PICKUP_DROPPED = 2; - #define CAPTURE_NORMAL 1 - #define CAPTURE_DROPPED 2 -const float CAPTURE_NORMAL = 1; -const float CAPTURE_DROPPED = 2; ++const int CAPTURE_NORMAL = 1; ++const int CAPTURE_DROPPED = 2; - #define RETURN_TIMEOUT 1 - #define RETURN_DROPPED 2 - #define RETURN_DAMAGE 3 - #define RETURN_SPEEDRUN 4 - #define RETURN_NEEDKILL 5 -const float RETURN_TIMEOUT = 1; -const float RETURN_DROPPED = 2; -const float RETURN_DAMAGE = 3; -const float RETURN_SPEEDRUN = 4; -const float RETURN_NEEDKILL = 5; ++const int RETURN_TIMEOUT = 1; ++const int RETURN_DROPPED = 2; ++const int RETURN_DAMAGE = 3; ++const int RETURN_SPEEDRUN = 4; ++const int RETURN_NEEDKILL = 5; // flag properties #define ctf_spawnorigin dropped_origin --float ctf_stalemate; // indicates that a stalemate is active ++bool ctf_stalemate; // indicates that a stalemate is active float ctf_captimerecord; // record time for capturing the flag .float ctf_pickuptime; .float ctf_droptime; --.float ctf_status; // status of the flag (FLAG_BASE, FLAG_DROPPED, FLAG_CARRY declared globally) ++.int ctf_status; // status of the flag (FLAG_BASE, FLAG_DROPPED, FLAG_CARRY declared globally) .entity ctf_dropper; // don't allow spam of dropping the flag --.float max_flag_health; ++.int max_flag_health; .float next_take_time; - .float ctf_flagdamaged; - float ctf_teams; ++.bool ctf_flagdamaged; ++int ctf_teams; // passing/throwing properties .float pass_distance; @@@ -110,56 -110,28 +115,57 @@@ .entity pass_target; .float throw_antispam; .float throw_prevtime; --.float throw_count; ++.int throw_count; // CaptureShield: If the player is too bad to be allowed to capture, shield them from taking the flag. --.float ctf_captureshielded; // set to 1 if the player is too bad to be allowed to capture ++.bool ctf_captureshielded; // set to 1 if the player is too bad to be allowed to capture float ctf_captureshield_min_negscore; // punish at -20 points float ctf_captureshield_max_ratio; // punish at most 30% of each team float ctf_captureshield_force; // push force of the shield +// 1 flag ctf - float ctf_oneflag; // indicates whether or not a neutral flag has been found ++bool ctf_oneflag; // indicates whether or not a neutral flag has been found + // bot player logic - #define HAVOCBOT_CTF_ROLE_NONE 0 - #define HAVOCBOT_CTF_ROLE_DEFENSE 2 - #define HAVOCBOT_CTF_ROLE_MIDDLE 4 - #define HAVOCBOT_CTF_ROLE_OFFENSE 8 - #define HAVOCBOT_CTF_ROLE_CARRIER 16 - #define HAVOCBOT_CTF_ROLE_RETRIEVER 32 - #define HAVOCBOT_CTF_ROLE_ESCORT 64 -const float HAVOCBOT_CTF_ROLE_NONE = 0; -const float HAVOCBOT_CTF_ROLE_DEFENSE = 2; -const float HAVOCBOT_CTF_ROLE_MIDDLE = 4; -const float HAVOCBOT_CTF_ROLE_OFFENSE = 8; -const float HAVOCBOT_CTF_ROLE_CARRIER = 16; -const float HAVOCBOT_CTF_ROLE_RETRIEVER = 32; -const float HAVOCBOT_CTF_ROLE_ESCORT = 64; ++const int HAVOCBOT_CTF_ROLE_NONE = 0; ++const int HAVOCBOT_CTF_ROLE_DEFENSE = 2; ++const int HAVOCBOT_CTF_ROLE_MIDDLE = 4; ++const int HAVOCBOT_CTF_ROLE_OFFENSE = 8; ++const int HAVOCBOT_CTF_ROLE_CARRIER = 16; ++const int HAVOCBOT_CTF_ROLE_RETRIEVER = 32; ++const int HAVOCBOT_CTF_ROLE_ESCORT = 64; --.float havocbot_cantfindflag; ++.bool havocbot_cantfindflag; vector havocbot_ctf_middlepoint; float havocbot_ctf_middlepoint_radius; --void havocbot_role_ctf_setrole(entity bot, float role); ++void havocbot_role_ctf_setrole(entity bot, int role); + +// team checking +#define CTF_SAMETEAM(a,b) ((autocvar_g_ctf_reverse || (ctf_oneflag && autocvar_g_ctf_oneflag_reverse)) ? DIFF_TEAM(a,b) : SAME_TEAM(a,b)) +#define CTF_DIFFTEAM(a,b) ((autocvar_g_ctf_reverse || (ctf_oneflag && autocvar_g_ctf_oneflag_reverse)) ? SAME_TEAM(a,b) : DIFF_TEAM(a,b)) + ++// networked flag statuses ++.int ctf_flagstatus; #endif + - // networked flag statuses - .float ctf_flagstatus; - - const float CTF_RED_FLAG_TAKEN = 1; - const float CTF_RED_FLAG_LOST = 2; - const float CTF_RED_FLAG_CARRYING = 3; - const float CTF_BLUE_FLAG_TAKEN = 4; - const float CTF_BLUE_FLAG_LOST = 8; - const float CTF_BLUE_FLAG_CARRYING = 12; - const float CTF_YELLOW_FLAG_TAKEN = 16; - const float CTF_YELLOW_FLAG_LOST = 32; - const float CTF_YELLOW_FLAG_CARRYING = 48; - const float CTF_PINK_FLAG_TAKEN = 64; - const float CTF_PINK_FLAG_LOST = 128; - const float CTF_PINK_FLAG_CARRYING = 192; - const float CTF_NEUTRAL_FLAG_TAKEN = 256; - const float CTF_NEUTRAL_FLAG_LOST = 512; - const float CTF_NEUTRAL_FLAG_CARRYING = 768; - const float CTF_FLAG_NEUTRAL = 2048; - const float CTF_SHIELDED = 4096; ++const int CTF_RED_FLAG_TAKEN = 1; ++const int CTF_RED_FLAG_LOST = 2; ++const int CTF_RED_FLAG_CARRYING = 3; ++const int CTF_BLUE_FLAG_TAKEN = 4; ++const int CTF_BLUE_FLAG_LOST = 8; ++const int CTF_BLUE_FLAG_CARRYING = 12; ++const int CTF_YELLOW_FLAG_TAKEN = 16; ++const int CTF_YELLOW_FLAG_LOST = 32; ++const int CTF_YELLOW_FLAG_CARRYING = 48; ++const int CTF_PINK_FLAG_TAKEN = 64; ++const int CTF_PINK_FLAG_LOST = 128; ++const int CTF_PINK_FLAG_CARRYING = 192; ++const int CTF_NEUTRAL_FLAG_TAKEN = 256; ++const int CTF_NEUTRAL_FLAG_LOST = 512; ++const int CTF_NEUTRAL_FLAG_CARRYING = 768; ++const int CTF_FLAG_NEUTRAL = 2048; ++const int CTF_SHIELDED = 4096; ++ + #endif