]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/turrets/sv_turrets.qc
Implement TakeResource
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / turrets / sv_turrets.qc
index 4d598db543a1ba0f006702b26f1f31119590eb80..a02ce07aca2454367cacbc86cea4242fb6bf05b5 100644 (file)
@@ -184,7 +184,7 @@ void turret_die(entity this)
        this.event_damage                 = func_null;
        this.takedamage                  = DAMAGE_NO;
 
-       this.health                      = 0;
+       SetResourceAmountExplicit(this, RESOURCE_HEALTH, 0);
 
 // Go boom
        //RadiusDamage (this,this, min(this.ammo,50),min(this.ammo,50) * 0.25,250,NULL,min(this.ammo,50)*5,DEATH_TURRET,NULL);
@@ -212,7 +212,7 @@ void turret_die(entity this)
        }
 }
 
-void turret_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector vforce)
+void turret_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector vforce)
 {
        // Enough already!
        if(this.deadflag == DEAD_DEAD)
@@ -230,7 +230,7 @@ void turret_damage(entity this, entity inflictor, entity attacker, float damage,
                        return;
        }
 
-       this.health -= damage;
+       TakeResource(this, RESOURCE_HEALTH, damage);
 
        // thorw head slightly off aim when hit?
        if (this.damage_flags & TFL_DMG_HEADSHAKE)
@@ -244,7 +244,7 @@ void turret_damage(entity this, entity inflictor, entity attacker, float damage,
        if (this.turret_flags & TUR_FLAG_MOVE)
                this.velocity = this.velocity + vforce;
 
-       if (this.health <= 0)
+       if (GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
        {
                this.event_damage                 = func_null;
                this.tur_head.event_damage = func_null;
@@ -271,7 +271,7 @@ void turret_respawn(entity this)
        this.avelocity                          = '0 0 0';
        this.tur_head.avelocity         = this.avelocity;
        this.tur_head.angles            = this.idle_aim;
-       this.health                                     = this.max_health;
+       SetResourceAmountExplicit(this, RESOURCE_HEALTH, this.max_health);
        this.enemy                                      = NULL;
        this.volly_counter                      = this.shot_volly;
        this.ammo                                       = this.ammo_max;
@@ -313,9 +313,7 @@ bool turret_send(entity this, entity to, float sf)
        {
                WriteByte(MSG_ENTITY, this.m_id);
 
-               WriteCoord(MSG_ENTITY, this.origin_x);
-               WriteCoord(MSG_ENTITY, this.origin_y);
-               WriteCoord(MSG_ENTITY, this.origin_z);
+               WriteVector(MSG_ENTITY, this.origin);
 
                WriteAngle(MSG_ENTITY, this.angles_x);
                WriteAngle(MSG_ENTITY, this.angles_y);
@@ -335,13 +333,9 @@ bool turret_send(entity this, entity to, float sf)
 
        if(sf & TNSF_MOVE)
        {
-               WriteShort(MSG_ENTITY, rint(this.origin_x));
-               WriteShort(MSG_ENTITY, rint(this.origin_y));
-               WriteShort(MSG_ENTITY, rint(this.origin_z));
+               WriteVector(MSG_ENTITY, this.origin);
 
-               WriteShort(MSG_ENTITY, rint(this.velocity_x));
-               WriteShort(MSG_ENTITY, rint(this.velocity_y));
-               WriteShort(MSG_ENTITY, rint(this.velocity_z));
+               WriteVector(MSG_ENTITY, this.velocity);
 
                WriteShort(MSG_ENTITY, rint(this.angles_y));
        }
@@ -356,10 +350,10 @@ bool turret_send(entity this, entity to, float sf)
        {
                WriteByte(MSG_ENTITY, this.team);
 
-               if(this.health <= 0)
+               if(GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
                        WriteByte(MSG_ENTITY, 0);
                else
-                       WriteByte(MSG_ENTITY, ceil((this.health / this.max_health) * 255));
+                       WriteByte(MSG_ENTITY, ceil((GetResourceAmount(this, RESOURCE_HEALTH) / this.max_health) * 255));
        }
 
        return true;
@@ -390,7 +384,7 @@ void load_unit_settings(entity ent, bool is_reload)
                ent.tur_head.angles = '0 0 0';
        }
 
-       ent.health       = cvar(strcat(sbase,"_health")) * ent.turret_scale_health;
+       SetResourceAmountExplicit(ent, RESOURCE_HEALTH, cvar(strcat(sbase,"_health")) * ent.turret_scale_health);
        ent.respawntime = cvar(strcat(sbase,"_respawntime")) * ent.turret_scale_respawn;
 
        ent.shot_dmg             = cvar(strcat(sbase,"_shot_dmg")) * ent.turret_scale_damage;
@@ -439,11 +433,11 @@ void turret_projectile_explode(entity this)
        this.event_damage = func_null;
 #ifdef TURRET_DEBUG
        float d;
-       d = RadiusDamage (this, this.owner, this.owner.shot_dmg, 0, this.owner.shot_radius, this, NULL, this.owner.shot_force, this.totalfrags, NULL);
+       d = RadiusDamage (this, this.owner, this.owner.shot_dmg, 0, this.owner.shot_radius, this, NULL, this.owner.shot_force, this.totalfrags, DMG_NOWEP, NULL);
        this.owner.tur_debug_dmg_t_h = this.owner.tur_debug_dmg_t_h + d;
        this.owner.tur_debug_dmg_t_f = this.owner.tur_debug_dmg_t_f + this.owner.shot_dmg;
 #else
-       RadiusDamage (this, this.realowner, this.owner.shot_dmg, 0, this.owner.shot_radius, this, NULL, this.owner.shot_force, this.totalfrags, NULL);
+       RadiusDamage (this, this.realowner, this.owner.shot_dmg, 0, this.owner.shot_radius, this, NULL, this.owner.shot_force, this.totalfrags, DMG_NOWEP, NULL);
 #endif
        delete(this);
 }
@@ -454,12 +448,12 @@ void turret_projectile_touch(entity this, entity toucher)
        turret_projectile_explode(this);
 }
 
-void turret_projectile_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector vforce)
+void turret_projectile_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector vforce)
 {
        this.velocity  += vforce;
-       this.health     -= damage;
+       TakeResource(this, RESOURCE_HEALTH, damage);
        //this.realowner = attacker; // Dont change realowner, it does not make much sense for turrets
-       if(this.health <= 0)
+       if(GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
                W_PrepareExplosionByDamage(this, this.owner, turret_projectile_explode);
 }
 
@@ -489,7 +483,7 @@ entity turret_projectile(entity actor, Sound _snd, float _size, float _health, f
        PROJECTILE_MAKETRIGGER(proj);
        if(_health)
        {
-               proj.health              = _health;
+               SetResourceAmountExplicit(proj, RESOURCE_HEALTH, _health);
                proj.takedamage  = DAMAGE_YES;
                proj.event_damage  = turret_projectile_damage;
        }
@@ -726,7 +720,7 @@ float turret_validate_target(entity e_turret, entity e_target, float validate_fl
                if (e_target.vehicle_health <= 0)
                        return -6;
        }
-       else if (e_target.health <= 0)
+       else if (GetResourceAmount(e_target, RESOURCE_HEALTH) <= 0)
                return -6;
        else if(STAT(FROZEN, e_target) > 0)
                return -6;
@@ -789,7 +783,7 @@ float turret_validate_target(entity e_turret, entity e_target, float validate_fl
        }
 
        // Can we even aim this thing?
-       tvt_thadv = angleofs3(e_turret.tur_head.origin, e_turret.angles + e_turret.tur_head.angles, e_target);
+       tvt_thadv = angleofs3(e_turret.tur_head.origin, e_turret.angles + e_turret.tur_head.angles, e_target.origin);
        tvt_tadv = shortangle_vxy(angleofs(e_turret, e_target), e_turret.angles);
        tvt_thadf = vlen(tvt_thadv);
        tvt_tadf = vlen(tvt_tadv);
@@ -1245,6 +1239,36 @@ void turret_initparams(entity tur)
        #undef TRY
 }
 
+bool turret_closetotarget(entity this, vector targ)
+{
+       vector path_extra_size = '64 64 64';
+       return boxesoverlap(targ - path_extra_size, targ + path_extra_size, this.absmin - path_extra_size, this.absmax + path_extra_size);
+}
+
+void turret_findtarget(entity this)
+{
+       entity e = find(NULL, classname, "turret_manager");
+       if(!e)
+       {
+               e = new(turret_manager);
+               setthink(e, turrets_manager_think);
+               e.nextthink = time + 2;
+       }
+
+       entity targ = find(NULL, targetname, this.target);
+       if(targ.classname == "turret_checkpoint")
+               return; // turrets don't defend checkpoints?
+
+       if (!targ)
+       {
+               this.target = "";
+               LOG_TRACE("Turret has invalid defendpoint!");
+       }
+
+       this.tur_defend = targ;
+       this.idle_aim = this.tur_head.angles + angleofs(this.tur_head, targ);
+}
+
 bool turret_initialize(entity this, Turret tur)
 {
        if(!autocvar_g_turrets)
@@ -1260,14 +1284,6 @@ bool turret_initialize(entity this, Turret tur)
                IL_PUSH(g_bot_targets, this);
        }
 
-       entity e = find(NULL, classname, "turret_manager");
-       if(!e)
-       {
-               e = new(turret_manager);
-               setthink(e, turrets_manager_think);
-               e.nextthink = time + 2;
-       }
-
        if(!(this.spawnflags & TSF_SUSPENDED))
                droptofloor(this);
 
@@ -1276,7 +1292,7 @@ bool turret_initialize(entity this, Turret tur)
 
        if(!this.team || !teamplay)             { this.team = FLOAT_MAX; }
        if(!this.ticrate)                               { this.ticrate = ((this.turret_flags & TUR_FLAG_SUPPORT) ? 0.2 : 0.1); }
-       if(!this.health)                                { this.health = 1000; }
+       if(!GetResourceAmount(this, RESOURCE_HEALTH)) { SetResourceAmountExplicit(this, RESOURCE_HEALTH, 1000); }
        if(!this.shot_refire)                   { this.shot_refire = 1; }
        if(!this.tur_shotorg)                   { this.tur_shotorg = '50 0 50'; }
        if(!this.turret_flags)                  { this.turret_flags = TUR_FLAG_SPLASH | TUR_FLAG_MEDPROJ | TUR_FLAG_PLAYER; }
@@ -1333,7 +1349,7 @@ bool turret_initialize(entity this, Turret tur)
        this.effects                            = EF_NODRAW;
        this.netname                            = tur.turret_name;
        this.ticrate                            = bound(sys_frametime, this.ticrate, 60);
-       this.max_health                         = this.health;
+       this.max_health                         = GetResourceAmount(this, RESOURCE_HEALTH);
        this.target_validate_flags      = this.target_select_flags;
        this.ammo                                       = this.ammo_max;
        this.ammo_recharge                 *= this.ticrate;
@@ -1341,6 +1357,7 @@ bool turret_initialize(entity this, Turret tur)
        this.takedamage                         = DAMAGE_AIM;
        set_movetype(this, MOVETYPE_NOCLIP);
        this.view_ofs                           = '0 0 0';
+       this.idle_aim                           = '0 0 0';
        this.turret_firecheckfunc       = turret_firecheck;
        this.event_damage                       = turret_damage;
        this.use                                        = turret_use;
@@ -1363,21 +1380,8 @@ bool turret_initialize(entity this, Turret tur)
 
        this.weaponentities[0] = this; // lol
 
-       if(!this.tur_defend)
-       if(this.target != "")
-       {
-               this.tur_defend = find(NULL, targetname, this.target);
-               if (this.tur_defend == NULL)
-               {
-                       this.target = "";
-                       LOG_TRACE("Turret has invalid defendpoint!");
-               }
-       }
-
-       if (this.tur_defend)
-               this.idle_aim = this.tur_head.angles + angleofs(this.tur_head, this.tur_defend);
-       else
-               this.idle_aim = '0 0 0';
+       if(!this.tur_defend && this.target != "")
+               InitializeEntity(this, turret_findtarget, INITPRIO_FINDTARGET);
 
 #ifdef TURRET_DEBUG
        this.tur_debug_start = this.nextthink;