]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/mutators/mutator_physical_items.qc
Merge remote-tracking branch 'origin/master' into samual/lightning_gun
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / mutator_physical_items.qc
index e362b11f413555f1c23b70b12742a9b75ed10207..74b7db2f0db66fad25135150525f6d762f1dfd61 100644 (file)
@@ -1,12 +1,12 @@
 .vector spawn_origin, spawn_angles;
 
-void thrown_wep_ode_think()
+void physical_item_think()
 {
        self.nextthink = time;
 
        self.alpha = self.owner.alpha; // apply fading and ghosting
 
-       if(!self.cnt) // map item, not dropped weapon
+       if(!self.cnt) // map item, not dropped
        {
                // copy ghost item properties
                self.colormap = self.owner.colormap;
@@ -14,7 +14,7 @@ void thrown_wep_ode_think()
                self.glowmod = self.owner.glowmod;
 
                // if the item is not spawned, make sure the invisible / ghost item returns to its origin and stays there
-               if(autocvar_g_ode_items_reset)
+               if(autocvar_g_physical_items_reset)
                {
                        if(self.owner.nextthink > time) // awaiting respawn
                        {
@@ -32,10 +32,10 @@ void thrown_wep_ode_think()
        }
 
        if(!self.owner.modelindex)
-               remove(self); // the real weapon is gone, remove this
+               remove(self); // the real item is gone, remove this
 }
 
-void thrown_wep_ode_touch()
+void physical_item_touch()
 {
        if(!self.cnt) // not for dropped items
        if (ITEM_TOUCH_NEEDKILL())
@@ -45,9 +45,19 @@ void thrown_wep_ode_touch()
        }
 }
 
+void physical_item_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+{
+       if(!self.cnt) // not for dropped items
+       if(ITEM_DAMAGE_NEEDKILL(deathtype))
+       {
+               setorigin(self, self.spawn_origin);
+               self.angles = self.spawn_angles;
+       }
+}
+
 MUTATOR_HOOKFUNCTION(item_spawning)
 {
-       if(self.owner == world && autocvar_g_ode_items <= 1)
+       if(self.owner == world && autocvar_g_physical_items <= 1)
                return FALSE;
        if (self.spawnflags & 1) // floating item
                return FALSE;
@@ -69,13 +79,14 @@ MUTATOR_HOOKFUNCTION(item_spawning)
        wep.effects |= EF_NOMODELFLAGS; // disable the spinning
        wep.colormap = self.owner.colormap;
        wep.glowmod = self.owner.glowmod;
-       wep.damageforcescale = autocvar_g_ode_items_damageforcescale;
+       wep.damageforcescale = autocvar_g_physical_items_damageforcescale;
        wep.dphitcontentsmask = self.dphitcontentsmask;
        wep.cnt = (self.owner != world);
 
-       wep.think = thrown_wep_ode_think;
+       wep.think = physical_item_think;
        wep.nextthink = time;
-       wep.touch = thrown_wep_ode_touch;
+       wep.touch = physical_item_touch;
+       wep.event_damage = physical_item_damage;
 
        wep.spawn_origin = self.origin;
        wep.spawn_angles = self.angles;
@@ -89,10 +100,28 @@ MUTATOR_HOOKFUNCTION(item_spawning)
 
 MUTATOR_DEFINITION(mutator_physical_items)
 {
-       if(!autocvar_physics_ode)
-               return FALSE;
-
        MUTATOR_HOOK(Item_Spawn, item_spawning, CBC_ORDER_ANY);
 
-       return FALSE;
+       // check if we have a physics engine
+       MUTATOR_ONADD
+       {
+               if not(autocvar_physics_ode && checkextension("DP_PHYSICS_ODE"))
+               {
+                       dprint("Warning: Physical items are enabled but no physics engine can be used. Reverting to old items.\n");
+                       return -1;
+               }
+       }
+
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // nothing to roll back
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               print("This cannot be removed at runtime\n");
+               return -1;
+       }
+
+       return 0;
 }