ons_notification_time[this.team] = time;
}
- this.health = this.health - damage;
+ TakeResource(this, RESOURCE_HEALTH, damage);
if(this.owner.iscaptured)
- WaypointSprite_UpdateHealth(this.owner.sprite, this.health);
+ WaypointSprite_UpdateHealth(this.owner.sprite, GetResourceAmount(this, RESOURCE_HEALTH));
else
- WaypointSprite_UpdateBuildFinished(this.owner.sprite, time + (this.max_health - this.health) / (this.count / ONS_CP_THINKRATE));
+ WaypointSprite_UpdateBuildFinished(this.owner.sprite, time + (this.max_health - GetResourceAmount(this, RESOURCE_HEALTH)) / (this.count / ONS_CP_THINKRATE));
this.pain_finished = time + 1;
// particles on every hit
pointparticles(EFFECT_SPARKS, hitloc, force*-1, 1);
else
sound(this, CH_TRIGGER, SND_ONS_HIT2, VOL_BASE+0.3, ATTEN_NORM);
- if (this.health < 0)
+ if (GetResourceAmount(this, RESOURCE_HEALTH) < 0)
{
sound(this, CH_TRIGGER, SND_GRENADE_IMPACT, VOL_BASE, ATTEN_NORM);
pointparticles(EFFECT_ROCKET_EXPLODE, this.origin, '0 0 0', 1);
this.SendFlags |= CPSF_STATUS;
}
+bool ons_ControlPoint_Icon_Heal(entity targ, entity inflictor, float amount, float limit)
+{
+ float hlth = GetResourceAmount(targ, RESOURCE_HEALTH);
+ float true_limit = ((limit != RESOURCE_LIMIT_NONE) ? limit : targ.max_health);
+ if (hlth <= 0 || hlth >= true_limit)
+ return false;
+
+ GiveResourceWithLimit(targ, RESOURCE_HEALTH, amount, true_limit);
+ hlth = GetResourceAmount(targ, RESOURCE_HEALTH);
+ if(targ.owner.iscaptured)
+ WaypointSprite_UpdateHealth(targ.owner.sprite, hlth);
+ else
+ WaypointSprite_UpdateBuildFinished(targ.owner.sprite, time + (targ.max_health - hlth) / (targ.count / ONS_CP_THINKRATE));
+ targ.SendFlags |= CPSF_STATUS;
+ return true;
+}
+
void ons_ControlPoint_Icon_Think(entity this)
{
this.nextthink = time + ONS_CP_THINKRATE;
_friendly_count = _friendly_count * (autocvar_g_onslaught_cp_proxydecap_dps * ONS_CP_THINKRATE);
_enemy_count = _enemy_count * (autocvar_g_onslaught_cp_proxydecap_dps * ONS_CP_THINKRATE);
- this.health = bound(0, this.health + (_friendly_count - _enemy_count), this.max_health);
+ GiveResourceWithLimit(this, RESOURCE_HEALTH, (_friendly_count - _enemy_count), this.max_health);
this.SendFlags |= CPSF_STATUS;
- if(this.health <= 0)
+ if(GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
{
ons_ControlPoint_Icon_Damage(this, this, this, 1, 0, DMG_NOWEP, this.origin, '0 0 0');
return;
if (time > this.pain_finished + 5)
{
- if(this.health < this.max_health)
+ if(GetResourceAmount(this, RESOURCE_HEALTH) < this.max_health)
{
- this.health = this.health + this.count;
- if (this.health >= this.max_health)
- this.health = this.max_health;
- WaypointSprite_UpdateHealth(this.owner.sprite, this.health);
+ GiveResourceWithLimit(this, RESOURCE_HEALTH, this.count, this.max_health);
+ WaypointSprite_UpdateHealth(this.owner.sprite, GetResourceAmount(this, RESOURCE_HEALTH));
}
}
}
// damaged fx
- if(random() < 0.6 - this.health / this.max_health)
+ if(random() < 0.6 - GetResourceAmount(this, RESOURCE_HEALTH) / this.max_health)
{
Send_Effect(EFFECT_ELECTRIC_SPARKS, this.origin + randompos('-10 -10 -20', '10 10 20'), '0 0 0', 1);
if(!a)
return;
- this.health = this.health + this.count;
+ GiveResource(this, RESOURCE_HEALTH, this.count);
this.SendFlags |= CPSF_STATUS;
- if (this.health >= this.max_health)
+ if (GetResourceAmount(this, RESOURCE_HEALTH) >= this.max_health)
{
- this.health = this.max_health;
+ SetResourceAmountExplicit(this, RESOURCE_HEALTH, this.max_health);
this.count = autocvar_g_onslaught_cp_regen * ONS_CP_THINKRATE; // slow repair rate from now on
setthink(this, ons_ControlPoint_Icon_Think);
sound(this, CH_TRIGGER, SND_ONS_CONTROLPOINT_BUILT, VOL_BASE, ATTEN_NORM);
Send_Effect(EFFECT_CAP(this.owner.team), this.owner.origin, '0 0 0', 1);
WaypointSprite_UpdateMaxHealth(this.owner.sprite, this.max_health);
- WaypointSprite_UpdateHealth(this.owner.sprite, this.health);
+ WaypointSprite_UpdateHealth(this.owner.sprite, GetResourceAmount(this, RESOURCE_HEALTH));
if(IS_PLAYER(this.owner.ons_toucher))
{
if(this.owner.model != MDL_ONS_CP_PAD2.model_str())
setmodel_fixsize(this.owner, MDL_ONS_CP_PAD2);
- if(random() < 0.9 - this.health / this.max_health)
+ if(random() < 0.9 - GetResourceAmount(this, RESOURCE_HEALTH) / this.max_health)
Send_Effect(EFFECT_RAGE, this.origin + 10 * randomvec(), '0 0 -1', 1);
}
e.owner = cp;
e.max_health = autocvar_g_onslaught_cp_health;
- e.health = autocvar_g_onslaught_cp_buildhealth;
+ SetResourceAmountExplicit(e, RESOURCE_HEALTH, autocvar_g_onslaught_cp_buildhealth);
e.solid = SOLID_NOT;
e.takedamage = DAMAGE_AIM;
e.bot_attack = true;
IL_PUSH(g_bot_targets, e);
e.event_damage = ons_ControlPoint_Icon_Damage;
+ e.event_heal = ons_ControlPoint_Icon_Heal;
e.team = player.team;
e.colormap = 1024 + (e.team - 1) * 17;
- e.count = (e.max_health - e.health) * ONS_CP_THINKRATE / autocvar_g_onslaught_cp_buildtime; // how long it takes to build
+ e.count = (e.max_health - GetResourceAmount(e, RESOURCE_HEALTH)) * ONS_CP_THINKRATE / autocvar_g_onslaught_cp_buildtime; // how long it takes to build
sound(e, CH_TRIGGER, SND_ONS_CONTROLPOINT_BUILD, VOL_BASE, ATTEN_NORM);
Send_Effect(EFFECT_FLAG_TOUCH(player.team), e.origin, '0 0 0', 1);
- WaypointSprite_UpdateBuildFinished(cp.sprite, time + (e.max_health - e.health) / (e.count / ONS_CP_THINKRATE));
+ WaypointSprite_UpdateBuildFinished(cp.sprite, time + (e.max_health - GetResourceAmount(e, RESOURCE_HEALTH)) / (e.count / ONS_CP_THINKRATE));
WaypointSprite_UpdateRule(cp.sprite,cp.team,SPRITERULE_TEAMPLAY);
cp.sprite.SendFlags |= 16;
else
{
WaypointSprite_UpdateMaxHealth(e.sprite, e.goalentity.max_health);
- WaypointSprite_UpdateHealth(e.sprite, e.goalentity.health);
+ WaypointSprite_UpdateHealth(e.sprite, GetResourceAmount(e.goalentity, RESOURCE_HEALTH));
}
}
if(e.lastshielded)
play2team(this.team, SND(ONS_GENERATOR_UNDERATTACK));
}
}
- this.health = this.health - damage;
- WaypointSprite_UpdateHealth(this.sprite, this.health);
+ TakeResource(this, RESOURCE_HEALTH, damage);
+ float hlth = GetResourceAmount(this, RESOURCE_HEALTH);
+ WaypointSprite_UpdateHealth(this.sprite, hlth);
// choose an animation frame based on health
- this.frame = 10 * bound(0, (1 - this.health / this.max_health), 1);
+ this.frame = 10 * bound(0, (1 - hlth / this.max_health), 1);
// see if the generator is still functional, or dying
- if (this.health > 0)
+ if (hlth > 0)
{
- this.lasthealth = this.health;
+ this.lasthealth = hlth;
}
else
{
this.isshielded = false;
this.takedamage = DAMAGE_NO; // can't be hurt anymore
this.event_damage = func_null; // won't do anything if hurt
+ this.event_heal = func_null;
this.count = 0; // reset counter
setthink(this, func_null);
this.nextthink = 0;
this.SendFlags |= GSF_STATUS;
}
+bool ons_GeneratorHeal(entity targ, entity inflictor, float amount, float limit)
+{
+ float true_limit = ((limit != RESOURCE_LIMIT_NONE) ? limit : targ.max_health);
+ float hlth = GetResourceAmount(targ, RESOURCE_HEALTH);
+ if (hlth <= 0 || hlth >= true_limit)
+ return false;
+
+ GiveResourceWithLimit(targ, RESOURCE_HEALTH, amount, true_limit);
+ hlth = GetResourceAmount(targ, RESOURCE_HEALTH);
+ WaypointSprite_UpdateHealth(targ.sprite, hlth);
+ targ.frame = 10 * bound(0, (1 - hlth / targ.max_health), 1);
+ targ.lasthealth = hlth;
+ targ.SendFlags |= GSF_STATUS;
+ return true;
+}
+
void ons_GeneratorThink(entity this)
{
this.nextthink = time + GEN_THINKRATE;
- if (!game_stopped)
+
+ if (game_stopped || this.isshielded || time < this.wait)
+ return;
+
+ this.wait = time + 5;
+ FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it),
{
- if(!this.isshielded && this.wait < time)
+ if (SAME_TEAM(it, this))
{
- this.wait = time + 5;
- FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), {
- if(SAME_TEAM(it, this))
- {
- Send_Notification(NOTIF_ONE, it, MSG_CENTER, CENTER_ONS_NOTSHIELDED_TEAM);
- soundto(MSG_ONE, it, CHAN_AUTO, SND(KH_ALARM), VOL_BASE, ATTEN_NONE); // FIXME: unique sound?
- }
- else
- Send_Notification(NOTIF_ONE, it, MSG_CENTER, APP_TEAM_NUM(this.team, CENTER_ONS_NOTSHIELDED));
- });
+ Send_Notification(NOTIF_ONE, it, MSG_CENTER, CENTER_ONS_NOTSHIELDED_TEAM);
+ msg_entity = it;
+ soundto(MSG_ONE, this, CHAN_AUTO, SND(KH_ALARM), VOL_BASE, ATTEN_NONE); // FIXME: unique sound?
}
- }
+ else
+ Send_Notification(NOTIF_ONE, it, MSG_CENTER, APP_TEAM_NUM(this.team, CENTER_ONS_NOTSHIELDED));
+ });
}
void ons_GeneratorReset(entity this)
{
this.team = this.team_saved;
- this.lasthealth = this.max_health = this.health = autocvar_g_onslaught_gen_health;
+ SetResourceAmountExplicit(this, RESOURCE_HEALTH, autocvar_g_onslaught_gen_health);
+ this.lasthealth = this.max_health = autocvar_g_onslaught_gen_health;
this.takedamage = DAMAGE_AIM;
this.bot_attack = true;
if(!IL_CONTAINS(g_bot_targets, this))
this.islinked = true;
this.isshielded = true;
this.event_damage = ons_GeneratorDamage;
+ this.event_heal = ons_GeneratorHeal;
setthink(this, ons_GeneratorThink);
this.nextthink = time + GEN_THINKRATE;
this.SendFlags |= GSF_STATUS;
WaypointSprite_UpdateMaxHealth(this.sprite, this.max_health);
- WaypointSprite_UpdateHealth(this.sprite, this.health);
+ WaypointSprite_UpdateHealth(this.sprite, GetResourceAmount(this, RESOURCE_HEALTH));
WaypointSprite_UpdateRule(this.sprite,this.team,SPRITERULE_TEAMPLAY);
onslaught_updatelinks();
gen.team_saved = teamnumber;
IL_PUSH(g_saved_team, gen);
set_movetype(gen, MOVETYPE_NONE);
- gen.lasthealth = gen.max_health = gen.health = autocvar_g_onslaught_gen_health;
+ gen.lasthealth = gen.max_health = autocvar_g_onslaught_gen_health;
+ SetResourceAmountExplicit(gen, RESOURCE_HEALTH, autocvar_g_onslaught_gen_health);
gen.takedamage = DAMAGE_AIM;
gen.bot_attack = true;
IL_PUSH(g_bot_targets, gen);
gen.event_damage = ons_GeneratorDamage;
+ gen.event_heal = ons_GeneratorHeal;
gen.reset = ons_GeneratorReset;
setthink(gen, ons_GeneratorThink);
gen.nextthink = time + GEN_THINKRATE;
WaypointSprite_SpawnFixed(WP_Null, gen.origin + CPGEN_WAYPOINT_OFFSET, gen, sprite, RADARICON_NONE);
WaypointSprite_UpdateRule(gen.sprite, gen.team, SPRITERULE_TEAMPLAY);
WaypointSprite_UpdateMaxHealth(gen.sprite, gen.max_health);
- WaypointSprite_UpdateHealth(gen.sprite, gen.health);
+ WaypointSprite_UpdateHealth(gen.sprite, GetResourceAmount(gen, RESOURCE_HEALTH));
InitializeEntity(gen, ons_DelayedGeneratorSetup, INITPRIO_SETLOCATION);
}
void Onslaught_count_generators()
{
entity e;
- total_generators = redowned = blueowned = yellowowned = pinkowned = 0;
+ total_generators = 0;
+ for (int i = 1; i <= NUM_TEAMS; ++i)
+ {
+ Team_SetNumberOfControlPoints(Team_GetTeamFromIndex(i), 0);
+ }
for(e = ons_worldgeneratorlist; e; e = e.ons_worldgeneratornext)
{
++total_generators;
- redowned += (e.team == NUM_TEAM_1 && e.health > 0);
- blueowned += (e.team == NUM_TEAM_2 && e.health > 0);
- yellowowned += (e.team == NUM_TEAM_3 && e.health > 0);
- pinkowned += (e.team == NUM_TEAM_4 && e.health > 0);
+ if (GetResourceAmount(e, RESOURCE_HEALTH) < 1)
+ {
+ continue;
+ }
+ entity team_ = Entity_GetTeam(e);
+ int num_control_points = Team_GetNumberOfControlPoints(team_);
+ ++num_control_points;
+ Team_SetNumberOfControlPoints(team_, num_control_points);
}
}
int Onslaught_GetWinnerTeam()
{
int winner_team = 0;
- if(redowned > 0)
- winner_team = NUM_TEAM_1;
- if(blueowned > 0)
+ if (Team_GetNumberOfControlPoints(Team_GetTeamFromIndex(1)) >= 1)
{
- if(winner_team) return 0;
- winner_team = NUM_TEAM_2;
+ winner_team = NUM_TEAM_1;
}
- if(yellowowned > 0)
+ for (int i = 2; i <= NUM_TEAMS; ++i)
{
- if(winner_team) return 0;
- winner_team = NUM_TEAM_3;
+ if (Team_GetNumberOfControlPoints(Team_GetTeamFromIndex(i)) >= 1)
+ {
+ if (winner_team != 0)
+ {
+ return 0;
+ }
+ winner_team = Team_IndexToTeam(i);
+ }
}
- if(pinkowned > 0)
+ if (winner_team)
{
- if(winner_team) return 0;
- winner_team = NUM_TEAM_4;
- }
- if(winner_team)
return winner_team;
+ }
return -1; // no generators left?
}
void nades_Clear(entity e);
-#define ONS_OWNED_GENERATORS() ((redowned > 0) + (blueowned > 0) + (yellowowned > 0) + (pinkowned > 0))
-#define ONS_OWNED_GENERATORS_OK() (ONS_OWNED_GENERATORS() > 1)
bool Onslaught_CheckWinner()
{
if ((autocvar_timelimit && time > game_starttime + autocvar_timelimit * 60) || (round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0))
Onslaught_count_generators();
- if(ONS_OWNED_GENERATORS_OK())
+ if (Team_GetNumberOfTeamsWithControlPoints() > 1)
+ {
return 0;
+ }
int winner_team = Onslaught_GetWinnerTeam();
bool needarmor = false, needweapons = false;
// Needs armor/health?
- if(this.health<100)
+ if(GetResourceAmount(this, RESOURCE_HEALTH) < 100)
needarmor = true;
// Needs weapons?
int c = 0;
FOREACH(Weapons, it != WEP_Null, {
- if(this.weapons & (it.m_wepset))
+ if(STAT(WEAPONS, this) & (it.m_wepset))
if(++c >= 4)
break;
});
{
// gather health and armor only
if (it.solid)
- if ( ((it.health || it.armorvalue) && needarmor) || (it.weapons && needweapons ) )
+ if ( ((GetResourceAmount(it, RESOURCE_HEALTH) || GetResourceAmount(it, RESOURCE_ARMOR)) && needarmor) || (STAT(WEAPONS, it) && needweapons ) )
if (vdist(it.origin - org, <, sradius))
{
int t = it.bot_pickupevalfunc(this, it);
return true;
}
-MUTATOR_HOOKFUNCTION(ons, CheckAllowedTeams)
+MUTATOR_HOOKFUNCTION(ons, TeamBalance_CheckAllowedTeams)
{
// onslaught is special
for(entity tmp_entity = ons_worldgeneratorlist; tmp_entity; tmp_entity = tmp_entity.ons_worldgeneratornext)
{
- switch(tmp_entity.team)
+ if (Team_IsValidTeam(tmp_entity.team))
{
- case NUM_TEAM_1: c1 = 0; break;
- case NUM_TEAM_2: c2 = 0; break;
- case NUM_TEAM_3: c3 = 0; break;
- case NUM_TEAM_4: c4 = 0; break;
+ M_ARGV(0, float) |= Team_TeamToBit(tmp_entity.team);
}
}
{
entity source_point = ons_Nearest_ControlPoint(player, player.origin, autocvar_g_onslaught_teleport_radius);
- if ( !source_point && player.health > 0 )
+ if ( !source_point && GetResourceAmount(player, RESOURCE_HEALTH) > 0 )
{
sprint(player, "\nYou need to be next to a control point\n");
return true;
return true;
}
- if ( player.health <= 0 )
+ if ( GetResourceAmount(player, RESOURCE_HEALTH) <= 0 )
{
player.ons_spawn_by = closest_target;
player.respawn_flags = player.respawn_flags | RESPAWN_FORCE;
{
entity wp_owner = wp.owner;
entity e = WaypointSprite_getviewentity(to);
- if(SAME_TEAM(e, wp_owner) && wp_owner.goalentity.health >= wp_owner.goalentity.max_health) { wp_flag |= 2; }
+ if(SAME_TEAM(e, wp_owner) && GetResourceAmount(wp_owner.goalentity, RESOURCE_HEALTH) >= wp_owner.goalentity.max_health) { wp_flag |= 2; }
if(!ons_ControlPoint_Attackable(wp_owner, e.team)) { wp_flag |= 2; }
}
if(wp.owner.classname == "onslaught_generator")
{
entity wp_owner = wp.owner;
- if(wp_owner.isshielded && wp_owner.health >= wp_owner.max_health) { wp_flag |= 2; }
- if(wp_owner.health <= 0) { wp_flag |= 2; }
+ if(wp_owner.isshielded && GetResourceAmount(wp_owner, RESOURCE_HEALTH) >= wp_owner.max_health) { wp_flag |= 2; }
+ if(GetResourceAmount(wp_owner, RESOURCE_HEALTH) <= 0) { wp_flag |= 2; }
}
}
// scoreboard setup
void ons_ScoreRules()
{
- CheckAllowedTeams(NULL);
- int teams = 0;
- if(c1 >= 0) teams |= BIT(0);
- if(c2 >= 0) teams |= BIT(1);
- if(c3 >= 0) teams |= BIT(2);
- if(c4 >= 0) teams |= BIT(3);
+ entity balance = TeamBalance_CheckAllowedTeams(NULL);
+ int teams = TeamBalance_GetAllowedTeams(balance);
+ TeamBalance_Destroy(balance);
GameRules_scoring(teams, SFL_SORT_PRIO_PRIMARY, 0, {
field_team(ST_ONS_CAPS, "destroyed", SFL_SORT_PRIO_PRIMARY);
field(SP_ONS_CAPS, "caps", SFL_SORT_PRIO_SECONDARY);