- made the automap an object.

This simplifies handling a lot because it allows to make the level the owner of its map.
This commit is contained in:
Christoph Oelckers 2019-01-26 15:21:20 +01:00
commit 05830455e7
14 changed files with 839 additions and 791 deletions

File diff suppressed because it is too large Load diff

View file

@ -22,31 +22,44 @@
#ifndef __AMMAP_H__ #ifndef __AMMAP_H__
#define __AMMAP_H__ #define __AMMAP_H__
#include "dobject.h"
struct event_t; struct event_t;
class FSerializer; class FSerializer;
struct FLevelLocals;
class DAutomapBase : public DObject
{
DECLARE_ABSTRACT_CLASS(DAutomapBase, DObject);
public:
FLevelLocals *Level; // temporary location so that it can be set from the outside.
// Called by main loop.
virtual bool Responder(event_t* ev, bool last) = 0;
// Called by main loop.
virtual void Ticker(void) = 0;
// Called by main loop,
// called instead of view drawer if automap active.
virtual void Drawer(int bottom) = 0;
virtual void NewResolution() = 0;
virtual void LevelInit() = 0;
virtual void UpdateShowAllLines() = 0;
virtual void GoBig() = 0;
virtual void ResetFollowLocation() = 0;
virtual int addMark() = 0;
virtual bool clearMarks() = 0;
virtual DVector2 GetPosition() = 0;
virtual void startDisplay() = 0;
};
void AM_StaticInit(); void AM_StaticInit();
void AM_ClearColorsets(); // reset data for a restart. void AM_ClearColorsets(); // reset data for a restart.
DAutomapBase *AM_Create(FLevelLocals *Level);
// Called by main loop. void AM_Stop();
bool AM_Responder (event_t* ev, bool last); void AM_ToggleMap();
// Called by main loop.
void AM_Ticker (void);
// Called by main loop,
// called instead of view drawer if automap active.
void AM_Drawer (int bottom);
// Called to force the automap to quit
// if the level is completed while it is up.
void AM_Stop (void);
void AM_NewResolution ();
void AM_ToggleMap ();
void AM_LevelInit ();
void AM_SerializeMarkers(FSerializer &arc);
#endif #endif

View file

@ -758,7 +758,7 @@ void D_Display ()
screen->DrawBlend(viewsec); screen->DrawBlend(viewsec);
if (automapactive) if (automapactive)
{ {
AM_Drawer (hud_althud? viewheight : StatusBar->GetTopOfStatusbar()); currentUILevel->automap->Drawer (hud_althud? viewheight : StatusBar->GetTopOfStatusbar());
} }
// for timing the statusbar code. // for timing the statusbar code.

View file

@ -955,7 +955,7 @@ bool G_Responder (event_t *ev)
{ {
if (ST_Responder (ev)) if (ST_Responder (ev))
return true; // status window ate it return true; // status window ate it
if (!viewactive && AM_Responder (ev, false)) if (!viewactive && currentUILevel->automap->Responder (ev, false))
return true; // automap ate it return true; // automap ate it
} }
else if (gamestate == GS_FINALE) else if (gamestate == GS_FINALE)
@ -986,7 +986,7 @@ bool G_Responder (event_t *ev)
// the events *last* so that any bound keys get precedence. // the events *last* so that any bound keys get precedence.
if (gamestate == GS_LEVEL && viewactive) if (gamestate == GS_LEVEL && viewactive)
return AM_Responder (ev, true); return currentUILevel->automap->Responder (ev, true);
return (ev->type == EV_KeyDown || return (ev->type == EV_KeyDown ||
ev->type == EV_Mouse); ev->type == EV_Mouse);
@ -1179,7 +1179,7 @@ void G_Ticker ()
{ {
case GS_LEVEL: case GS_LEVEL:
P_Ticker (); P_Ticker ();
AM_Ticker (); currentUILevel->automap->Ticker ();
break; break;
case GS_TITLELEVEL: case GS_TITLELEVEL:

View file

@ -1019,9 +1019,8 @@ void G_DoLoadLevel (int position, bool autosave, bool newGame)
E_NewGame(EventHandlerType::Global); E_NewGame(EventHandlerType::Global);
} }
P_SetupLevel (level.MapName, position, newGame); P_SetupLevel (&level, position, newGame);
AM_LevelInit();
// [RH] Start lightning, if MAPINFO tells us to // [RH] Start lightning, if MAPINFO tells us to
if (level.flags & LEVEL_STARTLIGHTNING) if (level.flags & LEVEL_STARTLIGHTNING)
@ -1126,6 +1125,7 @@ void G_DoLoadLevel (int position, bool autosave, bool newGame)
{ {
I_Error("no start for player %d found.", pnumerr); I_Error("no start for player %d found.", pnumerr);
} }
P_ResetSightCounters(true);
} }
@ -1452,8 +1452,6 @@ int G_FinishTravel ()
void FLevelLocals::Init() void FLevelLocals::Init()
{ {
level_info_t *info;
BaseBlendA = 0.0f; // Remove underwater blend effect, if any BaseBlendA = 0.0f; // Remove underwater blend effect, if any
gravity = sv_gravity * 35/TICRATE; gravity = sv_gravity * 35/TICRATE;
@ -1465,7 +1463,6 @@ void FLevelLocals::Init()
info = FindLevelInfo (MapName); info = FindLevelInfo (MapName);
info = info;
skyspeed1 = info->skyspeed1; skyspeed1 = info->skyspeed1;
skyspeed2 = info->skyspeed2; skyspeed2 = info->skyspeed2;
skytexture1 = TexMan.GetTextureID(info->SkyPic1, ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst); skytexture1 = TexMan.GetTextureID(info->SkyPic1, ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst);
@ -1976,6 +1973,7 @@ void FLevelLocals::Mark()
GC::Mark(SpotState); GC::Mark(SpotState);
GC::Mark(FraggleScriptThinker); GC::Mark(FraggleScriptThinker);
GC::Mark(ACSThinker); GC::Mark(ACSThinker);
GC::Mark(automap);
canvasTextureInfo.Mark(); canvasTextureInfo.Mark();
for (auto &c : CorpseQueue) for (auto &c : CorpseQueue)
{ {

View file

@ -87,6 +87,7 @@ class DACSThinker;
class DFraggleThinker; class DFraggleThinker;
class DSpotState; class DSpotState;
struct FStrifeDialogueNode; struct FStrifeDialogueNode;
class DAutomapBase;
typedef TMap<int, int> FDialogueIDMap; // maps dialogue IDs to dialogue array index (for ACS) typedef TMap<int, int> FDialogueIDMap; // maps dialogue IDs to dialogue array index (for ACS)
typedef TMap<FName, int> FDialogueMap; // maps actor class names to dialogue array index typedef TMap<FName, int> FDialogueMap; // maps actor class names to dialogue array index
@ -235,10 +236,10 @@ public:
{ {
return FLineIdIterator(tagManager, tag); return FLineIdIterator(tagManager, tag);
} }
template<class T> TThinkerIterator<T> GetThinkerIterator(FName subtype = NAME_None) template<class T> TThinkerIterator<T> GetThinkerIterator(FName subtype = NAME_None, int statnum = MAX_STATNUM+1)
{ {
if (subtype == NAME_None) return TThinkerIterator<T>(); if (subtype == NAME_None) return TThinkerIterator<T>(statnum);
else return TThinkerIterator<T>(subtype); else return TThinkerIterator<T>(subtype, statnum);
} }
FActorIterator GetActorIterator(int tid) FActorIterator GetActorIterator(int tid)
{ {
@ -357,6 +358,7 @@ public:
static const int BODYQUESIZE = 32; static const int BODYQUESIZE = 32;
TObjPtr<AActor*> bodyque[BODYQUESIZE]; TObjPtr<AActor*> bodyque[BODYQUESIZE];
TObjPtr<DAutomapBase*> automap;
int bodyqueslot; int bodyqueslot;
int NumMapSections; int NumMapSections;

View file

@ -1075,3 +1075,4 @@ xx(lightflags)
xx(lighttype) xx(lighttype)
xx(InternalDynamicLight) xx(InternalDynamicLight)
xx(_a_chase_default) xx(_a_chase_default)
xx(MapMarker)

View file

@ -965,7 +965,8 @@ void G_SerializeLevel(FSerializer &arc, FLevelLocals *Level, bool hubload)
("fragglethinker", Level->FraggleScriptThinker) ("fragglethinker", Level->FraggleScriptThinker)
("acsthinker", Level->ACSThinker) ("acsthinker", Level->ACSThinker)
("impactdecalcount", Level->ImpactDecalCount) ("impactdecalcount", Level->ImpactDecalCount)
("scrolls", Level->Scrolls); ("scrolls", Level->Scrolls)
("automap", Level->automap);
// Hub transitions must keep the current total time // Hub transitions must keep the current total time
@ -988,7 +989,10 @@ void G_SerializeLevel(FSerializer &arc, FLevelLocals *Level, bool hubload)
arc("zones", Level->Zones); arc("zones", Level->Zones);
arc("lineportals", Level->linePortals); arc("lineportals", Level->linePortals);
arc("sectorportals", Level->sectorPortals); arc("sectorportals", Level->sectorPortals);
if (arc.isReading()) Level->FinalizePortals(); if (arc.isReading())
{
Level->FinalizePortals();
}
// [ZZ] serialize health groups // [ZZ] serialize health groups
P_SerializeHealthGroups(arc); P_SerializeHealthGroups(arc);
@ -998,12 +1002,12 @@ void G_SerializeLevel(FSerializer &arc, FLevelLocals *Level, bool hubload)
arc("polyobjs", Level->Polyobjects); arc("polyobjs", Level->Polyobjects);
SerializeSubsectors(arc, "subsectors"); SerializeSubsectors(arc, "subsectors");
StatusBar->SerializeMessages(arc); StatusBar->SerializeMessages(arc);
AM_SerializeMarkers(arc);
FRemapTable::StaticSerializeTranslations(arc); FRemapTable::StaticSerializeTranslations(arc);
Level->canvasTextureInfo.Serialize(arc); Level->canvasTextureInfo.Serialize(arc);
P_SerializePlayers(Level, arc, hubload); P_SerializePlayers(Level, arc, hubload);
P_SerializeSounds(arc); P_SerializeSounds(arc);
// Regenerate some data that wasn't saved
if (arc.isReading()) if (arc.isReading())
{ {
for (auto &sec : Level->sectors) for (auto &sec : Level->sectors)
@ -1012,12 +1016,17 @@ void G_SerializeLevel(FSerializer &arc, FLevelLocals *Level, bool hubload)
} }
for (int i = 0; i < MAXPLAYERS; ++i) for (int i = 0; i < MAXPLAYERS; ++i)
{ {
if (playeringame[i] && players[i].mo != NULL) if (playeringame[i] && players[i].mo != nullptr)
{ {
FWeaponSlots::SetupWeaponSlots(players[i].mo); FWeaponSlots::SetupWeaponSlots(players[i].mo);
} }
} }
AActor::RecreateAllAttachedLights();
InitPortalGroups(Level);
Level->automap->Level = Level; // Temporary workaround. At the moment this cannot be deserialized yet.
Level->automap->UpdateShowAllLines();
} }
AActor::RecreateAllAttachedLights();
InitPortalGroups(Level);
} }

View file

@ -71,6 +71,7 @@
#include "a_specialspot.h" #include "a_specialspot.h"
#include "maploader/maploader.h" #include "maploader/maploader.h"
#include "p_acs.h" #include "p_acs.h"
#include "am_map.h"
#include "fragglescript/t_script.h" #include "fragglescript/t_script.h"
void P_ClearUDMFKeys(); void P_ClearUDMFKeys();
@ -260,6 +261,8 @@ void FLevelLocals::ClearPortals()
void FLevelLocals::ClearLevelData() void FLevelLocals::ClearLevelData()
{ {
ClearAllSubsectorLinks(); // can't be done as part of the polyobj deletion process.
total_monsters = total_items = total_secrets = total_monsters = total_items = total_secrets =
killed_monsters = found_items = found_secrets = killed_monsters = found_items = found_secrets =
wminfo.maxfrags = 0; wminfo.maxfrags = 0;
@ -348,7 +351,6 @@ void P_FreeLevelData ()
P_ClearUDMFKeys(); P_ClearUDMFKeys();
interpolator.ClearInterpolations(); // [RH] Nothing to interpolate on a fresh level. interpolator.ClearInterpolations(); // [RH] Nothing to interpolate on a fresh level.
level.ClearAllSubsectorLinks(); // can't be done as part of the polyobj deletion process.
SN_StopAllSequences (); SN_StopAllSequences ();
DThinker::DestroyAllThinkers (); DThinker::DestroyAllThinkers ();
@ -363,20 +365,20 @@ void P_FreeLevelData ()
// //
//=========================================================================== //===========================================================================
void P_SetupLevel(const char *lumpname, int position, bool newGame) void P_SetupLevel(FLevelLocals *Level, int position, bool newGame)
{ {
int i; int i;
level.ShaderStartTime = I_msTimeFS(); // indicate to the shader system that the level just started Level->ShaderStartTime = I_msTimeFS(); // indicate to the shader system that the level just started
// This is motivated as follows: // This is motivated as follows:
level.maptype = MAPTYPE_UNKNOWN; Level->maptype = MAPTYPE_UNKNOWN;
wminfo.partime = 180; wminfo.partime = 180;
if (!savegamerestore) if (!savegamerestore)
{ {
level.SetMusicVolume(level.MusicVolume); Level->SetMusicVolume(Level->MusicVolume);
for (i = 0; i < MAXPLAYERS; ++i) for (i = 0; i < MAXPLAYERS; ++i)
{ {
players[i].killcount = players[i].secretcount players[i].killcount = players[i].secretcount
@ -411,10 +413,10 @@ void P_SetupLevel(const char *lumpname, int position, bool newGame)
// Free all level data from the previous map // Free all level data from the previous map
P_FreeLevelData(); P_FreeLevelData();
MapData *map = P_OpenMapData(lumpname, true); MapData *map = P_OpenMapData(Level->MapName, true);
if (map == nullptr) if (map == nullptr)
{ {
I_Error("Unable to open map '%s'\n", lumpname); I_Error("Unable to open map '%s'\n", Level->MapName.GetChars());
} }
// [ZZ] init per-map static handlers. we need to call this before everything is set up because otherwise scripts don't receive PlayerEntered event // [ZZ] init per-map static handlers. we need to call this before everything is set up because otherwise scripts don't receive PlayerEntered event
@ -422,17 +424,17 @@ void P_SetupLevel(const char *lumpname, int position, bool newGame)
E_InitStaticHandlers(true); E_InitStaticHandlers(true);
// generate a checksum for the level, to be included and checked with savegames. // generate a checksum for the level, to be included and checked with savegames.
map->GetChecksum(level.md5); map->GetChecksum(Level->md5);
// find map num // find map num
level.lumpnum = map->lumpnum; Level->lumpnum = map->lumpnum;
if (newGame) if (newGame)
{ {
E_NewGame(EventHandlerType::PerMap); E_NewGame(EventHandlerType::PerMap);
} }
MapLoader loader(&level); MapLoader loader(Level);
loader.LoadLevel(map, lumpname, position); loader.LoadLevel(map, Level->MapName.GetChars(), position);
delete map; delete map;
// if deathmatch, randomly spawn the active players // if deathmatch, randomly spawn the active players
@ -448,7 +450,7 @@ void P_SetupLevel(const char *lumpname, int position, bool newGame)
} }
} }
// the same, but for random single/coop player starts // the same, but for random single/coop player starts
else if (level.flags2 & LEVEL2_RANDOMPLAYERSTARTS) else if (Level->flags2 & LEVEL2_RANDOMPLAYERSTARTS)
{ {
for (i = 0; i < MAXPLAYERS; ++i) for (i = 0; i < MAXPLAYERS; ++i)
{ {
@ -456,14 +458,14 @@ void P_SetupLevel(const char *lumpname, int position, bool newGame)
{ {
players[i].mo = nullptr; players[i].mo = nullptr;
FPlayerStart *mthing = G_PickPlayerStart(i); FPlayerStart *mthing = G_PickPlayerStart(i);
P_SpawnPlayer(mthing, i, (level.flags2 & LEVEL2_PRERAISEWEAPON) ? SPF_WEAPONFULLYUP : 0); P_SpawnPlayer(mthing, i, (Level->flags2 & LEVEL2_PRERAISEWEAPON) ? SPF_WEAPONFULLYUP : 0);
} }
} }
} }
// [SP] move unfriendly players around // [SP] move unfriendly players around
// horribly hacky - yes, this needs rewritten. // horribly hacky - yes, this needs rewritten.
if (level.deathmatchstarts.Size() > 0) if (Level->deathmatchstarts.Size() > 0)
{ {
for (i = 0; i < MAXPLAYERS; ++i) for (i = 0; i < MAXPLAYERS; ++i)
{ {
@ -522,7 +524,7 @@ void P_SetupLevel(const char *lumpname, int position, bool newGame)
// This check was previously done at run time each time the heightsec was checked. // This check was previously done at run time each time the heightsec was checked.
// However, since 3D floors are static data, we can easily precalculate this and store it in the sector's flags for quick access. // However, since 3D floors are static data, we can easily precalculate this and store it in the sector's flags for quick access.
for (auto &s : level.sectors) for (auto &s : Level->sectors)
{ {
if (s.heightsec != nullptr) if (s.heightsec != nullptr)
{ {
@ -537,17 +539,18 @@ void P_SetupLevel(const char *lumpname, int position, bool newGame)
} }
} }
P_ResetSightCounters(true);
// Create a backup of the map data so the savegame code can toss out all fields that haven't changed in order to reduce processing time and file size. // Create a backup of the map data so the savegame code can toss out all fields that haven't changed in order to reduce processing time and file size.
// Note that we want binary identity here, so assignment is not sufficient because it won't initialize any padding bytes. // Note that we want binary identity here, so assignment is not sufficient because it won't initialize any padding bytes.
// Note that none of these structures may contain non POD fields anyway. // Note that none of these structures may contain non POD fields anyway.
level.loadsectors.Resize(level.sectors.Size()); Level->loadsectors.Resize(Level->sectors.Size());
memcpy(&level.loadsectors[0], &level.sectors[0], level.sectors.Size() * sizeof(level.sectors[0])); memcpy(&Level->loadsectors[0], &Level->sectors[0], Level->sectors.Size() * sizeof(Level->sectors[0]));
level.loadlines.Resize(level.lines.Size()); Level->loadlines.Resize(Level->lines.Size());
memcpy(&level.loadlines[0], &level.lines[0], level.lines.Size() * sizeof(level.lines[0])); memcpy(&Level->loadlines[0], &Level->lines[0], Level->lines.Size() * sizeof(Level->lines[0]));
level.loadsides.Resize(level.sides.Size()); Level->loadsides.Resize(Level->sides.Size());
memcpy(&level.loadsides[0], &level.sides[0], level.sides.Size() * sizeof(level.sides[0])); memcpy(&Level->loadsides[0], &Level->sides[0], Level->sides.Size() * sizeof(Level->sides[0]));
Level->automap = AM_Create(Level);
Level->automap->LevelInit();
} }
// //

View file

@ -146,7 +146,7 @@ bool P_CheckMapData(const char * mapname);
// [RH] The only parameter used is mapname, so I removed playermask and skill. // [RH] The only parameter used is mapname, so I removed playermask and skill.
// On September 1, 1998, I added the position to indicate which set // On September 1, 1998, I added the position to indicate which set
// of single-player start spots should be spawned in the level. // of single-player start spots should be spawned in the level.
void P_SetupLevel (const char *mapname, int position, bool newGame); void P_SetupLevel (FLevelLocals *Level, int position, bool newGame);
void P_FreeLevelData(); void P_FreeLevelData();

View file

@ -46,6 +46,7 @@
#include "d_player.h" #include "d_player.h"
#include "p_setup.h" #include "p_setup.h"
#include "i_music.h" #include "i_music.h"
#include "am_map.h"
DVector2 AM_GetPosition(); DVector2 AM_GetPosition();
int Net_GetLatency(int *ld, int *ad); int Net_GetLatency(int *ld, int *ad);
@ -2529,15 +2530,17 @@ DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, FormatMapName, FormatMapName)
ACTION_RETURN_STRING(rets); ACTION_RETURN_STRING(rets);
} }
static void GetAutomapPosition(DVector2 *pos) static void GetAutomapPosition(FLevelLocals *self, DVector2 *pos)
{ {
*pos = AM_GetPosition(); *pos = self->automap->GetPosition();
} }
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, GetAutomapPosition, GetAutomapPosition) DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, GetAutomapPosition, GetAutomapPosition)
{ {
PARAM_PROLOGUE; PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
ACTION_RETURN_VEC2(AM_GetPosition()); DVector2 result;
GetAutomapPosition(self, &result);
ACTION_RETURN_VEC2(result);
} }
static int ZGetUDMFInt(FLevelLocals *self, int type, int index, int key) static int ZGetUDMFInt(FLevelLocals *self, int type, int index, int key)

View file

@ -66,6 +66,8 @@
#include "r_videoscale.h" #include "r_videoscale.h"
#include "i_time.h" #include "i_time.h"
#include "version.h" #include "version.h"
#include "g_levellocals.h"
#include "am_map.h"
EXTERN_CVAR(Bool, cl_capfps) EXTERN_CVAR(Bool, cl_capfps)
EXTERN_CVAR(Int, menu_resolution_custom_width) EXTERN_CVAR(Int, menu_resolution_custom_width)
@ -592,7 +594,8 @@ void V_OutputResized (int width, int height)
C_NewModeAdjust(); C_NewModeAdjust();
// Reload crosshair if transitioned to a different size // Reload crosshair if transitioned to a different size
ST_LoadCrosshair(true); ST_LoadCrosshair(true);
AM_NewResolution(); if (currentUILevel && currentUILevel->automap)
currentUILevel->automap->NewResolution();
} }
void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int realheight, int *cleanx, int *cleany, int *_cx1, int *_cx2) void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int realheight, int *cleanx, int *cleany, int *_cx1, int *_cx2)

View file

@ -687,7 +687,7 @@ struct LevelLocals native
native static void StartSlideshow(Name whichone = 'none'); native static void StartSlideshow(Name whichone = 'none');
native static void WorldDone(); native static void WorldDone();
native static void RemoveAllBots(bool fromlist); native static void RemoveAllBots(bool fromlist);
native static Vector2 GetAutomapPosition(); native ui Vector2 GetAutomapPosition();
native void SetInterMusic(String nextmap); native void SetInterMusic(String nextmap);
native String FormatMapName(int mapnamecolor); native String FormatMapName(int mapnamecolor);
native bool IsJumpingAllowed() const; native bool IsJumpingAllowed() const;
@ -722,8 +722,8 @@ struct LevelLocals native
return String.Format("%02d:%02d:%02d", sec / 3600, (sec % 3600) / 60, sec % 60); return String.Format("%02d:%02d:%02d", sec / 3600, (sec % 3600) / 60, sec % 60);
} }
native bool CreateCeiling(sector sec, int type, line ln, double speed, double speed2, double height = 0, int crush = -1, int silent = 0, int change = 0, int crushmode = crushDoom); native bool CreateCeiling(sector sec, int type, line ln, double speed, double speed2, double height = 0, int crush = -1, int silent = 0, int change = 0, int crushmode = 0 /*Floor.crushDoom*/);
native bool CreateFloor(sector sec, EFloor floortype, line ln, double speed, double height = 0, int crush = -1, int change = 0, bool crushmode = false, bool hereticlower = false); native bool CreateFloor(sector sec, int floortype, line ln, double speed, double height = 0, int crush = -1, int change = 0, bool crushmode = false, bool hereticlower = false);
} }
@ -926,7 +926,7 @@ class Floor : MovingFloor native
genFloorChg genFloorChg
}; };
deprecated("3.8") static bool CreateFloor(sector sec, EFloor floortype, line ln, double speed, double height = 0, int crush = -1, int change = 0, bool crushmode = false, bool hereticlower = false) deprecated("3.8") static bool CreateFloor(sector sec, int floortype, line ln, double speed, double height = 0, int crush = -1, int change = 0, bool crushmode = false, bool hereticlower = false)
{ {
return level.CreateFloor(sec, floortype, ln, speed, height, crush, change, crushmode, hereticlower); return level.CreateFloor(sec, floortype, ln, speed, height, crush, change, crushmode, hereticlower);
} }

View file

@ -31,11 +31,6 @@
** **
*/ */
/*
DVector2 AM_GetPosition();
*/
class AltHud ui class AltHud ui
{ {
TextureID tnt1a0; TextureID tnt1a0;