]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/mutators/gamemode_keyhunt.qc
Merge branch 'master' into Mario/ons_updates
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / gamemode_keyhunt.qc
index 0512fe3f0d7cbc7dff24dcddfadc2ea45b04eb57..5fa2f6db2b7a9ea384a442664612681cca80f108 100644 (file)
@@ -1,4 +1,8 @@
-#define FOR_EACH_KH_KEY(v) for(v = kh_worldkeylist; v; v = v.kh_worldkeynext )
+#include "gamemode_keyhunt.qh"
+#include "../_all.qh"
+
+#include "gamemode.qh"
+
 
 // #define KH_PLAYER_USE_ATTACHMENT
 // #define KH_PLAYER_USE_CARRIEDMODEL
@@ -46,10 +50,10 @@ float kh_Team_ByID(float t)
        return 0;
 }
 
-entity kh_worldkeylist;
+//entity kh_worldkeylist;
 .entity kh_worldkeynext;
 entity kh_controller;
-float kh_tracking_enabled;
+//float kh_tracking_enabled;
 float kh_teams;
 float kh_interferemsg_time, kh_interferemsg_team;
 .entity kh_next, kh_prev; // linked list
@@ -67,16 +71,16 @@ string kh_sound_alarm = "kh/alarm.wav";  // the new siren/alarm
 
 float kh_key_dropped, kh_key_carried;
 
-#define ST_KH_CAPS 1
-#define SP_KH_CAPS 4
-#define SP_KH_PUSHES 5
-#define SP_KH_DESTROYS 6
-#define SP_KH_PICKUPS 7
-#define SP_KH_KCKILLS 8
-#define SP_KH_LOSSES 9
+const float ST_KH_CAPS = 1;
+const float SP_KH_CAPS = 4;
+const float SP_KH_PUSHES = 5;
+const float SP_KH_DESTROYS = 6;
+const float SP_KH_PICKUPS = 7;
+const float SP_KH_KCKILLS = 8;
+const float SP_KH_LOSSES = 9;
 void kh_ScoreRules(float teams)
 {
-       ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, SFL_SORT_PRIO_PRIMARY, TRUE);
+       ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, SFL_SORT_PRIO_PRIMARY, true);
        ScoreInfo_SetLabel_TeamScore(  ST_KH_CAPS,      "caps",      SFL_SORT_PRIO_SECONDARY);
        ScoreInfo_SetLabel_PlayerScore(SP_KH_CAPS,      "caps",      SFL_SORT_PRIO_SECONDARY);
        ScoreInfo_SetLabel_PlayerScore(SP_KH_PUSHES,    "pushes",    0);
@@ -91,20 +95,20 @@ float kh_KeyCarrier_waypointsprite_visible_for_player(entity e)  // runs all the
 {
        if(!IS_PLAYER(e) || self.team != e.team)
                if(!kh_tracking_enabled)
-                       return FALSE;
+                       return false;
 
-       return TRUE;
+       return true;
 }
 
 float kh_Key_waypointsprite_visible_for_player(entity e) // ??
 {
        if(!kh_tracking_enabled)
-               return FALSE;
+               return false;
        if(!self.owner)
-               return TRUE;
+               return true;
        if(!self.owner.owner)
-               return TRUE;
-       return FALSE;  // draw only when key is not owned
+               return true;
+       return false;  // draw only when key is not owned
 }
 
 void kh_update_state()
@@ -200,7 +204,7 @@ vector kh_AttachedOrigin(entity e)  // runs when a team captures the flag, it ca
        if(e.tag_entity)
        {
                makevectors(e.tag_entity.angles);
-               return e.tag_entity.origin + e.origin_x * v_forward - e.origin_y * v_right + e.origin_z * v_up;
+               return e.tag_entity.origin + e.origin.x * v_forward - e.origin.y * v_right + e.origin.z * v_up;
        }
        else
                return e.origin;
@@ -237,7 +241,7 @@ void kh_Key_Attach(entity key)  // runs when a player picks up a key and several
 #else
        setattachment(key, key.owner, "");
        setorigin(key, '0 0 1' * KH_KEY_ZSHIFT);  // fixing x, y in think
-       key.angles_y -= key.owner.angles_y;
+       key.angles_y -= key.owner.angles.y;
 #endif
        key.flags = 0;
        key.solid = SOLID_NOT;
@@ -271,12 +275,12 @@ void kh_Key_Detach(entity key) // runs every time a key is dropped or lost. Runs
        }
        // in any case:
        setattachment(key, world, "");
-       setorigin(key, key.owner.origin + '0 0 1' * (PL_MIN_z - KH_KEY_MIN_z));
+       setorigin(key, key.owner.origin + '0 0 1' * (PL_MIN.z - KH_KEY_MIN_z));
        key.angles = key.owner.angles;
 #else
-       setorigin(key, key.owner.origin + key.origin_z * '0 0 1');
+       setorigin(key, key.owner.origin + key.origin.z * '0 0 1');
        setattachment(key, world, "");
-       key.angles_y += key.owner.angles_y;
+       key.angles_y += key.owner.angles.y;
 #endif
        key.flags = FL_ITEM;
        key.solid = SOLID_TRIGGER;
@@ -397,7 +401,7 @@ void kh_Key_AssignTo(entity key, entity player)  // runs every time a key is pic
        }
 }
 
-void kh_Key_Damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+void kh_Key_Damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
 {
        if(self.owner)
                return;
@@ -494,10 +498,10 @@ void kh_FinishRound()  // runs when a team captures the keys
        kh_interferemsg_time = 0;
        entity key;
 
-       kh_no_radar_circles = TRUE;
+       kh_no_radar_circles = true;
        FOR_EACH_KH_KEY(key)
                kh_Key_Remove(key);
-       kh_no_radar_circles = FALSE;
+       kh_no_radar_circles = false;
 
        Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_KEYHUNT_ROUNDSTART, autocvar_g_balance_keyhunt_delay_round);
        kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_round, kh_StartRound);
@@ -523,7 +527,7 @@ void kh_WinnerTeam(float teem)  // runs when a team wins // Samual: Teem?.... TE
                nades_GiveBonus(key.owner, autocvar_g_nades_bonus_score_high);
        }
 
-       first = TRUE;
+       first = true;
        string keyowner = "";
        FOR_EACH_KH_KEY(key)
                if(key.owner.kh_next == key)
@@ -531,12 +535,12 @@ void kh_WinnerTeam(float teem)  // runs when a team wins // Samual: Teem?.... TE
                        if(!first)
                                keyowner = strcat(keyowner, ", ");
                        keyowner = key.owner.netname;
-                       first = FALSE;
+                       first = false;
                }
 
        Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(teem, INFO_KEYHUNT_CAPTURE_), keyowner);
 
-       first = TRUE;
+       first = true;
        midpoint = '0 0 0';
        firstorigin = '0 0 0';
        lastorigin = '0 0 0';
@@ -553,7 +557,7 @@ void kh_WinnerTeam(float teem)  // runs when a team wins // Samual: Teem?.... TE
                lastorigin = thisorigin;
                if(first)
                        firstorigin = thisorigin;
-               first = FALSE;
+               first = false;
        }
        if(kh_teams > 2)
        {
@@ -668,8 +672,8 @@ void kh_Key_Think()  // runs all the time
        if(self.owner)
        {
 #ifndef KH_PLAYER_USE_ATTACHMENT
-               makevectors('0 1 0' * (self.cnt + mod(time, 360) * KH_KEY_XYSPEED));
-               setorigin(self, v_forward * KH_KEY_XYDIST + '0 0 1' * self.origin_z);
+               makevectors('0 1 0' * (self.cnt + (time % 360) * KH_KEY_XYSPEED));
+               setorigin(self, v_forward * KH_KEY_XYDIST + '0 0 1' * self.origin.z);
 #endif
        }
 
@@ -769,7 +773,7 @@ void kh_Key_Spawn(entity initial_owner, float angle, float i)  // runs every tim
 
        Send_Notification(NOTIF_ONE, initial_owner, MSG_CENTER, APP_TEAM_NUM_4(initial_owner.team, CENTER_KEYHUNT_START_));
 
-       WaypointSprite_Spawn("key-dropped", 0, 0, key, '0 0 1' * KH_KEY_WP_ZSHIFT, world, key.team, key, waypointsprite_attachedforcarrier, FALSE, RADARICON_FLAG, '0 1 1');
+       WaypointSprite_Spawn("key-dropped", 0, 0, key, '0 0 1' * KH_KEY_WP_ZSHIFT, world, key.team, key, waypointsprite_attachedforcarrier, false, RADARICON_FLAG, '0 1 1');
        key.waypointsprite_attachedforcarrier.waypointsprite_visible_for_player = kh_Key_waypointsprite_visible_for_player;
 
        kh_Key_AssignTo(key, initial_owner);
@@ -814,7 +818,7 @@ void kh_Key_DropOne(entity key)
 
        kh_Key_AssignTo(key, world);
        makevectors(player.v_angle);
-       key.velocity = W_CalculateProjectileVelocity(player.velocity, autocvar_g_balance_keyhunt_throwvelocity * v_forward, FALSE);
+       key.velocity = W_CalculateProjectileVelocity(player.velocity, autocvar_g_balance_keyhunt_throwvelocity * v_forward, false);
        key.pusher = world;
        key.pushltime = time + autocvar_g_balance_keyhunt_protecttime;
        key.kh_dropperteam = key.team;
@@ -839,7 +843,7 @@ void kh_Key_DropAll(entity player, float suicide) // runs whenever a player dies
                        Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(key, INFO_KEYHUNT_LOST_), player.netname);
                        kh_Key_AssignTo(key, world);
                        makevectors('-1 0 0' * (45 + 45 * random()) + '0 360 0' * random());
-                       key.velocity = W_CalculateProjectileVelocity(player.velocity, autocvar_g_balance_keyhunt_dropvelocity * v_forward, FALSE);
+                       key.velocity = W_CalculateProjectileVelocity(player.velocity, autocvar_g_balance_keyhunt_dropvelocity * v_forward, false);
                        key.pusher = mypusher;
                        key.pushltime = time + autocvar_g_balance_keyhunt_protecttime;
                        if(suicide)
@@ -867,6 +871,8 @@ float kh_CheckPlayers(float num)
        return 0;
 }
 
+#define KH_READY_TEAMS() (!p1 + !p2 + ((kh_teams >= 3) ? !p3 : p3) + ((kh_teams >= 4) ? !p4 : p4))
+#define KH_READY_TEAMS_OK() (KH_READY_TEAMS() == kh_teams)
 void kh_WaitForPlayers()  // delay start of the round until enough players are present
 {
        if(time < game_starttime)
@@ -875,15 +881,35 @@ void kh_WaitForPlayers()  // delay start of the round until enough players are p
                return;
        }
 
+       static float prev_missing_teams_mask;
        float p1 = kh_CheckPlayers(0), p2 = kh_CheckPlayers(1), p3 = kh_CheckPlayers(2), p4 = kh_CheckPlayers(3);
-       if (!(p1 || p2 || p3 || p4))
+       if(KH_READY_TEAMS_OK())
        {
+               if(prev_missing_teams_mask > 0)
+                       Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS);
+               prev_missing_teams_mask = -1;
                Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_KEYHUNT_ROUNDSTART, autocvar_g_balance_keyhunt_delay_round);
                kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_round, kh_StartRound);
        }
        else
        {
-               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_KEYHUNT_WAIT, p1, p2, p3, p4);
+               if(player_count == 0)
+               {
+                       if(prev_missing_teams_mask > 0)
+                               Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS);
+                       prev_missing_teams_mask = -1;
+               }
+               else
+               {
+                       float missing_teams_mask = (!!p1) + (!!p2) * 2;
+                       if(kh_teams >= 3) missing_teams_mask += (!!p3) * 4;
+                       if(kh_teams >= 4) missing_teams_mask += (!!p4) * 8;
+                       if(prev_missing_teams_mask != missing_teams_mask)
+                       {
+                               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_MISSING_TEAMS, missing_teams_mask);
+                               prev_missing_teams_mask = missing_teams_mask;
+                       }
+               }
                kh_Controller_SetThink(1, kh_WaitForPlayers);
        }
 }
@@ -893,7 +919,7 @@ void kh_EnableTrackingDevice()  // runs after each round
        Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_KEYHUNT);
        Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_KEYHUNT_OTHER);
 
-       kh_tracking_enabled = TRUE;
+       kh_tracking_enabled = true;
 }
 
 void kh_StartRound()  // runs at the start of each round
@@ -908,10 +934,9 @@ void kh_StartRound()  // runs at the start of each round
        }
 
        float p1 = kh_CheckPlayers(0), p2 = kh_CheckPlayers(1), p3 = kh_CheckPlayers(2), p4 = kh_CheckPlayers(3);
-       if(p1 || p2 || p3 || p4)
+       if(!KH_READY_TEAMS_OK())
        {
                kh_Controller_SetThink(1, kh_WaitForPlayers);
-               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_KEYHUNT_WAIT, p1, p2, p3, p4);
                return;
        }
 
@@ -935,7 +960,7 @@ void kh_StartRound()  // runs at the start of each round
                kh_Key_Spawn(my_player, 360 * i / kh_teams, i);
        }
 
-       kh_tracking_enabled = FALSE;
+       kh_tracking_enabled = false;
        Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_KEYHUNT_SCAN, autocvar_g_balance_keyhunt_delay_tracking);
        kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_tracking, kh_EnableTrackingDevice);
 }
@@ -1025,18 +1050,18 @@ void kh_finalize()
 
 MUTATOR_HOOKFUNCTION(kh_Key_DropAll)
 {
-       kh_Key_DropAll(self, TRUE);
+       kh_Key_DropAll(self, true);
        return 0;
 }
 
 MUTATOR_HOOKFUNCTION(kh_PlayerDies)
 {
        if(self == other)
-               kh_Key_DropAll(self, TRUE);
+               kh_Key_DropAll(self, true);
        else if(IS_PLAYER(other))
-               kh_Key_DropAll(self, FALSE);
+               kh_Key_DropAll(self, false);
        else
-               kh_Key_DropAll(self, TRUE);
+               kh_Key_DropAll(self, true);
        return 0;
 }