]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' of git://de.git.xonotic.org/xonotic/xonotic-data.pk3dir
authorJan Behrens <zykure@web.de>
Thu, 31 Jan 2013 17:40:52 +0000 (18:40 +0100)
committerJan Behrens <zykure@web.de>
Thu, 31 Jan 2013 17:40:52 +0000 (18:40 +0100)
23 files changed:
defaultXonotic.cfg
qcsrc/server/autocvars.qh
qcsrc/server/cl_weapons.qc
qcsrc/server/command/sv_cmd.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/mutators/base.qc
qcsrc/server/mutators/base.qh
qcsrc/server/mutators/gamemode_ctf.qc
qcsrc/server/mutators/gamemode_freezetag.qc
qcsrc/server/mutators/gamemode_keepaway.qc
qcsrc/server/mutators/gamemode_keyhunt.qc
qcsrc/server/mutators/gamemode_nexball.qc
qcsrc/server/mutators/gamemode_onslaught.qc
qcsrc/server/mutators/mutator_dodging.qc
qcsrc/server/mutators/mutator_new_toys.qc
qcsrc/server/mutators/mutator_nix.qc
qcsrc/server/mutators/mutator_physical_items.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator_superspec.qc
qcsrc/server/mutators/mutators.qh
qcsrc/server/mutators/sandbox.qc
qcsrc/server/progs.src
qcsrc/server/t_items.qc
qcsrc/server/w_minstanex.qc

index 1ad85c8bd01da28797e5aaa8cf42a8a97fd3b321..c51cc0c717cd3765e5e741627f3824759e2b793b 100644 (file)
@@ -1067,6 +1067,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 433261d45a94b464e25e1e5d4b2b3d6a53aefecd..c8db3db8a409c5749a6b1c4fef7e086cdb5d22dd 100644 (file)
@@ -1275,3 +1275,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 236c0923fdc330834469234bc9eb2285a1f6bb26..4df59a09afde775e7e73cca9fb0be6e248ad1205 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 0710ddfa8474874cca23787d9ed6221e44660ebd..8f3ea869d49e24bcdf0febd74dc5564c1002f7b6 100644 (file)
@@ -1415,6 +1415,7 @@ void GameCommand_stuffto(float request, float argc)
        // we can be certain they understand the risks of it... So to enable, compile server with -DSTUFFTO_ENABLED argument.
        
        #ifdef STUFFTO_ENABLED
+       #message "stuffto command enabled"
        switch(request)
        {
                case CMD_REQUEST_COMMAND:
index efb73540672df091703c6649b2aa90e7862ffb2b..7f8931bffe648c90d3bd4a7b3eada671725f66e6 100644 (file)
@@ -1121,6 +1121,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 368ab589824ef5a66464d99283c7d223184cdf3f..f4761b884dca28175d58da08589a777c589722c2 100644 (file)
@@ -116,8 +116,14 @@ float Mutator_Add(mutatorfunc_t func, string name)
                // good
                return 1;
        }
-       backtrace("WARNING: when adding mutator: adding failed\n");
-       Mutator_Remove(func, name);
+
+       backtrace("WARNING: when adding mutator: adding failed, rolling back\n");
+
+       if(func(MUTATOR_ROLLING_BACK) != 0)
+       {
+               // baaaaad
+               error("WARNING: when adding mutator: rolling back failed");
+       }
        return 0;
 }
 void Mutator_Remove(float(float) func, string name)
index 1b6cea8fc4501ee47eaa8b26089926d927544878..d90d564b501447acb3e3ef1def71530be1a521ee 100644 (file)
@@ -18,6 +18,7 @@ float CallbackChain_Call(entity cb);
 
 #define MUTATOR_REMOVING 0
 #define MUTATOR_ADDING 1
+#define MUTATOR_ROLLING_BACK 2
 typedef float(float) mutatorfunc_t;
 float Mutator_Add(mutatorfunc_t func, string name);
 void Mutator_Remove(mutatorfunc_t func, string name); // calls error() on fail
@@ -27,9 +28,10 @@ void Mutator_Remove(mutatorfunc_t func, string name); // calls error() on fail
 #define MUTATOR_DEFINITION(name) float MUTATOR_##name(float mode)
 #define MUTATOR_DECLARATION(name) float MUTATOR_##name(float mode)
 #define MUTATOR_HOOKFUNCTION(name) float HOOKFUNCTION_##name()
-#define MUTATOR_HOOK(cb,func,order) do { if(mode == MUTATOR_ADDING) { if(!HOOK_##cb) HOOK_##cb = CallbackChain_New(#cb); if(!CallbackChain_Add(HOOK_##cb,HOOKFUNCTION_##func,order)) { print("HOOK FAILED: ", #func, "\n"); return 1; } } else if(mode == MUTATOR_REMOVING) { if(HOOK_##cb) CallbackChain_Remove(HOOK_##cb,HOOKFUNCTION_##func); } } while(0)
+#define MUTATOR_HOOK(cb,func,order) do { if(mode == MUTATOR_ADDING) { if(!HOOK_##cb) HOOK_##cb = CallbackChain_New(#cb); if(!CallbackChain_Add(HOOK_##cb,HOOKFUNCTION_##func,order)) { print("HOOK FAILED: ", #func, "\n"); return 1; } } else if(mode == MUTATOR_REMOVING || mode == MUTATOR_ROLLING_BACK) { if(HOOK_##cb) CallbackChain_Remove(HOOK_##cb,HOOKFUNCTION_##func); } } while(0)
 #define MUTATOR_ONADD if(mode == MUTATOR_ADDING)
 #define MUTATOR_ONREMOVE if(mode == MUTATOR_REMOVING)
+#define MUTATOR_ONROLLBACK_OR_REMOVE if(mode == MUTATOR_REMOVING || mode == MUTATOR_ROLLING_BACK)
 
 #define MUTATOR_HOOKABLE(cb) entity HOOK_##cb
 #define MUTATOR_CALLHOOK(cb) CallbackChain_Call(HOOK_##cb)
@@ -205,6 +207,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
index 908d81cf3fe0a9d96b13a1c529a8db568f5008a9..134e979d1c17d0b09da3b1658b0fd724a791b55e 100644 (file)
@@ -2200,9 +2200,17 @@ MUTATOR_DEFINITION(gamemode_ctf)
                ctf_Initialize();
        }
 
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // we actually cannot roll back ctf_Initialize here
+               // BUT: we don't need to! If this gets called, adding always
+               // succeeds.
+       }
+
        MUTATOR_ONREMOVE
        {
-               error("This is a game type and it cannot be removed at runtime.");
+               print("This is a game type and it cannot be removed at runtime.");
+               return -1;
        }
 
        return 0;
index aedfd6364c942ef5f1d967b38d0dac04fa8d202f..116eecbbf6b773613f7b299568df3ee31a5817d6 100644 (file)
@@ -476,9 +476,17 @@ MUTATOR_DEFINITION(gamemode_freezetag)
                freezetag_Initialize();
        }
 
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // we actually cannot roll back freezetag_Initialize here
+               // BUT: we don't need to! If this gets called, adding always
+               // succeeds.
+       }
+
        MUTATOR_ONREMOVE
        {
-               error("This is a game type and it cannot be removed at runtime.");
+               print("This is a game type and it cannot be removed at runtime.");
+               return -1;
        }
 
        return 0;
index 9f8647d9dfa5cab3a61a1a37735360bcaf4602ec..3be0b035272b013598402f91188aed6c003069b6 100644 (file)
@@ -426,9 +426,17 @@ MUTATOR_DEFINITION(gamemode_keepaway)
                ka_Initialize();
        }
 
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // we actually cannot roll back ka_Initialize here
+               // BUT: we don't need to! If this gets called, adding always
+               // succeeds.
+       }
+
        MUTATOR_ONREMOVE
        {
-               error("This is a game type and it cannot be removed at runtime.");
+               print("This is a game type and it cannot be removed at runtime.");
+               return -1;
        }
 
        return 0;
index 58d732d7f70b926c6cb13c6f93aa0f9a5807f48e..592fa327cfb7af6ae6b413369dcc6759573523a2 100644 (file)
@@ -1111,9 +1111,17 @@ MUTATOR_DEFINITION(gamemode_keyhunt)
                kh_Initialize();
        }
 
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // we actually cannot roll back kh_Initialize here
+               // BUT: we don't need to! If this gets called, adding always
+               // succeeds.
+       }
+
        MUTATOR_ONREMOVE
        {
-               error("This is a game type and it cannot be removed at runtime.");
+               print("This is a game type and it cannot be removed at runtime.");
+               return -1;
        }
 
        return 0;
index 5f27b60a55f882e851cc99fe5bc876fec16e5601..62cfd01ad867250673f406bfc68ab7ea99841671 100644 (file)
@@ -979,5 +979,18 @@ MUTATOR_DEFINITION(gamemode_nexball)
                InitializeEntity(world, nb_delayedinit, INITPRIO_GAMETYPE);
        }
 
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // we actually cannot roll back nb_delayedinit here
+               // BUT: we don't need to! If this gets called, adding always
+               // succeeds.
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               print("This is a game type and it cannot be removed at runtime.");
+               return -1;
+       }
+
        return 0;
 }
index 8137cc3047d35ed2822d17a9841415e83c991ff5..dd0152ed084311be37509b34e5471531386afdcc 100644 (file)
@@ -1696,7 +1696,14 @@ MUTATOR_DEFINITION(gamemode_onslaught)
        
        MUTATOR_ONADD
        {
-               //InitializeEntity(world, nb_delayedinit, INITPRIO_GAMETYPE);
+               if(time > 1) // game loads at time 1
+                       error("This is a game type and it cannot be added at runtime.");
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               print("This is a game type and it cannot be removed at runtime.");
+               return -1;
        }
 
        return 0;
index bdd39b1283f487fe0e74ab42135b6d66f4b180c7..5cb328c2ea593f6ac43a08d3fba5ac54df4a9059 100644 (file)
 // the jump part of the dodge cannot be ramped
 .float dodging_single_action;
 
-void dodging_Initialize() {
-       // print("dodging_Initialize\n");
-
-       self.last_FORWARD_KEY_time = 0;
-       self.last_BACKWARD_KEY_time = 0;
-       self.last_RIGHT_KEY_time = 0;
-       self.last_LEFT_KEY_time = 0;
-       self.last_dodging_time = 0;
-       self.dodging_action = 0;
-       self.dodging_velocity_gain = 0;
-       self.dodging_single_action = 0;
-       self.dodging_direction_x = 0;
-       self.dodging_direction_y = 0;
-}
-
 MUTATOR_HOOKFUNCTION(dodging_GetCvars) {
        GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_dodging_timeout, "cl_dodging_timeout");
        return 0;
@@ -283,14 +268,17 @@ MUTATOR_DEFINITION(mutator_dodging)
        MUTATOR_ONADD
        {
                g_dodging = 1;
-               dodging_Initialize();
        }
 
        // this just turns off the cvar.
-       MUTATOR_ONREMOVE
-       {        
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
                g_dodging = 0;
        }
 
+       MUTATOR_ONREMOVE
+       {
+       }
+
        return 0;
 }
index cc4f94324b8273fadf9fbc113c4dc286c6b8066b..6ee3e87b3c193e52354dd4e9e40301a8b6a756fc 100644 (file)
@@ -208,9 +208,19 @@ MUTATOR_DEFINITION(mutator_new_toys)
                        if(nt_IsNewToy(i))
                                get_weaponinfo(i).spawnflags &~= WEP_FLAG_MUTATORBLOCKED;
        }
+
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               float i;
+               for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+                       if(nt_IsNewToy(i))
+                               get_weaponinfo(i).spawnflags |= WEP_FLAG_MUTATORBLOCKED;
+       }
+
        MUTATOR_ONREMOVE
        {
-               error("This cannot be removed at runtime\n");
+               print("This cannot be removed at runtime\n");
+               return -1;
        }
 
        return 0;
index dad19e4a3748f468c93db674b6b2e9c7e7e43a2c..b492ee60eb48add1046b6278fb171783bc85dea8 100644 (file)
@@ -247,6 +247,11 @@ MUTATOR_DEFINITION(mutator_nix)
                NIX_precache();
        }
 
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // nothing to roll back
+       }
+
        MUTATOR_ONREMOVE
        {
                // as the PlayerSpawn hook will no longer run, NIX is turned off by this!
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..74b7db2
--- /dev/null
@@ -0,0 +1,127 @@
+.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)
+{
+       MUTATOR_HOOK(Item_Spawn, item_spawning, CBC_ORDER_ANY);
+
+       // 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;
+}
index 87915f9af49b7cc1d175986ae26fe3df7613444a..0645b4805446b17cd1baafe035225d4b4793fceb 100644 (file)
@@ -518,13 +518,5 @@ MUTATOR_DEFINITION(mutator_superspec)
        //MUTATOR_HOOK(MakePlayerObserver, superspec_MakePlayerObserver, CBC_ORDER_ANY);
        MUTATOR_HOOK(ClientDisconnect, superspec_ClientDisconnect, CBC_ORDER_ANY);
 
-       MUTATOR_ONADD
-       {
-       }
-
-       MUTATOR_ONREMOVE
-       {
-       }
-
        return 0;
 }
index 2ac6094d339d578d174da5ec3ed06eed91fcad20..7fcfd9883bb9195f24b7f513ffc1e8189d03c014 100644 (file)
@@ -11,6 +11,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(mutator_superspec);
 
index 4d97b8eece8e8fc585377a84d5167ea9dc3fea1a..391e317423dffd4dd37e628effe9a988b452267f 100644 (file)
@@ -817,6 +817,16 @@ MUTATOR_DEFINITION(sandbox)
                        sandbox_Database_Load();
        }
 
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // nothing to roll back
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               // nothing to remove
+       }
+
        return FALSE;
 }
 
index 028519372f025ae24aa923d472ba0a6593de86b7..36936e38642e597bad39ca5b3d56621450a9dbe1 100644 (file)
@@ -220,6 +220,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
 mutators/mutator_superspec.qc
 
index bd6b9962cc2d623b81a13db5e3733c3b562e5a17..bf70da0286a837b98fb68fb2adbff927f8d30254 100644 (file)
@@ -1214,6 +1214,14 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime,
                Item_Reset();
         
     Net_LinkEntity(self, FALSE, 0, ItemSend);
+
+       // call this hook after everything else has been done
+       if(MUTATOR_CALLHOOK(Item_Spawn))
+       {
+               startitem_failed = TRUE;
+               remove(self);
+               return;
+       }
 }
 
 /* replace items in minstagib
index 1f1137e4b845b151321d1501c5dbdca9e325b2fd..a2d3b988734a6d75e9ff2c3fd3db737573821e30 100644 (file)
@@ -34,8 +34,8 @@ void W_MinstaNex_Attack (void)
                }
                if(damage_goodhits && self.minstanex_lasthit)
                {
-                       if(AnnounceTo(self, "impressive"))
-                               damage_goodhits = 0; // only every second time
+                       AnnounceTo(self, "impressive");
+                       damage_goodhits = 0; // only every second time
                }
        }