From 738d94bcf21dcefe014764a3e7f5de3d52927f87 Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Mon, 13 Jun 2011 15:58:57 +0200 Subject: [PATCH] Mines now stick to moving geometry --- qcsrc/server/g_hook.qc | 37 --------------------------------- qcsrc/server/miscfunctions.qc | 37 +++++++++++++++++++++++++++++++++ qcsrc/server/w_minelayer.qc | 39 +++++++++++++++++++++++++++++------ 3 files changed, 70 insertions(+), 43 deletions(-) diff --git a/qcsrc/server/g_hook.qc b/qcsrc/server/g_hook.qc index dd6d73eff..b7291dee3 100644 --- a/qcsrc/server/g_hook.qc +++ b/qcsrc/server/g_hook.qc @@ -47,43 +47,6 @@ And you should be done! ============================================*/ -.string aiment_classname; -.float aiment_deadflag; -void SetMovetypeFollow(entity ent, entity e) -{ - // FIXME this may not be warpzone aware - ent.movetype = MOVETYPE_FOLLOW; // make the hole follow - ent.solid = SOLID_NOT; // MOVETYPE_FOLLOW is always non-solid - this means this cannot be teleported by warpzones any more! Instead, we must notice when our owner gets teleported. - ent.aiment = e; // make the hole follow bmodel - ent.punchangle = e.angles; // the original angles of bmodel - ent.view_ofs = ent.origin - e.origin; // relative origin - ent.v_angle = ent.angles - e.angles; // relative angles - ent.aiment_classname = strzone(e.classname); - ent.aiment_deadflag = e.deadflag; -} -void UnsetMovetypeFollow(entity ent) -{ - ent.movetype = MOVETYPE_FLY; - PROJECTILE_MAKETRIGGER(ent); - ent.aiment = world; -} -float LostMovetypeFollow(entity ent) -{ -/* - if(ent.movetype != MOVETYPE_FOLLOW) - if(ent.aiment) - error("???"); -*/ - if(ent.aiment) - { - if(ent.aiment.classname != ent.aiment_classname) - return 1; - if(ent.aiment.deadflag != ent.aiment_deadflag) - return 1; - } - return 0; -} - .float hook_length; .float hook_switchweapon; diff --git a/qcsrc/server/miscfunctions.qc b/qcsrc/server/miscfunctions.qc index c16608821..8b7806e56 100644 --- a/qcsrc/server/miscfunctions.qc +++ b/qcsrc/server/miscfunctions.qc @@ -3086,3 +3086,40 @@ void defer(float fdelay, void() func) e.think = defer_think; e.nextthink = time + fdelay; } + +.string aiment_classname; +.float aiment_deadflag; +void SetMovetypeFollow(entity ent, entity e) +{ + // FIXME this may not be warpzone aware + ent.movetype = MOVETYPE_FOLLOW; // make the hole follow + ent.solid = SOLID_NOT; // MOVETYPE_FOLLOW is always non-solid - this means this cannot be teleported by warpzones any more! Instead, we must notice when our owner gets teleported. + ent.aiment = e; // make the hole follow bmodel + ent.punchangle = e.angles; // the original angles of bmodel + ent.view_ofs = ent.origin - e.origin; // relative origin + ent.v_angle = ent.angles - e.angles; // relative angles + ent.aiment_classname = strzone(e.classname); + ent.aiment_deadflag = e.deadflag; +} +void UnsetMovetypeFollow(entity ent) +{ + ent.movetype = MOVETYPE_FLY; + PROJECTILE_MAKETRIGGER(ent); + ent.aiment = world; +} +float LostMovetypeFollow(entity ent) +{ +/* + if(ent.movetype != MOVETYPE_FOLLOW) + if(ent.aiment) + error("???"); +*/ + if(ent.aiment) + { + if(ent.aiment.classname != ent.aiment_classname) + return 1; + if(ent.aiment.deadflag != ent.aiment_deadflag) + return 1; + } + return 0; +} diff --git a/qcsrc/server/w_minelayer.qc b/qcsrc/server/w_minelayer.qc index ae8db2fed..e9f6453fc 100644 --- a/qcsrc/server/w_minelayer.qc +++ b/qcsrc/server/w_minelayer.qc @@ -11,7 +11,7 @@ void spawnfunc_weapon_minelayer (void) weapon_defaultspawnfunc(WEP_MINE_LAYER); } -void W_Mine_Stick () +void W_Mine_Stick (entity to) { spamsound (self, CHAN_PROJECTILE, "weapons/mine_stick.wav", VOL_BASE, ATTN_NORM); @@ -51,6 +51,9 @@ void W_Mine_Stick () remove(self); self = newmine; + + if(to) + SetMovetypeFollow(self, to); } void W_Mine_Explode () @@ -89,7 +92,7 @@ void W_Mine_DoRemoteExplode () self.event_damage = SUB_Null; self.takedamage = DAMAGE_NO; - if(self.movetype == MOVETYPE_NONE) + if(self.movetype == MOVETYPE_NONE || self.movetype == MOVETYPE_FOLLOW) self.velocity = self.oldvelocity; RadiusDamage (self, self.owner, autocvar_g_balance_minelayer_remote_damage, autocvar_g_balance_minelayer_remote_edgedamage, autocvar_g_balance_minelayer_remote_radius, world, autocvar_g_balance_minelayer_remote_force, self.projectiledeathtype | HITTYPE_BOUNCE, world); @@ -157,6 +160,15 @@ void W_Mine_Think (void) entity head; self.nextthink = time; + + if(self.movetype == MOVETYPE_FOLLOW) + { + if(LostMovetypeFollow(self)) + { + UnsetMovetypeFollow(self); + self.movetype = MOVETYPE_NONE; + } + } // our lifetime has expired, it's time to die - mine_time just allows us to play a sound for this // TODO: replace this mine_trigger.wav sound with a real countdown @@ -209,10 +221,25 @@ void W_Mine_Think (void) void W_Mine_Touch (void) { PROJECTILE_TOUCH; - if(!other || (other.takedamage != DAMAGE_AIM && other.movetype == MOVETYPE_NONE)) - W_Mine_Stick(); - else if(self.movetype != MOVETYPE_NONE) // don't unstick a locked mine when someone touches it - self.velocity = '0 0 0'; + + if(other && other.takedamage == DAMAGE_AIM) + { + // hit some enemy + // we do nothing, other than clearing velocity (falling straight down) + // but only if we're still moving (not stuck yet) + if(self.movetype != MOVETYPE_NONE && self.movetype != MOVETYPE_FOLLOW) + { + // allow falling down, but no other movement, when hit an enemy + self.velocity_x = 0; + self.velocity_y = 0; + if(self.velocity_z > 0) + self.velocity_z = 0; + } + } + else + { + W_Mine_Stick(other); + } } void W_Mine_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) -- 2.39.2