#include "sv_assault.qh"
+#include <server/command/vote.qh>
+#include <common/mapobjects/func/breakable.qh>
+#include <common/mapobjects/triggers.qh>
+#include <common/turrets/sv_turrets.qh>
+#include <server/damage.qh>
+#include <server/world.qh>
+#include <server/spawnpoints.qh>
+
.entity sprite;
#define AS_ROUND_DELAY 5
-IntrusiveList g_assault_destructibles;
-IntrusiveList g_assault_objectivedecreasers;
-IntrusiveList g_assault_objectives;
-STATIC_INIT(g_assault)
-{
- g_assault_destructibles = IL_NEW();
- g_assault_objectivedecreasers = IL_NEW();
- g_assault_objectives = IL_NEW();
-}
-
// random functions
void assault_objective_use(entity this, entity actor, entity trigger)
{
spr = WaypointSprite_SpawnFixed(WP_AssaultDefend, 0.5 * (it.absmin + it.absmax), it, assault_sprite, RADARICON_OBJECTIVE);
spr.assault_decreaser = this;
spr.waypointsprite_visible_for_player = assault_decreaser_sprite_visible;
- spr.classname = "sprite_waypoint";
WaypointSprite_UpdateRule(spr, assault_attacker_team, SPRITERULE_TEAMPLAY);
if(it.classname == "func_assault_destructible")
{
// reset objectives, toggle spawnpoints, reset triggers, ...
void assault_new_round(entity this)
{
- //bprint("ASSAULT: new round\n");
-
// up round counter
this.winning = this.winning + 1;
// reset the level with a countdown
cvar_set("timelimit", ftos(ceil(time - AS_ROUND_DELAY - game_starttime) / 60));
- ReadyRestart_force(); // sets game_starttime
+ bprint("Starting second round...\n");
+ ReadyRestart_force(true); // sets game_starttime
}
entity as_round;
{
if(ent.winning) // round end has been triggered by attacking team
{
- bprint("Assault: round completed.\n");
+ bprint(Team_ColoredFullName(assault_attacker_team), " destroyed the objective in ", process_time(2, ceil(time - game_starttime)), "\n");
SetWinners(team, assault_attacker_team);
TeamScore_AddToTeam(assault_attacker_team, ST_ASSAULT_OBJECTIVES, 666 - TeamScore_AddToTeam(assault_attacker_team, ST_ASSAULT_OBJECTIVES, 0));
- if(ent.cnt == 1 || autocvar_g_campaign) // this was the second round
+ // in campaign the game ends when the player destroys the objective, there's no second round
+ if(ent.cnt == 1 || autocvar_g_campaign) // this was the second round or the only round in campaign
{
status = WINNING_YES;
}
{
if (!g_assault) { delete(this); return; }
- this.classname = "target_objective";
IL_PUSH(g_assault_objectives, this);
this.use = assault_objective_use;
this.reset = assault_objective_reset;
{
if (!g_assault) { delete(this); return; }
- this.classname = "target_objective_decrease";
IL_PUSH(g_assault_objectivedecreasers, this);
if(!this.dmg)
return true;
}
-spawnfunc(func_breakable);
spawnfunc(func_assault_destructible)
{
if (!g_assault) { delete(this); return; }
this.spawnflags = 3;
- this.classname = "func_assault_destructible";
this.event_heal = destructible_heal;
IL_PUSH(g_assault_destructibles, this);
else
this.team = NUM_TEAM_1;
- spawnfunc_func_breakable(this);
+ func_breakable_setup(this);
}
spawnfunc(func_assault_wall)
{
if (!g_assault) { delete(this); return; }
- this.classname = "func_assault_wall";
this.mdl = this.model;
_setmodel(this, this.mdl);
this.solid = SOLID_BSP;
if (!g_assault) { delete(this); return; }
this.winning = 0; // round not yet won by attackers
- this.classname = "target_assault_roundend";
this.use = target_assault_roundend_use;
this.cnt = 0; // first round
this.reset = target_assault_roundend_reset;
if (!g_assault) { delete(this); return; }
assault_attacker_team = NUM_TEAM_1;
- this.classname = "target_assault_roundstart";
this.use = assault_roundstart_use;
this.reset2 = assault_roundstart_use_this;
InitializeEntity(this, assault_roundstart_use_this, INITPRIO_FINDTARGET);
entity turret = M_ARGV(0, entity);
if(!turret.team || turret.team == FLOAT_MAX)
- turret.team = 5; // this gets reversed when match starts?
+ turret.team = assault_attacker_team; // this gets reversed when match starts (assault_roundstart_use)
}
MUTATOR_HOOKFUNCTION(as, VehicleInit)
MUTATOR_HOOKFUNCTION(as, OnEntityPreSpawn)
{
- entity ent = M_ARGV(0, entity);
+ entity ent = M_ARGV(0, entity);
switch(ent.classname)
{
MUTATOR_HOOKFUNCTION(as, ReadyRestart_Deny)
{
- // readyrestart not supported (yet)
+ // readyrestart not supported
+ // it's allowed only in campaign since the campaign requires readyrestart support
+ // to do so Assault is played in single round mode
+ if (autocvar_g_campaign)
+ return false;
return true;
}