mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-15 00:42:08 +00:00
- added true level compatibility map processing and deleted all related map hack code.
This commit is contained in:
parent
a6af6b88df
commit
0e113dab79
23 changed files with 133 additions and 149 deletions
|
@ -163,107 +163,6 @@ static int32_t LoadMapHack(const char *filename, SpawnSpriteDef& sprites)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("picnum"))
|
||||
{
|
||||
if (sc.CheckNumber())
|
||||
{
|
||||
if (currentwall != -1 && validateWall())
|
||||
{
|
||||
wall[currentwall].picnum = sc.Number;
|
||||
}
|
||||
else if (currentsprite != -1 && validateSprite())
|
||||
{
|
||||
sprites.sprites[currentsprite].picnum = sc.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("overpicnum"))
|
||||
{
|
||||
if (sc.CheckNumber() && validateWall())
|
||||
{
|
||||
wall[currentwall].overpicnum = sc.Number;
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("overpicnum"))
|
||||
{
|
||||
if (sc.CheckNumber() && validateWall())
|
||||
{
|
||||
wall[currentwall].overpicnum = sc.Number;
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("split"))
|
||||
{
|
||||
int start = -1, end = -1;
|
||||
if (sc.CheckNumber()) start = sc.Number;
|
||||
if (sc.CheckNumber()) end = sc.Number;
|
||||
if (end >= 0 && validateSector())
|
||||
{
|
||||
hw_SetSplitSector(currentsector, start, end);
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("dontclip"))
|
||||
{
|
||||
sector[currentsector].exflags |= SECTOREX_DONTCLIP;
|
||||
}
|
||||
else if (sc.Compare("clearflags"))
|
||||
{
|
||||
if (currentsector != -1 && validateSector())
|
||||
{
|
||||
sc.GetString();
|
||||
if (sc.Compare("floor") && sc.CheckNumber())
|
||||
{
|
||||
sector[currentsector].floorstat &= ESectorFlags::FromInt(~sc.Number);
|
||||
}
|
||||
else if (sc.Compare("ceiling") && sc.CheckNumber())
|
||||
{
|
||||
sector[currentsector].ceilingstat &= ESectorFlags::FromInt(~sc.Number);
|
||||
}
|
||||
else sc.ScriptError("Bad token %s", sc.String);
|
||||
}
|
||||
else if (sc.CheckNumber())
|
||||
{
|
||||
if (currentwall != -1 && validateWall())
|
||||
{
|
||||
wall[currentwall].cstat &= EWallFlags::FromInt(~sc.Number);
|
||||
}
|
||||
else if (currentsprite != -1 && validateSprite())
|
||||
{
|
||||
sprites.sprites[currentsprite].cstat &= ESpriteFlags::FromInt(~sc.Number);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("setflags"))
|
||||
{
|
||||
if (sc.CheckNumber())
|
||||
{
|
||||
if (currentwall != -1 && validateWall())
|
||||
{
|
||||
wall[currentwall].cstat |= EWallFlags::FromInt(sc.Number);
|
||||
}
|
||||
else if (currentsprite != -1 && validateSprite())
|
||||
{
|
||||
sprites.sprites[currentsprite].cstat |= ESpriteFlags::FromInt(sc.Number);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("lotag"))
|
||||
{
|
||||
if (sc.CheckNumber())
|
||||
{
|
||||
if (currentwall != -1 && validateWall())
|
||||
{
|
||||
wall[currentwall].lotag = sc.Number;
|
||||
}
|
||||
else if (currentsprite != -1 && validateSprite())
|
||||
{
|
||||
sprites.sprites[currentsprite].lotag = sc.Number;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("sw_serp_continue")) // This is a hack for SW's Last Warrior mod to continue from L4 to L5.
|
||||
{
|
||||
if (currentLevel) currentLevel->gameflags |= LEVEL_SW_DEATHEXIT_SERPENT_NEXT;
|
||||
}
|
||||
|
||||
else if (sc.Compare("angleoff") || sc.Compare("angoff"))
|
||||
{
|
||||
|
@ -383,8 +282,6 @@ static int32_t LoadMapHack(const char *filename, SpawnSpriteDef& sprites)
|
|||
|
||||
void loadMapHack(const char* filename, const uint8_t* md4, SpawnSpriteDef& sprites)
|
||||
{
|
||||
hw_ClearSplitSector();
|
||||
|
||||
FString internal = "engine/compatibility/";
|
||||
for (int j = 0; j < 16; ++j)
|
||||
{
|
||||
|
|
|
@ -543,6 +543,7 @@ void loadMap(const char* filename, int flags, DVector3* pos, int16_t* ang, secto
|
|||
auto buffer = fr.Read();
|
||||
uint8_t md4[16];
|
||||
md4once(buffer.Data(), buffer.Size(), md4);
|
||||
PostProcessLevel(md4, filename, sprites);
|
||||
loadMapHack(filename, md4, sprites);
|
||||
setWallSectors();
|
||||
hw_CreateSections();
|
||||
|
|
|
@ -698,6 +698,7 @@ TArray<walltype> loadMapWalls(const char* filename);
|
|||
void loadMapBackup(const char* filename);
|
||||
void loadMapHack(const char* filename, const uint8_t*, SpawnSpriteDef& sprites);
|
||||
void validateStartSector(const char* filename, const DVector3& pos, sectortype** cursectnum, unsigned numsectors, bool noabort = false);
|
||||
void PostProcessLevel(const uint8_t* checksum, const FString& mapname, SpawnSpriteDef& sprites);
|
||||
|
||||
// should only be used to read angles from map-loaded data (for proper documentation)
|
||||
constexpr DAngle mapangle(int mapang)
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
#include "vm.h"
|
||||
#include "printf.h"
|
||||
#include "types.h"
|
||||
#include "maptypes.h"
|
||||
#include "hw_sections.h"
|
||||
#include "mapinfo.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -48,13 +51,21 @@ class DLevelPostProcessor : public DObject
|
|||
{
|
||||
DECLARE_ABSTRACT_CLASS(DLevelPostProcessor, DObject)
|
||||
public:
|
||||
SpawnSpriteDef* sprites;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLASS(DLevelPostProcessor, true, false);
|
||||
|
||||
void PostProcessLevel(FName checksum, const FString& mapname)
|
||||
void PostProcessLevel(const uint8_t* md4, const FString& mapname, SpawnSpriteDef& sprites)
|
||||
{
|
||||
hw_ClearSplitSector();
|
||||
auto lc = Create<DLevelPostProcessor>();
|
||||
lc->sprites = &sprites;
|
||||
|
||||
char md4string[33];
|
||||
for (int i = 0; i < 16; i++) mysnprintf(md4string + 2 * i, 3, "%02x", md4[i]);
|
||||
FName checksum(md4string, true);
|
||||
if (checksum == NAME_None) return; // we do not have anything so save the work.
|
||||
|
||||
for(auto cls : PClass::AllClasses)
|
||||
{
|
||||
|
@ -83,21 +94,47 @@ void PostProcessLevel(FName checksum, const FString& mapname)
|
|||
DEFINE_ACTION_FUNCTION(DLevelPostProcessor, SetSpriteLotag)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DLevelPostProcessor);
|
||||
PARAM_INT(sprite);
|
||||
PARAM_UINT(sprite);
|
||||
PARAM_INT(lotag);
|
||||
|
||||
// todo
|
||||
if (sprite < self->sprites->sprites.Size())
|
||||
self->sprites->sprites[sprite].lotag = lotag;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DLevelPostProcessor, ChangeSpriteFlags)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DLevelPostProcessor);
|
||||
PARAM_INT(sprite);
|
||||
PARAM_UINT(sprite);
|
||||
PARAM_INT(clearmask);
|
||||
PARAM_INT(setflag);
|
||||
PARAM_INT(setmask);
|
||||
|
||||
if (sprite < self->sprites->sprites.Size())
|
||||
self->sprites->sprites[sprite].cstat = (self->sprites->sprites[sprite].cstat & ~ESpriteFlags::FromInt(clearmask)) | ESpriteFlags::FromInt(setmask);
|
||||
|
||||
// todo
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DLevelPostProcessor, SplitSector)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DLevelPostProcessor);
|
||||
PARAM_UINT(sectornum);
|
||||
PARAM_INT(firstwall);
|
||||
PARAM_INT(secondwall);
|
||||
|
||||
if (sectornum < sector.Size())
|
||||
{
|
||||
if (firstwall >= sector[sectornum].wallptr && firstwall < sector[sectornum].wallptr + sector[sectornum].wallnum &&
|
||||
secondwall >= sector[sectornum].wallptr && secondwall < sector[sectornum].wallptr + sector[sectornum].wallnum)
|
||||
|
||||
hw_SetSplitSector(sectornum, firstwall, secondwall);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DLevelPostProcessor, sw_serp_continue)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DLevelPostProcessor);
|
||||
currentLevel->gameflags |= LEVEL_SW_DEATHEXIT_SERPENT_NEXT;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -293,7 +293,7 @@ void InitThingdef()
|
|||
//secplanestruct->Size = sizeof(secplane_t);
|
||||
//secplanestruct->Align = alignof(secplane_t);
|
||||
|
||||
auto sectorstruct = NewStruct("Sector", nullptr, true);
|
||||
auto sectorstruct = NewStruct("sectortype", nullptr, true);
|
||||
sectorstruct->Size = sizeof(sectortype);
|
||||
sectorstruct->Align = alignof(sectortype);
|
||||
NewPointer(sectorstruct, false)->InstallHandlers(
|
||||
|
@ -308,7 +308,7 @@ void InitThingdef()
|
|||
}
|
||||
);
|
||||
|
||||
auto linestruct = NewStruct("Wall", nullptr, true);
|
||||
auto linestruct = NewStruct("walltype", nullptr, true);
|
||||
linestruct->Size = sizeof(walltype);
|
||||
linestruct->Align = alignof(walltype);
|
||||
NewPointer(linestruct, false)->InstallHandlers(
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#include "maptypes.h"
|
||||
#include "vm.h"
|
||||
#include "gamefuncs.h"
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
|
@ -496,6 +497,21 @@ DEFINE_ACTION_FUNCTION_NATIVE(_walltype, move, wall_move)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void wall_dragpoint(walltype* wal, double x, double y)
|
||||
{
|
||||
if (!wal) ThrowAbortException(X_READ_NIL, nullptr);
|
||||
dragpoint(wal, DVector2(x, y));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(_walltype, dragpoint, wall_dragpoint)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(walltype);
|
||||
PARAM_FLOAT(x);
|
||||
PARAM_FLOAT(y);
|
||||
wall_dragpoint(self, x, y);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wall_twosided(walltype* wal)
|
||||
{
|
||||
if (!wal) ThrowAbortException(X_READ_NIL, nullptr);
|
||||
|
|
|
@ -593,6 +593,7 @@ void dbLoadMap(const char* pPath, DVector3& pos, short* pAngle, sectortype** cur
|
|||
auto buffer = fr.Read();
|
||||
uint8_t md4[16];
|
||||
md4once(buffer.Data(), buffer.Size(), md4);
|
||||
PostProcessLevel(md4, mapname, sprites);
|
||||
loadMapHack(mapname, md4, sprites);
|
||||
|
||||
if (CalcCRC32(buffer.Data(), buffer.Size() - 4) != nCRC)
|
||||
|
|
|
@ -421,11 +421,6 @@ void prelevel_r(int g, TArray<DDukeActor*>& actors)
|
|||
prelevel_common(g);
|
||||
p = &ps[screenpeek];
|
||||
|
||||
if (currentLevel->levelNumber == 1001 && wall.Size() > 4687 && wall[4592].pos.X == 1612 && wall[4592].pos.Y == -2714) // fix sector overlap in E1L1 Taylor Town
|
||||
{
|
||||
dragpoint(&wall[4592], { 1615., -2715. });
|
||||
}
|
||||
|
||||
if (currentLevel->gameflags & LEVEL_RR_CLEARMOONSHINE)
|
||||
ps[myconnectindex].steroids_amount = 0;
|
||||
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
// RR E1L1.map sector bleeds into another area.
|
||||
sector 47 split 367 375
|
|
@ -1,2 +0,0 @@
|
|||
// Wanton Destruction $auto.map - workaround for sector object overlapping with an outer wall.
|
||||
sector 152 dontclip
|
|
@ -1,4 +0,0 @@
|
|||
// bad sky setting in WT's $volcano.map (original version)
|
||||
sector 118 clearflags ceiling 1
|
||||
sector 57 clearflags ceiling 1
|
||||
sector 281 clearflags ceiling 1
|
|
@ -1,2 +0,0 @@
|
|||
// missing texture in RR E1L2.
|
||||
wall 3312 setflags 2
|
|
@ -1,3 +0,0 @@
|
|||
// SW $plax1.map sector bleeds into another area.
|
||||
sector 64 split 281 283
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
// SW $bath.ap sector bleeds into another area.
|
||||
sector 198 split 1105 1125
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
// bad sky setting in WT's $volcano.map (fixed version)
|
||||
sector 118 clearflags ceiling 1
|
||||
sector 57 clearflags ceiling 1
|
||||
sector 281 clearflags ceiling 1
|
|
@ -1,2 +0,0 @@
|
|||
// SW's Last Warrior level 4. Do not make the serpent's death end the game. The menu has no second episode so this needs to continue.
|
||||
sw_serp_continue
|
|
@ -1,3 +0,0 @@
|
|||
// SW $outpost.map
|
||||
// silence a misplaced and *very* annoying ambient sound.
|
||||
sprite 442 lotag -1
|
|
@ -1,2 +0,0 @@
|
|||
// CP07 sector bleeds into another area.
|
||||
sector 33 split 192 196
|
|
@ -1,3 +0,0 @@
|
|||
// flip inverted keyholes in TD's $shore.map
|
||||
sprite 298 clearflags 8
|
||||
sprite 307 clearflags 8
|
|
@ -1,2 +0,0 @@
|
|||
// flip the inverted card reader in TD's level 10.
|
||||
sprite 179 clearflags 12
|
|
@ -7,6 +7,64 @@ class LevelCompatibility : LevelPostProcessor
|
|||
{
|
||||
case 'none':
|
||||
return;
|
||||
|
||||
case 'c3bfb6a6e7cded2e5fe16cea86632d79': // CP07
|
||||
SplitSector(33, 192, 196); // sector bleeds into another area.
|
||||
break;
|
||||
|
||||
case '24c7b1434070dbe01fa83c6a48926ed9': // RR E1L1.map
|
||||
SplitSector(47, 367, 375); // sector bleeds into another area.
|
||||
wall[4592].dragpoint((1615., -2715.)); // fix overlapping sectors
|
||||
break;
|
||||
|
||||
case 'd7bf49213531cd2607e0459b950ac454': // RR E2L7.map
|
||||
// need to add a sprite with picnum 11 (RRJAILDOOR) lotag = 48, hitag = 32, sector = 534
|
||||
// see premap_r.cpp, line 477.
|
||||
break;
|
||||
|
||||
case '491a04a732cd5aa253703216ff2feff4': // RR E1L2.map
|
||||
wall[3312].cstat |= CSTAT_WALL_BOTTOM_SWAP; // missing lower texture .
|
||||
break;
|
||||
|
||||
case '4f2233ed8fb32f6a3deebc7803dbed69': // SW $plax.map
|
||||
SplitSector(64, 281, 283); // sector bleeds into another area.
|
||||
break;
|
||||
|
||||
case '5e49c7f6c496e337d59d0c072ed1879b': // SW $bath.map
|
||||
SplitSector(198, 1105, 1125); // sector bleeds into another area.
|
||||
break;
|
||||
|
||||
case 'b4ee363e9d15adc5c9becd01520acd23': // SW $outpost.map
|
||||
SetSpriteLotag(442, -1); // silence a misplaced and *very* annoying ambient sound.
|
||||
break;
|
||||
|
||||
case '25d4164814f10cd71d26d52d494c4fb8': // WT $auto.map
|
||||
sector[152].exflags |= SECTOREX_DONTCLIP; // workaround for sector object overlapping with an outer wall.
|
||||
break;
|
||||
|
||||
case '2bac4971499306ee6c86462e6a03dae8': // WT $volcano.map (original version)
|
||||
case '67207fb90130ad561479301c0970c7ba': // WT $volcano.map (fixed version)
|
||||
sector[118].ceilingstat &= ~CSTAT_SECTOR_SKY;
|
||||
sector[57].ceilingstat &= ~CSTAT_SECTOR_SKY;
|
||||
sector[281].ceilingstat &= ~CSTAT_SECTOR_SKY;
|
||||
break;
|
||||
|
||||
case '745182e393945e0d308e8e0a5ee80c3c': // SW Last Warrior level 4.
|
||||
sw_serp_continue(); // Do not make the serpent's death end the game. The menu has no second episode so this needs to continue.
|
||||
break;
|
||||
|
||||
case 'c6f9e49e397c0b424e8030abc23ac003': // TD $shore.map
|
||||
ChangeSpriteFlags(298, CSTAT_SPRITE_YFLIP, 0); // flip inverted keyhole
|
||||
ChangeSpriteFlags(307, CSTAT_SPRITE_YFLIP, 0); // flip inverted keyhole
|
||||
break;
|
||||
|
||||
case 'ef6331237eb36c84a4f7b9f5c3cd225d': // TD level 10
|
||||
ChangeSpriteFlags(179, CSTAT_SPRITE_XFLIP | CSTAT_SPRITE_YFLIP, 0); // flip the inverted card reader
|
||||
break;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,4 +7,6 @@ class LevelPostProcessor native play
|
|||
|
||||
protected native void SetSpriteLotag(int sprite, int tag);
|
||||
protected native void ChangeSpriteFlags(int sprite, int set, int clear);
|
||||
protected native void sw_serp_continue();
|
||||
protected native void SplitSector(int sect, int wal1, int wal2);
|
||||
}
|
||||
|
|
|
@ -99,6 +99,13 @@ enum ETSprFlags
|
|||
TSPR_SLOPESPRITE = 8, // render as sloped sprite
|
||||
}
|
||||
|
||||
enum ESectorExBits
|
||||
{
|
||||
SECTOREX_CLOUDSCROLL = 1,
|
||||
SECTOREX_DRAGGED = 2,
|
||||
SECTOREX_DONTCLIP = 4,
|
||||
};
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
@ -262,6 +269,7 @@ struct walltype native
|
|||
|
||||
native double Length();
|
||||
native void move(Vector2 vec);
|
||||
native void dragpoint(Vector2 vec);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
|
Loading…
Reference in a new issue