]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/mutators/gamemode_assault.qc
Mutators: combine headers
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / gamemode_assault.qc
diff --git a/qcsrc/server/mutators/gamemode_assault.qc b/qcsrc/server/mutators/gamemode_assault.qc
deleted file mode 100644 (file)
index 8558faa..0000000
+++ /dev/null
@@ -1,638 +0,0 @@
-#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");
-
-       for (entity e = world; (e = find(e, target, this.targetname)); )
-       {
-               if (e.classname == "target_objective_decrease")
-               {
-                       WITH(entity, self, e, target_objective_decrease_activate());
-               }
-       }
-
-       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;
-}
-
-// 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
-               return;
-       }
-
-       if(other.assault_sprite)
-       {
-               WaypointSprite_Disown(other.assault_sprite, waypointsprite_deadlifetime);
-               if(other.classname == "func_assault_destructible")
-                       other.sprite = world;
-       }
-       else
-               return; // already activated! cannot activate again!
-
-       if(self.enemy.health < ASSAULT_VALUE_INACTIVE)
-       {
-               if(self.enemy.health - self.dmg > 0.5)
-               {
-                       PlayerTeamScore_Add(activator, SP_SCORE, ST_SCORE, self.dmg);
-                       self.enemy.health = self.enemy.health - self.dmg;
-               }
-               else
-               {
-                       PlayerTeamScore_Add(activator, SP_SCORE, ST_SCORE, self.enemy.health);
-                       PlayerTeamScore_Add(activator, SP_ASSAULT_OBJECTIVES, ST_ASSAULT_OBJECTIVES, 1);
-                       self.enemy.health = -1;
-
-                       entity oldactivator, head;
-
-                       setself(this.enemy);
-                       if(self.message)
-                       FOR_EACH_PLAYER(head)
-                               centerprint(head, self.message);
-
-                       oldactivator = activator;
-                       activator = this;
-                       SUB_UseTargets();
-                       activator = oldactivator;
-                       setself(this);
-               }
-       }
-}
-
-void assault_setenemytoobjective()
-{SELFPARAM();
-       entity objective;
-       for(objective = world; (objective = find(objective, targetname, self.target)); )
-       {
-               if(objective.classname == "target_objective")
-               {
-                       if(self.enemy == world)
-                               self.enemy = objective;
-                       else
-                               objerror("more than one objective as target - fix the map!");
-                       break;
-               }
-       }
-
-       if(self.enemy == world)
-               objerror("no objective as target - fix the map!");
-}
-
-float assault_decreaser_sprite_visible(entity e)
-{SELFPARAM();
-       entity decreaser;
-
-       decreaser = self.assault_decreaser;
-
-       if(decreaser.enemy.health >= ASSAULT_VALUE_INACTIVE)
-               return false;
-
-       return true;
-}
-
-void target_objective_decrease_activate()
-{SELFPARAM();
-       entity ent, spr;
-       self.owner = world;
-       for(ent = world; (ent = find(ent, target, self.targetname)); )
-       {
-               if(ent.assault_sprite != world)
-               {
-                       WaypointSprite_Disown(ent.assault_sprite, waypointsprite_deadlifetime);
-                       if(ent.classname == "func_assault_destructible")
-                               ent.sprite = world;
-               }
-
-               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, WP_AssaultDefend, WP_AssaultDestroy, WP_AssaultDestroy);
-                       WaypointSprite_UpdateMaxHealth(spr, ent.max_health);
-                       WaypointSprite_UpdateHealth(spr, ent.health);
-                       ent.sprite = spr;
-               }
-               else
-                       WaypointSprite_UpdateSprites(spr, WP_AssaultDefend, WP_AssaultPush, WP_AssaultPush);
-       }
-}
-
-void target_objective_decrease_findtarget()
-{
-       assault_setenemytoobjective();
-}
-
-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();
-
-       //(Re)spawn all turrets
-       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;
-
-               // Dubbles as teamchange
-               WITH(entity, self, ent, turret_respawn());
-       }
-}
-
-void assault_wall_think()
-{SELFPARAM();
-       if(self.enemy.health < 0)
-       {
-               self.model = "";
-               self.solid = SOLID_NOT;
-       }
-       else
-       {
-               self.model = self.mdl;
-               self.solid = SOLID_BSP;
-       }
-
-       self.nextthink = time + 0.2;
-}
-
-// 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;
-
-       // swap attacker/defender roles
-       if(assault_attacker_team == NUM_TEAM_1)
-               assault_attacker_team = NUM_TEAM_2;
-       else
-               assault_attacker_team = NUM_TEAM_1;
-
-       entity ent;
-       for(ent = world; (ent = nextent(ent)); )
-       {
-               if(clienttype(ent) == CLIENTTYPE_NOTACLIENT)
-               {
-                       if(ent.team_saved == NUM_TEAM_1)
-                               ent.team_saved = NUM_TEAM_2;
-                       else if(ent.team_saved == NUM_TEAM_2)
-                               ent.team_saved = NUM_TEAM_1;
-               }
-       }
-
-       // reset the level with a countdown
-       cvar_set("timelimit", ftos(ceil(time - game_starttime) / 60));
-       ReadyRestart_force(); // sets game_starttime
-}
-
-// spawnfuncs
-spawnfunc(info_player_attacker)
-{
-       if (!g_assault) { remove(self); return; }
-
-       self.team = NUM_TEAM_1; // red, gets swapped every round
-       spawnfunc_info_player_deathmatch(this);
-}
-
-spawnfunc(info_player_defender)
-{
-       if (!g_assault) { remove(self); return; }
-
-       self.team = NUM_TEAM_2; // blue, gets swapped every round
-       spawnfunc_info_player_deathmatch(this);
-}
-
-spawnfunc(target_objective)
-{
-       if (!g_assault) { remove(self); return; }
-
-       self.classname = "target_objective";
-       self.use = assault_objective_use;
-       assault_objective_reset();
-       self.reset = assault_objective_reset;
-       self.spawn_evalfunc = target_objective_spawn_evalfunc;
-}
-
-spawnfunc(target_objective_decrease)
-{
-       if (!g_assault) { remove(self); return; }
-
-       self.classname = "target_objective_decrease";
-
-       if(!self.dmg)
-               self.dmg = 101;
-
-       self.use = assault_objective_decrease_use;
-       self.health = ASSAULT_VALUE_INACTIVE;
-       self.max_health = ASSAULT_VALUE_INACTIVE;
-       self.enemy = world;
-
-       InitializeEntity(self, target_objective_decrease_findtarget, INITPRIO_FINDTARGET);
-}
-
-// destructible walls that can be used to trigger target_objective_decrease
-spawnfunc(func_breakable);
-spawnfunc(func_assault_destructible)
-{
-       if (!g_assault) { remove(self); return; }
-
-       self.spawnflags = 3;
-       self.classname = "func_assault_destructible";
-
-       if(assault_attacker_team == NUM_TEAM_1)
-               self.team = NUM_TEAM_2;
-       else
-               self.team = NUM_TEAM_1;
-
-       spawnfunc_func_breakable(this);
-}
-
-spawnfunc(func_assault_wall)
-{
-       if (!g_assault) { remove(self); return; }
-
-       self.classname = "func_assault_wall";
-       self.mdl = self.model;
-       _setmodel(self, self.mdl);
-       self.solid = SOLID_BSP;
-       self.think = assault_wall_think;
-       self.nextthink = time;
-       InitializeEntity(self, assault_setenemytoobjective, INITPRIO_FINDTARGET);
-}
-
-spawnfunc(target_assault_roundend)
-{
-       if (!g_assault) { remove(self); return; }
-
-       self.winning = 0; // round not yet won by attackers
-       self.classname = "target_assault_roundend";
-       self.use = target_assault_roundend_use;
-       self.cnt = 0; // first round
-       self.reset = target_assault_roundend_reset;
-}
-
-spawnfunc(target_assault_roundstart)
-{
-       if (!g_assault) { remove(self); return; }
-
-       assault_attacker_team = NUM_TEAM_1;
-       self.classname = "target_assault_roundstart";
-       self.use = assault_roundstart_use;
-       self.reset2 = assault_roundstart_use;
-       InitializeEntity(self, assault_roundstart_use, INITPRIO_FINDTARGET);
-}
-
-// legacy bot code
-void havocbot_goalrating_ast_targets(float ratingscale)
-{SELFPARAM();
-       entity ad, best, wp, tod;
-       float radius, found, bestvalue;
-       vector p;
-
-       ad = findchain(classname, "func_assault_destructible");
-
-       for (; ad; ad = ad.chain)
-       {
-               if (ad.target == "")
-                       continue;
-
-               if (!ad.bot_attack)
-                       continue;
-
-               found = false;
-               for(tod = world; (tod = find(tod, targetname, ad.target)); )
-               {
-                       if(tod.classname == "target_objective_decrease")
-                       {
-                               if(tod.enemy.health > 0 && tod.enemy.health < ASSAULT_VALUE_INACTIVE)
-                               {
-                               //      dprint(etos(ad),"\n");
-                                       found = true;
-                                       break;
-                               }
-                       }
-               }
-
-               if(!found)
-               {
-               ///     dprint("target not found\n");
-                       continue;
-               }
-               /// dprint("target #", etos(ad), " found\n");
-
-
-               p = 0.5 * (ad.absmin + ad.absmax);
-       //      dprint(vtos(ad.origin), " ", vtos(ad.absmin), " ", vtos(ad.absmax),"\n");
-       //      te_knightspike(p);
-       //      te_lightning2(world, '0 0 0', p);
-
-               // Find and rate waypoints around it
-               found = false;
-               best = world;
-               bestvalue = 99999999999;
-               for(radius=0; radius<1500 && !found; radius+=500)
-               {
-                       for(wp=findradius(p, radius); wp; wp=wp.chain)
-                       {
-                               if(!(wp.wpflags & WAYPOINTFLAG_GENERATED))
-                               if(wp.classname=="waypoint")
-                               if(checkpvs(wp.origin, ad))
-                               {
-                                       found = true;
-                                       if(wp.cnt<bestvalue)
-                                       {
-                                               best = wp;
-                                               bestvalue = wp.cnt;
-                                       }
-                               }
-                       }
-               }
-
-               if(best)
-               {
-               ///     dprint("waypoints around target were found\n");
-               //      te_lightning2(world, '0 0 0', best.origin);
-               //      te_knightspike(best.origin);
-
-                       navigation_routerating(best, ratingscale, 4000);
-                       best.cnt += 1;
-
-                       self.havocbot_attack_time = 0;
-
-                       if(checkpvs(self.view_ofs,ad))
-                       if(checkpvs(self.view_ofs,best))
-                       {
-                       //      dprint("increasing attack time for this target\n");
-                               self.havocbot_attack_time = time + 2;
-                       }
-               }
-       }
-}
-
-void havocbot_role_ast_offense()
-{SELFPARAM();
-       if(self.deadflag != DEAD_NO)
-       {
-               self.havocbot_attack_time = 0;
-               havocbot_ast_reset_role(self);
-               return;
-       }
-
-       // Set the role timeout if necessary
-       if (!self.havocbot_role_timeout)
-               self.havocbot_role_timeout = time + 120;
-
-       if (time > self.havocbot_role_timeout)
-       {
-               havocbot_ast_reset_role(self);
-               return;
-       }
-
-       if(self.havocbot_attack_time>time)
-               return;
-
-       if (self.bot_strategytime < time)
-       {
-               navigation_goalrating_start();
-               havocbot_goalrating_enemyplayers(20000, self.origin, 650);
-               havocbot_goalrating_ast_targets(20000);
-               havocbot_goalrating_items(15000, self.origin, 10000);
-               navigation_goalrating_end();
-
-               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-       }
-}
-
-void havocbot_role_ast_defense()
-{SELFPARAM();
-       if(self.deadflag != DEAD_NO)
-       {
-               self.havocbot_attack_time = 0;
-               havocbot_ast_reset_role(self);
-               return;
-       }
-
-       // Set the role timeout if necessary
-       if (!self.havocbot_role_timeout)
-               self.havocbot_role_timeout = time + 120;
-
-       if (time > self.havocbot_role_timeout)
-       {
-               havocbot_ast_reset_role(self);
-               return;
-       }
-
-       if(self.havocbot_attack_time>time)
-               return;
-
-       if (self.bot_strategytime < time)
-       {
-               navigation_goalrating_start();
-               havocbot_goalrating_enemyplayers(20000, self.origin, 3000);
-               havocbot_goalrating_ast_targets(20000);
-               havocbot_goalrating_items(15000, self.origin, 10000);
-               navigation_goalrating_end();
-
-               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-       }
-}
-
-void havocbot_role_ast_setrole(entity bot, float role)
-{
-       switch(role)
-       {
-               case HAVOCBOT_AST_ROLE_DEFENSE:
-                       bot.havocbot_role = havocbot_role_ast_defense;
-                       bot.havocbot_role_flags = HAVOCBOT_AST_ROLE_DEFENSE;
-                       bot.havocbot_role_timeout = 0;
-                       break;
-               case HAVOCBOT_AST_ROLE_OFFENSE:
-                       bot.havocbot_role = havocbot_role_ast_offense;
-                       bot.havocbot_role_flags = HAVOCBOT_AST_ROLE_OFFENSE;
-                       bot.havocbot_role_timeout = 0;
-                       break;
-       }
-}
-
-void havocbot_ast_reset_role(entity bot)
-{SELFPARAM();
-       if(self.deadflag != DEAD_NO)
-               return;
-
-       if(bot.team == assault_attacker_team)
-               havocbot_role_ast_setrole(bot, HAVOCBOT_AST_ROLE_OFFENSE);
-       else
-               havocbot_role_ast_setrole(bot, HAVOCBOT_AST_ROLE_DEFENSE);
-}
-
-// mutator hooks
-MUTATOR_HOOKFUNCTION(as, PlayerSpawn)
-{SELFPARAM();
-       if(self.team == assault_attacker_team)
-               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_ASSAULT_ATTACKING);
-       else
-               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_ASSAULT_DEFENDING);
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(as, TurretSpawn)
-{SELFPARAM();
-       if(!self.team || self.team == MAX_SHOT_DISTANCE)
-               self.team = 5; // this gets reversed when match starts?
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(as, VehicleSpawn)
-{SELFPARAM();
-       self.nextthink = time + 0.5;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(as, HavocBot_ChooseRole)
-{SELFPARAM();
-       havocbot_ast_reset_role(self);
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(as, PlayHitsound)
-{
-       return (frag_victim.classname == "func_assault_destructible");
-}
-
-MUTATOR_HOOKFUNCTION(as, GetTeamCount)
-{
-       // assault always has 2 teams
-       c1 = c2 = 0;
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(as, CheckRules_World)
-{
-       ret_float = WinningCondition_Assault();
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(as, ReadLevelCvars)
-{
-       // no assault warmups
-       warmup_stage = 0;
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(as, OnEntityPreSpawn)
-{
-       switch(self.classname)
-       {
-               case "info_player_team1":
-               case "info_player_team2":
-               case "info_player_team3":
-               case "info_player_team4":
-                       return true;
-       }
-
-       return false;
-}
-
-// scoreboard setup
-void assault_ScoreRules()
-{
-       ScoreRules_basics(2, SFL_SORT_PRIO_SECONDARY, SFL_SORT_PRIO_SECONDARY, true);
-       ScoreInfo_SetLabel_TeamScore(  ST_ASSAULT_OBJECTIVES,    "objectives",      SFL_SORT_PRIO_PRIMARY);
-       ScoreInfo_SetLabel_PlayerScore(SP_ASSAULT_OBJECTIVES,    "objectives",      SFL_SORT_PRIO_PRIMARY);
-       ScoreRules_basics_end();
-}
-
-REGISTER_MUTATOR(as, g_assault)
-{
-       ActivateTeamplay();
-       have_team_spawns = -1; // request team spawns
-
-       MUTATOR_ONADD
-       {
-               if(time > 1) // game loads at time 1
-                       error("This is a game type and it cannot be added at runtime.");
-               assault_ScoreRules();
-       }
-
-       MUTATOR_ONROLLBACK_OR_REMOVE
-       {
-               // we actually cannot roll back assault_Initialize here
-               // BUT: we don't need to! If this gets called, adding always
-               // succeeds.
-       }
-
-       MUTATOR_ONREMOVE
-       {
-               LOG_INFO("This is a game type and it cannot be removed at runtime.");
-               return -1;
-       }
-
-       return 0;
-}