diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 13e8e2fb9..099b83d64 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -771,7 +771,6 @@ set (PCH_SOURCES build/src/defs.cpp build/src/engine.cpp build/src/mdsprite.cpp - build/src/mhk.cpp build/src/polymost.cpp build/src/scriptfile.cpp build/src/voxmodel.cpp @@ -790,6 +789,7 @@ set (PCH_SOURCES core/gamecvars.cpp core/gamecontrol.cpp core/inputstate.cpp + core/maphack.cpp core/mapinfo.cpp core/searchpaths.cpp core/screenjob.cpp diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index 6598f3cab..562342e91 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -135,7 +135,6 @@ void StartLevel(MapRecord* level) } SECRET_SetMapName(currentLevel->DisplayName(), currentLevel->name); STAT_NewLevel(currentLevel->fileName); - G_LoadMapHack(currentLevel->fileName); wsrand(dbReadMapCRC(currentLevel->LabelName())); gKillMgr.Clear(); gSecretMgr.Clear(); diff --git a/source/blood/src/db.cpp b/source/blood/src/db.cpp index 20da50cca..4fac8c7aa 100644 --- a/source/blood/src/db.cpp +++ b/source/blood/src/db.cpp @@ -1049,6 +1049,8 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short fr.Seek(0, FileReader::SeekSet); auto buffer = fr.Read(); md4once(buffer.Data(), buffer.Size(), g_loadedMapHack.md4); + G_LoadMapHack(mapname); + if (CalcCRC32(buffer.Data(), buffer.Size() -4) != nCRC) { Printf("%s: Map File does not match CRC", mapname.GetChars()); diff --git a/source/build/include/build.h b/source/build/include/build.h index 3c5a0b9cf..5d3032894 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -267,16 +267,14 @@ EXTERN int32_t guniqhudid; EXTERN int32_t spritesortcnt; extern int32_t g_loadedMapVersion; -typedef struct { - char *mhkfile; - char *title; - uint8_t md4[16]; -} usermaphack_t; +struct usermaphack_t +{ + FString mhkfile; + FString title; + uint8_t md4[16]{}; +}; extern usermaphack_t g_loadedMapHack; -extern int compare_usermaphacks(const void *, const void *); -extern usermaphack_t *usermaphacks; -extern int32_t num_usermaphacks; #if !defined DEBUG_MAIN_ARRAYS EXTERN spriteext_t *spriteext; @@ -597,7 +595,6 @@ void initspritelists(void); int32_t engineLoadBoard(const char *filename, char flags, vec3_t *dapos, int16_t *daang, int16_t *dacursectnum); int32_t engineLoadMHK(const char *filename); void G_LoadMapHack(const char* filename); -void engineClearLightsFromMHK(); int32_t saveboard(const char *filename, const vec3_t *dapos, int16_t daang, int16_t dacursectnum); int32_t qloadkvx(int32_t voxindex, const char *filename); diff --git a/source/build/src/defs.cpp b/source/build/src/defs.cpp index 7083afc56..67e4b9ef6 100644 --- a/source/build/src/defs.cpp +++ b/source/build/src/defs.cpp @@ -18,6 +18,7 @@ #include "palettecontainer.h" #include "mapinfo.h" +void AddUserMapHack(usermaphack_t&); #if 0 // For later { @@ -2395,8 +2396,9 @@ static int32_t defsparser(scriptfile *script) case T_MAPINFO: { - FString mapmd4string, title, mhkfile, dummy; + FString mapmd4string; FScanner::SavedPos mapinfoend; + usermaphack_t mhk; static const tokenlist mapinfotokens[] = { { "mapfile", T_MAPFILE }, @@ -2404,7 +2406,6 @@ static int32_t defsparser(scriptfile *script) { "mapmd4", T_MAPMD4 }, { "mhkfile", T_MHKFILE }, }; - int32_t previous_usermaphacks = num_usermaphacks; if (scriptfile_getbraces(script,&mapinfoend)) break; while (script->textptr < mapinfoend.SavedScriptPtr) @@ -2412,38 +2413,29 @@ static int32_t defsparser(scriptfile *script) switch (getatoken(script,mapinfotokens,countof(mapinfotokens))) { case T_MAPFILE: - scriptfile_getstring(script,&dummy); + scriptfile_getstring(script,nullptr); break; case T_MAPTITLE: - scriptfile_getstring(script,&title); + scriptfile_getstring(script,&mhk.title); break; case T_MAPMD4: { scriptfile_getstring(script,&mapmd4string); - num_usermaphacks++; - usermaphacks = (usermaphack_t *)Xrealloc(usermaphacks, num_usermaphacks*sizeof(usermaphack_t)); - usermaphack_t *newusermaphack = &usermaphacks[num_usermaphacks - 1]; - for (int i = 0; i < 16; i++) { char smallbuf[3] = { mapmd4string[2 * i], mapmd4string[2 * i + 1], 0 }; - newusermaphack->md4[i] = strtol(smallbuf, NULL, 16); + mhk.md4[i] = strtol(smallbuf, NULL, 16); } break; } case T_MHKFILE: - scriptfile_getstring(script,&mhkfile); + scriptfile_getstring(script,&mhk.mhkfile); break; } } - - for (; previous_usermaphacks < num_usermaphacks; previous_usermaphacks++) - { - usermaphacks[previous_usermaphacks].mhkfile = mhkfile.IsNotEmpty() ? Xstrdup(mhkfile) : NULL; - usermaphacks[previous_usermaphacks].title = title.IsNotEmpty() ? Xstrdup(title) : NULL; - } + AddUserMapHack(mhk); } break; @@ -3452,9 +3444,6 @@ int32_t loaddefinitionsfile(const char *fn) DO_FREE_AND_NULL(faketilebuffer); faketilebuffersiz = 0; - if (usermaphacks != NULL) - qsort(usermaphacks, num_usermaphacks, sizeof(usermaphack_t), compare_usermaphacks); - if (!script) return -1; Printf(PRINT_NONOTIFY, "\n"); diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index faeba724f..78f05c08c 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -1025,14 +1025,6 @@ void engineUnInit(void) # endif TileFiles.CloseAll(); - - for (bssize_t i = 0; i < num_usermaphacks; i++) - { - Xfree(usermaphacks[i].mhkfile); - Xfree(usermaphacks[i].title); - } - DO_FREE_AND_NULL(usermaphacks); - num_usermaphacks = 0; } @@ -1987,6 +1979,9 @@ static FORCE_INLINE int32_t have_maptext(void) static void enginePrepareLoadBoard(FileReader & fr, vec3_t *dapos, int16_t *daang, int16_t *dacursectnum) { + memset(spriteext, 0, sizeof(spriteext_t) * MAXSPRITES); + memset(spritesmooth, 0, sizeof(spritesmooth_t) * (MAXSPRITES + MAXUNIQHUDID)); + initspritelists(); ClearAutomap(); @@ -2004,7 +1999,7 @@ static void enginePrepareLoadBoard(FileReader & fr, vec3_t *dapos, int16_t *daan } } -static int32_t engineFinishLoadBoard(const vec3_t *dapos, int16_t *dacursectnum, int16_t numsprites, char myflags) +static int32_t engineFinishLoadBoard(const char *filename, const vec3_t *dapos, int16_t *dacursectnum, int16_t numsprites, char myflags) { int32_t i, realnumsprites=numsprites, numremoved; @@ -2077,6 +2072,8 @@ static int32_t engineFinishLoadBoard(const vec3_t *dapos, int16_t *dacursectnum, guniqhudid = 0; + G_LoadMapHack(filename); + return numremoved; } @@ -2299,7 +2296,7 @@ int32_t engineLoadBoard(const char *filename, char flags, vec3_t *dapos, int16_t artSetupMapArt(filename); } - return engineFinishLoadBoard(dapos, dacursectnum, numsprites, myflags); + return engineFinishLoadBoard(filename, dapos, dacursectnum, numsprites, myflags); } @@ -2487,7 +2484,7 @@ int32_t engineLoadBoardV5V6(const char *filename, char fromwhere, vec3_t *dapos, g_loadedMapVersion = mapversion; - return engineFinishLoadBoard(dapos, dacursectnum, numsprites, 0); + return engineFinishLoadBoard(filename, dapos, dacursectnum, numsprites, 0); } diff --git a/source/build/src/mhk.cpp b/source/build/src/mhk.cpp deleted file mode 100644 index 8d0a4a0bc..000000000 --- a/source/build/src/mhk.cpp +++ /dev/null @@ -1,444 +0,0 @@ - -#include "compat.h" -#include "build.h" -#include "scriptfile.h" -#include "printf.h" - -usermaphack_t g_loadedMapHack; // used only for the MD4 part - -int compare_usermaphacks(const void *a, const void *b) -{ - return memcmp(((usermaphack_t const *) a)->md4, ((usermaphack_t const *) b)->md4, 16); -} -usermaphack_t *usermaphacks; -int32_t num_usermaphacks; - -#ifdef POLYMER -static int16_t maphacklightcnt=0; -static int16_t maphacklight[PR_MAXLIGHTS]; - -void engineClearLightsFromMHK() -{ - int32_t i; - for (i=0; i= 0) - polymer_deletelight(maphacklight[i]); - maphacklight[i] = -1; - } - - maphacklightcnt = 0; -} -#else -void engineClearLightsFromMHK() {} -#endif - -// -// loadmaphack -// -int32_t engineLoadMHK(const char *filename) -{ - enum - { - T_SPRITE = 0, - T_ANGOFF, - T_NOMODEL, - T_NOANIM, - T_PITCH, - T_ROLL, - T_MDPIVOTXOFF, - T_MDPIVOTYOFF, - T_MDPIVOTZOFF, - T_MDPOSITIONXOFF, - T_MDPOSITIONYOFF, - T_MDPOSITIONZOFF, - T_AWAY1, - T_AWAY2, - T_MHKRESET, - T_LIGHT, - }; - - static struct { const char *text; int32_t tokenid; } legaltokens [] = - { - { "sprite", T_SPRITE }, - { "angleoff", T_ANGOFF }, - { "angoff", T_ANGOFF }, - { "notmd2", T_NOMODEL }, - { "notmd3", T_NOMODEL }, - { "notmd", T_NOMODEL }, - { "nomd2anim", T_NOANIM }, - { "nomd3anim", T_NOANIM }, - { "nomdanim", T_NOANIM }, - { "pitch", T_PITCH }, - { "roll", T_ROLL }, - { "mdxoff", T_MDPIVOTXOFF }, - { "mdyoff", T_MDPIVOTYOFF }, - { "mdzoff", T_MDPIVOTZOFF }, - { "mdpivxoff", T_MDPIVOTXOFF }, - { "mdpivyoff", T_MDPIVOTYOFF }, - { "mdpivzoff", T_MDPIVOTZOFF }, - { "mdpivotxoff", T_MDPIVOTXOFF }, - { "mdpivotyoff", T_MDPIVOTYOFF }, - { "mdpivotzoff", T_MDPIVOTZOFF }, - { "mdposxoff", T_MDPOSITIONXOFF }, - { "mdposyoff", T_MDPOSITIONYOFF }, - { "mdposzoff", T_MDPOSITIONZOFF }, - { "mdpositionxoff", T_MDPOSITIONXOFF }, - { "mdpositionyoff", T_MDPOSITIONYOFF }, - { "mdpositionzoff", T_MDPOSITIONZOFF }, - { "away1", T_AWAY1 }, - { "away2", T_AWAY2 }, - { "mhkreset", T_MHKRESET }, - { "light", T_LIGHT }, - { NULL, -1 } - }; - - scriptfile *script = NULL; - char *tok, *cmdtokptr; - int32_t i; - int32_t whichsprite = -1; - static char fn[BMAX_PATH]; - -#ifdef POLYMER - int32_t toomanylights = 0; - - engineClearLightsFromMHK(); -#endif - - if (filename) - { - memset(spriteext, 0, sizeof(spriteext_t) * MAXSPRITES); - memset(spritesmooth, 0, sizeof(spritesmooth_t) *(MAXSPRITES+MAXUNIQHUDID)); - strcpy(fn, filename); - script = scriptfile_fromfile(filename); - } - else if (fn[0]) - { - // re-load - // XXX: what if we changed between levels? Could a wrong maphack be loaded? - script = scriptfile_fromfile(fn); - } - - if (!script) - { - fn[0] = 0; - return -1; - } - - while (1) - { - tok = scriptfile_gettoken(script); - if (!tok) break; - for (i=0; legaltokens[i].text; i++) if (!stricmp(tok, legaltokens[i].text)) break; - cmdtokptr = script->ltextptr; - - if (!filename && legaltokens[i].tokenid != T_LIGHT) continue; - - switch (legaltokens[i].tokenid) - { - case T_SPRITE: // sprite - if (scriptfile_getnumber(script, &whichsprite)) break; - - if ((unsigned) whichsprite >= (unsigned) MAXSPRITES) - { - // sprite number out of range - Printf("Sprite number out of range 0-%d on line %s:%d\n", - MAXSPRITES-1, script->filename, scriptfile_getlinum(script, cmdtokptr)); - whichsprite = -1; - break; - } - - break; - case T_ANGOFF: // angoff - { - int32_t ang; - if (scriptfile_getnumber(script, &ang)) break; - - if (whichsprite < 0) - { - // no sprite directive preceeding - Printf("Ignoring angle offset directive because of absent/invalid sprite number on line %s:%d\n", - script->filename, scriptfile_getlinum(script, cmdtokptr)); - break; - } - spriteext[whichsprite].angoff = (int16_t) ang; - } - break; - case T_NOMODEL: // notmd - if (whichsprite < 0) - { - // no sprite directive preceeding - Printf("Ignoring not-MD2/MD3 directive because of absent/invalid sprite number on line %s:%d\n", - script->filename, scriptfile_getlinum(script, cmdtokptr)); - break; - } - spriteext[whichsprite].flags |= SPREXT_NOTMD; - break; - case T_NOANIM: // nomdanim - if (whichsprite < 0) - { - // no sprite directive preceeding - Printf("Ignoring no-MD2/MD3-anim directive because of absent/invalid sprite number on line %s:%d\n", - script->filename, scriptfile_getlinum(script, cmdtokptr)); - break; - } - spriteext[whichsprite].flags |= SPREXT_NOMDANIM; - break; - case T_PITCH: // pitch - { - int32_t pitch; - if (scriptfile_getnumber(script, &pitch)) break; - - if (whichsprite < 0) - { - // no sprite directive preceeding - Printf("Ignoring pitch directive because of absent/invalid sprite number on line %s:%d\n", - script->filename, scriptfile_getlinum(script, cmdtokptr)); - break; - } - spriteext[whichsprite].pitch = (int16_t) pitch; - } - break; - case T_ROLL: // roll - { - int32_t roll; - if (scriptfile_getnumber(script, &roll)) break; - - if (whichsprite < 0) - { - // no sprite directive preceeding - Printf("Ignoring roll directive because of absent/invalid sprite number on line %s:%d\n", - script->filename, scriptfile_getlinum(script, cmdtokptr)); - break; - } - spriteext[whichsprite].roll = (int16_t) roll; - } - break; - case T_MDPIVOTXOFF: // mdpivxoff - { - int32_t i; - if (scriptfile_getnumber(script, &i)) break; - - if (whichsprite < 0) - { - // no sprite directive preceeding - Printf("Ignoring mdxoff/mdpivxoff directive because of absent/invalid sprite number on line %s:%d\n", - script->filename, scriptfile_getlinum(script, cmdtokptr)); - break; - } - spriteext[whichsprite].pivot_offset.x = i; - } - break; - case T_MDPIVOTYOFF: // mdpivyoff - { - int32_t i; - if (scriptfile_getnumber(script, &i)) break; - - if (whichsprite < 0) - { - // no sprite directive preceeding - Printf("Ignoring mdyoff/mdpivyoff directive because of absent/invalid sprite number on line %s:%d\n", - script->filename, scriptfile_getlinum(script, cmdtokptr)); - break; - } - spriteext[whichsprite].pivot_offset.y = i; - } - break; - case T_MDPIVOTZOFF: // mdpivzoff - { - int32_t i; - if (scriptfile_getnumber(script, &i)) break; - - if (whichsprite < 0) - { - // no sprite directive preceeding - Printf("Ignoring mdzoff/mdpivzoff directive because of absent/invalid sprite number on line %s:%d\n", - script->filename, scriptfile_getlinum(script, cmdtokptr)); - break; - } - spriteext[whichsprite].pivot_offset.z = i; - } - break; - case T_MDPOSITIONXOFF: // mdposxoff - { - int32_t i; - if (scriptfile_getnumber(script, &i)) break; - - if (whichsprite < 0) - { - // no sprite directive preceeding - Printf("Ignoring mdposxoff directive because of absent/invalid sprite number on line %s:%d\n", - script->filename, scriptfile_getlinum(script, cmdtokptr)); - break; - } - spriteext[whichsprite].position_offset.x = i; - } - break; - case T_MDPOSITIONYOFF: // mdposyoff - { - int32_t i; - if (scriptfile_getnumber(script, &i)) break; - - if (whichsprite < 0) - { - // no sprite directive preceeding - Printf("Ignoring mdposyoff directive because of absent/invalid sprite number on line %s:%d\n", - script->filename, scriptfile_getlinum(script, cmdtokptr)); - break; - } - spriteext[whichsprite].position_offset.y = i; - } - break; - case T_MDPOSITIONZOFF: // mdposzoff - { - int32_t i; - if (scriptfile_getnumber(script, &i)) break; - - if (whichsprite < 0) - { - // no sprite directive preceeding - Printf("Ignoring mdposzoff directive because of absent/invalid sprite number on line %s:%d\n", - script->filename, scriptfile_getlinum(script, cmdtokptr)); - break; - } - spriteext[whichsprite].position_offset.z = i; - } - break; - case T_AWAY1: // away1 - if (whichsprite < 0) - { - // no sprite directive preceeding - Printf("Ignoring moving away directive because of absent/invalid sprite number on line %s:%d\n", - script->filename, scriptfile_getlinum(script, cmdtokptr)); - break; - } - spriteext[whichsprite].flags |= SPREXT_AWAY1; - break; - case T_AWAY2: // away2 - if (whichsprite < 0) - { - // no sprite directive preceeding - Printf("Ignoring moving away directive because of absent/invalid sprite number on line %s:%d\n", - script->filename, scriptfile_getlinum(script, cmdtokptr)); - break; - } - spriteext[whichsprite].flags |= SPREXT_AWAY2; - break; - case T_MHKRESET: // mhkreset - { - if (whichsprite < 0) - { - // no sprite directive preceeding - Printf("Ignoring mhkreset directive because of absent/invalid sprite number on line %s:%d\n", - script->filename, scriptfile_getlinum(script, cmdtokptr)); - break; - } - auto pSpriteExt = &spriteext[whichsprite]; - pSpriteExt->angoff = 0; - pSpriteExt->flags &= ~(SPREXT_NOTMD|SPREXT_NOMDANIM|SPREXT_AWAY1|SPREXT_AWAY2); - pSpriteExt->pitch = 0; - pSpriteExt->roll = 0; - pSpriteExt->pivot_offset = {}; - pSpriteExt->position_offset = {}; - break; - } -#ifdef POLYMER - case T_LIGHT: // light sector x y z range r g b radius faderadius angle horiz minshade maxshade priority tilenum - { - int32_t value; - int16_t lightid; -#pragma pack(push,1) - _prlight light; -#pragma pack(pop) - if (toomanylights) - break; // ignore further light defs - - scriptfile_getnumber(script, &value); - light.sector = value; - scriptfile_getnumber(script, &value); - light.x = value; - scriptfile_getnumber(script, &value); - light.y = value; - scriptfile_getnumber(script, &value); - light.z = value; - scriptfile_getnumber(script, &value); - light.range = value; - scriptfile_getnumber(script, &value); - light.color[0] = value; - scriptfile_getnumber(script, &value); - light.color[1] = value; - scriptfile_getnumber(script, &value); - light.color[2] = value; - scriptfile_getnumber(script, &value); - light.radius = value; - scriptfile_getnumber(script, &value); - light.faderadius = value; - scriptfile_getnumber(script, &value); - light.angle = value; - scriptfile_getnumber(script, &value); - light.horiz = value; - scriptfile_getnumber(script, &value); - light.minshade = value; - scriptfile_getnumber(script, &value); - light.maxshade = value; - scriptfile_getnumber(script, &value); - light.priority = value; - scriptfile_getsymbol(script, &value); - light.tilenum = value; - - light.publicflags.emitshadow = 1; - light.publicflags.negative = 0; - - if (videoGetRenderMode() == REND_POLYMER) - { - if (maphacklightcnt == PR_MAXLIGHTS) - { - Printf("warning: max light count %d exceeded, " - "ignoring further light defs\n", PR_MAXLIGHTS); - toomanylights = 1; - break; - } - - lightid = polymer_addlight(&light); - if (lightid>=0) - maphacklight[maphacklightcnt++] = lightid; - } - - break; - } -#endif // POLYMER - - default: - // unrecognised token - break; - } - } - - scriptfile_close(script); - return 0; -} - -// taken out of the game modules - this code was repeated in all of them. -static int G_TryMapHack(const char* mhkfile) -{ - int const failure = engineLoadMHK(mhkfile); - - if (!failure) - Printf("Loaded map hack file \"%s\"\n", mhkfile); - - return failure; -} - -void G_LoadMapHack(const char* filename) -{ - FString hack = StripExtension(filename) + ".mhk"; - - if (G_TryMapHack(hack) && usermaphacks != NULL) - { - auto pMapInfo = (usermaphack_t*)bsearch(&g_loadedMapHack, usermaphacks, num_usermaphacks, - sizeof(usermaphack_t), compare_usermaphacks); - if (pMapInfo) - G_TryMapHack(pMapInfo->mhkfile); - } -} - diff --git a/source/core/maphack.cpp b/source/core/maphack.cpp new file mode 100644 index 000000000..fb9317922 --- /dev/null +++ b/source/core/maphack.cpp @@ -0,0 +1,219 @@ +/* +** maphack.cpp +** +** Newly implemented map hack loader, based on sc_man. +** +**--------------------------------------------------------------------------- +** Copyright 2020 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ +#include "build.h" +#include "sc_man.h" +#include "printf.h" + +usermaphack_t g_loadedMapHack; // used only for the MD4 part +static TArray usermaphacks; + +void AddUserMapHack(usermaphack_t& mhk) +{ + usermaphacks.Push(mhk); +} + +static int32_t LoadMapHack(const char *filename) +{ + int32_t currentsprite = -1; + + FScanner sc; + int lump = fileSystem.FindFile(filename); + if (lump < 0) + { + return -1; + } + sc.OpenLumpNum(lump); + + while (sc.GetString()) + { + FString token = sc.String; + int currentsprite = -1; + auto validateSprite = [&]() + { + if (currentsprite < 0) + { + sc.ScriptMessage("Using %s without a valid sprite", token.GetChars()); + return false; + } + return true; + }; + + if (sc.Compare("sprite")) + { + if (sc.CheckNumber()) + { + currentsprite = sc.Number; + if (currentsprite < 0 || currentsprite >= MAXSPRITES) + { + sc.ScriptMessage("Invalid sprite number %d", currentsprite); + currentsprite = -1; + } + } + else currentsprite = -1; + } + else if (sc.Compare("angleoff") || sc.Compare("angoff")) + { + if (sc.CheckNumber() && validateSprite()) + spriteext[currentsprite].angoff = (int16_t)sc.Number; + } + else if (sc.Compare("notmd") || sc.Compare("motmd2") || sc.Compare("motmd3")) + { + if (validateSprite()) + spriteext[currentsprite].flags |= SPREXT_NOTMD; + } + else if (sc.Compare("nomdanim") || sc.Compare("nomd2anim") || sc.Compare("nomd3anim")) + { + if (validateSprite()) + spriteext[currentsprite].flags |= SPREXT_NOMDANIM; + } + else if (sc.Compare("pitch")) + { + if (sc.CheckNumber() && validateSprite()) + spriteext[currentsprite].pitch = (int16_t)sc.Number; + } + else if (sc.Compare("roll")) + { + if (sc.CheckNumber() && validateSprite()) + spriteext[currentsprite].pitch = (int16_t)sc.Number; + } + else if (sc.Compare("mdxoff") || sc.Compare("mdpivxoff") || sc.Compare("mdpivotxoff")) + { + if (sc.CheckNumber() && validateSprite()) + spriteext[currentsprite].pivot_offset.x = sc.Number; + } + else if (sc.Compare("mdyoff") || sc.Compare("mdpivyoff") || sc.Compare("mdpivotyoff")) + { + if (sc.CheckNumber() && validateSprite()) + spriteext[currentsprite].pivot_offset.y = sc.Number; + } + else if (sc.Compare("mdzoff") || sc.Compare("mdpivzoff") || sc.Compare("mdpivotzoff")) + { + if (sc.CheckNumber() && validateSprite()) + spriteext[currentsprite].pivot_offset.z = sc.Number; + } + else if (sc.Compare("mdposxoff") || sc.Compare("mdpositionxoff")) + { + if (sc.CheckNumber() && validateSprite()) + spriteext[currentsprite].position_offset.x = sc.Number; + } + else if (sc.Compare("mdposyoff") || sc.Compare("mdpositionyoff")) + { + if (sc.CheckNumber() && validateSprite()) + spriteext[currentsprite].position_offset.x = sc.Number; + } + else if (sc.Compare("mdposzoff") || sc.Compare("mdpositionzoff")) + { + if (sc.CheckNumber() && validateSprite()) + spriteext[currentsprite].position_offset.x = sc.Number; + } + else if (sc.Compare("away1")) + { + if (validateSprite()) + spriteext[currentsprite].flags |= SPREXT_AWAY1; + } + else if (sc.Compare("away2")) + { + if (validateSprite()) + spriteext[currentsprite].flags |= SPREXT_AWAY2; + } + else if (sc.Compare("mhkreset")) + { + if (validateSprite()) + { + auto& sx = spriteext[currentsprite]; + sx.angoff = 0; + sx.flags &= ~(SPREXT_NOTMD | SPREXT_NOMDANIM | SPREXT_AWAY1 | SPREXT_AWAY2); + sx.pitch = 0; + sx.roll = 0; + sx.pivot_offset = {}; + sx.position_offset = {}; + } + } + else if (sc.Compare("light")) + { + // skip over it - once lights are working this should be reactivated. Assignments were kept as documentation. + sc.MustGetNumber(); + //light.sector= sc.Number; + sc.MustGetNumber(); + //light.x= sc.Number; + sc.MustGetNumber(); + //light.y= sc.Number; + sc.MustGetNumber(); + //light.z= sc.Number; + sc.MustGetNumber(); + //light.range= sc.Number; + sc.MustGetNumber(); + //light.color[0]= sc.Number; + sc.MustGetNumber(); + //light.color[1]= sc.Number; + sc.MustGetNumber(); + //light.color[2]= sc.Number; + sc.MustGetNumber(); + //light.radius= sc.Number; + sc.MustGetNumber(); + //light.faderadius= sc.Number; + sc.MustGetNumber(); + //light.angle= sc.Number; + sc.MustGetNumber(); + //light.horiz= sc.Number; + sc.MustGetNumber(); + //light.minshade= sc.Number; + sc.MustGetNumber(); + //light.maxshade= sc.Number; + sc.MustGetNumber(); + //light.priority= sc.Number; + sc.MustGetString(); + //light.tilenum= sc.Number; + } + } + return 0; +} + +void G_LoadMapHack(const char* filename) +{ + FString hack = StripExtension(filename) + ".mhk"; + + if (LoadMapHack(hack)) + { + for (auto& mhk : usermaphacks) + { + if (!memcmp(g_loadedMapHack.md4, mhk.md4, 16)) + { + LoadMapHack(mhk.mhkfile); + } + } + } +} + diff --git a/source/games/duke/src/premap.cpp b/source/games/duke/src/premap.cpp index f0c517c26..ea3e1978b 100644 --- a/source/games/duke/src/premap.cpp +++ b/source/games/duke/src/premap.cpp @@ -871,7 +871,6 @@ static int LoadTheMap(MapRecord *mi, struct player_struct *p, int gamemode) currentLevel = mi; SECRET_SetMapName(mi->DisplayName(), mi->name); STAT_NewLevel(mi->fileName); - G_LoadMapHack(mi->fileName); if (isRR() && !isRRRA() && mi->levelNumber == levelnum(1, 1)) {