]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/mutators/gamemode_assault.qc
Merge branch 'master' into terencehill/hud_cleanups
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / gamemode_assault.qc
index de0932263a1065f2d6ea0dbc2300bd747aaf60a8..85d975fbc60f7b89f26071138a0b081232b37b3f 100644 (file)
@@ -1,27 +1,30 @@
-#include "../../common/triggers/subs.qh"
+#include "gamemode_assault.qh"
+
+#include "gamemode.qh"
+
+.entity sprite;
 
 // random functions
 void assault_objective_use()
-{
+{SELFPARAM();
        // activate objective
        self.health = 100;
        //print("^2Activated objective ", self.targetname, "=", etos(self), "\n");
        //print("Activator is ", activator.classname, "\n");
 
-       entity oldself;
-       oldself = self;
-
-       for(self = world; (self = find(self, target, oldself.targetname)); )
+       for (entity e = world; (e = find(e, target, this.targetname)); )
        {
-               if(self.classname == "target_objective_decrease")
-                       target_objective_decrease_activate();
+               if (e.classname == "target_objective_decrease")
+               {
+                       WITH(entity, self, e, target_objective_decrease_activate());
+               }
        }
 
-       self = oldself;
+       setself(this);
 }
 
 vector target_objective_spawn_evalfunc(entity player, entity spot, vector current)
-{
+{SELFPARAM();
        if(self.health < 0 || self.health >= ASSAULT_VALUE_INACTIVE)
                return '-1 0 0';
        return current;
@@ -30,13 +33,13 @@ vector target_objective_spawn_evalfunc(entity player, entity spot, vector curren
 // reset this objective. Used when spawning an objective
 // and when a new round starts
 void assault_objective_reset()
-{
+{SELFPARAM();
        self.health = ASSAULT_VALUE_INACTIVE;
 }
 
 // decrease the health of targeted objectives
 void assault_objective_decrease_use()
-{
+{SELFPARAM();
        if(activator.team != assault_attacker_team)
        {
                // wrong team triggered decrease
@@ -65,25 +68,24 @@ void assault_objective_decrease_use()
                        PlayerTeamScore_Add(activator, SP_ASSAULT_OBJECTIVES, ST_ASSAULT_OBJECTIVES, 1);
                        self.enemy.health = -1;
 
-                       entity oldself, oldactivator, head;
+                       entity oldactivator, head;
 
-                       oldself = self;
-                       self = oldself.enemy;
+                       setself(this.enemy);
                        if(self.message)
                        FOR_EACH_PLAYER(head)
                                centerprint(head, self.message);
 
                        oldactivator = activator;
-                       activator = oldself;
+                       activator = this;
                        SUB_UseTargets();
                        activator = oldactivator;
-                       self = oldself;
+                       setself(this);
                }
        }
 }
 
 void assault_setenemytoobjective()
-{
+{SELFPARAM();
        entity objective;
        for(objective = world; (objective = find(objective, targetname, self.target)); )
        {
@@ -102,7 +104,7 @@ void assault_setenemytoobjective()
 }
 
 float assault_decreaser_sprite_visible(entity e)
-{
+{SELFPARAM();
        entity decreaser;
 
        decreaser = self.assault_decreaser;
@@ -114,7 +116,7 @@ float assault_decreaser_sprite_visible(entity e)
 }
 
 void target_objective_decrease_activate()
-{
+{SELFPARAM();
        entity ent, spr;
        self.owner = world;
        for(ent = world; (ent = find(ent, target, self.targetname)); )
@@ -126,20 +128,20 @@ void target_objective_decrease_activate()
                                ent.sprite = world;
                }
 
-               spr = WaypointSprite_SpawnFixed("<placeholder>", 0.5 * (ent.absmin + ent.absmax), ent, assault_sprite, RADARICON_OBJECTIVE, '1 0.5 0');
+               spr = WaypointSprite_SpawnFixed(WP_Assault, 0.5 * (ent.absmin + ent.absmax), ent, assault_sprite, RADARICON_OBJECTIVE);
                spr.assault_decreaser = self;
                spr.waypointsprite_visible_for_player = assault_decreaser_sprite_visible;
                spr.classname = "sprite_waypoint";
                WaypointSprite_UpdateRule(spr, assault_attacker_team, SPRITERULE_TEAMPLAY);
                if(ent.classname == "func_assault_destructible")
                {
-                       WaypointSprite_UpdateSprites(spr, "as-defend", "as-destroy", "as-destroy");
+                       WaypointSprite_UpdateSprites(spr, WP_AssaultDefend, WP_AssaultDestroy, WP_AssaultDestroy);
                        WaypointSprite_UpdateMaxHealth(spr, ent.max_health);
                        WaypointSprite_UpdateHealth(spr, ent.health);
                        ent.sprite = spr;
                }
                else
-                       WaypointSprite_UpdateSprites(spr, "as-defend", "as-push", "as-push");
+                       WaypointSprite_UpdateSprites(spr, WP_AssaultDefend, WP_AssaultPush, WP_AssaultPush);
        }
 }
 
@@ -149,48 +151,37 @@ void target_objective_decrease_findtarget()
 }
 
 void target_assault_roundend_reset()
-{
+{SELFPARAM();
        //print("round end reset\n");
        self.cnt = self.cnt + 1; // up round counter
        self.winning = 0; // up round
 }
 
 void target_assault_roundend_use()
-{
+{SELFPARAM();
        self.winning = 1; // round has been won by attackers
 }
 
 void assault_roundstart_use()
-{
+{SELFPARAM();
        activator = self;
        SUB_UseTargets();
 
-#ifdef TTURRETS_ENABLED
-       entity ent, oldself;
-
        //(Re)spawn all turrets
-       oldself = self;
-       ent = find(world, classname, "turret_main");
-       while(ent) {
+       for(entity ent = NULL; (ent = find(ent, classname, "turret_main")); ) {
                // Swap turret teams
                if(ent.team == NUM_TEAM_1)
                        ent.team = NUM_TEAM_2;
                else
                        ent.team = NUM_TEAM_1;
 
-               self = ent;
-
                // Dubbles as teamchange
-               turret_stdproc_respawn();
-
-               ent = find(ent, classname, "turret_main");
+               WITH(entity, self, ent, turret_respawn());
        }
-       self = oldself;
-#endif
 }
 
 void assault_wall_think()
-{
+{SELFPARAM();
        if(self.enemy.health < 0)
        {
                self.model = "";
@@ -207,8 +198,31 @@ void assault_wall_think()
 
 // trigger new round
 // reset objectives, toggle spawnpoints, reset triggers, ...
+void vehicles_clearreturn(entity veh);
+void vehicles_spawn();
 void assault_new_round()
-{
+{SELFPARAM();
+       //bprint("ASSAULT: new round\n");
+
+       // Eject players from vehicles
+       entity e;
+    FOR_EACH_PLAYER(e)
+    {
+        if(e.vehicle)
+        {
+               WITH(entity, self, e, vehicles_exit(VHEF_RELEASE));
+        }
+    }
+
+    for (entity e_ = findchainflags(vehicle_flags, VHF_ISVEHICLE); e_; e_ = e_.chain)
+    {
+       setself(e_);
+        vehicles_clearreturn(self);
+        vehicles_spawn();
+    }
+
+    setself(this);
+
        // up round counter
        self.winning = self.winning + 1;
 
@@ -236,23 +250,23 @@ void assault_new_round()
 }
 
 // spawnfuncs
-void spawnfunc_info_player_attacker()
+spawnfunc(info_player_attacker)
 {
        if (!g_assault) { remove(self); return; }
 
        self.team = NUM_TEAM_1; // red, gets swapped every round
-       spawnfunc_info_player_deathmatch();
+       spawnfunc_info_player_deathmatch(this);
 }
 
-void spawnfunc_info_player_defender()
+spawnfunc(info_player_defender)
 {
        if (!g_assault) { remove(self); return; }
 
        self.team = NUM_TEAM_2; // blue, gets swapped every round
-       spawnfunc_info_player_deathmatch();
+       spawnfunc_info_player_deathmatch(this);
 }
 
-void spawnfunc_target_objective()
+spawnfunc(target_objective)
 {
        if (!g_assault) { remove(self); return; }
 
@@ -263,7 +277,7 @@ void spawnfunc_target_objective()
        self.spawn_evalfunc = target_objective_spawn_evalfunc;
 }
 
-void spawnfunc_target_objective_decrease()
+spawnfunc(target_objective_decrease)
 {
        if (!g_assault) { remove(self); return; }
 
@@ -281,7 +295,8 @@ void spawnfunc_target_objective_decrease()
 }
 
 // destructible walls that can be used to trigger target_objective_decrease
-void spawnfunc_func_assault_destructible()
+spawnfunc(func_breakable);
+spawnfunc(func_assault_destructible)
 {
        if (!g_assault) { remove(self); return; }
 
@@ -293,23 +308,23 @@ void spawnfunc_func_assault_destructible()
        else
                self.team = NUM_TEAM_1;
 
-       spawnfunc_func_breakable();
+       spawnfunc_func_breakable(this);
 }
 
-void spawnfunc_func_assault_wall()
+spawnfunc(func_assault_wall)
 {
        if (!g_assault) { remove(self); return; }
 
        self.classname = "func_assault_wall";
        self.mdl = self.model;
-       setmodel(self, self.mdl);
+       _setmodel(self, self.mdl);
        self.solid = SOLID_BSP;
        self.think = assault_wall_think;
        self.nextthink = time;
        InitializeEntity(self, assault_setenemytoobjective, INITPRIO_FINDTARGET);
 }
 
-void spawnfunc_target_assault_roundend()
+spawnfunc(target_assault_roundend)
 {
        if (!g_assault) { remove(self); return; }
 
@@ -320,7 +335,7 @@ void spawnfunc_target_assault_roundend()
        self.reset = target_assault_roundend_reset;
 }
 
-void spawnfunc_target_assault_roundstart()
+spawnfunc(target_assault_roundstart)
 {
        if (!g_assault) { remove(self); return; }
 
@@ -333,7 +348,7 @@ void spawnfunc_target_assault_roundstart()
 
 // legacy bot code
 void havocbot_goalrating_ast_targets(float ratingscale)
-{
+{SELFPARAM();
        entity ad, best, wp, tod;
        float radius, found, bestvalue;
        vector p;
@@ -419,7 +434,7 @@ void havocbot_goalrating_ast_targets(float ratingscale)
 }
 
 void havocbot_role_ast_offense()
-{
+{SELFPARAM();
        if(self.deadflag != DEAD_NO)
        {
                self.havocbot_attack_time = 0;
@@ -453,7 +468,7 @@ void havocbot_role_ast_offense()
 }
 
 void havocbot_role_ast_defense()
-{
+{SELFPARAM();
        if(self.deadflag != DEAD_NO)
        {
                self.havocbot_attack_time = 0;
@@ -504,7 +519,7 @@ void havocbot_role_ast_setrole(entity bot, float role)
 }
 
 void havocbot_ast_reset_role(entity bot)
-{
+{SELFPARAM();
        if(self.deadflag != DEAD_NO)
                return;
 
@@ -516,7 +531,7 @@ void havocbot_ast_reset_role(entity bot)
 
 // mutator hooks
 MUTATOR_HOOKFUNCTION(assault_PlayerSpawn)
-{
+{SELFPARAM();
        if(self.team == assault_attacker_team)
                Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_ASSAULT_ATTACKING);
        else
@@ -526,26 +541,31 @@ MUTATOR_HOOKFUNCTION(assault_PlayerSpawn)
 }
 
 MUTATOR_HOOKFUNCTION(assault_TurretSpawn)
-{
-       if (!self.team)
-               self.team = 14;
+{SELFPARAM();
+       if(!self.team || self.team == MAX_SHOT_DISTANCE)
+               self.team = 5; // this gets reversed when match starts?
 
        return false;
 }
 
 MUTATOR_HOOKFUNCTION(assault_VehicleSpawn)
-{
+{SELFPARAM();
        self.nextthink = time + 0.5;
 
        return false;
 }
 
 MUTATOR_HOOKFUNCTION(assault_BotRoles)
-{
+{SELFPARAM();
        havocbot_ast_reset_role(self);
        return true;
 }
 
+MUTATOR_HOOKFUNCTION(assault_PlayHitsound)
+{
+       return (frag_victim.classname == "func_assault_destructible");
+}
+
 // scoreboard setup
 void assault_ScoreRules()
 {
@@ -561,6 +581,7 @@ MUTATOR_DEFINITION(gamemode_assault)
        MUTATOR_HOOK(TurretSpawn, assault_TurretSpawn, CBC_ORDER_ANY);
        MUTATOR_HOOK(VehicleSpawn, assault_VehicleSpawn, CBC_ORDER_ANY);
        MUTATOR_HOOK(HavocBot_ChooseRole, assault_BotRoles, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayHitsound, assault_PlayHitsound, CBC_ORDER_ANY);
 
        MUTATOR_ONADD
        {
@@ -578,7 +599,7 @@ MUTATOR_DEFINITION(gamemode_assault)
 
        MUTATOR_ONREMOVE
        {
-               print("This is a game type and it cannot be removed at runtime.");
+               LOG_INFO("This is a game type and it cannot be removed at runtime.");
                return -1;
        }