]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/gamemodes/gamemode/onslaught/sv_onslaught.qc
Add support for pitch shifting to the QC sound sending implementation, apply pitch...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / gamemodes / gamemode / onslaught / sv_onslaught.qc
index 3ae794ea08d72429f7cd32746cd56f11c5d939f4..1f3e43378c71919fce84baf73f2d26e2e59d4587 100644 (file)
@@ -27,7 +27,6 @@ float autocvar_g_onslaught_teleport_radius;
 float autocvar_g_onslaught_spawn_choose;
 float autocvar_g_onslaught_click_radius;
 
-void FixSize(entity e);
 entity cam;
 
 // =======================
@@ -114,12 +113,6 @@ void ons_CaptureShield_Spawn(entity generator, bool is_generator)
 // Junk Pile
 // ==========
 
-void setmodel_fixsize(entity e, Model m)
-{
-       setmodel(e, m);
-       FixSize(e);
-}
-
 void onslaught_updatelinks()
 {
        entity l;
@@ -320,15 +313,15 @@ void ons_DelayedLinkSetup(entity this)
 // Main Control Point Functions
 // =============================
 
-int ons_ControlPoint_CanBeLinked(entity cp, int teamnumber)
+int ons_ControlPoint_CanBeLinked(entity cp, int teamnum)
 {
-       if(cp.aregensneighbor & BIT(teamnumber)) return 2;
-       if(cp.arecpsneighbor & BIT(teamnumber)) return 1;
+       if(cp.aregensneighbor & BIT(teamnum)) return 2;
+       if(cp.arecpsneighbor & BIT(teamnum)) return 1;
 
        return 0;
 }
 
-int ons_ControlPoint_Attackable(entity cp, int teamnumber)
+int ons_ControlPoint_Attackable(entity cp, int teamnum)
        // -2: SAME TEAM, attackable by enemy!
        // -1: SAME TEAM!
        // 0: off limits
@@ -346,16 +339,16 @@ int ons_ControlPoint_Attackable(entity cp, int teamnumber)
        else if(cp.goalentity)
        {
                // if there's already an icon built, nothing happens
-               if(cp.team == teamnumber)
+               if(cp.team == teamnum)
                {
-                       a = ons_ControlPoint_CanBeLinked(cp, teamnumber);
+                       a = ons_ControlPoint_CanBeLinked(cp, teamnum);
                        if(a) // attackable by enemy?
                                return -2; // EMERGENCY!
                        return -1;
                }
                // we know it can be linked, so no need to check
                // but...
-               a = ons_ControlPoint_CanBeLinked(cp, teamnumber);
+               a = ons_ControlPoint_CanBeLinked(cp, teamnum);
                if(a == 2) // near our generator?
                        return 3; // EMERGENCY!
                return 1;
@@ -363,9 +356,9 @@ int ons_ControlPoint_Attackable(entity cp, int teamnumber)
        else
        {
                // free point
-               if(ons_ControlPoint_CanBeLinked(cp, teamnumber))
+               if(ons_ControlPoint_CanBeLinked(cp, teamnum))
                {
-                       a = ons_ControlPoint_CanBeLinked(cp, teamnumber); // why was this here NUM_TEAM_1 + NUM_TEAM_2 - t
+                       a = ons_ControlPoint_CanBeLinked(cp, teamnum); // why was this here NUM_TEAM_1 + NUM_TEAM_2 - t
                        if(a == 2)
                                return 4; // GET THIS ONE NOW!
                        else
@@ -400,11 +393,11 @@ void ons_ControlPoint_Icon_Damage(entity this, entity inflictor, entity attacker
                ons_notification_time[this.team] = time;
        }
 
-       TakeResource(this, RESOURCE_HEALTH, damage);
+       TakeResource(this, RES_HEALTH, damage);
        if(this.owner.iscaptured)
-               WaypointSprite_UpdateHealth(this.owner.sprite, GetResourceAmount(this, RESOURCE_HEALTH));
+               WaypointSprite_UpdateHealth(this.owner.sprite, GetResource(this, RES_HEALTH));
        else
-               WaypointSprite_UpdateBuildFinished(this.owner.sprite, time + (this.max_health - GetResourceAmount(this, RESOURCE_HEALTH)) / (this.count / ONS_CP_THINKRATE));
+               WaypointSprite_UpdateBuildFinished(this.owner.sprite, time + (this.max_health - GetResource(this, RES_HEALTH)) / (this.count / ONS_CP_THINKRATE));
        this.pain_finished = time + 1;
        // particles on every hit
        pointparticles(EFFECT_SPARKS, hitloc, force*-1, 1);
@@ -414,11 +407,14 @@ void ons_ControlPoint_Icon_Damage(entity this, entity inflictor, entity attacker
        else
                sound(this, CH_TRIGGER, SND_ONS_HIT2, VOL_BASE+0.3, ATTEN_NORM);
 
-       if (GetResourceAmount(this, RESOURCE_HEALTH) < 0)
+       if (GetResource(this, RES_HEALTH) < 0)
        {
                sound(this, CH_TRIGGER, SND_GRENADE_IMPACT, VOL_BASE, ATTEN_NORM);
                pointparticles(EFFECT_ROCKET_EXPLODE, this.origin, '0 0 0', 1);
-               Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(this.team, INFO_ONSLAUGHT_CPDESTROYED), this.owner.message, attacker.netname);
+               if (this.owner.message != "")
+                       Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(this.team, INFO_ONSLAUGHT_CPDESTROYED), this.owner.message, attacker.netname);
+               else
+                       Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(this.team, INFO_ONSLAUGHT_CPDESTROYED_NONAME), attacker.netname);
 
                GameRules_scoring_add(attacker, ONS_TAKES, 1);
                GameRules_scoring_add(attacker, SCORE, 10);
@@ -438,7 +434,7 @@ void ons_ControlPoint_Icon_Damage(entity this, entity inflictor, entity attacker
 
                this.owner.waslinked = this.owner.islinked;
                if(this.owner.model != "models/onslaught/controlpoint_pad.md3")
-                       setmodel_fixsize(this.owner, MDL_ONS_CP_PAD1);
+                       setmodel(this.owner, MDL_ONS_CP_PAD1);
                //setsize(this, '-32 -32 0', '32 32 8');
 
                delete(this);
@@ -447,6 +443,23 @@ void ons_ControlPoint_Icon_Damage(entity this, entity inflictor, entity attacker
        this.SendFlags |= CPSF_STATUS;
 }
 
+bool ons_ControlPoint_Icon_Heal(entity targ, entity inflictor, float amount, float limit)
+{
+       float hlth = GetResource(targ, RES_HEALTH);
+       float true_limit = ((limit != RES_LIMIT_NONE) ? limit : targ.max_health);
+       if (hlth <= 0 || hlth >= true_limit)
+               return false;
+
+       GiveResourceWithLimit(targ, RES_HEALTH, amount, true_limit);
+       hlth = GetResource(targ, RES_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;
@@ -469,9 +482,9 @@ void ons_ControlPoint_Icon_Think(entity this)
                _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);
 
-               GiveResourceWithLimit(this, RESOURCE_HEALTH, (_friendly_count - _enemy_count), this.max_health);
+               GiveResourceWithLimit(this, RES_HEALTH, (_friendly_count - _enemy_count), this.max_health);
                this.SendFlags |= CPSF_STATUS;
-               if(GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
+               if(GetResource(this, RES_HEALTH) <= 0)
                {
                        ons_ControlPoint_Icon_Damage(this, this, this, 1, 0, DMG_NOWEP, this.origin, '0 0 0');
                        return;
@@ -480,10 +493,10 @@ void ons_ControlPoint_Icon_Think(entity this)
 
        if (time > this.pain_finished + 5)
        {
-               if(GetResourceAmount(this, RESOURCE_HEALTH) < this.max_health)
+               if(GetResource(this, RES_HEALTH) < this.max_health)
                {
-                       GiveResourceWithLimit(this, RESOURCE_HEALTH, this.count, this.max_health);
-                       WaypointSprite_UpdateHealth(this.owner.sprite, GetResourceAmount(this, RESOURCE_HEALTH));
+                       GiveResourceWithLimit(this, RES_HEALTH, this.count, this.max_health);
+                       WaypointSprite_UpdateHealth(this.owner.sprite, GetResource(this, RES_HEALTH));
                }
        }
 
@@ -502,7 +515,7 @@ void ons_ControlPoint_Icon_Think(entity this)
        }
 
        // damaged fx
-       if(random() < 0.6 - GetResourceAmount(this, RESOURCE_HEALTH) / this.max_health)
+       if(random() < 0.6 - GetResource(this, RES_HEALTH) / this.max_health)
        {
                Send_Effect(EFFECT_ELECTRIC_SPARKS, this.origin + randompos('-10 -10 -20', '10 10 20'), '0 0 0', 1);
 
@@ -524,13 +537,13 @@ void ons_ControlPoint_Icon_BuildThink(entity this)
        if(!a)
                return;
 
-       GiveResource(this, RESOURCE_HEALTH, this.count);
+       GiveResource(this, RES_HEALTH, this.count);
 
        this.SendFlags |= CPSF_STATUS;
 
-       if (GetResourceAmount(this, RESOURCE_HEALTH) >= this.max_health)
+       if (GetResource(this, RES_HEALTH) >= this.max_health)
        {
-               SetResourceAmountExplicit(this, RESOURCE_HEALTH, this.max_health);
+               SetResourceExplicit(this, RES_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);
@@ -540,13 +553,22 @@ void ons_ControlPoint_Icon_BuildThink(entity this)
                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, GetResourceAmount(this, RESOURCE_HEALTH));
+               WaypointSprite_UpdateHealth(this.owner.sprite, GetResource(this, RES_HEALTH));
 
                if(IS_PLAYER(this.owner.ons_toucher))
                {
-                       Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_ONSLAUGHT_CAPTURE, this.owner.ons_toucher.netname, this.owner.message);
-                       Send_Notification(NOTIF_ALL_EXCEPT, this.owner.ons_toucher, MSG_CENTER, APP_TEAM_NUM(this.owner.ons_toucher.team, CENTER_ONS_CAPTURE_TEAM), this.owner.message);
-                       Send_Notification(NOTIF_ONE, this.owner.ons_toucher, MSG_CENTER, CENTER_ONS_CAPTURE, this.owner.message);
+                       if(this.owner.message != "")
+                       {
+                               Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_ONSLAUGHT_CAPTURE, this.owner.ons_toucher.netname, this.owner.message);
+                               Send_Notification(NOTIF_ALL_EXCEPT, this.owner.ons_toucher, MSG_CENTER, APP_TEAM_NUM(this.owner.ons_toucher.team, CENTER_ONS_CAPTURE_TEAM), this.owner.message);
+                               Send_Notification(NOTIF_ONE, this.owner.ons_toucher, MSG_CENTER, CENTER_ONS_CAPTURE, this.owner.message);
+                       }
+                       else
+                       {
+                               Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_ONSLAUGHT_CAPTURE_NONAME, this.owner.ons_toucher.netname);
+                               Send_Notification(NOTIF_ALL_EXCEPT, this.owner.ons_toucher, MSG_CENTER, APP_TEAM_NUM(this.owner.ons_toucher.team, CENTER_ONS_CAPTURE_TEAM_NONAME));
+                               Send_Notification(NOTIF_ONE, this.owner.ons_toucher, MSG_CENTER, CENTER_ONS_CAPTURE_NONAME);
+                       }
                        GameRules_scoring_add(this.owner.ons_toucher, ONS_CAPS, 1);
                        GameRules_scoring_add_team(this.owner.ons_toucher, SCORE, 10);
                }
@@ -561,9 +583,9 @@ void ons_ControlPoint_Icon_BuildThink(entity this)
                this.SendFlags |= CPSF_SETUP;
        }
        if(this.owner.model != MDL_ONS_CP_PAD2.model_str())
-               setmodel_fixsize(this.owner, MDL_ONS_CP_PAD2);
+               setmodel(this.owner, MDL_ONS_CP_PAD2);
 
-       if(random() < 0.9 - GetResourceAmount(this, RESOURCE_HEALTH) / this.max_health)
+       if(random() < 0.9 - GetResource(this, RES_HEALTH) / this.max_health)
                Send_Effect(EFFECT_RAGE, this.origin + 10 * randomvec(), '0 0 -1', 1);
 }
 
@@ -578,15 +600,16 @@ void ons_ControlPoint_Icon_Spawn(entity cp, entity player)
 
        e.owner = cp;
        e.max_health = autocvar_g_onslaught_cp_health;
-       SetResourceAmountExplicit(e, RESOURCE_HEALTH, autocvar_g_onslaught_cp_buildhealth);
+       SetResourceExplicit(e, RES_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 - GetResourceAmount(e, RESOURCE_HEALTH)) * ONS_CP_THINKRATE / autocvar_g_onslaught_cp_buildtime; // how long it takes to build
+       e.count = (e.max_health - GetResource(e, RES_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);
 
@@ -596,7 +619,7 @@ void ons_ControlPoint_Icon_Spawn(entity cp, entity player)
 
        Send_Effect(EFFECT_FLAG_TOUCH(player.team), e.origin, '0 0 0', 1);
 
-       WaypointSprite_UpdateBuildFinished(cp.sprite, time + (e.max_health - GetResourceAmount(e, RESOURCE_HEALTH)) / (e.count / ONS_CP_THINKRATE));
+       WaypointSprite_UpdateBuildFinished(cp.sprite, time + (e.max_health - GetResource(e, RES_HEALTH)) / (e.count / ONS_CP_THINKRATE));
        WaypointSprite_UpdateRule(cp.sprite,cp.team,SPRITERULE_TEAMPLAY);
        cp.sprite.SendFlags |= 16;
 
@@ -638,7 +661,7 @@ void ons_ControlPoint_UpdateSprite(entity e)
                        else
                        {
                                WaypointSprite_UpdateMaxHealth(e.sprite, e.goalentity.max_health);
-                               WaypointSprite_UpdateHealth(e.sprite, GetResourceAmount(e.goalentity, RESOURCE_HEALTH));
+                               WaypointSprite_UpdateHealth(e.sprite, GetResource(e.goalentity, RES_HEALTH));
                        }
                }
                if(e.lastshielded)
@@ -668,10 +691,11 @@ void ons_ControlPoint_Touch(entity this, entity toucher)
        int attackable;
 
        if(IS_VEHICLE(toucher) && toucher.owner)
-       if(autocvar_g_onslaught_allow_vehicle_touch)
+       {
+               if (!autocvar_g_onslaught_allow_vehicle_touch)
+                       return;
                toucher = toucher.owner;
-       else
-               return;
+       }
 
        if(!IS_PLAYER(toucher)) { return; }
        if(STAT(FROZEN, toucher)) { return; }
@@ -719,7 +743,7 @@ void ons_ControlPoint_Reset(entity this)
        setthink(this, ons_ControlPoint_Think);
        this.ons_toucher = NULL;
        this.nextthink = time + ONS_CP_THINKRATE;
-       setmodel_fixsize(this, MDL_ONS_CP_PAD1);
+       setmodel(this, MDL_ONS_CP_PAD1);
 
        WaypointSprite_UpdateMaxHealth(this.sprite, 0);
        WaypointSprite_UpdateRule(this.sprite,this.team,SPRITERULE_TEAMPLAY);
@@ -760,10 +784,8 @@ void ons_ControlPoint_Setup(entity cp)
        cp.islinked = false;
        cp.isshielded = true;
 
-       if(cp.message == "") { cp.message = "a"; }
-
        // appearence
-       setmodel_fixsize(cp, MDL_ONS_CP_PAD1);
+       setmodel(cp, MDL_ONS_CP_PAD1);
 
        // control point placement
        if((cp.spawnflags & 1) || cp.noalign) // don't drop to floor, just stay at fixed location
@@ -887,14 +909,15 @@ void ons_GeneratorDamage(entity this, entity inflictor, entity attacker, float d
                        play2team(this.team, SND(ONS_GENERATOR_UNDERATTACK));
                }
        }
-       TakeResource(this, RESOURCE_HEALTH, damage);
-       WaypointSprite_UpdateHealth(this.sprite, GetResourceAmount(this, RESOURCE_HEALTH));
+       TakeResource(this, RES_HEALTH, damage);
+       float hlth = GetResource(this, RES_HEALTH);
+       WaypointSprite_UpdateHealth(this.sprite, hlth);
        // choose an animation frame based on health
-       this.frame = 10 * bound(0, (1 - GetResourceAmount(this, RESOURCE_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 (GetResourceAmount(this, RESOURCE_HEALTH) > 0)
+       if (hlth > 0)
        {
-               this.lasthealth = GetResourceAmount(this, RESOURCE_HEALTH);
+               this.lasthealth = hlth;
        }
        else
        {
@@ -910,6 +933,7 @@ void ons_GeneratorDamage(entity this, entity inflictor, entity attacker, float d
                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;
@@ -944,6 +968,22 @@ void ons_GeneratorDamage(entity this, entity inflictor, entity attacker, float d
        this.SendFlags |= GSF_STATUS;
 }
 
+bool ons_GeneratorHeal(entity targ, entity inflictor, float amount, float limit)
+{
+       float true_limit = ((limit != RES_LIMIT_NONE) ? limit : targ.max_health);
+       float hlth = GetResource(targ, RES_HEALTH);
+       if (hlth <= 0 || hlth >= true_limit)
+               return false;
+
+       GiveResourceWithLimit(targ, RES_HEALTH, amount, true_limit);
+       hlth = GetResource(targ, RES_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;
@@ -958,7 +998,7 @@ void ons_GeneratorThink(entity this)
                {
                        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?
+                       soundto(MSG_ONE, this, CHAN_AUTO, SND(ONS_GENERATOR_ALARM), VOL_BASE, ATTEN_NONE, 0);
                }
                else
                        Send_Notification(NOTIF_ONE, it, MSG_CENTER, APP_TEAM_NUM(this.team, CENTER_ONS_NOTSHIELDED));
@@ -968,7 +1008,7 @@ void ons_GeneratorThink(entity this)
 void ons_GeneratorReset(entity this)
 {
        this.team = this.team_saved;
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, autocvar_g_onslaught_gen_health);
+       SetResourceExplicit(this, RES_HEALTH, autocvar_g_onslaught_gen_health);
        this.lasthealth = this.max_health = autocvar_g_onslaught_gen_health;
        this.takedamage = DAMAGE_AIM;
        this.bot_attack = true;
@@ -978,6 +1018,7 @@ void ons_GeneratorReset(entity 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;
 
@@ -987,7 +1028,7 @@ void ons_GeneratorReset(entity this)
        this.SendFlags |= GSF_STATUS;
 
        WaypointSprite_UpdateMaxHealth(this.sprite, this.max_health);
-       WaypointSprite_UpdateHealth(this.sprite, GetResourceAmount(this, RESOURCE_HEALTH));
+       WaypointSprite_UpdateHealth(this.sprite, GetResource(this, RES_HEALTH));
        WaypointSprite_UpdateRule(this.sprite,this.team,SPRITERULE_TEAMPLAY);
 
        onslaught_updatelinks();
@@ -1022,24 +1063,25 @@ void onslaught_generator_touch(entity this, entity toucher)
 void ons_GeneratorSetup(entity gen) // called when spawning a generator entity on the map as a spawnfunc
 {
        // declarations
-       int teamnumber = gen.team;
+       int teamnum = gen.team;
 
        // main setup
        gen.ons_worldgeneratornext = ons_worldgeneratorlist; // link generator into ons_worldgeneratorlist
        ons_worldgeneratorlist = gen;
 
-       gen.netname = sprintf("%s generator", Team_ColoredFullName(teamnumber));
+       gen.netname = sprintf("%s generator", Team_ColoredFullName(teamnum));
        gen.classname = "onslaught_generator";
        gen.solid = SOLID_BBOX;
-       gen.team_saved = teamnumber;
+       gen.team_saved = teamnum;
        IL_PUSH(g_saved_team, gen);
        set_movetype(gen, MOVETYPE_NONE);
        gen.lasthealth = gen.max_health = autocvar_g_onslaught_gen_health;
-       SetResourceAmountExplicit(gen, RESOURCE_HEALTH, autocvar_g_onslaught_gen_health);
+       SetResourceExplicit(gen, RES_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;
@@ -1052,7 +1094,7 @@ void ons_GeneratorSetup(entity gen) // called when spawning a generator entity o
        // model handled by CSQC
        setsize(gen, GENERATOR_MIN, GENERATOR_MAX);
        setorigin(gen, (gen.origin + CPGEN_SPAWN_OFFSET));
-       gen.colormap = 1024 + (teamnumber - 1) * 17;
+       gen.colormap = 1024 + (teamnum - 1) * 17;
 
        // generator placement
        droptofloor(gen);
@@ -1061,7 +1103,7 @@ void ons_GeneratorSetup(entity gen) // called when spawning a generator entity o
        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, GetResourceAmount(gen, RESOURCE_HEALTH));
+       WaypointSprite_UpdateHealth(gen.sprite, GetResource(gen, RES_HEALTH));
 
        InitializeEntity(gen, ons_DelayedGeneratorSetup, INITPRIO_SETLOCATION);
 }
@@ -1083,7 +1125,7 @@ void Onslaught_count_generators()
        for(e = ons_worldgeneratorlist; e; e = e.ons_worldgeneratornext)
        {
                ++total_generators;
-               if (GetResourceAmount(e, RESOURCE_HEALTH) < 1)
+               if (GetResource(e, RES_HEALTH) < 1)
                {
                        continue;
                }
@@ -1226,71 +1268,26 @@ void Onslaught_RoundStart()
 
 // NOTE: LEGACY CODE, needs to be re-written!
 
-void havocbot_goalrating_ons_offenseitems(entity this, float ratingscale, vector org, float sradius)
-{
-       bool needarmor = false, needweapons = false;
-
-       // Needs armor/health?
-       if(GetResourceAmount(this, RESOURCE_HEALTH) < 100)
-               needarmor = true;
-
-       // Needs weapons?
-       int c = 0;
-       FOREACH(Weapons, it != WEP_Null, {
-               if(STAT(WEAPONS, this) & (it.m_wepset))
-               if(++c >= 4)
-                       break;
-       });
-
-       if(c<4)
-               needweapons = true;
-
-       if(!needweapons && !needarmor)
-               return;
-
-       LOG_DEBUG(this.netname, " needs weapons ", ftos(needweapons));
-       LOG_DEBUG(this.netname, " needs armor ", ftos(needarmor));
-
-       // See what is around
-       IL_EACH(g_items, it.bot_pickup,
-       {
-               // gather health and armor only
-               if (it.solid)
-               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);
-                       if (t > 0)
-                               navigation_routerating(this, it, t * ratingscale, 500);
-               }
-       });
-}
-
 void havocbot_role_ons_setrole(entity this, int role)
 {
-       LOG_DEBUG(this.netname," switched to ");
        switch(role)
        {
                case HAVOCBOT_ONS_ROLE_DEFENSE:
-                       LOG_DEBUG("defense");
+                       LOG_DEBUG(this.netname, " switched to defense");
                        this.havocbot_role = havocbot_role_ons_defense;
-                       this.havocbot_role_flags = HAVOCBOT_ONS_ROLE_DEFENSE;
                        this.havocbot_role_timeout = 0;
                        break;
                case HAVOCBOT_ONS_ROLE_ASSISTANT:
-                       LOG_DEBUG("assistant");
+                       LOG_DEBUG(this.netname, " switched to assistant");
                        this.havocbot_role = havocbot_role_ons_assistant;
-                       this.havocbot_role_flags = HAVOCBOT_ONS_ROLE_ASSISTANT;
                        this.havocbot_role_timeout = 0;
                        break;
                case HAVOCBOT_ONS_ROLE_OFFENSE:
-                       LOG_DEBUG("offense");
+                       LOG_DEBUG(this.netname, " switched to offense");
                        this.havocbot_role = havocbot_role_ons_offense;
-                       this.havocbot_role_flags = HAVOCBOT_ONS_ROLE_OFFENSE;
                        this.havocbot_role_timeout = 0;
                        break;
        }
-       LOG_DEBUG("");
 }
 
 void havocbot_goalrating_ons_controlpoints_attack(entity this, float ratingscale)
@@ -1315,9 +1312,9 @@ void havocbot_goalrating_ons_controlpoints_attack(entity this, float ratingscale
 
                // Count team mates interested in this control point
                // (easier and cleaner than keeping counters per cp and teams)
-               FOREACH_CLIENT(IS_PLAYER(it), {
+               FOREACH_CLIENT(it != this && IS_PLAYER(it), {
                        if(SAME_TEAM(it, this))
-                       if(it.havocbot_role_flags & HAVOCBOT_ONS_ROLE_OFFENSE)
+                       if(it.havocbot_role == havocbot_role_ons_offense)
                        if(it.havocbot_ons_target == cp2)
                                ++c;
                });
@@ -1328,7 +1325,7 @@ void havocbot_goalrating_ons_controlpoints_attack(entity this, float ratingscale
        }
 
        // We'll consider only the best case
-       bestvalue = 99999999999;
+       bestvalue = FLOAT_MAX;
        cp = NULL;
        for(cp1 = ons_worldcplist; cp1; cp1 = cp1.ons_worldcpnext)
        {
@@ -1354,23 +1351,21 @@ void havocbot_goalrating_ons_controlpoints_attack(entity this, float ratingscale
                // Rate waypoints near it
                found = false;
                best = NULL;
-               bestvalue = 99999999999;
-               for(radius=0; radius<1000 && !found; radius+=500)
+               bestvalue = FLOAT_MAX;
+               for (radius = 500; radius <= 1000 && !found; radius += 500)
                {
-                       for(wp=findradius(cp.origin,radius); wp; wp=wp.chain)
+                       IL_EACH(g_waypoints, vdist(cp.origin - it.origin, <, radius),
                        {
-                               if(!(wp.wpflags & WAYPOINTFLAG_GENERATED))
-                               if(wp.classname=="waypoint")
-                               if(checkpvs(wp.origin,cp))
+                               if (!(it.wpflags & WAYPOINTFLAG_GENERATED) && checkpvs(it.origin, cp))
                                {
                                        found = true;
-                                       if(wp.cnt<bestvalue)
+                                       if (it.cnt < bestvalue)
                                        {
-                                               best = wp;
-                                               bestvalue = wp.cnt;
+                                               best = it;
+                                               bestvalue = it.cnt;
                                        }
                                }
-                       }
+                       });
                }
 
                if(best)
@@ -1393,22 +1388,7 @@ void havocbot_goalrating_ons_controlpoints_attack(entity this, float ratingscale
        {
                // Should be touched
                LOG_DEBUG(this.netname, " found a touchable controlpoint at ", vtos(cp.origin));
-               found = false;
-
-               // Look for auto generated waypoint
-               if (!bot_waypoints_for_items)
-               for (wp = findradius(cp.origin,100); wp; wp = wp.chain)
-               {
-                       if(wp.classname=="waypoint")
-                       {
-                               navigation_routerating(this, wp, ratingscale, 10000);
-                               found = true;
-                       }
-               }
-
-               // Nothing found, rate the controlpoint itself
-               if (!found)
-                       navigation_routerating(this, cp, ratingscale, 10000);
+               navigation_routerating(this, cp, ratingscale * 2, 10000);
        }
 }
 
@@ -1416,7 +1396,7 @@ bool havocbot_goalrating_ons_generator_attack(entity this, float ratingscale)
 {
        entity g, wp, bestwp;
        bool found;
-       int best;
+       int bestvalue;
 
        for(g = ons_worldgeneratorlist; g; g = g.ons_worldgeneratornext)
        {
@@ -1427,21 +1407,20 @@ bool havocbot_goalrating_ons_generator_attack(entity this, float ratingscale)
                // Rate waypoints near it
                found = false;
                bestwp = NULL;
-               best = 99999999999;
+               bestvalue = FLOAT_MAX;
 
-               for(wp=findradius(g.origin,400); wp; wp=wp.chain)
+               IL_EACH(g_waypoints, vdist(g.origin - it.origin, <, 400),
                {
-                       if(wp.classname=="waypoint")
-                       if(checkpvs(wp.origin,g))
+                       if (checkpvs(it.origin, g))
                        {
                                found = true;
-                               if(wp.cnt<best)
+                               if (it.cnt < bestvalue)
                                {
-                                       bestwp = wp;
-                                       best = wp.cnt;
+                                       bestwp = it;
+                                       bestvalue = it.cnt;
                                }
                        }
-               }
+               });
 
                if(bestwp)
                {
@@ -1494,9 +1473,9 @@ void havocbot_role_ons_offense(entity this)
        {
                navigation_goalrating_start(this);
                havocbot_goalrating_enemyplayers(this, 20000, this.origin, 650);
-               if(!havocbot_goalrating_ons_generator_attack(this, 20000))
-                       havocbot_goalrating_ons_controlpoints_attack(this, 20000);
-               havocbot_goalrating_ons_offenseitems(this, 10000, this.origin, 10000);
+               if(!havocbot_goalrating_ons_generator_attack(this, 10000))
+                       havocbot_goalrating_ons_controlpoints_attack(this, 10000);
+               havocbot_goalrating_items(this, 25000, this.origin, 10000);
                navigation_goalrating_end(this);
 
                navigation_goalrating_timeout_set(this);
@@ -1657,6 +1636,11 @@ bool ons_Teleport(entity player, entity tele_target, float range, bool tele_effe
                                player.angles = '0 1 0' * ( theta * RAD2DEG + 180 );
                                makevectors(player.angles);
                                player.fixangle = true;
+                               if (IS_BOT_CLIENT(player))
+                               {
+                                       player.v_angle = player.angles;
+                                       bot_aim_reset(player);
+                               }
                                player.teleport_antispam = time + autocvar_g_onslaught_teleport_wait;
 
                                if ( tele_effects )
@@ -1743,10 +1727,12 @@ MUTATOR_HOOKFUNCTION(ons, PlayerSpawn)
                for(tmp_entity = ons_worldcplist; tmp_entity; tmp_entity = tmp_entity.ons_worldcpnext)
                {
                        if(SAME_TEAM(tmp_entity, player))
-                       if(random_target)
-                               RandomSelection_AddEnt(tmp_entity, 1, 1);
-                       else if(vlen2(tmp_entity.origin - spawn_loc) <= vlen2(closest_target.origin - spawn_loc) || closest_target == NULL)
-                               closest_target = tmp_entity;
+                       {
+                               if(random_target)
+                                       RandomSelection_AddEnt(tmp_entity, 1, 1);
+                               else if(vlen2(tmp_entity.origin - spawn_loc) <= vlen2(closest_target.origin - spawn_loc) || closest_target == NULL)
+                                       closest_target = tmp_entity;
+                       }
                }
 
                if(random_target) { closest_target = RandomSelection_chosen_ent; }
@@ -1977,7 +1963,7 @@ MUTATOR_HOOKFUNCTION(ons, SV_ParseClientCommand)
                        {
                                entity source_point = ons_Nearest_ControlPoint(player, player.origin, autocvar_g_onslaught_teleport_radius);
 
-                               if ( !source_point && GetResourceAmount(player, RESOURCE_HEALTH) > 0 )
+                               if ( !source_point && GetResource(player, RES_HEALTH) > 0 )
                                {
                                        sprint(player, "\nYou need to be next to a control point\n");
                                        return true;
@@ -1992,7 +1978,7 @@ MUTATOR_HOOKFUNCTION(ons, SV_ParseClientCommand)
                                        return true;
                                }
 
-                               if ( GetResourceAmount(player, RESOURCE_HEALTH) <= 0 )
+                               if ( GetResource(player, RES_HEALTH) <= 0 )
                                {
                                        player.ons_spawn_by = closest_target;
                                        player.respawn_flags = player.respawn_flags | RESPAWN_FORCE;
@@ -2058,14 +2044,14 @@ MUTATOR_HOOKFUNCTION(ons, SendWaypoint)
                {
                        entity wp_owner = wp.owner;
                        entity e = WaypointSprite_getviewentity(to);
-                       if(SAME_TEAM(e, wp_owner) && GetResourceAmount(wp_owner.goalentity, RESOURCE_HEALTH) >= wp_owner.goalentity.max_health) { wp_flag |= 2; }
+                       if(SAME_TEAM(e, wp_owner) && GetResource(wp_owner.goalentity, RES_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 && GetResourceAmount(wp_owner, RESOURCE_HEALTH) >= wp_owner.max_health) { wp_flag |= 2; }
-                       if(GetResourceAmount(wp_owner, RESOURCE_HEALTH) <= 0) { wp_flag |= 2; }
+                       if(wp_owner.isshielded && GetResource(wp_owner, RES_HEALTH) >= wp_owner.max_health) { wp_flag |= 2; }
+                       if(GetResource(wp_owner, RES_HEALTH) <= 0) { wp_flag |= 2; }
                }
        }