diff --git a/source/games/duke/src/global.cpp b/source/games/duke/src/global.cpp index 6793d2141..f4d9f6f19 100644 --- a/source/games/duke/src/global.cpp +++ b/source/games/duke/src/global.cpp @@ -86,6 +86,7 @@ int show_shareware; // display only. int rtsplaying; // RTS playback state TArray mspos; TArray cranes; +TArray animates; bool sound445done; // used in checksectors_r. This was local state inside a function, but this must be maintained globally and serialized @@ -94,11 +95,6 @@ int spriteqloc; animwalltype animwall[MAXANIMWALLS]; // animated walls int numanimwalls; int animatecnt; // sector plane movement -sectortype* animatesect[MAXANIMATES]; -int8_t animatetype[MAXANIMATES]; -int animatetarget[MAXANIMATES]; -double animategoal[MAXANIMATES]; -double animatevel[MAXANIMATES]; int numclouds; // cloudy skies sectortype* clouds[256]; float cloudx; diff --git a/source/games/duke/src/global.h b/source/games/duke/src/global.h index 06337e1c3..a7acedf7d 100644 --- a/source/games/duke/src/global.h +++ b/source/games/duke/src/global.h @@ -70,7 +70,6 @@ extern int spriteqamount; extern int lastvisinc; extern animwalltype animwall[MAXANIMWALLS]; extern int numanimwalls; -extern int animatecnt; extern int numclouds; extern int numcyclers; extern int earthquaketime; @@ -88,11 +87,18 @@ enum animtype_t anim_vertexx, anim_vertexy, }; -extern sectortype* animatesect[MAXANIMATES]; -extern int animatetarget[MAXANIMATES]; -extern int8_t animatetype[MAXANIMATES]; -extern double animategoal[MAXANIMATES]; -extern double animatevel[MAXANIMATES]; + +struct animate +{ + sectortype* sect; + int target; + int8_t type; + double goal; + double vel; + +}; + +extern TArray animates; extern sectortype* clouds[256]; extern float cloudx; diff --git a/source/games/duke/src/savegame.cpp b/source/games/duke/src/savegame.cpp index 096717a70..b1181c137 100644 --- a/source/games/duke/src/savegame.cpp +++ b/source/games/duke/src/savegame.cpp @@ -340,6 +340,21 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, Cycler& w, Cycler* return arc; } +FSerializer& Serialize(FSerializer& arc, const char* keyname, animate& w, animate* def) +{ + static animate nul; + if (!def) def = &nul; + if (arc.BeginObject(keyname)) + { + arc("sector", w.sect, def->sect) + ("type", w.type, def->type) + ("target", w.target, def->target) + ("goal", w.goal, def->goal) + ("vel", w.vel, def->vel) + .EndObject(); + } + return arc; +} void GameInterface::SerializeGameState(FSerializer& arc) { @@ -387,13 +402,7 @@ void GameInterface::SerializeGameState(FSerializer& arc) ("gs.impact_damage", gs.impact_damage) ("numplayersprites", numplayersprites) ("spriteqloc", spriteqloc) - ("animatecnt", animatecnt) - - .Array("animatesect", animatesect, animatecnt) - .Array("animatetype", animatetype, animatecnt) - .Array("animatetarget", animatetarget, animatecnt) - .Array("animategoal", animategoal, animatecnt) - .Array("animatevel", animatevel, animatecnt) + ("animates", animates) ("numclouds", numclouds) ("cloudx", cloudx) diff --git a/source/games/duke/src/sectors.cpp b/source/games/duke/src/sectors.cpp index 592b2d293..0b6010982 100644 --- a/source/games/duke/src/sectors.cpp +++ b/source/games/duke/src/sectors.cpp @@ -128,8 +128,8 @@ int check_activator_motion(int lotag) { if (act->spr.lotag == lotag) { - for (int j = animatecnt - 1; j >= 0; j--) - if (act->sector() == animatesect[j]) + for (int j = animates.Size() - 1; j >= 0; j--) + if (act->sector() == animates[j].sect) return(1); DukeStatIterator it1(STAT_EFFECTOR); @@ -304,7 +304,7 @@ double getanimatevalue(int type, int index) double getanimatevalue(int i) { - return getanimatevalue(animatetype[i], animatetarget[i]); + return getanimatevalue(animates[i].type, animates[i].target); } //--------------------------------------------------------------------------- @@ -341,7 +341,7 @@ void setanimatevalue(int type, int index, double value) void setanimatevalue(int i, double value) { - return setanimatevalue(animatetype[i], animatetarget[i], value); + return setanimatevalue(animates[i].type, animates[i].target, value); } //--------------------------------------------------------------------------- @@ -352,25 +352,21 @@ void setanimatevalue(int i, double value) void doanimations(void) { - for (int i = animatecnt - 1; i >= 0; i--) + for (int i = animates.Size() - 1; i >= 0; i--) { double a = getanimatevalue(i); - double const v = animatevel[i] * TICSPERFRAME; - auto dasectp = animatesect[i]; + double const v = animates[i].vel * TICSPERFRAME; + auto dasectp = animates[i].sect; - if (a == animategoal[i]) + if (a == animates[i].goal) { - StopInterpolation(animatetarget[i], interptype[animatetype[i]]); + StopInterpolation(animates[i].target, interptype[animates[i].type]); - animatecnt--; - animatetype[i] = animatetype[animatecnt]; - animatetarget[i] = animatetarget[animatecnt]; - animategoal[i] = animategoal[animatecnt]; - animatevel[i] = animatevel[animatecnt]; - animatesect[i] = animatesect[animatecnt]; - dasectp = animatesect[i]; + animates[i] = animates.Last(); + animates.Pop(); + dasectp = animates[i].sect; if (dasectp->lotag == ST_18_ELEVATOR_DOWN || dasectp->lotag == ST_19_ELEVATOR_UP) - if (animatetype[i] == anim_ceilingz) + if (animates[i].type == anim_ceilingz) continue; if ((dasectp->lotag & 0xff) != ST_22_SPLITTING_DOOR) @@ -379,10 +375,10 @@ void doanimations(void) continue; } - if (v > 0) { a = min(a + v, animategoal[i]); } - else { a = max(a + v, animategoal[i]); } + if (v > 0) { a = min(a + v, animates[i].goal); } + else { a = max(a + v, animates[i].goal); } - if (animatetype[i] == anim_floorz) + if (animates[i].type == anim_floorz) { for (auto p = connecthead; p >= 0; p = connectpoint2[p]) if (ps[p].cursector == dasectp) @@ -420,8 +416,8 @@ int getanimationindex(int animtype, sectortype* animtargetp) j = -1; int animtarget = sectnum(animtargetp); - for (i = animatecnt - 1; i >= 0; i--) - if (animtype == animatetype[i] && animtarget == animatetarget[i]) + for (i = animates.Size() - 1; i >= 0; i--) + if (animtype == animates[i].type && animtarget == animates[i].target) { j = i; break; @@ -437,32 +433,28 @@ int getanimationindex(int animtype, sectortype* animtargetp) static int dosetanimation(sectortype* animsect, int animtype, int animtarget, double thegoal, double thevel) { - int i, j; + int j = -1; - if (animatecnt >= MAXANIMATES - 1) - return(-1); - - j = animatecnt; - for (i = 0; i < animatecnt; i++) - if (animtype == animatetype[i] && animtarget == animatetarget[i]) + for (unsigned i = 0; i < animates.Size(); i++) + if (animtype == animates[i].type && animtarget == animates[i].target) { j = i; break; } - auto animval = (int)getanimatevalue(animtype, animtarget); - animatesect[j] = animsect; - animatetype[j] = animtype; - animatetarget[j] = animtarget; - animategoal[j] = thegoal; + if (j == -1) j = animates.Reserve(1); + + auto animval = getanimatevalue(animtype, animtarget); + animates[j].sect = animsect; + animates[j].type = animtype; + animates[j].target = animtarget; + animates[j].goal = thegoal; if (thegoal >= animval) - animatevel[j] = thevel; + animates[j].vel = thevel; else - animatevel[j] = -thevel; + animates[j].vel = -thevel; - if (j == animatecnt) animatecnt++; - - StartInterpolation(animatetarget[i], interptype[animatetype[i]]); + StartInterpolation(animates[j].target, interptype[animates[j].type]); return(j); } @@ -790,10 +782,10 @@ static void handle_st21(sectortype* sptr, DDukeActor* actor) double j; if (i >= 0) { - if (animategoal[i] == sptr->ceilingz) - animategoal[i] = nextsectorneighborzptr(sptr, sptr->ceilingz, Find_FloorDown | Find_Safe)->floorz; - else animategoal[i] = sptr->ceilingz; - j = animategoal[i]; + if (animates[i].goal == sptr->ceilingz) + animates[i].goal = nextsectorneighborzptr(sptr, sptr->ceilingz, Find_FloorDown | Find_Safe)->floorz; + else animates[i].goal = sptr->ceilingz; + j = animates[i].goal; } else {