]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into mirceakitsune/physical_entities
authorMircea Kitsune <sonichedgehog_hyperblast00@yahoo.com>
Sun, 13 May 2012 09:08:03 +0000 (12:08 +0300)
committerMircea Kitsune <sonichedgehog_hyperblast00@yahoo.com>
Sun, 13 May 2012 09:08:03 +0000 (12:08 +0300)
defaultXonotic.cfg
qcsrc/server/autocvars.qh
qcsrc/server/cl_weapons.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/mutators/base.qh
qcsrc/server/mutators/mutator_physical_items.qc [new file with mode: 0644]
qcsrc/server/mutators/mutators.qh
qcsrc/server/progs.src
qcsrc/server/t_items.qc

index 0c399bb183cde7a50c4ff80e690bd59764527ffc..15b420d9dfe29f3c124906b201d29ced8eab9e1f 100644 (file)
@@ -1404,6 +1404,10 @@ alias sethostname "set menu_use_default_hostname 0; hostname $*"
 
 set sv_foginterval 1 "force enable fog in regular intervals"
 
+set g_physical_items 0 "1 uses ODE physics for dropped weapons, 2 for all items, requires physics_ode to be enabled"
+set g_physical_items_damageforcescale 3 "how affected physical weapons are by damage"
+set g_physical_items_reset 1 "return map items to their original lotation after being picked up"
+
 // Audio track names (for old-style "cd loop NUMBER" usage)
 set _cdtrack_first "1"
 alias _cdtrack_0 "g_cdtracks_remaplist \"$g_cdtracks_remaplist $1\""
index 5e1c65f796e159525962b01e0cd69074475710f8..1e6f6e835436e089247903d9a68c7941ca173e52 100644 (file)
@@ -1223,3 +1223,6 @@ float autocvar_g_sandbox_object_material_velocity_min;
 float autocvar_g_sandbox_object_material_velocity_factor;
 float autocvar_g_max_info_autoscreenshot;
 float autocvar_physics_ode;
+float autocvar_g_physical_items;
+float autocvar_g_physical_items_damageforcescale;
+float autocvar_g_physical_items_reset;
index 59efb74d5458508fab560ddb0f5338fa12013372..10ae0f44e2875351400b59275d4f66865067dd6f 100644 (file)
@@ -298,6 +298,7 @@ string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vecto
                wep.savenextthink = wep.nextthink;
                wep.nextthink = min(wep.nextthink, time + 0.5);
                wep.pickup_anyway = TRUE; // these are ALWAYS pickable
+
                return s;
        }
 }
index 3826b683af6c16ceb8ca7d33aa108ed06269e8e7..95f2cb533b49c758d2fe378ee79ddd5745ee862d 100644 (file)
@@ -1109,6 +1109,8 @@ void readlevelcvars(void)
                MUTATOR_ADD(mutator_dodging);
        if(cvar("g_spawn_near_teammate"))
                MUTATOR_ADD(mutator_spawn_near_teammate);
+       if(cvar("g_physical_items"))
+               MUTATOR_ADD(mutator_physical_items);
        if(!g_minstagib)
        {
                if(cvar("g_invincible_projectiles"))
index 236e311b6a0cb8c0fa7fa39631678b8b46f6ab64..57777e4b9a9379d79a9d6deaef692caaf69e55df 100644 (file)
@@ -205,6 +205,12 @@ MUTATOR_HOOKABLE(SV_StartFrame);
 MUTATOR_HOOKABLE(SetModname);
        // OUT
        string modname; // name of the mutator/mod if it warrants showing as such in the server browser
+       
+MUTATOR_HOOKABLE(Item_Spawn);
+       // called for each item being spawned on a map, including dropped weapons
+       // return 1 to remove an item
+       // INPUT
+       entity self; // the item
 
 MUTATOR_HOOKABLE(SetWeaponreplace);
        // IN
diff --git a/qcsrc/server/mutators/mutator_physical_items.qc b/qcsrc/server/mutators/mutator_physical_items.qc
new file mode 100644 (file)
index 0000000..285dc4a
--- /dev/null
@@ -0,0 +1,113 @@
+.vector spawn_origin, spawn_angles;
+
+void physical_item_think()
+{
+       self.nextthink = time;
+
+       self.alpha = self.owner.alpha; // apply fading and ghosting
+
+       if(!self.cnt) // map item, not dropped
+       {
+               // copy ghost item properties
+               self.colormap = self.owner.colormap;
+               self.colormod = self.owner.colormod;
+               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_physical_items_reset)
+               {
+                       if(self.owner.nextthink > time) // awaiting respawn
+                       {
+                               setorigin(self, self.spawn_origin);
+                               self.angles = self.spawn_angles;
+                               self.solid = SOLID_NOT;
+                               self.movetype = MOVETYPE_NONE;
+                       }
+                       else
+                       {
+                               self.solid = SOLID_CORPSE;
+                               self.movetype = MOVETYPE_PHYSICS;
+                       }
+               }
+       }
+
+       if(!self.owner.modelindex)
+               remove(self); // the real item is gone, remove this
+}
+
+void physical_item_touch()
+{
+       if(!self.cnt) // not for dropped items
+       if (ITEM_TOUCH_NEEDKILL())
+       {
+               setorigin(self, self.spawn_origin);
+               self.angles = self.spawn_angles;
+       }
+}
+
+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_physical_items <= 1)
+               return FALSE;
+       if (self.spawnflags & 1) // floating item
+               return FALSE;
+
+       // The actual item can't be physical and trigger at the same time, so make it invisible and use a second entity for physics.
+       // Ugly hack, but unless SOLID_TRIGGER is gotten to work with MOVETYPE_PHYSICS in the engine it can't be fixed.
+       entity wep;
+       wep = spawn();
+       setmodel(wep, self.model);
+       setsize(wep, self.mins, self.maxs);
+       setorigin(wep, self.origin);
+       wep.angles = self.angles;
+       wep.velocity = self.velocity;
+
+       wep.owner = self;
+       wep.solid = SOLID_CORPSE;
+       wep.movetype = MOVETYPE_PHYSICS;
+       wep.takedamage = DAMAGE_AIM;
+       wep.effects |= EF_NOMODELFLAGS; // disable the spinning
+       wep.colormap = self.owner.colormap;
+       wep.glowmod = self.owner.glowmod;
+       wep.damageforcescale = autocvar_g_physical_items_damageforcescale;
+       wep.dphitcontentsmask = self.dphitcontentsmask;
+       wep.cnt = (self.owner != world);
+
+       wep.think = physical_item_think;
+       wep.nextthink = time;
+       wep.touch = physical_item_touch;
+       wep.event_damage = physical_item_damage;
+
+       wep.spawn_origin = self.origin;
+       wep.spawn_angles = self.angles;
+
+       self.effects |= EF_NODRAW; // hide the original weapon
+       self.movetype = MOVETYPE_FOLLOW;
+       self.aiment = wep; // attach the original weapon
+
+       return FALSE;
+}
+
+MUTATOR_DEFINITION(mutator_physical_items)
+{
+       // check if we have a physics engine
+       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 FALSE;
+       }
+
+       MUTATOR_HOOK(Item_Spawn, item_spawning, CBC_ORDER_ANY);
+
+       return FALSE;
+}
index 4e7d9a6512bd47b8806d2f791fa5fc04cd9ab035..66aa94a33faa5a8f4f907bef58da070817910a25 100644 (file)
@@ -9,6 +9,7 @@ MUTATOR_DECLARATION(mutator_new_toys);
 MUTATOR_DECLARATION(mutator_nix);
 MUTATOR_DECLARATION(mutator_rocketflying);
 MUTATOR_DECLARATION(mutator_spawn_near_teammate);
+MUTATOR_DECLARATION(mutator_physical_items);
 MUTATOR_DECLARATION(mutator_vampire);
 
 MUTATOR_DECLARATION(sandbox);
index 1890eddd97a679ae3f279e258dcfe0eb55c6c9f4..f2e0114990b5a790cef02c7262bd1169022b0db6 100644 (file)
@@ -216,6 +216,7 @@ mutators/mutator_dodging.qc
 mutators/mutator_rocketflying.qc
 mutators/mutator_vampire.qc
 mutators/mutator_spawn_near_teammate.qc
+mutators/mutator_physical_items.qc
 mutators/sandbox.qc
 
 ../warpzonelib/anglestransform.qc
index ac029e6577659f3e243a610219b9a3f290d15bc4..a08333e768e9f9767e91cf9e70361729613c74d3 100644 (file)
@@ -917,6 +917,14 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime,
        }
        else
                Item_Reset();
+
+       // call this hook after everything else has been done
+       if(MUTATOR_CALLHOOK(Item_Spawn))
+       {
+               startitem_failed = TRUE;
+               remove(self);
+               return;
+       }
 }
 
 /* replace items in minstagib