]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/w_minelayer.qc
Rename and correct a float
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / w_minelayer.qc
index 99c86201f97d319388c6aafd95a04d76ef236421..7342d1e2bb4a9c8c1fd6fb80bf869038d02faca2 100644 (file)
@@ -1,22 +1,22 @@
-/*TODO list (things left to do before this weapon should be ready, delete once it's all done):
-- The mine model needs to face properly when it sticks to a surface. Once we'll have a correct mine model, we can't afford the model facing any way it falls to the ground. Should probably look at the porto code to see how portals face in the right direction when sticking to walls. 
-*/
-
 #ifdef REGISTER_WEAPON
 REGISTER_WEAPON(MINE_LAYER, w_minelayer, IT_ROCKETS, 4, WEP_FLAG_NORMAL | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_HIGH, "minelayer", "minelayer", "Mine Layer");
 #else
 #ifdef SVQC
-.float minelayer_detonate;
-.float mine_number, mine_time;
+.float minelayer_detonate, minelayer_mines;
+.float mine_time;
 
 void spawnfunc_weapon_minelayer (void)
 {
        weapon_defaultspawnfunc(WEP_MINE_LAYER);
 }
 
-void W_Mine_RespawnEntity ()
+void W_Mine_Stick ()
 {
-       entity newmine;
+       spamsound (self, CHAN_PROJECTILE, "weapons/mine_stick.wav", VOL_BASE, ATTN_NORM);
+
+       // in order for mines to face properly when sticking to the ground, they must be a server side entity rather than a csqc projectile
+
+       local entity newmine;
        newmine = spawn();
        newmine.classname = self.classname;
 
@@ -27,17 +27,16 @@ void W_Mine_RespawnEntity ()
        setsize(newmine, '-4 -4 -4', '4 4 4');
        setorigin(newmine, self.origin);
        setmodel(newmine, "models/mine.md3");
-       newmine.angles = vectoangles(-trace_plane_normal);
+       newmine.angles = vectoangles(-trace_plane_normal); // face against the surface
 
        newmine.takedamage = self.takedamage;
        newmine.damageforcescale = self.damageforcescale;
        newmine.health = self.health;
        newmine.event_damage = self.event_damage;
 
-       newmine.movetype = MOVETYPE_NONE;
+       newmine.movetype = MOVETYPE_NONE; // lock the mine in place
        newmine.projectiledeathtype = self.projectiledeathtype;
 
-       newmine.mine_number = self.mine_number;
        newmine.mine_time = self.mine_time;
 
        newmine.touch = SUB_Null;
@@ -94,7 +93,7 @@ void W_Mine_DoRemoteExplode ()
        remove (self);
 }
 
-void W_Mine_RemoteExplode()
+void W_Mine_RemoteExplode ()
 {
        if(self.owner.deadflag == DEAD_NO)
                if((self.spawnshieldtime >= 0)
@@ -106,7 +105,7 @@ void W_Mine_RemoteExplode()
                }
 }
 
-void W_Mine_ProximityExplode()
+void W_Mine_ProximityExplode ()
 {
        // make sure no friend is in the mine's radius. If there is any, explosion is delayed until he's at a safe distance
        if(cvar("g_balance_minelayer_protection"))
@@ -134,12 +133,22 @@ void W_Mine_Think (void)
        {
                other = world;
                self.projectiledeathtype |= HITTYPE_BOUNCE;
-               W_Mine_Explode ();
+               W_Mine_Explode();
+               return;
+       }
+
+       // a player's mines shall explode if he disconnects or dies
+       // TODO: Do this on team change too
+       if(self.owner.classname != "player" || self.owner.deadflag != DEAD_NO)
+       {
+               other = world;
+               self.projectiledeathtype |= HITTYPE_BOUNCE;
+               W_Mine_Explode();
                return;
        }
 
-       // set the mine for detonation when a foe gets too close
-       head = findradius(self.origin, cvar("g_balance_minelayer_detectionradius"));
+       // set the mine for detonation when a foe gets close enough
+       head = findradius(self.origin, cvar("g_balance_minelayer_proximityradius"));
        while(head)
        {
                if(head.classname == "player" && head.deadflag == DEAD_NO)
@@ -170,12 +179,7 @@ void W_Mine_Touch (void)
 {
        PROJECTILE_TOUCH;
        if(!other || (other.takedamage != DAMAGE_AIM && other.movetype == MOVETYPE_NONE))
-       {
-               spamsound (self, CHAN_PROJECTILE, "weapons/mine_stick.wav", VOL_BASE, ATTN_NORM);
-               self.movetype = MOVETYPE_NONE; // lock the mine in place
-
-               W_Mine_RespawnEntity();
-       }
+               W_Mine_Stick();
        else if(self.movetype != MOVETYPE_NONE) // don't unstick a locked mine when someone touches it
                self.velocity = '0 0 0';
 }
@@ -198,11 +202,11 @@ void W_Mine_Attack (void)
        // scan how many mines we placed, and return if we reached our limit
        if(cvar("g_balance_minelayer_limit"))
        {
-               self.mine_number = 0;
+               self.minelayer_mines = 0;
                for(mine = world; (mine = find(mine, classname, "mine")); ) if(mine.owner == self)
-                       self.mine_number += 1;
+                       self.minelayer_mines += 1;
 
-               if(self.mine_number >= cvar("g_balance_minelayer_limit"))
+               if(self.minelayer_mines >= cvar("g_balance_minelayer_limit"))
                {
                        // the refire delay keeps this message from being spammed
                        sprint(self, strcat("You cannot place more than ^2", cvar_string("g_balance_minelayer_limit"), " ^7mines at a time\n") );
@@ -389,6 +393,7 @@ float w_minelayer(float req)
        else if (req == WR_PRECACHE)
        {
                precache_model ("models/flash.md3");
+               precache_model ("models/mine.md3");
                precache_model ("models/weapons/g_minelayer.md3");
                precache_model ("models/weapons/v_minelayer.md3");
                precache_model ("models/weapons/h_minelayer.iqm");