X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fcommon%2Fweapons%2Fweapon%2Fseeker.qc;h=5af840505dba1f432e1565dad6a5f02cc97d6a2e;hb=fd20a1f1eae2b2ba955ce9ddedc20cd151a6f362;hp=1686ff5290fec13b21f13b7c773a598ca75a15d5;hpb=1af8ea71282d19f66c96622815c68943eaa36aba;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/common/weapons/weapon/seeker.qc b/qcsrc/common/weapons/weapon/seeker.qc index 1686ff529..5af840505 100644 --- a/qcsrc/common/weapons/weapon/seeker.qc +++ b/qcsrc/common/weapons/weapon/seeker.qc @@ -1,111 +1,116 @@ #ifndef IMPLEMENTATION -REGISTER_WEAPON( -/* WEP_##id */ SEEKER, -/* function */ W_Seeker, -/* ammotype */ ammo_rockets, -/* impulse */ 8, -/* flags */ WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH, -/* rating */ BOT_PICKUP_RATING_MID, -/* color */ '0.5 1 0', -/* modelname */ "seeker", -/* simplemdl */ "foobar", -/* crosshair */ "gfx/crosshairseeker 0.8", -/* wepimg */ "weaponseeker", -/* refname */ "seeker", -/* wepname */ _("T.A.G. Seeker") -); - -#define SEEKER_SETTINGS(w_cvar,w_prop) SEEKER_SETTINGS_LIST(w_cvar, w_prop, SEEKER, seeker) -#define SEEKER_SETTINGS_LIST(w_cvar,w_prop,id,sn) \ - w_cvar(id, sn, NONE, type) \ - w_cvar(id, sn, NONE, flac_ammo) \ - w_cvar(id, sn, NONE, flac_animtime) \ - w_cvar(id, sn, NONE, flac_damage) \ - w_cvar(id, sn, NONE, flac_edgedamage) \ - w_cvar(id, sn, NONE, flac_force) \ - w_cvar(id, sn, NONE, flac_lifetime) \ - w_cvar(id, sn, NONE, flac_lifetime_rand) \ - w_cvar(id, sn, NONE, flac_radius) \ - w_cvar(id, sn, NONE, flac_refire) \ - w_cvar(id, sn, NONE, flac_speed) \ - w_cvar(id, sn, NONE, flac_speed_up) \ - w_cvar(id, sn, NONE, flac_speed_z) \ - w_cvar(id, sn, NONE, flac_spread) \ - w_cvar(id, sn, NONE, missile_accel) \ - w_cvar(id, sn, NONE, missile_ammo) \ - w_cvar(id, sn, NONE, missile_animtime) \ - w_cvar(id, sn, NONE, missile_count) \ - w_cvar(id, sn, NONE, missile_damage) \ - w_cvar(id, sn, NONE, missile_damageforcescale) \ - w_cvar(id, sn, NONE, missile_decel) \ - w_cvar(id, sn, NONE, missile_delay) \ - w_cvar(id, sn, NONE, missile_edgedamage) \ - w_cvar(id, sn, NONE, missile_force) \ - w_cvar(id, sn, NONE, missile_health) \ - w_cvar(id, sn, NONE, missile_lifetime) \ - w_cvar(id, sn, NONE, missile_proxy) \ - w_cvar(id, sn, NONE, missile_proxy_delay) \ - w_cvar(id, sn, NONE, missile_proxy_maxrange) \ - w_cvar(id, sn, NONE, missile_radius) \ - w_cvar(id, sn, NONE, missile_refire) \ - w_cvar(id, sn, NONE, missile_smart) \ - w_cvar(id, sn, NONE, missile_smart_mindist) \ - w_cvar(id, sn, NONE, missile_smart_trace_max) \ - w_cvar(id, sn, NONE, missile_smart_trace_min) \ - w_cvar(id, sn, NONE, missile_speed) \ - w_cvar(id, sn, NONE, missile_speed_max) \ - w_cvar(id, sn, NONE, missile_speed_up) \ - w_cvar(id, sn, NONE, missile_speed_z) \ - w_cvar(id, sn, NONE, missile_spread) \ - w_cvar(id, sn, NONE, missile_turnrate) \ - w_cvar(id, sn, NONE, tag_ammo) \ - w_cvar(id, sn, NONE, tag_animtime) \ - w_cvar(id, sn, NONE, tag_damageforcescale) \ - w_cvar(id, sn, NONE, tag_health) \ - w_cvar(id, sn, NONE, tag_lifetime) \ - w_cvar(id, sn, NONE, tag_refire) \ - w_cvar(id, sn, NONE, tag_speed) \ - w_cvar(id, sn, NONE, tag_spread) \ - w_cvar(id, sn, NONE, tag_tracker_lifetime) \ - w_prop(id, sn, float, reloading_ammo, reload_ammo) \ - w_prop(id, sn, float, reloading_time, reload_time) \ - w_prop(id, sn, float, switchdelay_raise, switchdelay_raise) \ - w_prop(id, sn, float, switchdelay_drop, switchdelay_drop) \ - w_prop(id, sn, string, weaponreplace, weaponreplace) \ - w_prop(id, sn, float, weaponstart, weaponstart) \ - w_prop(id, sn, float, weaponstartoverride, weaponstartoverride) \ - w_prop(id, sn, float, weaponthrowable, weaponthrowable) +CLASS(Seeker, Weapon) +/* ammotype */ ATTRIB(Seeker, ammo_field, .int, ammo_rockets) +/* impulse */ ATTRIB(Seeker, impulse, int, 8) +/* flags */ ATTRIB(Seeker, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH); +/* rating */ ATTRIB(Seeker, bot_pickupbasevalue, float, BOT_PICKUP_RATING_HIGH); +/* color */ ATTRIB(Seeker, wpcolor, vector, '0.5 1 0'); +/* modelname */ ATTRIB(Seeker, mdl, string, "seeker"); +#ifndef MENUQC +/* model */ ATTRIB(Seeker, m_model, Model, MDL_SEEKER_ITEM); +#endif +/* crosshair */ ATTRIB(Seeker, w_crosshair, string, "gfx/crosshairseeker"); +/* crosshair */ ATTRIB(Seeker, w_crosshair_size, float, 0.8); +/* wepimg */ ATTRIB(Seeker, model2, string, "weaponseeker"); +/* refname */ ATTRIB(Seeker, netname, string, "seeker"); +/* wepname */ ATTRIB(Seeker, m_name, string, _("T.A.G. Seeker")); + +#define X(BEGIN, P, END, class, prefix) \ + BEGIN(class) \ + P(class, prefix, flac_ammo, float, NONE) \ + P(class, prefix, flac_animtime, float, NONE) \ + P(class, prefix, flac_damage, float, NONE) \ + P(class, prefix, flac_edgedamage, float, NONE) \ + P(class, prefix, flac_force, float, NONE) \ + P(class, prefix, flac_lifetime, float, NONE) \ + P(class, prefix, flac_lifetime_rand, float, NONE) \ + P(class, prefix, flac_radius, float, NONE) \ + P(class, prefix, flac_refire, float, NONE) \ + P(class, prefix, flac_speed, float, NONE) \ + P(class, prefix, flac_speed_up, float, NONE) \ + P(class, prefix, flac_speed_z, float, NONE) \ + P(class, prefix, flac_spread, float, NONE) \ + P(class, prefix, missile_accel, float, NONE) \ + P(class, prefix, missile_ammo, float, NONE) \ + P(class, prefix, missile_animtime, float, NONE) \ + P(class, prefix, missile_count, float, NONE) \ + P(class, prefix, missile_damageforcescale, float, NONE) \ + P(class, prefix, missile_damage, float, NONE) \ + P(class, prefix, missile_decel, float, NONE) \ + P(class, prefix, missile_delay, float, NONE) \ + P(class, prefix, missile_edgedamage, float, NONE) \ + P(class, prefix, missile_force, float, NONE) \ + P(class, prefix, missile_health, float, NONE) \ + P(class, prefix, missile_lifetime, float, NONE) \ + P(class, prefix, missile_proxy, float, NONE) \ + P(class, prefix, missile_proxy_delay, float, NONE) \ + P(class, prefix, missile_proxy_maxrange, float, NONE) \ + P(class, prefix, missile_radius, float, NONE) \ + P(class, prefix, missile_refire, float, NONE) \ + P(class, prefix, missile_smart, float, NONE) \ + P(class, prefix, missile_smart_mindist, float, NONE) \ + P(class, prefix, missile_smart_trace_max, float, NONE) \ + P(class, prefix, missile_smart_trace_min, float, NONE) \ + P(class, prefix, missile_speed, float, NONE) \ + P(class, prefix, missile_speed_max, float, NONE) \ + P(class, prefix, missile_speed_up, float, NONE) \ + P(class, prefix, missile_speed_z, float, NONE) \ + P(class, prefix, missile_spread, float, NONE) \ + P(class, prefix, missile_turnrate, float, NONE) \ + P(class, prefix, reload_ammo, float, NONE) \ + P(class, prefix, reload_time, float, NONE) \ + P(class, prefix, switchdelay_drop, float, NONE) \ + P(class, prefix, switchdelay_raise, float, NONE) \ + P(class, prefix, tag_ammo, float, NONE) \ + P(class, prefix, tag_animtime, float, NONE) \ + P(class, prefix, tag_damageforcescale, float, NONE) \ + P(class, prefix, tag_health, float, NONE) \ + P(class, prefix, tag_lifetime, float, NONE) \ + P(class, prefix, tag_refire, float, NONE) \ + P(class, prefix, tag_speed, float, NONE) \ + P(class, prefix, tag_spread, float, NONE) \ + P(class, prefix, tag_tracker_lifetime, float, NONE) \ + P(class, prefix, type, float, NONE) \ + P(class, prefix, weaponreplace, string, NONE) \ + P(class, prefix, weaponstartoverride, float, NONE) \ + P(class, prefix, weaponstart, float, NONE) \ + P(class, prefix, weaponthrowable, float, NONE) \ + END() + W_PROPS(X, Seeker, seeker) +#undef X +ENDCLASS(Seeker) +REGISTER_WEAPON(SEEKER, seeker, NEW(Seeker)); + #ifdef SVQC -SEEKER_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP) .entity tag_target, wps_tag_tracker; .float tag_time; #endif #endif #ifdef IMPLEMENTATION #ifdef SVQC -spawnfunc(weapon_seeker) { weapon_defaultspawnfunc(WEP_SEEKER.m_id); } +spawnfunc(weapon_seeker) { weapon_defaultspawnfunc(this, WEP_SEEKER); } // ============================ // Begin: Missile functions, these are general functions to be manipulated by other code // ============================ -void W_Seeker_Missile_Explode(void) -{SELFPARAM(); +void W_Seeker_Missile_Explode(entity this) +{ self.event_damage = func_null; RadiusDamage(self, self.realowner, WEP_CVAR(seeker, missile_damage), WEP_CVAR(seeker, missile_edgedamage), WEP_CVAR(seeker, missile_radius), world, world, WEP_CVAR(seeker, missile_force), self.projectiledeathtype, other); remove(self); } -void W_Seeker_Missile_Touch(void) +void W_Seeker_Missile_Touch(entity this) { PROJECTILE_TOUCH; - W_Seeker_Missile_Explode(); + W_Seeker_Missile_Explode(this); } -void W_Seeker_Missile_Think(void) -{SELFPARAM(); +void W_Seeker_Missile_Think(entity this) +{ entity e; vector desireddir, olddir, newdir, eorg; float turnrate; @@ -115,7 +120,7 @@ void W_Seeker_Missile_Think(void) if(time > self.cnt) { self.projectiledeathtype |= HITTYPE_SPLASH; - W_Seeker_Missile_Explode(); + W_Seeker_Missile_Explode(self); } spd = vlen(self.velocity); @@ -126,7 +131,7 @@ void W_Seeker_Missile_Think(void) ); if(self.enemy != world) - if(self.enemy.takedamage != DAMAGE_AIM || self.enemy.deadflag != DEAD_NO) + if(self.enemy.takedamage != DAMAGE_AIM || IS_DEAD(self.enemy)) self.enemy = world; if(self.enemy != world) @@ -142,7 +147,7 @@ void W_Seeker_Missile_Think(void) if(WEP_CVAR(seeker, missile_smart) && (dist > WEP_CVAR(seeker, missile_smart_mindist))) { // Is it a better idea (shorter distance) to trace to the target itself? - if( vlen(self.origin + olddir * self.wait) < dist) + if( vdist(self.origin + olddir * self.wait, <, dist)) traceline(self.origin, self.origin + olddir * self.wait, false, self); else traceline(self.origin, eorg, false, self); @@ -173,7 +178,7 @@ void W_Seeker_Missile_Think(void) { if(self.autoswitch <= time) { - W_Seeker_Missile_Explode(); + W_Seeker_Missile_Explode(self); self.autoswitch = 0; } } @@ -186,7 +191,7 @@ void W_Seeker_Missile_Think(void) } /////////////// - if(self.enemy.deadflag != DEAD_NO) + if(IS_DEAD(self.enemy)) { self.enemy = world; self.cnt = time + 1 + (random() * 4); @@ -201,31 +206,31 @@ void W_Seeker_Missile_Think(void) -void W_Seeker_Missile_Damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force) -{SELFPARAM(); - if(self.health <= 0) +void W_Seeker_Missile_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force) +{ + if(this.health <= 0) return; - if(!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, -1)) // no exceptions + if(!W_CheckProjectileDamage(inflictor.realowner, this.realowner, deathtype, -1)) // no exceptions return; // g_projectiles_damage says to halt - if(self.realowner == attacker) - self.health = self.health - (damage * 0.25); + if(this.realowner == attacker) + this.health = this.health - (damage * 0.25); else - self.health = self.health - damage; + this.health = this.health - damage; - if(self.health <= 0) - W_PrepareExplosionByDamage(attacker, W_Seeker_Missile_Explode); + if(this.health <= 0) + W_PrepareExplosionByDamage(this, attacker, W_Seeker_Missile_Explode); } /* -void W_Seeker_Missile_Animate(void) +void W_Seeker_Missile_Animate() { self.frame = self.frame +1; self.nextthink = time + 0.05; if(self.enemy != world) - if(self.enemy.takedamage != DAMAGE_AIM || self.enemy.deadflag != DEAD_NO) + if(self.enemy.takedamage != DAMAGE_AIM || IS_DEAD(self.enemy)) self.enemy = world; if(self.frame == 5) @@ -243,27 +248,26 @@ void W_Seeker_Missile_Animate(void) } */ -void W_Seeker_Fire_Missile(vector f_diff, entity m_target) -{SELFPARAM(); +void W_Seeker_Fire_Missile(Weapon thiswep, entity actor, vector f_diff, entity m_target) +{entity this = actor; entity missile; - W_DecreaseAmmo(WEP_CVAR(seeker, missile_ammo)); + W_DecreaseAmmo(thiswep, self, WEP_CVAR(seeker, missile_ammo)); makevectors(self.v_angle); - W_SetupShot_ProjectileSize(self, '-2 -2 -2', '2 2 2', false, 2, SND(SEEKER_FIRE), CH_WEAPON_A, 0); + W_SetupShot_ProjectileSize(self, '-2 -2 -2', '2 2 2', false, 2, SND_SEEKER_FIRE, CH_WEAPON_A, 0); w_shotorg += f_diff; Send_Effect(EFFECT_SEEKER_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1); //self.detornator = false; - missile = spawn(); + missile = new(seeker_missile); missile.owner = missile.realowner = self; - missile.classname = "seeker_missile"; missile.bot_dodge = true; missile.bot_dodgerating = WEP_CVAR(seeker, missile_damage); - missile.think = W_Seeker_Missile_Think; - missile.touch = W_Seeker_Missile_Touch; + setthink(missile, W_Seeker_Missile_Think); + settouch(missile, W_Seeker_Missile_Touch); missile.event_damage = W_Seeker_Missile_Damage; missile.nextthink = time;// + 0.2;// + cvar("g_balance_seeker_missile_activate_delay"); missile.cnt = time + WEP_CVAR(seeker, missile_lifetime); @@ -300,8 +304,8 @@ void W_Seeker_Fire_Missile(vector f_diff, entity m_target) // ============================ // Begin: FLAC, close range attack meant for defeating rockets which are coming at you. // ============================ -void W_Seeker_Flac_Explode(void) -{SELFPARAM(); +void W_Seeker_Flac_Explode(entity this) +{ self.event_damage = func_null; RadiusDamage(self, self.realowner, WEP_CVAR(seeker, flac_damage), WEP_CVAR(seeker, flac_edgedamage), WEP_CVAR(seeker, flac_radius), world, world, WEP_CVAR(seeker, flac_force), self.projectiledeathtype, other); @@ -309,20 +313,18 @@ void W_Seeker_Flac_Explode(void) remove(self); } -void W_Seeker_Flac_Touch(void) +void W_Seeker_Flac_Explode_use(entity this, entity actor, entity trigger) { - PROJECTILE_TOUCH; - - W_Seeker_Flac_Explode(); + WITHSELF(this, W_Seeker_Flac_Explode(this)); } -void W_Seeker_Fire_Flac(void) -{SELFPARAM(); +void W_Seeker_Fire_Flac(Weapon thiswep, entity actor) +{entity this = actor; entity missile; vector f_diff; float c; - W_DecreaseAmmo(WEP_CVAR(seeker, flac_ammo)); + W_DecreaseAmmo(thiswep, self, WEP_CVAR(seeker, flac_ammo)); c = self.bulletcounter % 4; switch(c) @@ -341,19 +343,18 @@ void W_Seeker_Fire_Flac(void) f_diff = '+1.25 +3.75 0'; break; } - W_SetupShot_ProjectileSize(self, '-2 -2 -2', '2 2 2', false, 2, SND(FLAC_FIRE), CH_WEAPON_A, WEP_CVAR(seeker, flac_damage)); + W_SetupShot_ProjectileSize(self, '-2 -2 -2', '2 2 2', false, 2, SND_FLAC_FIRE, CH_WEAPON_A, WEP_CVAR(seeker, flac_damage)); w_shotorg += f_diff; Send_Effect(EFFECT_HAGAR_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1); - missile = spawn(); + missile = new(missile); missile.owner = missile.realowner = self; - missile.classname = "missile"; missile.bot_dodge = true; missile.bot_dodgerating = WEP_CVAR(seeker, flac_damage); - missile.touch = W_Seeker_Flac_Explode; - missile.use = W_Seeker_Flac_Explode; - missile.think = adaptor_think2use_hittype_splash; + settouch(missile, W_Seeker_Flac_Explode); + missile.use = W_Seeker_Flac_Explode_use; + setthink(missile, adaptor_think2use_hittype_splash); missile.nextthink = time + WEP_CVAR(seeker, flac_lifetime) + WEP_CVAR(seeker, flac_lifetime_rand); missile.solid = SOLID_BBOX; missile.movetype = MOVETYPE_FLY; @@ -388,8 +389,8 @@ entity W_Seeker_Tagged_Info(entity isowner, entity istarget) return world; } -void W_Seeker_Attack(void) -{SELFPARAM(); +void W_Seeker_Attack(entity actor) +{entity this = actor; entity tracker, closest_target; closest_target = world; @@ -397,7 +398,7 @@ void W_Seeker_Attack(void) { if(closest_target) { - if(vlen(self.origin - tracker.tag_target.origin) < vlen(self.origin - closest_target.origin)) + if(vlen2(self.origin - tracker.tag_target.origin) < vlen2(self.origin - closest_target.origin)) closest_target = tracker.tag_target; } else @@ -408,54 +409,54 @@ void W_Seeker_Attack(void) if((!closest_target) || ((trace_fraction < 1) && (trace_ent != closest_target))) closest_target = world; - W_Seeker_Fire_Missile('0 0 0', closest_target); + W_Seeker_Fire_Missile(WEP_SEEKER, actor, '0 0 0', closest_target); } -void W_Seeker_Vollycontroller_Think(void) // TODO: Merge this with W_Seeker_Attack -{SELFPARAM(); +void W_Seeker_Vollycontroller_Think(entity this) // TODO: Merge this with W_Seeker_Attack +{ float c; entity oldenemy; - self.cnt = self.cnt - 1; + this.cnt = this.cnt - 1; - if((!(self.realowner.items & IT_UNLIMITED_AMMO) && self.realowner.WEP_AMMO(SEEKER) < WEP_CVAR(seeker, missile_ammo)) || (self.cnt <= -1) || (self.realowner.deadflag != DEAD_NO) || (self.realowner.switchweapon != WEP_SEEKER.m_id)) + Weapon thiswep = WEP_SEEKER; + if((!(this.realowner.items & IT_UNLIMITED_AMMO) && this.realowner.(thiswep.ammo_field) < WEP_CVAR(seeker, missile_ammo)) || (this.cnt <= -1) || (IS_DEAD(this.realowner)) || (PS(this.realowner).m_switchweapon != WEP_SEEKER)) { - remove(self); + remove(this); return; } - self.nextthink = time + WEP_CVAR(seeker, missile_delay) * W_WeaponRateFactor(); + this.nextthink = time + WEP_CVAR(seeker, missile_delay) * W_WeaponRateFactor(); - setself(self.realowner); + entity own = this.realowner; - oldenemy = self.enemy; - self.enemy = this.enemy; + oldenemy = own.enemy; + own.enemy = this.enemy; - c = self.cnt % 4; + c = own.cnt % 4; switch(c) { case 0: - W_Seeker_Fire_Missile('-1.25 -3.75 0', self.enemy); + WITHSELF(own, W_Seeker_Fire_Missile(WEP_SEEKER, own, '-1.25 -3.75 0', own.enemy)); break; case 1: - W_Seeker_Fire_Missile('+1.25 -3.75 0', self.enemy); + WITHSELF(own, W_Seeker_Fire_Missile(WEP_SEEKER, own, '+1.25 -3.75 0', own.enemy)); break; case 2: - W_Seeker_Fire_Missile('-1.25 +3.75 0', self.enemy); + WITHSELF(own, W_Seeker_Fire_Missile(WEP_SEEKER, own, '-1.25 +3.75 0', own.enemy)); break; case 3: default: - W_Seeker_Fire_Missile('+1.25 +3.75 0', self.enemy); + WITHSELF(own, W_Seeker_Fire_Missile(WEP_SEEKER, own, '+1.25 +3.75 0', own.enemy)); break; } - self.enemy = oldenemy; - setself(this); + own.enemy = oldenemy; } -void W_Seeker_Tracker_Think(void) -{SELFPARAM(); +void W_Seeker_Tracker_Think(entity this) +{ // commit suicide if: You die OR target dies OR you switch away from the seeker OR commit suicide if lifetime is up - if((self.realowner.deadflag != DEAD_NO) || (self.tag_target.deadflag != DEAD_NO) || (self.realowner.switchweapon != WEP_SEEKER.m_id) + if((IS_DEAD(self.realowner)) || (IS_DEAD(self.tag_target)) || (PS(self.realowner).m_switchweapon != WEP_SEEKER) || (time > self.tag_time + WEP_CVAR(seeker, tag_tracker_lifetime))) { if(self) @@ -473,26 +474,26 @@ void W_Seeker_Tracker_Think(void) // ============================ // Begin: Tag projectile // ============================ -void W_Seeker_Tag_Explode(void) -{SELFPARAM(); - //if(other==self.realowner) +void W_Seeker_Tag_Explode(entity this) +{ + //if(other==this.realowner) // return; - Damage_DamageInfo(self.origin, 0, 0, 0, self.velocity, WEP_SEEKER.m_id | HITTYPE_BOUNCE, other.species, self); + Damage_DamageInfo(this.origin, 0, 0, 0, this.velocity, WEP_SEEKER.m_id | HITTYPE_BOUNCE, other.species, this); - remove(self); + remove(this); } -void W_Seeker_Tag_Damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force) -{SELFPARAM(); - if(self.health <= 0) +void W_Seeker_Tag_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force) +{ + if(this.health <= 0) return; - self.health = self.health - damage; - if(self.health <= 0) - W_Seeker_Tag_Explode(); + this.health = this.health - damage; + if(this.health <= 0) + W_Seeker_Tag_Explode(this); } -void W_Seeker_Tag_Touch(void) -{SELFPARAM(); +void W_Seeker_Tag_Touch(entity this) +{ vector dir; vector org2; entity e; @@ -507,7 +508,7 @@ void W_Seeker_Tag_Touch(void) self.event_damage = func_null; Damage_DamageInfo(self.origin, 0, 0, 0, self.velocity, WEP_SEEKER.m_id | HITTYPE_BOUNCE | HITTYPE_SECONDARY, other.species, self); - if(other.takedamage == DAMAGE_AIM && other.deadflag == DEAD_NO) + if(other.takedamage == DAMAGE_AIM && !IS_DEAD(other)) { // check to see if this person is already tagged by me entity tag = W_Seeker_Tagged_Info(self.realowner, other); @@ -522,9 +523,8 @@ void W_Seeker_Tag_Touch(void) else { //sprint(self.realowner, strcat("You just tagged ^2", other.netname, "^7 with a tracking device!\n")); - e = spawn(); + e = new(tag_tracker); e.cnt = WEP_CVAR(seeker, missile_count); - e.classname = "tag_tracker"; e.owner = self.owner; e.realowner = self.realowner; @@ -532,12 +532,12 @@ void W_Seeker_Tag_Touch(void) { e.tag_target = other; e.tag_time = time; - e.think = W_Seeker_Tracker_Think; + setthink(e, W_Seeker_Tracker_Think); } else { e.enemy = other; - e.think = W_Seeker_Vollycontroller_Think; + setthink(e, W_Seeker_Vollycontroller_Think); } e.nextthink = time; @@ -554,20 +554,19 @@ void W_Seeker_Tag_Touch(void) return; } -void W_Seeker_Fire_Tag(void) -{SELFPARAM(); +void W_Seeker_Fire_Tag(Weapon thiswep, entity actor) +{entity this = actor; entity missile; - W_DecreaseAmmo(WEP_CVAR(seeker, tag_ammo)); + W_DecreaseAmmo(thiswep, self, WEP_CVAR(seeker, tag_ammo)); - W_SetupShot_ProjectileSize(self, '-2 -2 -2', '2 2 2', false, 2, SND(TAG_FIRE), CH_WEAPON_A, WEP_CVAR(seeker, missile_damage) * WEP_CVAR(seeker, missile_count)); + W_SetupShot_ProjectileSize(self, '-2 -2 -2', '2 2 2', false, 2, SND_TAG_FIRE, CH_WEAPON_A, WEP_CVAR(seeker, missile_damage) * WEP_CVAR(seeker, missile_count)); - missile = spawn(); + missile = new(seeker_tag); missile.owner = missile.realowner = self; - missile.classname = "seeker_tag"; missile.bot_dodge = true; missile.bot_dodgerating = 50; - missile.touch = W_Seeker_Tag_Touch; - missile.think = SUB_Remove; + settouch(missile, W_Seeker_Tag_Touch); + setthink(missile, SUB_Remove); missile.nextthink = time + WEP_CVAR(seeker, tag_lifetime); missile.movetype = MOVETYPE_FLY; missile.solid = SOLID_BBOX; @@ -596,184 +595,150 @@ void W_Seeker_Fire_Tag(void) // Begin: Genereal weapon functions // ============================ -bool W_Seeker(int req) -{SELFPARAM(); - float ammo_amount; - - switch(req) - { - case WR_AIM: - { - if(WEP_CVAR(seeker, type) == 1) - if(W_Seeker_Tagged_Info(self, self.enemy) != world) - self.BUTTON_ATCK = bot_aim(WEP_CVAR(seeker, missile_speed_max), 0, WEP_CVAR(seeker, missile_lifetime), false); - else - self.BUTTON_ATCK2 = bot_aim(WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), false); - else - self.BUTTON_ATCK = bot_aim(WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), false); - return true; - } - case WR_THINK: - { - if(autocvar_g_balance_seeker_reload_ammo && self.clip_load < min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo))) // forced reload - WEP_ACTION(self.weapon, WR_RELOAD); - - else if(self.BUTTON_ATCK) - { - if(WEP_CVAR(seeker, type) == 1) - { - if(weapon_prepareattack(0, WEP_CVAR(seeker, missile_refire))) - { - W_Seeker_Attack(); - weapon_thinkf(WFRAME_FIRE2, WEP_CVAR(seeker, missile_animtime), w_ready); - } - } - else - { - if(weapon_prepareattack(0, WEP_CVAR(seeker, tag_refire))) - { - W_Seeker_Fire_Tag(); - weapon_thinkf(WFRAME_FIRE2, WEP_CVAR(seeker, tag_animtime), w_ready); - } - } - } - - else if(self.BUTTON_ATCK2) - { - if(WEP_CVAR(seeker, type) == 1) - { - if(weapon_prepareattack(0, WEP_CVAR(seeker, tag_refire))) - { - W_Seeker_Fire_Tag(); - weapon_thinkf(WFRAME_FIRE2, WEP_CVAR(seeker, tag_animtime), w_ready); - } - } - else - { - if(weapon_prepareattack(0, WEP_CVAR(seeker, flac_refire))) - { - W_Seeker_Fire_Flac(); - weapon_thinkf(WFRAME_FIRE2, WEP_CVAR(seeker, flac_animtime), w_ready); - } - } - } - - return true; - } - case WR_INIT: - { - SEEKER_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP); - return true; - } - case WR_CHECKAMMO1: - { - if(WEP_CVAR(seeker, type) == 1) - { - ammo_amount = self.WEP_AMMO(SEEKER) >= WEP_CVAR(seeker, missile_ammo); - ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, missile_ammo); - } - else - { - ammo_amount = self.WEP_AMMO(SEEKER) >= WEP_CVAR(seeker, tag_ammo); - ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, tag_ammo); - } - return ammo_amount; - } - case WR_CHECKAMMO2: - { - if(WEP_CVAR(seeker, type) == 1) - { - ammo_amount = self.WEP_AMMO(SEEKER) >= WEP_CVAR(seeker, tag_ammo); - ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, tag_ammo); - } - else - { - ammo_amount = self.WEP_AMMO(SEEKER) >= WEP_CVAR(seeker, flac_ammo); - ammo_amount += self.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, flac_ammo); - } - return ammo_amount; - } - case WR_CONFIG: - { - SEEKER_SETTINGS(WEP_CONFIG_WRITE_CVARS, WEP_CONFIG_WRITE_PROPS); - return true; - } - case WR_RELOAD: - { - W_Reload(min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo)), SND(RELOAD)); - return true; - } - case WR_SUICIDEMESSAGE: - { - return WEAPON_SEEKER_SUICIDE; - } - case WR_KILLMESSAGE: - { - if(w_deathtype & HITTYPE_SECONDARY) - return WEAPON_SEEKER_MURDER_TAG; - else - return WEAPON_SEEKER_MURDER_SPRAY; - } - } - return false; +METHOD(Seeker, wr_aim, void(entity thiswep, entity actor)) +{ + entity this = actor; + if(WEP_CVAR(seeker, type) == 1) + if(W_Seeker_Tagged_Info(self, self.enemy) != world) + PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(self, WEP_CVAR(seeker, missile_speed_max), 0, WEP_CVAR(seeker, missile_lifetime), false); + else + PHYS_INPUT_BUTTON_ATCK2(self) = bot_aim(self, WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), false); + else + PHYS_INPUT_BUTTON_ATCK(self) = bot_aim(self, WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), false); +} +METHOD(Seeker, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire)) +{ + if(autocvar_g_balance_seeker_reload_ammo && actor.clip_load < min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo))) { // forced reload + thiswep.wr_reload(thiswep, actor, weaponentity); + } else if(fire & 1) + { + if(WEP_CVAR(seeker, type) == 1) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(seeker, missile_refire))) + { + W_Seeker_Attack(actor); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(seeker, missile_animtime), w_ready); + } + } + else + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(seeker, tag_refire))) + { + W_Seeker_Fire_Tag(thiswep, actor); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(seeker, tag_animtime), w_ready); + } + } + } + + else if(fire & 2) + { + if(WEP_CVAR(seeker, type) == 1) + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(seeker, tag_refire))) + { + W_Seeker_Fire_Tag(thiswep, actor); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(seeker, tag_animtime), w_ready); + } + } + else + { + if(weapon_prepareattack(thiswep, actor, weaponentity, false, WEP_CVAR(seeker, flac_refire))) + { + W_Seeker_Fire_Flac(thiswep, actor); + weapon_thinkf(actor, weaponentity, WFRAME_FIRE2, WEP_CVAR(seeker, flac_animtime), w_ready); + } + } + } +} +METHOD(Seeker, wr_checkammo1, bool(entity thiswep, entity actor)) +{ + float ammo_amount; + if(WEP_CVAR(seeker, type) == 1) + { + ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR(seeker, missile_ammo); + ammo_amount += actor.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, missile_ammo); + } + else + { + ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR(seeker, tag_ammo); + ammo_amount += actor.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, tag_ammo); + } + return ammo_amount; +} +METHOD(Seeker, wr_checkammo2, bool(entity thiswep, entity actor)) +{ + float ammo_amount; + if(WEP_CVAR(seeker, type) == 1) + { + ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR(seeker, tag_ammo); + ammo_amount += actor.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, tag_ammo); + } + else + { + ammo_amount = actor.(thiswep.ammo_field) >= WEP_CVAR(seeker, flac_ammo); + ammo_amount += actor.(weapon_load[WEP_SEEKER.m_id]) >= WEP_CVAR(seeker, flac_ammo); + } + return ammo_amount; +} +METHOD(Seeker, wr_reload, void(entity thiswep, entity actor, .entity weaponentity)) +{ + W_Reload(actor, min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo)), SND_RELOAD); +} +METHOD(Seeker, wr_suicidemessage, Notification(entity thiswep)) +{ + return WEAPON_SEEKER_SUICIDE; } +METHOD(Seeker, wr_killmessage, Notification(entity thiswep)) +{ + if(w_deathtype & HITTYPE_SECONDARY) + return WEAPON_SEEKER_MURDER_TAG; + else + return WEAPON_SEEKER_MURDER_SPRAY; +} + #endif #ifdef CSQC -bool W_Seeker(int req) -{SELFPARAM(); - switch(req) - { - case WR_IMPACTEFFECT: - { - vector org2; - org2 = w_org + w_backoff * 6; - if(w_deathtype & HITTYPE_BOUNCE) - { - if(w_deathtype & HITTYPE_SECONDARY) - { - if(!w_issilent) - sound(self, CH_SHOTS, SND_TAG_IMPACT, 1, ATTEN_NORM); - } - else - { - pointparticles(particleeffectnum(EFFECT_HAGAR_EXPLODE), org2, '0 0 0', 1); - if(!w_issilent) - { - if(w_random<0.15) - sound(self, CH_SHOTS, SND_TAGEXP1, 1, ATTEN_NORM); - else if(w_random<0.7) - sound(self, CH_SHOTS, SND_TAGEXP2, 1, ATTEN_NORM); - else - sound(self, CH_SHOTS, SND_TAGEXP3, 1, ATTEN_NORM); - } - } - } - else - { - pointparticles(particleeffectnum(EFFECT_HAGAR_EXPLODE), org2, '0 0 0', 1); - if(!w_issilent) - { - if(w_random<0.15) - sound(self, CH_SHOTS, SND_SEEKEREXP1, 1, ATTEN_NORM); - else if(w_random<0.7) - sound(self, CH_SHOTS, SND_SEEKEREXP2, 1, ATTEN_NORM); - else - sound(self, CH_SHOTS, SND_SEEKEREXP3, 1, ATTEN_NORM); - } - } - return true; - } - case WR_INIT: - { - return true; - } - case WR_ZOOMRETICLE: - { - // no weapon specific image for this weapon - return false; - } - } - return false; + +METHOD(Seeker, wr_impacteffect, void(entity thiswep, entity actor)) +{ + entity this = actor; + vector org2; + org2 = w_org + w_backoff * 6; + if(w_deathtype & HITTYPE_BOUNCE) + { + if(w_deathtype & HITTYPE_SECONDARY) + { + if(!w_issilent) + sound(self, CH_SHOTS, SND_TAG_IMPACT, 1, ATTEN_NORM); + } + else + { + pointparticles(EFFECT_HAGAR_EXPLODE, org2, '0 0 0', 1); + if(!w_issilent) + { + if(w_random<0.15) + sound(self, CH_SHOTS, SND_TAGEXP1, 1, ATTEN_NORM); + else if(w_random<0.7) + sound(self, CH_SHOTS, SND_TAGEXP2, 1, ATTEN_NORM); + else + sound(self, CH_SHOTS, SND_TAGEXP3, 1, ATTEN_NORM); + } + } + } + else + { + pointparticles(EFFECT_HAGAR_EXPLODE, org2, '0 0 0', 1); + if(!w_issilent) + { + if(w_random<0.15) + sound(self, CH_SHOTS, SND_SEEKEREXP1, 1, ATTEN_NORM); + else if(w_random<0.7) + sound(self, CH_SHOTS, SND_SEEKEREXP2, 1, ATTEN_NORM); + else + sound(self, CH_SHOTS, SND_SEEKEREXP3, 1, ATTEN_NORM); + } + } } + #endif #endif