diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index 621031502..626b8ea2a 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -644,6 +644,7 @@ void movecrane(DDukeActor *actor, int crane) auto spri = actor->s; auto sectp = spri->sector(); int x; + auto& cpt = cranes[t[4]]; //t[0] = state //t[1] = checking sector number @@ -661,8 +662,8 @@ void movecrane(DDukeActor *actor, int crane) case STAT_ZOMBIEACTOR: case STAT_STANDABLE: case STAT_PLAYER: - spri->ang = getangle(msx[t[4] + 1] - spri->x, msy[t[4] + 1] - spri->y); - setsprite(a2, msx[t[4] + 1], msy[t[4] + 1], a2->s->z); + spri->ang = getangle(cpt.polex - spri->x, cpt.poley - spri->y); + setsprite(a2, cpt.polex, cpt.poley, a2->s->z); t[0]++; return; } @@ -758,7 +759,7 @@ void movecrane(DDukeActor *actor, int crane) if ((sectp->floorz - spri->z) > 8192) spri->picnum++; - if (spri->z < msx[t[4] + 2]) + if (spri->z < cpt.z) { t[0]++; spri->xvel = 0; @@ -770,16 +771,16 @@ void movecrane(DDukeActor *actor, int crane) { if (spri->xvel < 192) spri->xvel += 8; - spri->ang = getangle(msx[t[4]] - spri->x, msy[t[4]] - spri->y); + spri->ang = getangle(cpt.x - spri->x, cpt.y - spri->y); ssp(actor, CLIPMASK0); - if (((spri->x - msx[t[4]]) * (spri->x - msx[t[4]]) + (spri->y - msy[t[4]]) * (spri->y - msy[t[4]])) < (128 * 128)) + if (((spri->x - cpt.x) * (spri->x - cpt.x) + (spri->y - cpt.y) * (spri->y - cpt.y)) < (128 * 128)) t[0]++; } else if (t[0] == 9) t[0] = 0; - setsprite(ScriptIndexToActor(msy[t[4] + 2]), spri->x, spri->y, spri->z - (34 << 8)); + setsprite(cpt.poleactor, spri->x, spri->y, spri->z - (34 << 8)); auto Owner = actor->GetOwner(); if (Owner != nullptr || actor->IsActiveCrane()) diff --git a/source/games/duke/src/constants.h b/source/games/duke/src/constants.h index 2ada74e68..e0ebee802 100644 --- a/source/games/duke/src/constants.h +++ b/source/games/duke/src/constants.h @@ -267,6 +267,7 @@ enum MAXANIMATES = 1024, MAXANIMWALLS = 512, MAXANIMPOINTS = 2048, + MAXCRANES = 16, }; enum amoveflags_t diff --git a/source/games/duke/src/global.cpp b/source/games/duke/src/global.cpp index 9a1ceaa70..a7df7869b 100644 --- a/source/games/duke/src/global.cpp +++ b/source/games/duke/src/global.cpp @@ -87,6 +87,8 @@ int show_shareware; // display only. int rtsplaying; // RTS playback state int tempwallptr; // msx/y index. int msx[MAXANIMPOINTS], msy[MAXANIMPOINTS]; +TArray cranes; + bool sound445done; // used in checksectors_r. This was local state inside a function, but this must be maintained globally and serialized // serialized diff --git a/source/games/duke/src/global.h b/source/games/duke/src/global.h index 3a125611f..b87d5019b 100644 --- a/source/games/duke/src/global.h +++ b/source/games/duke/src/global.h @@ -120,7 +120,8 @@ extern int geocnt; extern short ambientlotag[64]; extern short ambienthitag[64]; extern unsigned ambientfx; -extern int msx[MAXANIMPOINTS], msy[MAXANIMPOINTS]; +extern int msx[MAXANIMPOINTS], msy[MAXANIMPOINTS]; // todo: unlimit +extern TArray cranes; extern int WindTime, WindDir; extern short fakebubba_spawn, mamaspawn_count, banjosound; extern short BellTime; diff --git a/source/games/duke/src/premap.cpp b/source/games/duke/src/premap.cpp index a9fd69054..0f4663381 100644 --- a/source/games/duke/src/premap.cpp +++ b/source/games/duke/src/premap.cpp @@ -420,6 +420,7 @@ void resetprestat(int snum,int g) paused = 0; ud.cameraactor =nullptr; tempwallptr = 0; + cranes.Clear(); camsprite =nullptr; earthquaketime = 0; diff --git a/source/games/duke/src/savegame.cpp b/source/games/duke/src/savegame.cpp index 55278b9b1..8879ffbd3 100644 --- a/source/games/duke/src/savegame.cpp +++ b/source/games/duke/src/savegame.cpp @@ -55,6 +55,21 @@ void lava_serialize(FSerializer& arc); void SerializeGameVars(FSerializer &arc); +FSerializer& Serialize(FSerializer& arc, const char* keyname, CraneDef& w, CraneDef* def) +{ + if (arc.BeginObject(keyname)) + { + arc("x", w.x) + ("y", w.y) + ("z", w.z) + ("polex", w.polex) + ("poley", w.poley) + ("pole", w.poleactor) + .EndObject(); + } + return arc; +} + FSerializer& Serialize(FSerializer& arc, const char* keyname, animwalltype& w, animwalltype* def) { if (arc.BeginObject(keyname)) @@ -373,6 +388,7 @@ void GameInterface::SerializeGameState(FSerializer& arc) .Array("sectorextra", sectorextra, numsectors) ("rtsplaying", rtsplaying) ("tempwallptr", tempwallptr) + ("cranes", cranes) ("sound445done", sound445done) .Array("players", ps, ud.multimode) ("spriteqamount", spriteqamount) diff --git a/source/games/duke/src/spawn.cpp b/source/games/duke/src/spawn.cpp index d4712a8ff..5eba8ded8 100644 --- a/source/games/duke/src/spawn.cpp +++ b/source/games/duke/src/spawn.cpp @@ -488,11 +488,12 @@ void initcrane(DDukeActor* actj, DDukeActor* acti, int CRANEPOLE) sp->picnum += 2; sp->z = sector[sect].ceilingz + (48 << 8); - t[4] = tempwallptr; + t[4] = cranes.Reserve(1); - msx[tempwallptr] = sp->x; - msy[tempwallptr] = sp->y; - msx[tempwallptr + 2] = sp->z; + auto& apt = cranes[t[4]]; + apt.x = sp->x; + apt.y = sp->y; + apt.z = sp->z; DukeStatIterator it(STAT_DEFAULT); while (auto act = it.Next()) @@ -500,15 +501,15 @@ void initcrane(DDukeActor* actj, DDukeActor* acti, int CRANEPOLE) auto ss = act->s; if (ss->picnum == CRANEPOLE && sp->hitag == (ss->hitag)) { - msy[tempwallptr + 2] = ActorToScriptIndex(act); + apt.poleactor = act; t[1] = ss->sectnum; ss->xrepeat = 48; ss->yrepeat = 128; - msx[tempwallptr + 1] = ss->x; - msy[tempwallptr + 1] = ss->y; + apt.polex = ss->x; + apt.poley = ss->y; ss->x = sp->x; ss->y = sp->y; @@ -520,7 +521,6 @@ void initcrane(DDukeActor* actj, DDukeActor* acti, int CRANEPOLE) } } - tempwallptr += 3; acti->SetOwner(nullptr); sp->extra = 8; changeactorstat(acti, STAT_STANDABLE); diff --git a/source/games/duke/src/types.h b/source/games/duke/src/types.h index e70fd75f2..14afdc6d1 100644 --- a/source/games/duke/src/types.h +++ b/source/games/duke/src/types.h @@ -160,6 +160,13 @@ struct player_orig short oa, os; }; +struct CraneDef +{ + int x, y, z; + int polex, poley; + DDukeActor* poleactor; +}; + struct player_struct { // This is basically the version from JFDuke but this first block contains a few changes to make it work with other parts of Raze.