]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
various mutator system fixes; add proper rollback of failed add, fixes #1145
authorRudolf Polzer <divverent@xonotic.org>
Wed, 30 Jan 2013 13:22:46 +0000 (14:22 +0100)
committerRudolf Polzer <divverent@xonotic.org>
Wed, 30 Jan 2013 13:26:16 +0000 (14:26 +0100)
14 files changed:
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
qcsrc/server/mutators/mutator_superspec.qc
qcsrc/server/mutators/sandbox.qc

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 a422d25bc94153f653d939e9cabcf571ffbc47f5..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)
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!
index 285dc4a7cbe4d9a886cd2c706503d6bc5a1d3075..74b7db2f0db66fad25135150525f6d762f1dfd61 100644 (file)
@@ -100,14 +100,28 @@ MUTATOR_HOOKFUNCTION(item_spawning)
 
 MUTATOR_DEFINITION(mutator_physical_items)
 {
+       MUTATOR_HOOK(Item_Spawn, item_spawning, CBC_ORDER_ANY);
+
        // check if we have a physics engine
-       if not(autocvar_physics_ode && checkextension("DP_PHYSICS_ODE"))
+       MUTATOR_ONADD
        {
-               dprint("Warning: Physical items are enabled but no physics engine can be used. Reverting to old items.\n");
-               return FALSE;
+               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_HOOK(Item_Spawn, item_spawning, CBC_ORDER_ANY);
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // nothing to roll back
+       }
 
-       return FALSE;
+       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 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;
 }