- Changed all thing coordinates that were stored as shorts into fixed_t.

- Separated mapthing2_t into mapthinghexen_t and the internal FMapThing so
  that it is easier to add new features in the UDMF map format.
- Added some initial code to read UDMF maps.


SVN r956 (trunk)
This commit is contained in:
Christoph Oelckers 2008-05-08 08:06:26 +00:00
parent 80aebe9044
commit d5563fe478
19 changed files with 343 additions and 173 deletions

View File

@ -1,3 +1,9 @@
May 8, 2008 (Changes by Graf Zahl)
- Changed all thing coordinates that were stored as shorts into fixed_t.
- Separated mapthing2_t into mapthinghexen_t and the internal FMapThing so
that it is easier to add new features in the UDMF map format.
- Added some initial code to read UDMF maps.
May 2, 2008 (Changes by Graf Zahl)
- Split off the slope creation code from p_Setup.cpp into its own file.
- Separated the linedef activation types into a bit mask that allows combination

View File

@ -665,7 +665,7 @@ public:
// no matter what (even if shot)
player_s *player; // only valid if type of APlayerPawn
TObjPtr<AActor> LastLookActor; // Actor last looked for (if TIDtoHate != 0)
WORD SpawnPoint[3]; // For nightmare respawn
fixed_t SpawnPoint[3]; // For nightmare respawn
WORD SpawnAngle;
int skillrespawncount;
TObjPtr<AActor> tracer; // Thing being chased/attacked for tracers

View File

@ -29,6 +29,7 @@
// Some global defines, that configure the game.
#include "doomdef.h"
#include "m_swap.h"
@ -55,12 +56,16 @@ enum
ML_BLOCKMAP, // LUT, motion clipping, walls/grid element
ML_BEHAVIOR, // [RH] Hexen-style scripts. If present, THINGS
// and LINEDEFS are also Hexen-style.
ML_CONVERSATION, // Strife dialog (only for TEXTMAP format)
ML_MAX,
// [RH] These are compressed (and extended) nodes. They combine the data from
// vertexes, segs, ssectors, and nodes into a single lump.
ML_ZNODES = ML_NODES,
ML_GLZNODES = ML_SSECTORS
ML_GLZNODES = ML_SSECTORS,
// for text map format
ML_TEXTMAP = ML_THINGS,
};
@ -248,7 +253,7 @@ typedef struct
} mapthing_t;
// [RH] Hexen-compatible MapThing.
typedef struct MapThing
typedef struct
{
unsigned short thingid;
short x;
@ -259,9 +264,37 @@ typedef struct MapThing
short flags;
BYTE special;
BYTE args[5];
} mapthinghexen_t;
// Internal representation of a mapthing
struct FMapThing
{
unsigned short thingid;
fixed_t x;
fixed_t y;
fixed_t z;
short angle;
short type;
short flags;
short special;
int args[5];
void Serialize (FArchive &);
} mapthing2_t;
FMapThing &operator =(mapthinghexen_t &mt)
{
thingid = mt.thingid;
x = LittleShort(mt.x)<<FRACBITS;
y = LittleShort(mt.y)<<FRACBITS;
z = LittleShort(mt.z)<<FRACBITS;
angle = LittleShort(mt.angle);
type = LittleShort(mt.type);
flags = LittleShort(mt.flags);
special = mt.special;
for(int i=0;i<5;i++) args[i] = mt.args[i];
return *this;
}
};
// [RH] MapThing flags.

View File

@ -188,10 +188,10 @@ extern bool playeringame[MAXPLAYERS];
// Player spawn spots for deathmatch.
extern TArray<mapthing2_t> deathmatchstarts;
extern TArray<FMapThing> deathmatchstarts;
// Player spawn spots.
extern mapthing2_t playerstarts[MAXPLAYERS];
extern FMapThing playerstarts[MAXPLAYERS];
// Intermission stats.
// Parameters for world map / intermission.

View File

@ -1236,20 +1236,20 @@ void G_PlayerReborn (int player)
//
// G_CheckSpot
// Returns false if the player cannot be respawned
// at the given mapthing2_t spot
// at the given mapthing spot
// because something is occupying it
//
bool G_CheckSpot (int playernum, mapthing2_t *mthing)
bool G_CheckSpot (int playernum, FMapThing *mthing)
{
fixed_t x;
fixed_t y;
fixed_t z, oldz;
int i;
x = mthing->x << FRACBITS;
y = mthing->y << FRACBITS;
z = mthing->z << FRACBITS;
x = mthing->x;
y = mthing->y;
z = mthing->z;
z += P_PointInSector (x, y)->floorplane.ZatPoint (x, y);
@ -1288,8 +1288,8 @@ bool G_CheckSpot (int playernum, mapthing2_t *mthing)
// called at level load and each death
//
// [RH] Returns the distance of the closest player to the given mapthing2_t.
static fixed_t PlayersRangeFromSpot (mapthing2_t *spot)
// [RH] Returns the distance of the closest player to the given mapthing
static fixed_t PlayersRangeFromSpot (FMapThing *spot)
{
fixed_t closest = INT_MAX;
fixed_t distance;
@ -1300,8 +1300,8 @@ static fixed_t PlayersRangeFromSpot (mapthing2_t *spot)
if (!playeringame[i] || !players[i].mo || players[i].health <= 0)
continue;
distance = P_AproxDistance (players[i].mo->x - spot->x * FRACUNIT,
players[i].mo->y - spot->y * FRACUNIT);
distance = P_AproxDistance (players[i].mo->x - spot->x,
players[i].mo->y - spot->y);
if (distance < closest)
closest = distance;
@ -1311,10 +1311,10 @@ static fixed_t PlayersRangeFromSpot (mapthing2_t *spot)
}
// [RH] Select the deathmatch spawn spot farthest from everyone.
static mapthing2_t *SelectFarthestDeathmatchSpot (size_t selections)
static FMapThing *SelectFarthestDeathmatchSpot (size_t selections)
{
fixed_t bestdistance = 0;
mapthing2_t *bestspot = NULL;
FMapThing *bestspot = NULL;
unsigned int i;
for (i = 0; i < selections; i++)
@ -1332,7 +1332,7 @@ static mapthing2_t *SelectFarthestDeathmatchSpot (size_t selections)
}
// [RH] Select a deathmatch spawn spot at random (original mechanism)
static mapthing2_t *SelectRandomDeathmatchSpot (int playernum, unsigned int selections)
static FMapThing *SelectRandomDeathmatchSpot (int playernum, unsigned int selections)
{
unsigned int i, j;
@ -1352,7 +1352,7 @@ static mapthing2_t *SelectRandomDeathmatchSpot (int playernum, unsigned int sele
void G_DeathMatchSpawnPlayer (int playernum)
{
unsigned int selections;
mapthing2_t *spot;
FMapThing *spot;
selections = deathmatchstarts.Size ();
// [RH] We can get by with just 1 deathmatch start

View File

@ -279,8 +279,8 @@ void P_TeleportToPlayerStarts (AActor *victim)
selections++;
}
i = pr_telestarts() % selections;
destX = playerstarts[i].x << FRACBITS;
destY = playerstarts[i].y << FRACBITS;
destX = playerstarts[i].x;
destY = playerstarts[i].y;
destAngle = ANG45 * (playerstarts[i].angle/45);
P_Teleport (victim, destX, destY, ONFLOORZ, destAngle, true, true, false);
}
@ -301,8 +301,8 @@ void P_TeleportToDeathmatchStarts (AActor *victim)
if (selections > 0)
{
i = pr_teledm() % selections;
destX = deathmatchstarts[i].x << FRACBITS;
destY = deathmatchstarts[i].y << FRACBITS;
destX = deathmatchstarts[i].x;
destY = deathmatchstarts[i].y;
destAngle = ANG45 * (deathmatchstarts[i].angle/45);
P_Teleport (victim, destX, destY, ONFLOORZ, destAngle, true, true, false);
}

View File

@ -48,14 +48,14 @@ bool AArtiTeleport::Use (bool pickup)
{
unsigned int selections = deathmatchstarts.Size ();
unsigned int i = pr_tele() % selections;
destX = deathmatchstarts[i].x << FRACBITS;
destY = deathmatchstarts[i].y << FRACBITS;
destX = deathmatchstarts[i].x;
destY = deathmatchstarts[i].y;
destAngle = ANG45 * (deathmatchstarts[i].angle/45);
}
else
{
destX = playerstarts[Owner->player - players].x << FRACBITS;
destY = playerstarts[Owner->player - players].y << FRACBITS;
destX = playerstarts[Owner->player - players].x;
destY = playerstarts[Owner->player - players].y;
destAngle = ANG45 * (playerstarts[Owner->player - players].angle/45);
}
P_Teleport (Owner, destX, destY, ONFLOORZ, destAngle, true, true, false);

View File

@ -332,8 +332,8 @@ void A_RestoreSpecialPosition (AActor *self)
fixed_t _x, _y;
sector_t *sec;
_x = self->SpawnPoint[0] << FRACBITS;
_y = self->SpawnPoint[1] << FRACBITS;
_x = self->SpawnPoint[0];
_y = self->SpawnPoint[1];
sec = P_PointInSector (_x, _y);
self->SetOrigin (_x, _y, sec->floorplane.ZatPoint (_x, _y));
@ -341,7 +341,7 @@ void A_RestoreSpecialPosition (AActor *self)
if (self->flags & MF_SPAWNCEILING)
{
self->z = self->ceilingz - self->height - (self->SpawnPoint[2] << FRACBITS);
self->z = self->ceilingz - self->height - self->SpawnPoint[2];
}
else if (self->flags2 & MF2_SPAWNFLOAT)
{
@ -358,7 +358,7 @@ void A_RestoreSpecialPosition (AActor *self)
}
else
{
self->z = (self->SpawnPoint[2] << FRACBITS) + self->floorz;
self->z = self->SpawnPoint[2] + self->floorz;
if (self->flags2 & MF2_FLOATBOB)
{
self->z += FloatBobOffsets[(self->FloatBobPhase + level.maptime) & 63];

View File

@ -39,10 +39,13 @@ bool APuzzleItem::Use (bool pickup)
}
// [RH] Always play the sound if the use fails.
S_Sound (Owner, CHAN_VOICE, "*puzzfail", 1, ATTN_IDLE);
const char *message = GetClass()->Meta.GetMetaString (AIMETA_PuzzFailMessage);
if (message != NULL && *message=='$') message = GStrings[message + 1];
if (message == NULL) message = GStrings("TXT_USEPUZZLEFAILED");
C_MidPrintBold (message);
if (Owner != NULL && Owner->CheckLocalView (consoleplayer))
{
const char *message = GetClass()->Meta.GetMetaString (AIMETA_PuzzFailMessage);
if (message != NULL && *message=='$') message = GStrings[message + 1];
if (message == NULL) message = GStrings("TXT_USEPUZZLEFAILED");
C_MidPrintBold (message);
}
return false;
}

View File

@ -220,3 +220,35 @@ xx(MapSpot)
xx(PatrolPoint)
xx(PatrolSpecial)
xx(Communicator)
// Textmap properties
//xx(X)
//xx(Y)
//xx(Z)
//xx(Tid)
//xx(Angle)
xx(Type)
//xx(Special)
xx(Arg0)
xx(Arg1)
xx(Arg2)
xx(Arg3)
xx(Arg4)
xx(Id)
xx(V1)
xx(V2)
xx(Frontside)
xx(Backside)
xx(Offsetx)
xx(Offsety)
xx(Texturetop)
xx(Texturebottom)
xx(Texturemiddle)
xx(Sector)
xx(Floorheight)
xx(Ceilingheight)
xx(Lightlevel)
xx(Tag)
xx(Floorpic)
xx(Ceilingpic)

View File

@ -124,12 +124,12 @@ void P_AdjustLine (line_t *line);
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
static bool P_LoadBloodMap (BYTE *data, size_t len, mapthing2_t **sprites, int *numsprites);
static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **sprites, int *numsprites);
static void LoadSectors (sectortype *bsectors);
static void LoadWalls (walltype *walls, int numwalls, sectortype *bsectors);
static int LoadSprites (spritetype *sprites, int numsprites, sectortype *bsectors, mapthing2_t *mapthings);
static int LoadSprites (spritetype *sprites, int numsprites, sectortype *bsectors, FMapThing *mapthings);
static vertex_t *FindVertex (fixed_t x, fixed_t y);
static void CreateStartSpot (fixed_t *pos, mapthing2_t *start);
static void CreateStartSpot (fixed_t *pos, FMapThing *start);
static void CalcPlane (SlopeWork &slope, secplane_t &plane);
static void Decrypt (void *to, const void *from, int len, int key);
@ -147,7 +147,7 @@ static void Decrypt (void *to, const void *from, int len, int key);
//
//==========================================================================
bool P_LoadBuildMap (BYTE *data, size_t len, mapthing2_t **sprites, int *numspr)
bool P_LoadBuildMap (BYTE *data, size_t len, FMapThing **sprites, int *numspr)
{
if (len < 26)
{
@ -178,7 +178,7 @@ bool P_LoadBuildMap (BYTE *data, size_t len, mapthing2_t **sprites, int *numspr)
(sectortype *)(data + 22));
numsprites = *(WORD *)(data + 24 + numsectors*sizeof(sectortype) + numwalls*sizeof(walltype));
*sprites = new mapthing2_t[numsprites + 1];
*sprites = new FMapThing[numsprites + 1];
CreateStartSpot ((fixed_t *)(data + 4), *sprites);
*numspr = 1 + LoadSprites ((spritetype *)(data + 26 + numsectors*sizeof(sectortype) + numwalls*sizeof(walltype)),
numsprites, (sectortype *)(data + 22), *sprites + 1);
@ -192,7 +192,7 @@ bool P_LoadBuildMap (BYTE *data, size_t len, mapthing2_t **sprites, int *numspr)
//
//==========================================================================
static bool P_LoadBloodMap (BYTE *data, size_t len, mapthing2_t **mapthings, int *numspr)
static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **mapthings, int *numspr)
{
BYTE infoBlock[37];
int mapver = data[5];
@ -303,7 +303,7 @@ static bool P_LoadBloodMap (BYTE *data, size_t len, mapthing2_t **mapthings, int
// BUILD info from the map we need. (Sprites are ignored.)
LoadSectors (bsec);
LoadWalls (bwal, numWalls, bsec);
*mapthings = new mapthing2_t[numsprites + 1];
*mapthings = new FMapThing[numsprites + 1];
CreateStartSpot ((fixed_t *)infoBlock, *mapthings);
*numspr = 1 + LoadSprites (bspr, numsprites, bsec, *mapthings + 1);
@ -606,7 +606,7 @@ static void LoadWalls (walltype *walls, int numwalls, sectortype *bsec)
//==========================================================================
static int LoadSprites (spritetype *sprites, int numsprites, sectortype *bsectors,
mapthing2_t *mapthings)
FMapThing *mapthings)
{
char name[9];
int picnum;
@ -621,9 +621,9 @@ static int LoadSprites (spritetype *sprites, int numsprites, sectortype *bsector
picnum = TexMan.GetTexture (name, FTexture::TEX_Build);
mapthings[count].thingid = 0;
mapthings[count].x = (short)(sprites[i].x >> 4);
mapthings[count].y = -(short)(sprites[i].y >> 4);
mapthings[count].z = (short)((bsectors[sprites[i].sectnum].floorz - sprites[i].z) >> 8);
mapthings[count].x = (sprites[i].x << 12);
mapthings[count].y = -(sprites[i].y << 12);
mapthings[count].z = (bsectors[sprites[i].sectnum].floorz - sprites[i].z) << 8;
mapthings[count].angle = (((2048-sprites[i].ang) & 2047) * 360) >> 11;
mapthings[count].type = 9988;
mapthings[count].flags = MTF_FIGHTER|MTF_CLERIC|MTF_MAGE|MTF_SINGLE|MTF_COOPERATIVE|MTF_DEATHMATCH|MTF_EASY|MTF_NORMAL|MTF_HARD;
@ -671,12 +671,12 @@ vertex_t *FindVertex (fixed_t x, fixed_t y)
//
//==========================================================================
static void CreateStartSpot (fixed_t *pos, mapthing2_t *start)
static void CreateStartSpot (fixed_t *pos, FMapThing *start)
{
short angle = LittleShort(*(WORD *)(&pos[3]));
mapthing2_t mt =
FMapThing mt =
{
0, short(LittleLong(pos[0])>>4), short((-LittleLong(pos[1]))>>4), 0,// tid, x, y, z
0, (LittleLong(pos[0])<<12), ((-LittleLong(pos[1]))<<12), 0,// tid, x, y, z
short(Scale ((2048-angle)&2047, 360, 2048)), 1, // angle, type
7|MTF_SINGLE|224, // flags
// special and args are 0

View File

@ -51,6 +51,7 @@
#include "p_enemy.h"
#include "gstrings.h"
#include "sound/i_music.h"
#include "p_setup.h"
// The conversations as they exist inside a SCRIPTxx lump.
struct Response
@ -107,8 +108,9 @@ static int ConversationPauseTic;
static bool ShowGold;
static void LoadScriptFile (const char *name);
static FStrifeDialogueNode *ReadRetailNode (FWadLump *lump, DWORD &prevSpeakerType);
static FStrifeDialogueNode *ReadTeaserNode (FWadLump *lump, DWORD &prevSpeakerType);
static void LoadScriptFile(FileReader *lump, int numnodes);
static FStrifeDialogueNode *ReadRetailNode (FileReader *lump, DWORD &prevSpeakerType);
static FStrifeDialogueNode *ReadTeaserNode (FileReader *lump, DWORD &prevSpeakerType);
static void ParseReplies (FStrifeDialogueReply **replyptr, Response *responses);
static void DrawConversationMenu ();
static void PickConversationReply ();
@ -148,16 +150,25 @@ static const PClass *GetStrifeType (int typenum)
//
//============================================================================
void P_LoadStrifeConversations (const char *mapname)
void P_LoadStrifeConversations (MapData *map, const char *mapname)
{
if (strnicmp (mapname, "MAP", 3) != 0)
if (map->Size(ML_CONVERSATION) > 0)
{
return;
LoadScriptFile ("SCRIPT00");
map->Seek(ML_CONVERSATION);
LoadScriptFile (map->file, map->Size(ML_CONVERSATION));
}
char scriptname[9] = { 'S','C','R','I','P','T',mapname[3],mapname[4],0 };
else
{
if (strnicmp (mapname, "MAP", 3) != 0)
{
return;
}
char scriptname[9] = { 'S','C','R','I','P','T',mapname[3],mapname[4],0 };
LoadScriptFile ("SCRIPT00");
LoadScriptFile (scriptname);
LoadScriptFile ("SCRIPT00");
LoadScriptFile (scriptname);
}
}
//============================================================================
@ -216,17 +227,23 @@ static char *ncopystring (const char *string)
static void LoadScriptFile (const char *name)
{
int lumpnum = Wads.CheckNumForName (name);
int numnodes, i;
DWORD prevSpeakerType;
FStrifeDialogueNode *node;
FWadLump *lump;
FileReader *lump;
if (lumpnum < 0)
{
return;
}
lump = Wads.ReopenLumpNum (lumpnum);
LoadScriptFile(lump, Wads.LumpLength(lumpnum));
}
static void LoadScriptFile(FileReader *lump, int numnodes)
{
int i;
DWORD prevSpeakerType;
FStrifeDialogueNode *node;
numnodes = Wads.LumpLength (lumpnum);
if (!(gameinfo.flags & GI_SHAREWARE))
{
// Strife scripts are always a multiple of 1516 bytes because each entry
@ -247,7 +264,6 @@ static void LoadScriptFile (const char *name)
numnodes /= 1488;
}
lump = Wads.ReopenLumpNum (lumpnum);
prevSpeakerType = 0;
for (i = 0; i < numnodes; ++i)
@ -273,7 +289,7 @@ static void LoadScriptFile (const char *name)
//
//============================================================================
static FStrifeDialogueNode *ReadRetailNode (FWadLump *lump, DWORD &prevSpeakerType)
static FStrifeDialogueNode *ReadRetailNode (FileReader *lump, DWORD &prevSpeakerType)
{
FStrifeDialogueNode *node;
Speech speech;
@ -343,7 +359,7 @@ static FStrifeDialogueNode *ReadRetailNode (FWadLump *lump, DWORD &prevSpeakerTy
//
//============================================================================
static FStrifeDialogueNode *ReadTeaserNode (FWadLump *lump, DWORD &prevSpeakerType)
static FStrifeDialogueNode *ReadTeaserNode (FileReader *lump, DWORD &prevSpeakerType)
{
FStrifeDialogueNode *node;
TeaserSpeech speech;

View File

@ -65,7 +65,9 @@ extern TArray<FStrifeDialogueNode *> StrifeDialogues;
// initialized as part of the actor's setup in infodefaults.cpp.
extern const PClass *StrifeTypes[1001];
void P_LoadStrifeConversations (const char *mapname);
struct MapData;
void P_LoadStrifeConversations (MapData *map, const char *mapname);
void P_FreeStrifeConversations ();
void P_StartConversation (AActor *npc, AActor *pc, bool facetalker, bool saveangle);

View File

@ -87,7 +87,7 @@ void P_UnPredictPlayer ();
extern fixed_t FloatBobOffsets[64];
APlayerPawn *P_SpawnPlayer (mapthing2_t* mthing, bool tempplayer=false);
APlayerPawn *P_SpawnPlayer (FMapThing *mthing, bool tempplayer=false);
void P_ThrustMobj (AActor *mo, angle_t angle, fixed_t move);
int P_FaceMobj (AActor *source, AActor *target, angle_t *delta);

View File

@ -414,7 +414,7 @@ void AActor::Serialize (FArchive &arc)
}
}
void MapThing::Serialize (FArchive &arc)
void FMapThing::Serialize (FArchive &arc)
{
arc << thingid << x << y << z << angle << type << flags << special
<< args[0] << args[1] << args[2] << args[3] << args[4];
@ -2185,19 +2185,19 @@ void P_NightmareRespawn (AActor *mobj)
else if (info->flags2 & MF2_SPAWNFLOAT)
z = FLOATRANDZ;
else if (info->flags2 & MF2_FLOATBOB)
z = mobj->SpawnPoint[2] << FRACBITS;
z = mobj->SpawnPoint[2];
else
z = ONFLOORZ;
// spawn it
x = mobj->SpawnPoint[0] << FRACBITS;
y = mobj->SpawnPoint[1] << FRACBITS;
x = mobj->SpawnPoint[0];
y = mobj->SpawnPoint[1];
mo = Spawn (RUNTIME_TYPE(mobj), x, y, z, NO_REPLACE);
if (z == ONFLOORZ)
mo->z += mo->SpawnPoint[2] << FRACBITS;
mo->z += mo->SpawnPoint[2];
else if (z == ONCEILINGZ)
mo->z -= mo->SpawnPoint[2] << FRACBITS;
mo->z -= mo->SpawnPoint[2];
// something is occupying its position?
if (!P_TestMobjLocation (mo))
@ -3252,8 +3252,8 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t
actor->ceilingsector = actor->Sector;
}
actor->SpawnPoint[0] = ix >> FRACBITS;
actor->SpawnPoint[1] = iy >> FRACBITS;
actor->SpawnPoint[0] = ix;
actor->SpawnPoint[1] = iy;
if (iz == ONFLOORZ)
{
@ -3278,7 +3278,7 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t
}
else
{
actor->SpawnPoint[2] = (actor->z - actor->floorz) >> FRACBITS;
actor->SpawnPoint[2] = (actor->z - actor->floorz);
}
if (actor->flags2 & MF2_FLOATBOB)
@ -3500,7 +3500,7 @@ EXTERN_CVAR (Bool, chasedemo)
extern bool demonew;
APlayerPawn *P_SpawnPlayer (mapthing2_t *mthing, bool tempplayer)
APlayerPawn *P_SpawnPlayer (FMapThing *mthing, bool tempplayer)
{
int playernum;
player_t *p;
@ -3571,8 +3571,8 @@ APlayerPawn *P_SpawnPlayer (mapthing2_t *mthing, bool tempplayer)
}
else
{
spawn_x = mthing->x << FRACBITS;
spawn_y = mthing->y << FRACBITS;
spawn_x = mthing->x;
spawn_y = mthing->y;
spawn_angle = ANG45 * (mthing->angle/45);
}
@ -3738,7 +3738,7 @@ APlayerPawn *P_SpawnPlayer (mapthing2_t *mthing, bool tempplayer)
// already be in host byte order.
//
// [RH] position is used to weed out unwanted start spots
AActor *P_SpawnMapThing (mapthing2_t *mthing, int position)
AActor *P_SpawnMapThing (FMapThing *mthing, int position)
{
const PClass *i;
int mask;
@ -3786,8 +3786,8 @@ AActor *P_SpawnMapThing (mapthing2_t *mthing, int position)
{
polyspawns_t *polyspawn = new polyspawns_t;
polyspawn->next = polyspawns;
polyspawn->x = mthing->x << FRACBITS;
polyspawn->y = mthing->y << FRACBITS;
polyspawn->x = mthing->x;
polyspawn->y = mthing->y;
polyspawn->angle = mthing->angle;
polyspawn->type = mthing->type;
polyspawns = polyspawn;
@ -3888,8 +3888,7 @@ AActor *P_SpawnMapThing (mapthing2_t *mthing, int position)
// [RH] sound sequence overriders
if (mthing->type >= 1400 && mthing->type < 1410)
{
P_PointInSector (mthing->x<<FRACBITS,
mthing->y<<FRACBITS)->seqType = mthing->type - 1400;
P_PointInSector (mthing->x, mthing->y)->seqType = mthing->type - 1400;
return NULL;
}
else if (mthing->type == 1411)
@ -3907,8 +3906,7 @@ AActor *P_SpawnMapThing (mapthing2_t *mthing, int position)
}
else
{
P_PointInSector (mthing->x << FRACBITS,
mthing->y << FRACBITS)->seqType = type;
P_PointInSector (mthing->x, mthing->y)->seqType = type;
}
return NULL;
}
@ -3932,7 +3930,7 @@ AActor *P_SpawnMapThing (mapthing2_t *mthing, int position)
// [RH] Don't die if the map tries to spawn an unknown thing
Printf ("Unknown type %i at (%i, %i)\n",
mthing->type,
mthing->x, mthing->y);
mthing->x>>FRACBITS, mthing->y>>FRACBITS);
i = PClass::FindClass("Unknown");
}
// [RH] If the thing's corresponding sprite has no frames, also map
@ -3948,7 +3946,7 @@ AActor *P_SpawnMapThing (mapthing2_t *mthing, int position)
sprites[defaults->SpawnState->sprite.index].numframes == 0)
{
Printf ("%s at (%i, %i) has no frames\n",
i->TypeName.GetChars(), mthing->x, mthing->y);
i->TypeName.GetChars(), mthing->x>>FRACBITS, mthing->y>>FRACBITS);
i = PClass::FindClass("Unknown");
}
}
@ -4002,8 +4000,8 @@ AActor *P_SpawnMapThing (mapthing2_t *mthing, int position)
}
// spawn it
x = mthing->x << FRACBITS;
y = mthing->y << FRACBITS;
x = mthing->x;
y = mthing->y;
if (info->flags & MF_SPAWNCEILING)
z = ONCEILINGZ;
@ -4017,9 +4015,9 @@ AActor *P_SpawnMapThing (mapthing2_t *mthing, int position)
SpawningMapThing = false;
if (z == ONFLOORZ)
mobj->z += mthing->z << FRACBITS;
mobj->z += mthing->z;
else if (z == ONCEILINGZ)
mobj->z -= mthing->z << FRACBITS;
mobj->z -= mthing->z;
mobj->SpawnPoint[0] = mthing->x;
mobj->SpawnPoint[1] = mthing->y;

View File

@ -61,11 +61,11 @@
#include "p_setup.h"
#include "r_translate.h"
void P_SpawnSlopeMakers (mapthing2_t *firstmt, mapthing2_t *lastmt);
void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt);
void P_SetSlopes ();
extern AActor *P_SpawnMapThing (mapthing2_t *mthing, int position);
extern bool P_LoadBuildMap (BYTE *mapdata, size_t len, mapthing2_t **things, int *numthings);
extern AActor *P_SpawnMapThing (FMapThing *mthing, int position);
extern bool P_LoadBuildMap (BYTE *mapdata, size_t len, FMapThing **things, int *numthings);
extern void P_LoadTranslator(const char *lump);
extern void P_TranslateLineDef (line_t *ld, maplinedef_t *mld);
@ -116,6 +116,8 @@ zone_t* zones;
FExtraLight* ExtraLights;
FLightStack* LightStacks;
static TArray<FMapThing> MapThingsConverted;
int sidecount;
struct sidei_t // [RH] Only keep BOOM sidedef init stuff around for init
{
@ -175,8 +177,8 @@ BYTE* rejectmatrix;
static bool ForceNodeBuild;
// Maintain single and multi player starting spots.
TArray<mapthing2_t> deathmatchstarts (16);
mapthing2_t playerstarts[MAXPLAYERS];
TArray<FMapThing> deathmatchstarts (16);
FMapThing playerstarts[MAXPLAYERS];
static void P_AllocateSideDefs (int count);
static void P_SetSideNum (DWORD *sidenum_p, WORD sidenum);
@ -303,20 +305,67 @@ MapData *P_OpenMapData(const char * mapname)
}
int index = 0;
for(int i = 1;; i++)
if (stricmp(Wads.GetLumpFullName(lump_name + 1), "TEXTMAP"))
{
// Since levels must be stored in WADs they can't really have full
// names and for any valid level lump this always returns the short name.
const char * lumpname = Wads.GetLumpFullName(lump_name + i);
index = GetMapIndex(mapname, index, lumpname, i != 1 || map->MapLumps[0].Size == 0);
if (index == ML_BEHAVIOR) map->HasBehavior = true;
for(int i = 1;; i++)
{
// Since levels must be stored in WADs they can't really have full
// names and for any valid level lump this always returns the short name.
const char * lumpname = Wads.GetLumpFullName(lump_name + i);
index = GetMapIndex(mapname, index, lumpname, i != 1 || map->MapLumps[0].Size == 0);
if (index == ML_BEHAVIOR) map->HasBehavior = true;
// The next lump is not part of this map anymore
if (index < 0) break;
// The next lump is not part of this map anymore
if (index < 0) break;
map->MapLumps[index].FilePos = Wads.GetLumpOffset(lump_name + i);
map->MapLumps[index].Size = Wads.LumpLength(lump_name + i);
strncpy(map->MapLumps[index].Name, lumpname, 8);
map->MapLumps[index].FilePos = Wads.GetLumpOffset(lump_name + i);
map->MapLumps[index].Size = Wads.LumpLength(lump_name + i);
strncpy(map->MapLumps[index].Name, lumpname, 8);
}
}
else
{
map->MapLumps[1].FilePos = Wads.GetLumpOffset(lump_name + 1);
map->MapLumps[1].Size = Wads.LumpLength(lump_name + 1);
for(int i = 2;; i++)
{
const char * lumpname = Wads.GetLumpFullName(lump_name + i);
if (lumpname == NULL)
{
I_Error("Invalid map definition for %s", mapname);
}
else if (!stricmp(lumpname, "ZNODES"))
{
index = ML_GLZNODES;
}
else if (!stricmp(lumpname, "BLOCKMAP"))
{
// there is no real point in creating a blockmap but let's use it anyway
index = ML_BLOCKMAP;
}
else if (!stricmp(lumpname, "REJECT"))
{
index = ML_REJECT;
}
else if (!stricmp(lumpname, "DIALOGUE"))
{
index = ML_CONVERSATION;
}
else if (!stricmp(lumpname, "BEHAVIOR"))
{
index = ML_BEHAVIOR;
}
else if (!stricmp(lumpname, "ENDMAP"))
{
break;
}
else continue;
map->MapLumps[index].FilePos = Wads.GetLumpOffset(lump_name + i);
map->MapLumps[index].Size = Wads.LumpLength(lump_name + i);
strncpy(map->MapLumps[index].Name, lumpname, 8);
}
}
return map;
}
@ -356,6 +405,50 @@ MapData *P_OpenMapData(const char * mapname)
(*map->file) >> offset >> size;
map->file->Read(lumpname, 8);
if (i == 1 && !strnicmp(lumpname, "TEXTMAP", 8))
{
map->MapLumps[1].FilePos = offset;
map->MapLumps[1].Size = size;
for(int i = 2;; i++)
{
(*map->file) >> offset >> size;
long v = map->file->Read(lumpname, 8);
if (v < 8)
{
I_Error("Invalid map definition for %s", mapname);
}
else if (!stricmp(lumpname, "ZNODES"))
{
index = ML_GLZNODES;
}
else if (!stricmp(lumpname, "BLOCKMAP"))
{
// there is no real point in creating a blockmap but let's use it anyway
index = ML_BLOCKMAP;
}
else if (!stricmp(lumpname, "REJECT"))
{
index = ML_REJECT;
}
else if (!stricmp(lumpname, "DIALOGUE"))
{
index = ML_CONVERSATION;
}
else if (!stricmp(lumpname, "BEHAVIOR"))
{
index = ML_BEHAVIOR;
}
else if (!stricmp(lumpname, "ENDMAP"))
{
return map;
}
else continue;
map->MapLumps[index].FilePos = offset;
map->MapLumps[index].Size = size;
strncpy(map->MapLumps[index].Name, lumpname, 8);
}
}
if (i>0)
{
index = GetMapIndex(maplabel, index, lumpname, true);
@ -1225,13 +1318,13 @@ void P_LoadNodes (MapData * map)
//===========================================================================
CVAR(Bool, dumpspawnedthings, false, 0)
static void SpawnMapThing(int index, mapthing2_t *mt, int position)
static void SpawnMapThing(int index, FMapThing *mt, int position)
{
AActor *spawned = P_SpawnMapThing(mt, position);
if (dumpspawnedthings)
{
Printf("%5d: (%5d, %5d, %5d), doomednum = %5d, flags = %04x, type = %s\n",
index, mt->x, mt->y, mt->z, mt->type, mt->flags,
index, mt->x>>FRACBITS, mt->y>>FRACBITS, mt->z>>FRACBITS, mt->type, mt->flags,
spawned? spawned->GetClass()->TypeName.GetChars() : "(none)");
}
}
@ -1244,7 +1337,7 @@ static void SpawnMapThing(int index, mapthing2_t *mt, int position)
void P_LoadThings (MapData * map, int position)
{
mapthing2_t mt2; // [RH] for translation
FMapThing mt2; // [RH] for translation
int lumplen = map->Size(ML_THINGS);
int numthings = lumplen / sizeof(mapthing_t);
@ -1291,8 +1384,8 @@ void P_LoadThings (MapData * map, int position)
}
if (flags & BTF_NOTSINGLE) mt2.flags &= ~MTF_SINGLE;
mt2.x = LittleShort(mt->x);
mt2.y = LittleShort(mt->y);
mt2.x = LittleShort(mt->x) << FRACBITS;
mt2.y = LittleShort(mt->y) << FRACBITS;
mt2.angle = LittleShort(mt->angle);
mt2.type = LittleShort(mt->type);
@ -1316,36 +1409,31 @@ void P_LoadThings (MapData * map, int position)
void P_LoadThings2 (MapData * map, int position)
{
int lumplen = map->MapLumps[ML_THINGS].Size;
int numthings = lumplen / sizeof(mapthing2_t);
int numthings = lumplen / sizeof(mapthinghexen_t);
int i;
char *mtp;
mapthing2_t *mt;
MapThingsConverted.Resize(numthings);
FMapThing *mti = &MapThingsConverted[0];
mtp = new char[lumplen];
map->Read(ML_THINGS, mtp);
mapthinghexen_t *mth = (mapthinghexen_t*)mtp;
#ifdef WORDS_BIGENDIAN
for (i=0, mt = (mapthing2_t*)mtp; i < numthings; i++,mt++)
for(int i = 0; i< numthings; i++)
{
mt->thingid = LittleShort(mt->thingid);
mt->x = LittleShort(mt->x);
mt->y = LittleShort(mt->y);
mt->z = LittleShort(mt->z);
mt->angle = LittleShort(mt->angle);
mt->type = LittleShort(mt->type);
mt->flags = LittleShort(mt->flags);
}
#endif
// [RH] Spawn slope creating things first.
P_SpawnSlopeMakers ((mapthing2_t*)mtp, ((mapthing2_t*)mtp)+numthings);
for (i=0, mt = (mapthing2_t*)mtp; i < numthings; i++,mt++)
{
SpawnMapThing (i, mt, position);
mti[i] = mth[i];
}
delete[] mtp;
// [RH] Spawn slope creating things first.
P_SpawnSlopeMakers (mti, mti + numthings);
for (i=0; i < numthings; i++)
{
SpawnMapThing (i, &mti[i], position);
}
}
@ -2818,38 +2906,30 @@ void P_GetPolySpots (MapData * map, TArray<FNodeBuilder::FPolyStart> &spots, TAr
{
int spot1, spot2, spot3, anchor;
int lumplen = map->Size(ML_THINGS);
int num = lumplen / sizeof(mapthing2_t);
mapthing2_t *mt;
map->Seek(ML_THINGS);
mt = new mapthing2_t[num];
map->file->Read(mt, num * sizeof(mapthing2_t));
if (gameinfo.gametype == GAME_Hexen)
{
spot1 = LittleShort(PO_HEX_SPAWN_TYPE);
spot2 = LittleShort(PO_HEX_SPAWNCRUSH_TYPE);
anchor = LittleShort(PO_HEX_ANCHOR_TYPE);
spot1 = PO_HEX_SPAWN_TYPE;
spot2 = PO_HEX_SPAWNCRUSH_TYPE;
anchor = PO_HEX_ANCHOR_TYPE;
}
else
{
spot1 = LittleShort(PO_SPAWN_TYPE);
spot2 = LittleShort(PO_SPAWNCRUSH_TYPE);
anchor = LittleShort(PO_ANCHOR_TYPE);
spot1 = PO_SPAWN_TYPE;
spot2 = PO_SPAWNCRUSH_TYPE;
anchor = PO_ANCHOR_TYPE;
}
spot3 = LittleShort(PO_SPAWNHURT_TYPE);
spot3 = PO_SPAWNHURT_TYPE;
for (int i = 0; i < num; ++i)
for (unsigned int i = 0; i < MapThingsConverted.Size(); ++i)
{
if (mt[i].type == spot1 || mt[i].type == spot2 || mt[i].type == spot3 || mt[i].type == anchor)
if (MapThingsConverted[i].type == spot1 || MapThingsConverted[i].type == spot2 ||
MapThingsConverted[i].type == spot3 || MapThingsConverted[i].type == anchor)
{
FNodeBuilder::FPolyStart newvert;
newvert.x = LittleShort(mt[i].x) << FRACBITS;
newvert.y = LittleShort(mt[i].y) << FRACBITS;
newvert.polynum = LittleShort(mt[i].angle);
if (mt[i].type == anchor)
newvert.x = MapThingsConverted[i].x;
newvert.y = MapThingsConverted[i].y;
newvert.polynum = MapThingsConverted[i].angle;
if (MapThingsConverted[i].type == anchor)
{
anchors.Push (newvert);
}
@ -2859,7 +2939,6 @@ void P_GetPolySpots (MapData * map, TArray<FNodeBuilder::FPolyStart> &spots, TAr
}
}
}
delete[] mt;
}
}
@ -3027,7 +3106,7 @@ void P_FreeExtraLevelData()
void P_SetupLevel (char *lumpname, int position)
{
cycle_t times[20] = { 0 };
mapthing2_t *buildthings;
FMapThing *buildthings;
int numbuildthings;
int i;
bool buildmap;
@ -3126,7 +3205,7 @@ void P_SetupLevel (char *lumpname, int position)
}
FBehavior::StaticLoadDefaultModules ();
P_LoadStrifeConversations (lumpname);
P_LoadStrifeConversations (map, lumpname);
clock (times[0]);
P_LoadVertexes (map);
@ -3386,6 +3465,7 @@ void P_SetupLevel (char *lumpname, int position)
Printf ("Time%3d:%10llu cycles (%s)\n", i, times[i], timenames[i]);
}
}
MapThingsConverted.Clear();
}

View File

@ -269,10 +269,10 @@ enum
//
//==========================================================================
static void P_SetSlopesFromVertexHeights(mapthing2_t *firstmt, mapthing2_t *lastmt)
static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt)
{
TMap<int, fixed_t> vt_heights[2];
mapthing2_t *mt;
FMapThing *mt;
bool vt_found = false;
for (mt = firstmt; mt < lastmt; ++mt)
@ -281,15 +281,15 @@ static void P_SetSlopesFromVertexHeights(mapthing2_t *firstmt, mapthing2_t *last
{
for(int i=0; i<numvertexes; i++)
{
if (vertexes[i].x == mt->x << FRACBITS && vertexes[i].y == mt->y << FRACBITS)
if (vertexes[i].x == mt->x && vertexes[i].y == mt->y)
{
if (mt->type == THING_VertexFloorZ)
{
vt_heights[0][i] = mt->z << FRACBITS;
vt_heights[0][i] = mt->z;
}
else
{
vt_heights[1][i] = mt->z << FRACBITS;
vt_heights[1][i] = mt->z;
}
vt_found = true;
}
@ -381,9 +381,9 @@ static void P_SetSlopesFromVertexHeights(mapthing2_t *firstmt, mapthing2_t *last
//
//===========================================================================
void P_SpawnSlopeMakers (mapthing2_t *firstmt, mapthing2_t *lastmt)
void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt)
{
mapthing2_t *mt;
FMapThing *mt;
for (mt = firstmt; mt < lastmt; ++mt)
{
@ -395,8 +395,8 @@ void P_SpawnSlopeMakers (mapthing2_t *firstmt, mapthing2_t *lastmt)
secplane_t *refplane;
sector_t *sec;
x = mt->x << FRACBITS;
y = mt->y << FRACBITS;
x = mt->x;
y = mt->y;
sec = P_PointInSector (x, y);
if (mt->type & 1)
{
@ -406,10 +406,10 @@ void P_SpawnSlopeMakers (mapthing2_t *firstmt, mapthing2_t *lastmt)
{
refplane = &sec->floorplane;
}
z = refplane->ZatPoint (x, y) + (mt->z << FRACBITS);
z = refplane->ZatPoint (x, y) + (mt->z);
if (mt->type==THING_VavoomFloor || mt->type==THING_VavoomCeiling)
{
P_VavoomSlope(sec, mt->thingid, x, y, mt->z<<FRACBITS, mt->type & 1);
P_VavoomSlope(sec, mt->thingid, x, y, mt->z, mt->type & 1);
}
else if (mt->type <= THING_SlopeCeilingPointLine)
{
@ -428,7 +428,7 @@ void P_SpawnSlopeMakers (mapthing2_t *firstmt, mapthing2_t *lastmt)
if (mt->type == THING_CopyFloorPlane ||
mt->type == THING_CopyCeilingPlane)
{
P_CopyPlane (mt->args[0], mt->x << FRACBITS, mt->y << FRACBITS, mt->type & 1);
P_CopyPlane (mt->args[0], mt->x, mt->y, mt->type & 1);
mt->type = 0;
}
}

View File

@ -94,7 +94,7 @@ CCMD (dumpmap)
static int WriteTHINGS (FILE *file)
{
mapthing2_t mt = { 0 };
mapthinghexen_t mt = { 0 };
AActor *mo = players[consoleplayer].mo;
mt.x = LittleShort(short(mo->x >> FRACBITS));

View File

@ -2037,8 +2037,8 @@ void A_Stop (AActor *self)
//===========================================================================
void A_Respawn (AActor *actor)
{
fixed_t x = actor->SpawnPoint[0] << FRACBITS;
fixed_t y = actor->SpawnPoint[1] << FRACBITS;
fixed_t x = actor->SpawnPoint[0];
fixed_t y = actor->SpawnPoint[1];
sector_t *sec;
actor->flags |= MF_SOLID;