From 17e053499e327a8603c2db4fb47ec433a4b1fc1f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 29 Dec 2018 10:19:31 +0100 Subject: [PATCH] - reworked the lock code to remove the 255 locks limit and to allow it to automatically deinitialize. --- src/fragglescript/t_func.cpp | 2 - src/g_inventory/a_keys.cpp | 140 +++++++++++++---------------------- src/g_inventory/a_keys.h | 1 - src/p_setup.cpp | 1 - src/tarray.h | 30 ++++++++ 5 files changed, 81 insertions(+), 93 deletions(-) diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index eca7df767..487335835 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -4048,8 +4048,6 @@ void FParser::SF_ScriptRunning() void DFraggleThinker::InitFunctions() { - cycle_t clock; - for(unsigned i=0;i keylist; + TArray keylist; TArray locksound; FString Message; FString RemoteMsg; - int rgb; - - Lock() - { - rgb=0; - } - - ~Lock() - { - for(unsigned int i=0;icheck(owner)) return false; + if (!keylist[i].check(owner)) return false; } return true; } }; +static TMap Locks; +static bool keysdone = false; // have the locks been initialized? +static TArray KeyTypes; // List of all keys sorted by lock. This is for use by the status bar to draw ordered key lists. + //=========================================================================== // // //=========================================================================== -static Lock *locks[256]; // all valid locks -static bool keysdone=false; // have the locks been initialized? -static int currentnumber; // number to be assigned to next key -static bool ignorekey; // set to true when the current lock is not being used -static TArray KeyTypes; // List of all keys sorted by lock. - -static void ClearLocks(); - static const char * keywords_lock[]={ "ANY", "MESSAGE", @@ -171,7 +156,7 @@ static const char * keywords_lock[]={ // //=========================================================================== -static void AddOneKey(Keygroup *keygroup, PClassActor *mi, FScanner &sc) +static void AddOneKey(Keygroup *keygroup, PClassActor *mi, FScanner &sc, bool ignorekey, int ¤tnumber) { if (mi) { @@ -208,26 +193,18 @@ static void AddOneKey(Keygroup *keygroup, PClassActor *mi, FScanner &sc) // //=========================================================================== -static Keygroup *ParseKeygroup(FScanner &sc) +static void ParseKeygroup(Keygroup *keygroup, FScanner &sc, bool ignorekey, int ¤tnumber) { - Keygroup *keygroup; PClassActor *mi; sc.MustGetStringName("{"); - keygroup = new Keygroup; while (!sc.CheckString("}")) { sc.MustGetString(); mi = PClass::FindActor(sc.String); - AddOneKey(keygroup, mi, sc); - } - if (keygroup->anykeylist.Size() == 0) - { - delete keygroup; - return NULL; + AddOneKey(keygroup, mi, sc, ignorekey, currentnumber); } keygroup->anykeylist.ShrinkToFit(); - return keygroup; } //=========================================================================== @@ -257,8 +234,6 @@ static void ParseLock(FScanner &sc) int i,r,g,b; int keynum; Lock sink; - Lock *lock = &sink; - Keygroup *keygroup; PClassActor *mi; sc.MustGetNumber(); @@ -271,23 +246,17 @@ static void ParseLock(FScanner &sc) sc.MustGetStringName("{"); } - ignorekey = true; - if (keynum > 0 && keynum <= 255) - { - lock = new Lock; - if (locks[keynum]) - { - delete locks[keynum]; - } - locks[keynum] = lock; - locks[keynum]->locksound.Push("*keytry"); - locks[keynum]->locksound.Push("misc/keytry"); - ignorekey=false; - } - else if (keynum != -1) + int currentnumber = 0; + if (keynum == 0 || keynum < -1) { sc.ScriptError("Lock index %d out of range", keynum); } + bool ignorekey = keynum == -1; // tell the parsing functions to ignore what they read for other games' keys. + + auto lock = keynum == -1? &sink : &Locks.InsertNew(keynum); + + lock->locksound.Push("*keytry"); + lock->locksound.Push("misc/keytry"); while (!sc.CheckString("}")) { @@ -295,12 +264,15 @@ static void ParseLock(FScanner &sc) switch(i = sc.MatchString(keywords_lock)) { case 0: // Any - keygroup = ParseKeygroup(sc); - if (keygroup) + { + lock->keylist.Reserve(1); + ParseKeygroup(&lock->keylist.Last(), sc, ignorekey, currentnumber); + if (lock->keylist.Last().anykeylist.Size() == 0) { - lock->keylist.Push(keygroup); + lock->keylist.Pop(); } break; + } case 1: // message sc.MustGetString(); @@ -344,12 +316,11 @@ static void ParseLock(FScanner &sc) mi = PClass::FindActor(sc.String); if (mi) { - keygroup = new Keygroup; - AddOneKey(keygroup, mi, sc); - if (keygroup) + lock->keylist.Reserve(1); + AddOneKey(&lock->keylist.Last(), mi, sc, ignorekey, currentnumber); + if (lock->keylist.Last().anykeylist.Size() == 0) { - keygroup->anykeylist.ShrinkToFit(); - lock->keylist.Push(keygroup); + lock->keylist.Pop(); } } break; @@ -389,15 +360,7 @@ static void ClearLocks() } } } - for(i = 0; i < 256; i++) - { - if (locks[i] != NULL) - { - delete locks[i]; - locks[i] = NULL; - } - } - currentnumber = 0; + Locks.Clear(); keysdone = false; } @@ -485,17 +448,6 @@ void P_InitKeyMessages() keysdone = true; } -//=========================================================================== -// -// P_DeinitKeyMessages -// -//=========================================================================== - -void P_DeinitKeyMessages() -{ - ClearLocks(); -} - //=========================================================================== // // P_CheckKeys @@ -513,13 +465,14 @@ int P_CheckKeys (AActor *owner, int keynum, bool remote, bool quiet) int numfailsounds; if (owner == NULL) return false; - if (keynum<=0 || keynum>255) return true; + if (keynum<=0) return true; // Just a safety precaution. The messages should have been initialized upon game start. if (!keysdone) P_InitKeyMessages(); FSoundID failage[2] = { "*keytry", "misc/keytry" }; - if (!locks[keynum]) + auto lock = Locks.CheckKey(keynum); + if (!lock) { if (quiet) return false; if (keynum == 103 && (gameinfo.flags & GI_SHAREWARE)) @@ -532,11 +485,11 @@ int P_CheckKeys (AActor *owner, int keynum, bool remote, bool quiet) } else { - if (locks[keynum]->check(owner)) return true; + if (lock->check(owner)) return true; if (quiet) return false; - failtext = remote? locks[keynum]->RemoteMsg : locks[keynum]->Message; - failsound = &locks[keynum]->locksound[0]; - numfailsounds = locks[keynum]->locksound.Size(); + failtext = remote? lock->RemoteMsg : lock->Message; + failsound = &lock->locksound[0]; + numfailsounds = lock->locksound.Size(); } // If we get here, that means the actor isn't holding an appropriate key. @@ -570,11 +523,13 @@ int P_CheckKeys (AActor *owner, int keynum, bool remote, bool quiet) // //========================================================================== -int P_GetMapColorForLock (int lock) +int P_GetMapColorForLock (int locknum) { - if (lock > 0 && lock < 256) + if (locknum > 0) { - if (locks[lock]) return locks[lock]->rgb; + auto lock = Locks.CheckKey(locknum); + + if (lock) return lock->rgb; } return -1; } @@ -587,11 +542,18 @@ int P_GetMapColorForLock (int lock) int P_GetMapColorForKey (AActor * key) { - int i; + decltype(Locks)::Iterator it(Locks); + decltype(Locks)::Pair *pair; - for (i = 0; i < 256; i++) + int foundlock = INT_MAX; + int rgb = 0; + while (it.NextPair(pair)) { - if (locks[i] && locks[i]->check(key)) return locks[i]->rgb; + if (pair->Key < foundlock && pair->Value.check(key)) + { + rgb = pair->Value.rgb; + foundlock = pair->Key; + } } return 0; } diff --git a/src/g_inventory/a_keys.h b/src/g_inventory/a_keys.h index dc95e17bb..15c19c017 100644 --- a/src/g_inventory/a_keys.h +++ b/src/g_inventory/a_keys.h @@ -6,7 +6,6 @@ class PClassActor; int P_CheckKeys (AActor *owner, int keynum, bool remote, bool quiet = false); void P_InitKeyMessages (); -void P_DeinitKeyMessages (); int P_GetMapColorForLock (int lock); int P_GetMapColorForKey (AActor *key); int P_GetKeyTypeCount(); diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 2f4299426..a78c21541 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -507,7 +507,6 @@ void P_Init () static void P_Shutdown () { DThinker::DestroyThinkersInList(STAT_STATIC); - P_DeinitKeyMessages (); P_FreeLevelData (); // [ZZ] delete global event handlers E_Shutdown(false); diff --git a/src/tarray.h b/src/tarray.h index 3ecdf67f1..255fa9f0a 100644 --- a/src/tarray.h +++ b/src/tarray.h @@ -943,6 +943,36 @@ public: return n->Pair.Value; } + VT &Insert(const KT key, VT &&value) + { + Node *n = FindKey(key); + if (n != NULL) + { + n->Pair.Value = value; + } + else + { + n = NewKey(key); + ::new(&n->Pair.Value) VT(value); + } + return n->Pair.Value; + } + + VT &InsertNew(const KT key) + { + Node *n = FindKey(key); + if (n != NULL) + { + n->Pair.Value.~VT(); + } + else + { + n = NewKey(key); + } + ::new(&n->Pair.Value) VT; + return n->Pair.Value; + } + //======================================================================= // // Remove