- continued with the 'level' eradication.

This commit is contained in:
Christoph Oelckers 2019-01-07 20:50:34 +01:00
parent 0441c9c950
commit f251e341a8
34 changed files with 375 additions and 312 deletions

View file

@ -942,7 +942,7 @@ void G_DoLoadLevel (int position, bool autosave, bool newGame)
else
lastposition = position;
G_InitLevelLocals ();
level.InitLevelLocals ();
StatusBar->DetachAllMessages ();
// Force 'teamplay' to 'true' if need be.
@ -1014,7 +1014,7 @@ void G_DoLoadLevel (int position, bool autosave, bool newGame)
E_NewGame(EventHandlerType::Global);
}
P_SetupLevel (level.MapName, position, newGame);
P_SetupLevel (&level, level.MapName, position, newGame);
AM_LevelInit();
@ -1445,95 +1445,88 @@ int G_FinishTravel ()
//
//==========================================================================
void G_InitLevelLocals ()
void FLevelLocals::InitLevelLocals ()
{
level_info_t *info;
BaseBlendA = 0.0f; // Remove underwater blend effect, if any
level.gravity = sv_gravity * 35/TICRATE;
level.aircontrol = sv_aircontrol;
level.teamdamage = teamdamage;
level.flags = 0;
level.flags2 = 0;
level.flags3 = 0;
gravity = sv_gravity * 35/TICRATE;
aircontrol = sv_aircontrol;
teamdamage = teamdamage;
flags = 0;
flags2 = 0;
flags3 = 0;
info = FindLevelInfo (level.MapName);
info = FindLevelInfo (MapName);
level.info = info;
level.skyspeed1 = info->skyspeed1;
level.skyspeed2 = info->skyspeed2;
level.skytexture1 = TexMan.GetTextureID(info->SkyPic1, ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst);
level.skytexture2 = TexMan.GetTextureID(info->SkyPic2, ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst);
level.fadeto = info->fadeto;
level.cdtrack = info->cdtrack;
level.cdid = info->cdid;
level.FromSnapshot = false;
if (level.fadeto == 0)
skyspeed1 = info->skyspeed1;
skyspeed2 = info->skyspeed2;
skytexture1 = TexMan.GetTextureID(info->SkyPic1, ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst);
skytexture2 = TexMan.GetTextureID(info->SkyPic2, ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst);
fadeto = info->fadeto;
cdtrack = info->cdtrack;
cdid = info->cdid;
FromSnapshot = false;
if (fadeto == 0)
{
if (strnicmp (info->FadeTable, "COLORMAP", 8) != 0)
{
level.flags |= LEVEL_HASFADETABLE;
flags |= LEVEL_HASFADETABLE;
}
}
level.airsupply = info->airsupply*TICRATE;
level.outsidefog = info->outsidefog;
level.WallVertLight = info->WallVertLight*2;
level.WallHorizLight = info->WallHorizLight*2;
airsupply = info->airsupply*TICRATE;
outsidefog = info->outsidefog;
WallVertLight = info->WallVertLight*2;
WallHorizLight = info->WallHorizLight*2;
if (info->gravity != 0.f)
{
level.gravity = info->gravity * 35/TICRATE;
}
if (info->aircontrol != 0.f)
{
level.aircontrol = info->aircontrol;
gravity = info->gravity * 35/TICRATE;
}
if (info->teamdamage != 0.f)
{
level.teamdamage = info->teamdamage;
teamdamage = info->teamdamage;
}
G_AirControlChanged ();
ChangeAirControl(info->aircontrol != 0.f? info->aircontrol : *sv_aircontrol);
cluster_info_t *clus = FindClusterInfo (info->cluster);
level.partime = info->partime;
level.sucktime = info->sucktime;
level.cluster = info->cluster;
level.clusterflags = clus ? clus->flags : 0;
level.flags |= info->flags;
level.flags2 |= info->flags2;
level.flags3 |= info->flags3;
level.levelnum = info->levelnum;
level.Music = info->Music;
level.musicorder = info->musicorder;
level.MusicVolume = 1.f;
level.HasHeightSecs = false;
partime = info->partime;
sucktime = info->sucktime;
cluster = info->cluster;
clusterflags = clus ? clus->flags : 0;
flags |= info->flags;
flags2 |= info->flags2;
flags3 |= info->flags3;
levelnum = info->levelnum;
Music = info->Music;
musicorder = info->musicorder;
MusicVolume = 1.f;
HasHeightSecs = false;
level.LevelName = level.info->LookupLevelName();
level.NextMap = info->NextMap;
level.NextSecretMap = info->NextSecretMap;
level.F1Pic = info->F1Pic;
level.hazardcolor = info->hazardcolor;
level.hazardflash = info->hazardflash;
LevelName = info->LookupLevelName();
NextMap = info->NextMap;
NextSecretMap = info->NextSecretMap;
F1Pic = info->F1Pic;
hazardcolor = info->hazardcolor;
hazardflash = info->hazardflash;
// GL fog stuff modifiable by SetGlobalFogParameter.
level.fogdensity = info->fogdensity;
level.outsidefogdensity = info->outsidefogdensity;
level.skyfog = info->skyfog;
level.deathsequence = info->deathsequence;
fogdensity = info->fogdensity;
outsidefogdensity = info->outsidefogdensity;
skyfog = info->skyfog;
deathsequence = info->deathsequence;
level.pixelstretch = info->pixelstretch;
pixelstretch = info->pixelstretch;
compatflags.Callback();
compatflags2.Callback();
level.DefaultEnvironment = info->DefaultEnvironment;
DefaultEnvironment = info->DefaultEnvironment;
level.lightMode = info->lightmode == ELightMode::NotSet? (ELightMode)*gl_lightmode : info->lightmode;
level.brightfog = info->brightfog < 0? gl_brightfog : !!info->brightfog;
level.lightadditivesurfaces = info->lightadditivesurfaces < 0 ? gl_lightadditivesurfaces : !!info->lightadditivesurfaces;
level.notexturefill = info->notexturefill < 0 ? gl_notexturefill : !!info->notexturefill;
lightMode = info->lightmode == ELightMode::NotSet? (ELightMode)*gl_lightmode : info->lightmode;
brightfog = info->brightfog < 0? gl_brightfog : !!info->brightfog;
lightadditivesurfaces = info->lightadditivesurfaces < 0 ? gl_lightadditivesurfaces : !!info->lightadditivesurfaces;
notexturefill = info->notexturefill < 0 ? gl_notexturefill : !!info->notexturefill;
FLightDefaults::SetAttenuationForLevel();
}
@ -1626,16 +1619,17 @@ FString CalcMapName (int episode, int level)
//
//==========================================================================
void G_AirControlChanged ()
void FLevelLocals::ChangeAirControl(double newval)
{
if (level.aircontrol <= 1/256.)
aircontrol = newval;
if (aircontrol <= 1/256.)
{
level.airfriction = 1.;
airfriction = 1.;
}
else
{
// Friction is inversely proportional to the amount of control
level.airfriction = level.aircontrol * -0.0941 + 1.0004;
airfriction = aircontrol * -0.0941 + 1.0004;
}
}

View file

@ -116,6 +116,8 @@ struct FLevelLocals : public FLevelData
void FormatMapName(FString &mapname, const char *mapnamecolor);
void TranslateTeleportThings(void);
void ClearAllSubsectorLinks();
void ChangeAirControl(double newval);
void InitLevelLocals();
uint8_t md5[16]; // for savegame validation. If the MD5 does not match the savegame won't be loaded.
int time; // time in the hub
@ -336,4 +338,13 @@ inline bool line_t::hitSkyWall(AActor* mo) const
backsector->GetTexture(sector_t::ceiling) == skyflatnum &&
mo->Z() >= backsector->ceilingplane.ZatPoint(mo->PosRelative(this));
}
// For handling CVARs that alter level settings.
// If we add multi-level handling later they need to be able to adjust and with a function like this the change can be done right now.
template<class T>
inline void ForAllLevels(T func)
{
func(&level);
}
#endif

View file

@ -85,12 +85,15 @@ CUSTOM_CVAR (Bool, gl_light_shadowmap, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
{
if (!self)
{
auto light = level.lights;
while (light)
ForAllLevels([](FLevelLocals *Level)
{
light->mShadowmapIndex = 1024;
light = light->next;
}
auto light = Level->lights;
while (light)
{
light->mShadowmapIndex = 1024;
light = light->next;
}
});
}
}

View file

@ -287,7 +287,10 @@ void cht_DoCheat (player_t *player, int cheat)
if (i == 4)
{
level.flags2 ^= LEVEL2_ALLMAP;
ForAllLevels([](FLevelLocals *Level)
{
Level->flags2 ^= LEVEL2_ALLMAP;
});
}
else if (player->mo != NULL && player->health >= 0)
{

View file

@ -3184,7 +3184,7 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position)
CopySlopes();
// Spawn 3d floors - must be done before spawning things so it can't be done in P_SpawnSpecials
P_Spawn3DFloors();
P_Spawn3DFloors(Level);
SpawnThings(position);
@ -3218,7 +3218,7 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position)
}
InitRenderInfo(); // create hardware independent renderer resources for the Level-> This must be done BEFORE the PolyObj Spawn!!!
P_ClearDynamic3DFloorData(); // CreateVBO must be run on the plain 3D floor data.
P_ClearDynamic3DFloorData(Level); // CreateVBO must be run on the plain 3D floor data.
screen->mVertexData->CreateVBO(Level->sectors);
for (auto &sec : Level->sectors)

View file

@ -211,11 +211,12 @@ static int P_Set3DFloor(line_t * line, int param, int param2, int alpha)
int flags;
int tag = line->args[0];
sector_t * sec = line->frontsector, *ss;
auto Level = sec->Level;
FSectorTagIterator itr(tag);
while ((s = itr.Next()) >= 0)
{
ss = &level.sectors[s];
ss = &Level->sectors[s];
if (param == 0)
{
@ -656,9 +657,9 @@ void P_Recalculate3DFloors(sector_t * sector)
//
//==========================================================================
void P_ClearDynamic3DFloorData()
void P_ClearDynamic3DFloorData(FLevelLocals *Level)
{
for (auto &sec : level.sectors)
for (auto &sec : Level->sectors)
{
TArray<F3DFloor*> & ffloors = sec.e->XFloor.ffloors;
@ -882,11 +883,11 @@ void P_LineOpening_XFloors (FLineOpening &open, AActor * thing, const line_t *li
// Spawns 3D floors
//
//==========================================================================
void P_Spawn3DFloors (void)
void P_Spawn3DFloors (FLevelLocals *Level)
{
static int flagvals[] = {512, 2+512, 512+1024};
for (auto &line : level.lines)
for (auto &line : Level->lines)
{
switch(line.special)
{
@ -900,7 +901,7 @@ void P_Spawn3DFloors (void)
// The flag high-byte/line id is only needed in Hexen format.
// UDMF can set both of these parameters without any restriction of the usable values.
// In Doom format the translators can take full integers for the tag and the line ID always is the same as the tag.
if (level.maptype == MAPTYPE_HEXEN)
if (Level->maptype == MAPTYPE_HEXEN)
{
if (line.args[1]&8)
{
@ -922,7 +923,7 @@ void P_Spawn3DFloors (void)
line.args[0] = line.args[1] = line.args[2] = line.args[3] = line.args[4] = 0;
}
for (auto &sec : level.sectors)
for (auto &sec : Level->sectors)
{
P_Recalculate3DFloors(&sec);
}
@ -1015,28 +1016,25 @@ int P_Find3DFloor(sector_t * sec, const DVector3 &pos, bool above, bool floor, d
CCMD (dump3df)
{
if (argv.argc() > 1)
ForAllLevels([](FLevelLocals *Level)
{
int sec = (int)strtoll(argv[1], NULL, 10);
if ((unsigned)sec >= level.sectors.Size())
Printf("%s - %s\n", Level->MapName.GetChars(), Level->LevelName.GetChars());
for (auto &sec : Level->sectors)
{
Printf("Sector %d does not exist.\n", sec);
return;
}
sector_t *sector = &level.sectors[sec];
TArray<F3DFloor*> & ffloors=sector->e->XFloor.ffloors;
TArray<F3DFloor*> & ffloors = sec.e->XFloor.ffloors;
for (unsigned int i = 0; i < ffloors.Size(); i++)
{
double height=ffloors[i]->top.plane->ZatPoint(sector->centerspot);
double bheight=ffloors[i]->bottom.plane->ZatPoint(sector->centerspot);
for (unsigned int i = 0; i < ffloors.Size(); i++)
{
double height = ffloors[i]->top.plane->ZatPoint(sec.centerspot);
double bheight = ffloors[i]->bottom.plane->ZatPoint(sec.centerspot);
IGNORE_FORMAT_PRE
Printf("FFloor %d @ top = %f (model = %d), bottom = %f (model = %d), flags = %B, alpha = %d %s %s\n",
i, height, ffloors[i]->top.model->sectornum,
bheight, ffloors[i]->bottom.model->sectornum,
ffloors[i]->flags, ffloors[i]->alpha, (ffloors[i]->flags&FF_EXISTS)? "Exists":"", (ffloors[i]->flags&FF_DYNAMIC)? "Dynamic":"");
IGNORE_FORMAT_POST
IGNORE_FORMAT_PRE
Printf("FFloor %d @ top = %f (model = %d), bottom = %f (model = %d), flags = %B, alpha = %d %s %s\n",
i, height, ffloors[i]->top.model->sectornum,
bheight, ffloors[i]->bottom.model->sectornum,
ffloors[i]->flags, ffloors[i]->alpha, (ffloors[i]->flags&FF_EXISTS) ? "Exists" : "", (ffloors[i]->flags&FF_DYNAMIC) ? "Dynamic" : "");
IGNORE_FORMAT_POST
}
}
}
});
}

View file

@ -123,10 +123,10 @@ void P_Recalculate3DFloors(sector_t *);
void P_RecalculateAttached3DFloors(sector_t * sec);
void P_RecalculateLights(sector_t *sector);
void P_RecalculateAttachedLights(sector_t *sector);
void P_ClearDynamic3DFloorData();
void P_ClearDynamic3DFloorData(FLevelLocals *Level);
lightlist_t * P_GetPlaneLight(sector_t * , secplane_t * plane, bool underside);
void P_Spawn3DFloors( void );
void P_Spawn3DFloors(FLevelLocals *);
struct FLineOpening;

View file

@ -121,13 +121,14 @@ void P_Attach3dMidtexLinesToSector(sector_t *sector, int lineid, int tag, bool c
}
extsector_t::midtex::plane &scrollplane = ceiling? sector->e->Midtex.Ceiling : sector->e->Midtex.Floor;
auto Level = sector->Level;
// Bit arrays that mark whether a line or sector is to be attached.
uint8_t *found_lines = new uint8_t[(level.lines.Size()+7)/8];
uint8_t *found_sectors = new uint8_t[(level.sectors.Size()+7)/8];
uint8_t *found_lines = new uint8_t[(Level->lines.Size()+7)/8];
uint8_t *found_sectors = new uint8_t[(Level->sectors.Size()+7)/8];
memset(found_lines, 0, sizeof (uint8_t) * ((level.lines.Size()+7)/8));
memset(found_sectors, 0, sizeof (uint8_t) * ((level.sectors.Size()+7)/8));
memset(found_lines, 0, sizeof (uint8_t) * ((Level->lines.Size()+7)/8));
memset(found_sectors, 0, sizeof (uint8_t) * ((Level->sectors.Size()+7)/8));
// mark all lines and sectors that are already attached to this one
// and clear the arrays. The old data will be re-added automatically
@ -153,7 +154,7 @@ void P_Attach3dMidtexLinesToSector(sector_t *sector, int lineid, int tag, bool c
int line;
while ((line = itr.Next()) >= 0)
{
line_t *ln = &level.lines[line];
line_t *ln = &Level->lines[line];
if (ln->frontsector == NULL || ln->backsector == NULL || !(ln->flags & ML_3DMIDTEX))
{
@ -169,7 +170,7 @@ void P_Attach3dMidtexLinesToSector(sector_t *sector, int lineid, int tag, bool c
int sec;
while ((sec = it.Next()) >= 0)
{
for (auto ln : level.sectors[sec].Lines)
for (auto ln : Level->sectors[sec].Lines)
{
if (lineid != 0 && !tagManager.LineHasID(ln, lineid)) continue;
@ -185,28 +186,28 @@ void P_Attach3dMidtexLinesToSector(sector_t *sector, int lineid, int tag, bool c
}
for(unsigned i=0; i < level.lines.Size(); i++)
for(unsigned i=0; i < Level->lines.Size(); i++)
{
if (found_lines[i>>3] & (1 << (i&7)))
{
auto &line = level.lines[i];
auto &line = Level->lines[i];
scrollplane.AttachedLines.Push(&line);
v = line.frontsector->Index();
assert(v < (int)level.sectors.Size());
assert(v < (int)Level->sectors.Size());
found_sectors[v>>3] |= 1 << (v&7);
v = line.backsector->Index();
assert(v < (int)level.sectors.Size());
assert(v < (int)Level->sectors.Size());
found_sectors[v>>3] |= 1 << (v&7);
}
}
for (unsigned i=0; i < level.sectors.Size(); i++)
for (unsigned i=0; i < Level->sectors.Size(); i++)
{
if (found_sectors[i>>3] & (1 << (i&7)))
{
scrollplane.AttachedSectors.Push(&level.sectors[i]);
scrollplane.AttachedSectors.Push(&Level->sectors[i]);
}
}

View file

@ -9062,15 +9062,13 @@ scriptwait:
break;
case PCD_SETAIRCONTROL:
level.aircontrol = ACSToDouble(STACK(1));
level.ChangeAirControl(ACSToDouble(STACK(1)));
sp--;
G_AirControlChanged ();
break;
case PCD_SETAIRCONTROLDIRECT:
level.aircontrol = ACSToDouble(uallong(pc[0]));
level.ChangeAirControl(ACSToDouble(uallong(pc[0])));
pc++;
G_AirControlChanged ();
break;
case PCD_SPAWN:

View file

@ -1956,6 +1956,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Respawn)
bool oktorespawn = false;
DVector3 pos = self->Pos();
auto Level = self->__GetLevel();
self->flags |= MF_SOLID;
self->Height = self->GetDefault()->Height;
@ -2012,7 +2013,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Respawn)
}
if (self->CountsAsKill())
{
level.total_monsters++;
Level->total_monsters++;
}
}
else
@ -2610,9 +2611,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_ChangeCountFlags)
PARAM_INT(item);
PARAM_INT(secret);
if (self->CountsAsKill() && self->health > 0) --level.total_monsters;
if (self->flags & MF_COUNTITEM) --level.total_items;
if (self->flags5 & MF5_COUNTSECRET) --level.total_secrets;
auto Level = self->__GetLevel();
if (self->CountsAsKill() && self->health > 0) --Level->total_monsters;
if (self->flags & MF_COUNTITEM) --Level->total_items;
if (self->flags5 & MF5_COUNTSECRET) --Level->total_secrets;
if (kill != -1)
{
@ -2631,9 +2633,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_ChangeCountFlags)
if (secret == 0) self->flags5 &= ~MF5_COUNTSECRET;
else self->flags5 |= MF5_COUNTSECRET;
}
if (self->CountsAsKill() && self->health > 0) ++level.total_monsters;
if (self->flags & MF_COUNTITEM) ++level.total_items;
if (self->flags5 & MF5_COUNTSECRET) ++level.total_secrets;
if (self->CountsAsKill() && self->health > 0) ++Level->total_monsters;
if (self->flags & MF_COUNTITEM) ++Level->total_items;
if (self->flags5 & MF5_COUNTSECRET) ++Level->total_secrets;
return 0;
}

View file

@ -1258,7 +1258,8 @@ AActor *LookForTIDInBlock (AActor *lookee, int index, void *extparams)
AActor *link;
AActor *other;
for (block = level.blockmap.blocklinks[index]; block != NULL; block = block->NextActor)
auto Level = lookee->__GetLevel();
for (block = Level->blockmap.blocklinks[index]; block != NULL; block = block->NextActor)
{
link = block->Me;
@ -1429,7 +1430,8 @@ AActor *LookForEnemiesInBlock (AActor *lookee, int index, void *extparam)
AActor *other;
FLookExParams *params = (FLookExParams *)extparam;
for (block = level.blockmap.blocklinks[index]; block != NULL; block = block->NextActor)
auto Level = lookee->__GetLevel();
for (block = Level->blockmap.blocklinks[index]; block != NULL; block = block->NextActor)
{
link = block->Me;
@ -1757,13 +1759,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_Look)
if (self->flags5 & MF5_INCONVERSATION)
return 0;
auto Level = self->__GetLevel();
// [RH] Set goal now if appropriate
if (self->special == Thing_SetGoal && self->args[0] == 0)
{
NActorIterator iterator (NAME_PatrolPoint, self->args[1]);
self->special = 0;
self->goal = iterator.Next ();
self->reactiontime = self->args[2] * TICRATE + level.maptime;
self->reactiontime = self->args[2] * TICRATE + Level->maptime;
if (self->args[3] == 0) self->flags5 &= ~MF5_CHASEGOAL;
else self->flags5 |= MF5_CHASEGOAL;
}
@ -1838,7 +1842,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Look)
// [RH] Don't start chasing after a goal if it isn't time yet.
if (self->target == self->goal)
{
if (self->reactiontime > level.maptime)
if (self->reactiontime > Level->maptime)
self->target = nullptr;
}
else if (self->SeeSound)
@ -1886,13 +1890,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_LookEx)
if (self->flags5 & MF5_INCONVERSATION)
return 0;
auto Level = self->__GetLevel();
// [RH] Set goal now if appropriate
if (self->special == Thing_SetGoal && self->args[0] == 0)
{
NActorIterator iterator(NAME_PatrolPoint, self->args[1]);
self->special = 0;
self->goal = iterator.Next ();
self->reactiontime = self->args[2] * TICRATE + level.maptime;
self->reactiontime = self->args[2] * TICRATE + Level->maptime;
if (self->args[3] == 0)
self->flags5 &= ~MF5_CHASEGOAL;
else
@ -2020,7 +2026,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LookEx)
// [RH] Don't start chasing after a goal if it isn't time yet.
if (self->target == self->goal)
{
if (self->reactiontime > level.maptime)
if (self->reactiontime > Level->maptime)
self->target = nullptr;
}
else if (self->SeeSound && !(flags & LOF_NOSEESOUND))
@ -2147,10 +2153,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_Look2)
{
targ = NULL;
}
auto Level = self->__GetLevel();
if (targ && (targ->flags & MF_SHOOTABLE))
{
if ((level.flags & LEVEL_NOALLIES) ||
if ((Level->flags & LEVEL_NOALLIES) ||
(self->flags & MF_FRIENDLY) != (targ->flags & MF_FRIENDLY))
{
if (self->flags & MF_AMBUSH)
@ -2371,6 +2378,8 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi
if (result)
{
auto Level = actor->__GetLevel();
// reached the goal
NActorIterator iterator (NAME_PatrolPoint, actor->goal->args[0]);
NActorIterator specit (NAME_PatrolSpecial, actor->goal->tid);
@ -2390,7 +2399,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi
if (newgoal != NULL && actor->goal == actor->target)
{
delay = newgoal->args[1];
actor->reactiontime = delay * TICRATE + level.maptime;
actor->reactiontime = delay * TICRATE + Level->maptime;
}
else
{
@ -3074,9 +3083,10 @@ void A_BossDeath(AActor *self)
// Do generic special death actions first
bool checked = false;
for (unsigned i = 0; i < level.info->specialactions.Size(); i++)
auto Level = self->__GetLevel();
for (unsigned i = 0; i < Level->info->specialactions.Size(); i++)
{
FSpecialAction *sa = &level.info->specialactions[i];
FSpecialAction *sa = &Level->info->specialactions[i];
if (type == sa->Type || mytype == sa->Type)
{
@ -3094,7 +3104,7 @@ void A_BossDeath(AActor *self)
// [RH] These all depend on the presence of level flags now
// rather than being hard-coded to specific levels/episodes.
if ((level.flags & (LEVEL_MAP07SPECIAL|
if ((Level->flags & (LEVEL_MAP07SPECIAL|
LEVEL_BRUISERSPECIAL|
LEVEL_CYBORGSPECIAL|
LEVEL_SPIDERSPECIAL|
@ -3104,13 +3114,13 @@ void A_BossDeath(AActor *self)
return;
if ((i_compatflags & COMPATF_ANYBOSSDEATH) || ( // [GZ] Added for UAC_DEAD
((level.flags & LEVEL_MAP07SPECIAL) && (type == NAME_Fatso || type == NAME_Arachnotron)) ||
((level.flags & LEVEL_BRUISERSPECIAL) && (type == NAME_BaronOfHell)) ||
((level.flags & LEVEL_CYBORGSPECIAL) && (type == NAME_Cyberdemon)) ||
((level.flags & LEVEL_SPIDERSPECIAL) && (type == NAME_SpiderMastermind)) ||
((level.flags & LEVEL_HEADSPECIAL) && (type == NAME_Ironlich)) ||
((level.flags & LEVEL_MINOTAURSPECIAL) && (type == NAME_Minotaur)) ||
((level.flags & LEVEL_SORCERER2SPECIAL) && (type == NAME_Sorcerer2))
((Level->flags & LEVEL_MAP07SPECIAL) && (type == NAME_Fatso || type == NAME_Arachnotron)) ||
((Level->flags & LEVEL_BRUISERSPECIAL) && (type == NAME_BaronOfHell)) ||
((Level->flags & LEVEL_CYBORGSPECIAL) && (type == NAME_Cyberdemon)) ||
((Level->flags & LEVEL_SPIDERSPECIAL) && (type == NAME_SpiderMastermind)) ||
((Level->flags & LEVEL_HEADSPECIAL) && (type == NAME_Ironlich)) ||
((Level->flags & LEVEL_MINOTAURSPECIAL) && (type == NAME_Minotaur)) ||
((Level->flags & LEVEL_SORCERER2SPECIAL) && (type == NAME_Sorcerer2))
))
;
else
@ -3122,11 +3132,11 @@ void A_BossDeath(AActor *self)
}
// victory!
if (level.flags & LEVEL_SPECKILLMONSTERS)
if (Level->flags & LEVEL_SPECKILLMONSTERS)
{ // Kill any remaining monsters
P_Massacre ();
}
if (level.flags & LEVEL_MAP07SPECIAL)
if (Level->flags & LEVEL_MAP07SPECIAL)
{
if (type == NAME_Fatso)
{
@ -3142,7 +3152,7 @@ void A_BossDeath(AActor *self)
}
else
{
switch (level.flags & LEVEL_SPECACTIONSMASK)
switch (Level->flags & LEVEL_SPECACTIONSMASK)
{
case LEVEL_SPECLOWERFLOOR:
EV_DoFloor (DFloor::floorLowerToLowest, NULL, 666, 1., 0, -1, 0, false);
@ -3158,7 +3168,7 @@ void A_BossDeath(AActor *self)
}
}
// [RH] If noexit, then don't end the level.
// [RH] If noexit, then don't end the Level->
if ((deathmatch || alwaysapplydmflags) && (dmflags & DF_NO_EXIT))
return;

View file

@ -349,10 +349,12 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOf
// [ZZ] Fire WorldThingDied script hook.
E_WorldThingDied(this, inflictor);
auto Level = __GetLevel();
// [JM] Fire KILL type scripts for actor. Not needed for players, since they have the "DEATH" script type.
if (!player && !(flags7 & MF7_NOKILLSCRIPTS) && ((flags7 & MF7_USEKILLSCRIPTS) || gameinfo.forcekillscripts))
{
level.Behaviors.StartTypedScripts(SCRIPT_Kill, this, true, 0, true);
Level->Behaviors.StartTypedScripts(SCRIPT_Kill, this, true, 0, true);
}
flags &= ~(MF_SHOOTABLE|MF_FLOAT|MF_SKULLFLY);
@ -387,7 +389,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOf
}
if (CountsAsKill())
level.killed_monsters++;
Level->killed_monsters++;
if (source && source->player)
{
@ -399,7 +401,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOf
// Don't count any frags at level start, because they're just telefrags
// resulting from insufficient deathmatch starts, and it wouldn't be
// fair to count them toward a player's score.
if (player && level.maptime)
if (player && Level->maptime)
{
source->player->frags[player - players]++;
if (player == source->player) // [RH] Cumulative frag count
@ -492,7 +494,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOf
source->player->multicount++;
if (source->player->lastkilltime > 0)
{
if (source->player->lastkilltime < level.time - 3*TICRATE)
if (source->player->lastkilltime < Level->time - 3*TICRATE)
{
source->player->multicount = 1;
}
@ -535,7 +537,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOf
}
}
}
source->player->lastkilltime = level.time;
source->player->lastkilltime = Level->time;
}
// [RH] Implement fraglimit
@ -563,10 +565,10 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOf
E_PlayerDied(int(player - players));
// Death script execution, care of Skull Tag
level.Behaviors.StartTypedScripts (SCRIPT_Death, this, true);
Level->Behaviors.StartTypedScripts (SCRIPT_Death, this, true);
// [RH] Force a delay between death and respawn
player->respawn_time = level.time + TICRATE;
player->respawn_time = Level->time + TICRATE;
//Added by MC: Respawn bots
if (bglobal.botnum && !demoplayback)
@ -618,7 +620,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOf
// [RH] If this is the unmorphed version of another monster, destroy this
// actor, because the morphed version is the one that will stick around in
// the level.
// the Level->
if (flags & MF_UNMORPHED)
{
Destroy ();
@ -1186,6 +1188,8 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da
}
auto Level = target->__GetLevel();
//[RC] Backported from the Zandronum source.. Mostly.
if( target->player &&
damage > 0 &&
@ -1247,7 +1251,7 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da
//Use the original damage to check for telefrag amount. Don't let the now-amplified damagetypes do it.
if (!telefragDamage || (target->flags7 & MF7_LAXTELEFRAGDMG))
{ // Still allow telefragging :-(
damage = (int)(damage * level.teamdamage);
damage = (int)(damage * Level->teamdamage);
if (damage <= 0)
{
return (damage < 0) ? -1 : 0;
@ -1679,9 +1683,10 @@ bool P_PoisonPlayer (player_t *player, AActor *poisoner, AActor *source, int poi
{
return false;
}
auto Level = player->mo->__GetLevel();
if (source != NULL && source->player != player && player->mo->IsTeammate (source))
{
poison = (int)(poison * level.teamdamage);
poison = (int)(poison * Level->teamdamage);
}
if (poison > 0)
{
@ -1802,7 +1807,9 @@ void P_PoisonDamage (player_t *player, AActor *source, int damage, bool playPain
return;
}
}
if (!(level.time&63) && playPainSound)
auto Level = player->mo->__GetLevel();
if (!(Level->time & 63) && playPainSound)
{
FState *painstate = target->FindState(NAME_Pain, player->poisonpaintype);
if (painstate != NULL)

View file

@ -308,6 +308,7 @@ static void RemoveTaggedSectors(extsector_t::linked::plane &scrollplane, int tag
bool P_AddSectorLinks(sector_t *control, int tag, INTBOOL ceiling, int movetype)
{
int param = movetype;
auto Level = control->Level;
// can't be done if the control sector is moving.
if ((ceiling && control->PlaneMoving(sector_t::ceiling)) ||
@ -331,12 +332,12 @@ bool P_AddSectorLinks(sector_t *control, int tag, INTBOOL ceiling, int movetype)
while ((sec = itr.Next()) >= 0)
{
// Don't attach to self (but allow attaching to this sector's oposite plane.
if (control == &level.sectors[sec])
if (control == &Level->sectors[sec])
{
if (ceiling == sector_t::floor && movetype & LINK_FLOOR) continue;
if (ceiling == sector_t::ceiling && movetype & LINK_CEILING) continue;
}
AddSingleSector(scrollplane, &level.sectors[sec], movetype);
AddSingleSector(scrollplane, &Level->sectors[sec], movetype);
}
}
else
@ -359,12 +360,13 @@ bool P_AddSectorLinks(sector_t *control, int tag, INTBOOL ceiling, int movetype)
void P_AddSectorLinksByID(sector_t *control, int id, INTBOOL ceiling)
{
extsector_t::linked::plane &scrollplane = ceiling? control->e->Linked.Ceiling : control->e->Linked.Floor;
auto Level = control->Level;
FLineIdIterator itr(id);
int line;
while ((line = itr.Next()) >= 0)
{
line_t *ld = &level.lines[line];
line_t *ld = &Level->lines[line];
if (ld->special == Static_Init && ld->args[1] == Init_SectorLink)
{

View file

@ -2227,7 +2227,7 @@ FUNC(LS_Sector_ChangeFlags)
void AdjustPusher(int tag, int magnitude, int angle, bool wind);
void AdjustPusher(FLevelLocals *l, int tag, int magnitude, int angle, bool wind);
FUNC(LS_Sector_SetWind)
// Sector_SetWind (tag, amount, angle)
@ -2235,7 +2235,7 @@ FUNC(LS_Sector_SetWind)
if (arg3)
return false;
AdjustPusher (arg0, arg1, arg2, true);
AdjustPusher (Level, arg0, arg1, arg2, true);
return true;
}
@ -2245,7 +2245,7 @@ FUNC(LS_Sector_SetCurrent)
if (arg3)
return false;
AdjustPusher (arg0, arg1, arg2, false);
AdjustPusher (Level, arg0, arg1, arg2, false);
return true;
}

View file

@ -413,7 +413,7 @@ bool P_TeleportMove(AActor* thing, const DVector3 &pos, bool telefrag, bool modi
spechit.Clear(); // this is needed so that no more specials get activated after crossing a teleporter.
bool StompAlwaysFrags = ((thing->flags2 & MF2_TELESTOMP) || (level.flags & LEVEL_MONSTERSTELEFRAG) || telefrag) && !(thing->flags7 & MF7_NOTELESTOMP);
bool StompAlwaysFrags = ((thing->flags2 & MF2_TELESTOMP) || (thing->__GetLevel()->flags & LEVEL_MONSTERSTELEFRAG) || telefrag) && !(thing->flags7 & MF7_NOTELESTOMP);
// P_LineOpening requires the thing's z to be the destination z in order to work.
double savedz = thing->Z();
@ -975,7 +975,7 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
// better than Strife's handling of rails, which lets you jump into rails
// from either side. How long until somebody reports this as a bug and I'm
// forced to say, "It's not a bug. It's a feature?" Ugh.
(!(level.flags2 & LEVEL2_RAILINGHACK) ||
(!(ld->GetLevel()->flags2 & LEVEL2_RAILINGHACK) ||
open.bottom == tm.thing->Sector->floorplane.ZatPoint(ref)))
{
open.bottom += 32;
@ -1359,16 +1359,17 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch
P_DamageMobj(thing, NULL, NULL, thing->health, NAME_None, DMG_FORCED); // kill object
return true;
}
auto Level = thing->__GetLevel();
// Check for MF6_BUMPSPECIAL
// By default, only players can activate things by bumping into them
if ((thing->flags6 & MF6_BUMPSPECIAL) && ((tm.thing->player != NULL)
|| ((thing->activationtype & THINGSPEC_MonsterTrigger) && (tm.thing->flags3 & MF3_ISMONSTER))
|| ((thing->activationtype & THINGSPEC_MissileTrigger) && (tm.thing->flags & MF_MISSILE))
) && (level.maptime > thing->lastbump)) // Leave the bumper enough time to go away
) && (Level->maptime > thing->lastbump)) // Leave the bumper enough time to go away
{
if (P_ActivateThingSpecial(thing, tm.thing))
thing->lastbump = level.maptime + TICRATE;
thing->lastbump = Level->maptime + TICRATE;
}
}
@ -2041,7 +2042,7 @@ void P_FakeZMovement(AActor *mo)
}
if (mo->player && mo->flags&MF_NOGRAVITY && (mo->Z() > mo->floorz) && !mo->IsNoClip2())
{
mo->AddZ(DAngle(4.5 * level.maptime).Sin());
mo->AddZ(DAngle(4.5 * mo->__GetLevel()->maptime).Sin());
}
//
@ -2066,6 +2067,7 @@ void P_FakeZMovement(AActor *mo)
static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, DVector2 *posforwindowcheck)
{
auto Level = mobj->__GetLevel();
if (line->special && !(mobj->flags6 & MF6_NOTRIGGER))
{
if (posforwindowcheck && !(i_compatflags2 & COMPATF2_PUSHWINDOW) && line->backsector != NULL)
@ -2111,7 +2113,7 @@ static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, DVector2 *
}
else if (mobj->flags2 & MF2_IMPACT)
{
if ((level.flags2 & LEVEL2_MISSILESACTIVATEIMPACT) ||
if ((Level->flags2 & LEVEL2_MISSILESACTIVATEIMPACT) ||
!(mobj->flags & MF_MISSILE) ||
(mobj->target == NULL))
{
@ -4265,6 +4267,7 @@ DAngle P_AimLineAttack(AActor *t1, DAngle angle, double distance, FTranslatedLin
int flags, AActor *target, AActor *friender)
{
double shootz = t1->Center() - t1->Floorclip + t1->AttackOffset();
auto Level = t1->__GetLevel();
// can't shoot outside view angles
if (vrange == 0)
@ -4375,6 +4378,7 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags, FTranslatedLineTarget*victim, int *actualdamage,
double sz, double offsetforward, double offsetside)
{
auto Level = t1->__GetLevel();
bool nointeract = !!(flags & LAF_NOINTERACT);
DVector3 direction;
double shootz;
@ -4442,7 +4446,7 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
AActor *tempuff = NULL;
if (pufftype != NULL)
tempuff = Spawn(t1->__GetLevel(), pufftype, t1->Pos(), ALLOW_REPLACE);
tempuff = Spawn(Level, pufftype, t1->Pos(), ALLOW_REPLACE);
if (tempuff != NULL)
{
TData.PuffSpecies = tempuff->GetSpecies();
@ -6167,7 +6171,8 @@ void P_DoCrunch(AActor *thing, FChangePosition *cpos)
if (!(thing && thing->CallGrind(true) && cpos)) return;
cpos->nofit = true;
if ((cpos->crushchange > 0) && !(level.maptime & 3))
auto Level = thing->__GetLevel();
if ((cpos->crushchange > 0) && !(Level->maptime & 3))
{
int newdam = P_DamageMobj(thing, NULL, NULL, cpos->crushchange, NAME_Crush);
@ -6789,6 +6794,7 @@ static void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff
bool P_ActivateThingSpecial(AActor * thing, AActor * trigger, bool death)
{
bool res = false;
auto Level = thing->__GetLevel();
// Target switching mechanism
if (thing->activationtype & THINGSPEC_ThingTargets) thing->target = trigger;
@ -6829,14 +6835,14 @@ bool P_ActivateThingSpecial(AActor * thing, AActor * trigger, bool death)
{
res = !!P_ExecuteSpecial(thing->special, NULL,
// TriggerActs overrides the level flag, which only concerns thing activated by death
(((death && level.flags & LEVEL_ACTOWNSPECIAL && !(thing->activationtype & THINGSPEC_TriggerActs))
(((death && Level->flags & LEVEL_ACTOWNSPECIAL && !(thing->activationtype & THINGSPEC_TriggerActs))
|| (thing->activationtype & THINGSPEC_ThingActs)) // Who triggers?
? thing : trigger),
false, thing->args[0], thing->args[1], thing->args[2], thing->args[3], thing->args[4]);
// Clears the special if it was run on thing's death or if flag is set.
// Note that Hexen originally did not clear the special which some original maps depend on (e.g. the bell in HEXDD.)
if ((death && !(level.flags2 & LEVEL2_HEXENHACK)) || (thing->activationtype & THINGSPEC_ClearSpecial && res)) thing->special = 0;
if ((death && !(Level->flags2 & LEVEL2_HEXENHACK)) || (thing->activationtype & THINGSPEC_ClearSpecial && res)) thing->special = 0;
}
// Returns the result

View file

@ -355,18 +355,19 @@ void AActor::UnlinkFromWorld (FLinkContext *ctx)
bool AActor::FixMapthingPos()
{
sector_t *secstart = P_PointInSectorBuggy(X(), Y());
auto Level = __GetLevel();
int blockx = level.blockmap.GetBlockX(X());
int blocky = level.blockmap.GetBlockY(Y());
int blockx = Level->blockmap.GetBlockX(X());
int blocky = Level->blockmap.GetBlockY(Y());
bool success = false;
if (level.blockmap.isValidBlock(blockx, blocky))
if (Level->blockmap.isValidBlock(blockx, blocky))
{
int *list;
for (list = level.blockmap.GetLines(blockx, blocky); *list != -1; ++list)
for (list = Level->blockmap.GetLines(blockx, blocky); *list != -1; ++list)
{
line_t *ldef = &level.lines[*list];
line_t *ldef = &Level->lines[*list];
if (ldef->frontsector == ldef->backsector)
{ // Skip two-sided lines inside a single sector
@ -439,6 +440,7 @@ bool AActor::FixMapthingPos()
void AActor::LinkToWorld(FLinkContext *ctx, bool spawningmapthing, sector_t *sector)
{
bool spawning = spawningmapthing;
auto Level = __GetLevel();
if (spawning)
{
@ -512,25 +514,25 @@ void AActor::LinkToWorld(FLinkContext *ctx, bool spawningmapthing, sector_t *sec
{
DVector3 pos = i==-1? Pos() : PosRelative(check[i] & ~FPortalGroupArray::FLAT);
int x1 = level.blockmap.GetBlockX(pos.X - radius);
int x2 = level.blockmap.GetBlockX(pos.X + radius);
int y1 = level.blockmap.GetBlockY(pos.Y - radius);
int y2 = level.blockmap.GetBlockY(pos.Y + radius);
int x1 = Level->blockmap.GetBlockX(pos.X - radius);
int x2 = Level->blockmap.GetBlockX(pos.X + radius);
int y1 = Level->blockmap.GetBlockY(pos.Y - radius);
int y2 = Level->blockmap.GetBlockY(pos.Y + radius);
if (x1 >= level.blockmap.bmapwidth || x2 < 0 || y1 >= level.blockmap.bmapheight || y2 < 0)
if (x1 >= Level->blockmap.bmapwidth || x2 < 0 || y1 >= Level->blockmap.bmapheight || y2 < 0)
{ // thing is off the map
}
else
{ // [RH] Link into every block this actor touches, not just the center one
x1 = MAX(0, x1);
y1 = MAX(0, y1);
x2 = MIN(level.blockmap.bmapwidth - 1, x2);
y2 = MIN(level.blockmap.bmapheight - 1, y2);
x2 = MIN(Level->blockmap.bmapwidth - 1, x2);
y2 = MIN(Level->blockmap.bmapheight - 1, y2);
for (int y = y1; y <= y2; ++y)
{
for (int x = x1; x <= x2; ++x)
{
FBlockNode **link = &level.blockmap.blocklinks[y*level.blockmap.bmapwidth + x];
FBlockNode **link = &Level->blockmap.blocklinks[y*Level->blockmap.bmapwidth + x];
FBlockNode *node = FBlockNode::Create(this, x, y, this->Sector->PortalGroup);
// Link in to block
@ -1690,14 +1692,15 @@ AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, in
int finalStop;
int count;
AActor *target;
int bmapwidth = level.blockmap.bmapwidth;
int bmapheight = level.blockmap.bmapheight;
auto Level = mo->__GetLevel();
int bmapwidth = Level->blockmap.bmapwidth;
int bmapheight = Level->blockmap.bmapheight;
startX = level.blockmap.GetBlockX(mo->X());
startY = level.blockmap.GetBlockY(mo->Y());
startX = Level->blockmap.GetBlockX(mo->X());
startY = Level->blockmap.GetBlockY(mo->Y());
validcount++;
if (level.blockmap.isValidBlock(startX, startY))
if (Level->blockmap.isValidBlock(startX, startY))
{
if ( (target = check (mo, startY*bmapwidth+startX, params)) )
{ // found a target right away

View file

@ -147,7 +147,10 @@ FRandom pr_spawnmobj ("SpawnActor");
CUSTOM_CVAR (Float, sv_gravity, 800.f, CVAR_SERVERINFO|CVAR_NOSAVE)
{
level.gravity = self;
ForAllLevels([&](FLevelLocals *Level)
{
Level->gravity = self;
});
}
CVAR (Bool, cl_missiledecals, true, CVAR_ARCHIVE)

View file

@ -43,6 +43,7 @@
#include "v_text.h"
#include "cmdlib.h"
#include "g_levellocals.h"
#include "actorinlines.h"
#include "vm.h"
#include "sbar.h"
@ -966,7 +967,7 @@ DAngle P_BulletSlope (AActor *mo, FTranslatedLineTarget *pLineTarget, int aimfla
pitch = P_AimLineAttack (mo, an, 16.*64, pLineTarget, 0., aimflags);
if (mo->player != NULL &&
level.IsFreelookAllowed() &&
mo->__GetLevel()->IsFreelookAllowed() &&
mo->player->userinfo.GetAimDist() <= 0.5)
{
break;

View file

@ -55,7 +55,7 @@ public:
};
DPusher ();
DPusher (EPusher type, line_t *l, int magnitude, int angle, AActor *source, int affectee);
DPusher (EPusher type, line_t *l, int magnitude, int angle, AActor *source, sector_t *affectee);
void Serialize(FSerializer &arc);
int CheckForSectorMatch (EPusher type, int tag);
void ChangeValues (int magnitude, int angle)
@ -73,7 +73,7 @@ protected:
DVector2 m_PushVec;
double m_Magnitude; // Vector strength for point pusher
double m_Radius; // Effective radius for point pusher
int m_Affectee; // Number of affected sector
sector_t *m_Affectee; // Number of affected sector
friend bool PIT_PushThing (AActor *thing);
};
@ -151,8 +151,7 @@ void DPusher::Serialize(FSerializer &arc)
//
// Add a push thinker to the thinker list
DPusher::DPusher (DPusher::EPusher type, line_t *l, int magnitude, int angle,
AActor *source, int affectee)
DPusher::DPusher (DPusher::EPusher type, line_t *l, int magnitude, int angle, AActor *source, sector_t *affectee)
{
m_Source = source;
m_Type = type;
@ -175,7 +174,7 @@ DPusher::DPusher (DPusher::EPusher type, line_t *l, int magnitude, int angle,
int DPusher::CheckForSectorMatch (EPusher type, int tag)
{
if (m_Type == type && tagManager.SectorHasTag(m_Affectee, tag))
return m_Affectee;
return m_Affectee->Index();
else
return -1;
}
@ -196,7 +195,7 @@ void DPusher::Tick ()
if (!var_pushers)
return;
sec = &level.sectors[m_Affectee];
sec = m_Affectee;
// Be sure the special sector type is still turned on. If so, proceed.
// Else, bail out; the sector type has been changed on us.
@ -338,12 +337,10 @@ void DPusher::Tick ()
// P_GetPushThing() returns a pointer to an MT_PUSH or MT_PULL thing,
// NULL otherwise.
AActor *P_GetPushThing (int s)
AActor *P_GetPushThing (sector_t *sec)
{
AActor* thing;
sector_t* sec;
sec = &level.sectors[s];
thing = sec->thinglist;
while (thing &&
@ -360,12 +357,12 @@ AActor *P_GetPushThing (int s)
// Initialize the sectors where pushers are present
//
void P_SpawnPushers ()
void P_SpawnPushers (FLevelLocals *Level)
{
line_t *l = &level.lines[0];
line_t *l = &Level->lines[0];
int s;
for (unsigned i = 0; i < level.lines.Size(); i++, l++)
for (unsigned i = 0; i < Level->lines.Size(); i++, l++)
{
switch (l->special)
{
@ -373,7 +370,7 @@ void P_SpawnPushers ()
{
FSectorTagIterator itr(l->args[0]);
while ((s = itr.Next()) >= 0)
Create<DPusher>(DPusher::p_wind, l->args[3] ? l : nullptr, l->args[1], l->args[2], nullptr, s);
Create<DPusher>(DPusher::p_wind, l->args[3] ? l : nullptr, l->args[1], l->args[2], nullptr, &Level->sectors[s]);
l->special = 0;
break;
}
@ -382,7 +379,7 @@ void P_SpawnPushers ()
{
FSectorTagIterator itr(l->args[0]);
while ((s = itr.Next()) >= 0)
Create<DPusher>(DPusher::p_current, l->args[3] ? l : nullptr, l->args[1], l->args[2], nullptr, s);
Create<DPusher>(DPusher::p_current, l->args[3] ? l : nullptr, l->args[1], l->args[2], nullptr, &Level->sectors[s]);
l->special = 0;
break;
}
@ -392,12 +389,11 @@ void P_SpawnPushers ()
FSectorTagIterator itr(l->args[0]);
while ((s = itr.Next()) >= 0)
{
AActor *thing = P_GetPushThing (s);
AActor *thing = P_GetPushThing (&Level->sectors[s]);
if (thing) { // No MT_P* means no effect
// [RH] Allow narrowing it down by tid
if (!l->args[1] || l->args[1] == thing->tid)
Create<DPusher> (DPusher::p_push, l->args[3] ? l : NULL, l->args[2],
0, thing, s);
Create<DPusher> (DPusher::p_push, l->args[3] ? l : NULL, l->args[2], 0, thing, &Level->sectors[s]);
}
}
} else { // [RH] Find thing by tid
@ -409,7 +405,7 @@ void P_SpawnPushers ()
if (thing->GetClass()->TypeName == NAME_PointPusher ||
thing->GetClass()->TypeName == NAME_PointPuller)
{
Create<DPusher> (DPusher::p_push, l->args[3] ? l : NULL, l->args[2], 0, thing, thing->Sector->Index());
Create<DPusher> (DPusher::p_push, l->args[3] ? l : NULL, l->args[2], 0, thing, thing->Sector);
}
}
}
@ -419,7 +415,7 @@ void P_SpawnPushers ()
}
}
void AdjustPusher (int tag, int magnitude, int angle, bool wind)
void AdjustPusher (FLevelLocals *Level, int tag, int magnitude, int angle, bool wind)
{
DPusher::EPusher type = wind? DPusher::p_wind : DPusher::p_current;
@ -454,7 +450,7 @@ void AdjustPusher (int tag, int magnitude, int angle, bool wind)
}
if (i == numcollected)
{
Create<DPusher> (type, nullptr, magnitude, angle, nullptr, secnum);
Create<DPusher> (type, nullptr, magnitude, angle, nullptr, &Level->sectors[secnum]);
}
}
}

View file

@ -965,6 +965,7 @@ void G_SerializeLevel(FSerializer &arc, FLevelLocals *Level, bool hubload)
("total_monsters", Level->total_monsters)
("gravity", Level->gravity)
("aircontrol", Level->aircontrol)
("airfriction", Level->airfriction)
("teamdamage", Level->teamdamage)
("maptime", Level->maptime)
("totaltime", i)
@ -991,7 +992,6 @@ void G_SerializeLevel(FSerializer &arc, FLevelLocals *Level, bool hubload)
sky1texture = Level->skytexture1;
sky2texture = Level->skytexture2;
R_InitSkyMap();
G_AirControlChanged();
}
Level->Behaviors.SerializeModuleStates(arc);

View file

@ -468,7 +468,7 @@ FBlockNode *FBlockNode::Create(AActor *who, int x, int y, int group)
{
block = (FBlockNode *)secnodearena.Alloc(sizeof(FBlockNode));
}
block->BlockIndex = x + y * level.blockmap.bmapwidth;
block->BlockIndex = x + y * who->__GetLevel()->blockmap.bmapwidth;
block->Me = who;
block->NextActor = nullptr;
block->PrevActor = nullptr;

View file

@ -1530,7 +1530,7 @@ int side_t::GetLightLevel (bool foggy, int baselight, bool is3dlight, int *pfake
}
auto Level = sector->Level;
if (!foggy || level.flags3 & LEVEL3_FORCEFAKECONTRAST) // Don't do relative lighting in foggy sectors
if (!foggy || Level->flags3 & LEVEL3_FORCEFAKECONTRAST) // Don't do relative lighting in foggy sectors
{
if (!(Flags & WALLF_NOFAKECONTRAST) && r_fakecontrast != 0)
{

View file

@ -355,20 +355,20 @@ void P_FreeLevelData ()
//
//===========================================================================
void P_SetupLevel(const char *lumpname, int position, bool newGame)
void P_SetupLevel(FLevelLocals *Level, const char *lumpname, int position, bool newGame)
{
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:
level.maptype = MAPTYPE_UNKNOWN;
Level->maptype = MAPTYPE_UNKNOWN;
wminfo.partime = 180;
if (!savegamerestore)
{
level.SetMusicVolume(level.MusicVolume);
Level->SetMusicVolume(Level->MusicVolume);
for (i = 0; i < MAXPLAYERS; ++i)
{
players[i].killcount = players[i].secretcount
@ -414,16 +414,16 @@ void P_SetupLevel(const char *lumpname, int position, bool newGame)
E_InitStaticHandlers(true);
// generate a checksum for the level, to be included and checked with savegames.
map->GetChecksum(level.md5);
map->GetChecksum(Level->md5);
// find map num
level.lumpnum = map->lumpnum;
Level->lumpnum = map->lumpnum;
if (newGame)
{
E_NewGame(EventHandlerType::PerMap);
}
MapLoader loader(&level);
MapLoader loader(Level);
loader.LoadLevel(map, lumpname, position);
delete map;
@ -440,7 +440,7 @@ void P_SetupLevel(const char *lumpname, int position, bool newGame)
}
}
// 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)
{
@ -448,14 +448,14 @@ void P_SetupLevel(const char *lumpname, int position, bool newGame)
{
players[i].mo = nullptr;
FPlayerStart *mthing = G_PickPlayerStart(i);
P_SpawnPlayer(&level, mthing, i, (level.flags2 & LEVEL2_PRERAISEWEAPON) ? SPF_WEAPONFULLYUP : 0);
P_SpawnPlayer(Level, mthing, i, (Level->flags2 & LEVEL2_PRERAISEWEAPON) ? SPF_WEAPONFULLYUP : 0);
}
}
}
// [SP] move unfriendly players around
// horribly hacky - yes, this needs rewritten.
if (level.deathmatchstarts.Size() > 0)
if (Level->deathmatchstarts.Size() > 0)
{
for (i = 0; i < MAXPLAYERS; ++i)
{
@ -490,7 +490,7 @@ void P_SetupLevel(const char *lumpname, int position, bool newGame)
}
}
T_PreprocessScripts(&level); // preprocess FraggleScript scripts
T_PreprocessScripts(Level); // preprocess FraggleScript scripts
// build subsector connect matrix
// UNUSED P_ConnectSubsectors ();
@ -503,7 +503,7 @@ void P_SetupLevel(const char *lumpname, int position, bool newGame)
// preload graphics and sounds
if (precache)
{
PrecacheLevel(&level);
PrecacheLevel(Level);
S_PrecacheLevel();
}
@ -514,7 +514,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.
// 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)
{
@ -534,12 +534,12 @@ void P_SetupLevel(const char *lumpname, int position, bool newGame)
// 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 none of these structures may contain non POD fields anyway.
level.loadsectors.Resize(level.sectors.Size());
memcpy(&level.loadsectors[0], &level.sectors[0], level.sectors.Size() * sizeof(level.sectors[0]));
level.loadlines.Resize(level.lines.Size());
memcpy(&level.loadlines[0], &level.lines[0], level.lines.Size() * sizeof(level.lines[0]));
level.loadsides.Resize(level.sides.Size());
memcpy(&level.loadsides[0], &level.sides[0], level.sides.Size() * sizeof(level.sides[0]));
Level->loadsectors.Resize(Level->sectors.Size());
memcpy(&Level->loadsectors[0], &Level->sectors[0], Level->sectors.Size() * sizeof(Level->sectors[0]));
Level->loadlines.Resize(Level->lines.Size());
memcpy(&Level->loadlines[0], &Level->lines[0], Level->lines.Size() * sizeof(Level->lines[0]));
Level->loadsides.Resize(Level->sides.Size());
memcpy(&Level->loadsides[0], &Level->sides[0], Level->sides.Size() * sizeof(Level->sides[0]));
}
//
@ -576,42 +576,46 @@ static void P_Shutdown ()
CCMD(dumpgeometry)
{
for (auto &sector : level.sectors)
ForAllLevels([](FLevelLocals *Level)
{
Printf(PRINT_LOG, "Sector %d\n", sector.sectornum);
for (int j = 0; j<sector.subsectorcount; j++)
Printf("%s - %s\n", Level->MapName.GetChars(), Level->LevelName.GetChars());
for (auto &sector : Level->sectors)
{
subsector_t * sub = sector.subsectors[j];
Printf(PRINT_LOG, " Subsector %d - real sector = %d - %s\n", int(sub->Index()), sub->sector->sectornum, sub->hacked & 1 ? "hacked" : "");
for (uint32_t k = 0; k<sub->numlines; k++)
Printf(PRINT_LOG, "Sector %d\n", sector.sectornum);
for (int j = 0; j < sector.subsectorcount; j++)
{
seg_t * seg = sub->firstline + k;
if (seg->linedef)
{
Printf(PRINT_LOG, " (%4.4f, %4.4f), (%4.4f, %4.4f) - seg %d, linedef %d, side %d",
seg->v1->fX(), seg->v1->fY(), seg->v2->fX(), seg->v2->fY(),
seg->Index(), seg->linedef->Index(), seg->sidedef != seg->linedef->sidedef[0]);
}
else
{
Printf(PRINT_LOG, " (%4.4f, %4.4f), (%4.4f, %4.4f) - seg %d, miniseg",
seg->v1->fX(), seg->v1->fY(), seg->v2->fX(), seg->v2->fY(), seg->Index());
}
if (seg->PartnerSeg)
{
subsector_t * sub2 = seg->PartnerSeg->Subsector;
Printf(PRINT_LOG, ", back sector = %d, real back sector = %d", sub2->render_sector->sectornum, seg->PartnerSeg->frontsector->sectornum);
}
else if (seg->backsector)
{
Printf(PRINT_LOG, ", back sector = %d (no partnerseg)", seg->backsector->sectornum);
}
subsector_t * sub = sector.subsectors[j];
Printf(PRINT_LOG, "\n");
Printf(PRINT_LOG, " Subsector %d - real sector = %d - %s\n", int(sub->Index()), sub->sector->sectornum, sub->hacked & 1 ? "hacked" : "");
for (uint32_t k = 0; k < sub->numlines; k++)
{
seg_t * seg = sub->firstline + k;
if (seg->linedef)
{
Printf(PRINT_LOG, " (%4.4f, %4.4f), (%4.4f, %4.4f) - seg %d, linedef %d, side %d",
seg->v1->fX(), seg->v1->fY(), seg->v2->fX(), seg->v2->fY(),
seg->Index(), seg->linedef->Index(), seg->sidedef != seg->linedef->sidedef[0]);
}
else
{
Printf(PRINT_LOG, " (%4.4f, %4.4f), (%4.4f, %4.4f) - seg %d, miniseg",
seg->v1->fX(), seg->v1->fY(), seg->v2->fX(), seg->v2->fY(), seg->Index());
}
if (seg->PartnerSeg)
{
subsector_t * sub2 = seg->PartnerSeg->Subsector;
Printf(PRINT_LOG, ", back sector = %d, real back sector = %d", sub2->render_sector->sectornum, seg->PartnerSeg->frontsector->sectornum);
}
else if (seg->backsector)
{
Printf(PRINT_LOG, ", back sector = %d (no partnerseg)", seg->backsector->sectornum);
}
Printf(PRINT_LOG, "\n");
}
}
}
}
});
}
//==========================================================================
@ -622,17 +626,21 @@ CCMD(dumpgeometry)
CCMD(listmapsections)
{
for (int i = 0; i < 100; i++)
ForAllLevels([](FLevelLocals *Level)
{
for (auto &sub : level.subsectors)
Printf("%s - %s\n", Level->MapName.GetChars(), Level->LevelName.GetChars());
for (int i = 0; i < 1000; i++)
{
if (sub.mapsection == i)
for (auto &sub : Level->subsectors)
{
Printf("Mapsection %d, sector %d, line %d\n", i, sub.render_sector->Index(), sub.firstline->linedef->Index());
break;
if (sub.mapsection == i)
{
Printf("Mapsection %d, sector %d, line %d\n", i, sub.render_sector->Index(), sub.firstline->linedef->Index());
break;
}
}
}
}
});
}
//==========================================================================

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.
// On September 1, 1998, I added the position to indicate which set
// 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, const char *mapname, int position, bool newGame);
void P_FreeLevelData();

View file

@ -109,7 +109,7 @@ EXTERN_CVAR(Bool, forcewater)
// killough 3/7/98: Initialize generalized scrolling
void P_SpawnScrollers(FLevelLocals *Level);
static void P_SpawnFriction (FLevelLocals *l); // phares 3/16/98
void P_SpawnPushers (); // phares 3/20/98
void P_SpawnPushers (FLevelLocals *Level); // phares 3/20/98
// [RH] Check dmflags for noexit and respond accordingly
@ -1303,7 +1303,7 @@ void P_SpawnSpecials (MapLoader *ml)
P_SpawnScrollers(Level); // killough 3/7/98: Add generalized scrollers
P_SpawnFriction(Level); // phares 3/12/98: New friction model using linedefs
P_SpawnPushers(); // phares 3/20/98: New pusher model using linedefs
P_SpawnPushers(Level); // phares 3/20/98: New pusher model using linedefs
TThinkerIterator<AActor> it2("SkyCamCompat");
AActor *pt2;

View file

@ -994,8 +994,10 @@ void P_CheckPlayerSprite(AActor *actor, int &spritenum, DVector2 &scale)
CUSTOM_CVAR (Float, sv_aircontrol, 0.00390625f, CVAR_SERVERINFO|CVAR_NOSAVE)
{
level.aircontrol = self;
G_AirControlChanged ();
ForAllLevels([&](FLevelLocals *Level)
{
Level->ChangeAirControl(self);
});
}
//==========================================================================

View file

@ -1322,15 +1322,19 @@ bool P_CollectConnectedGroups(FLevelLocals *Level, int startgroup, const DVector
CCMD(dumplinktable)
{
for (int x = 1; x < level.Displacements.size; x++)
ForAllLevels([](FLevelLocals *Level)
{
for (int y = 1; y < level.Displacements.size; y++)
Printf("%s - %s\n", Level->MapName.GetChars(), Level->LevelName.GetChars());
for (int x = 1; x < Level->Displacements.size; x++)
{
FDisplacement &disp = level.Displacements(x, y);
Printf("%c%c(%6d, %6d)", TEXTCOLOR_ESCAPE, 'C' + disp.indirect, int(disp.pos.X), int(disp.pos.Y));
for (int y = 1; y < Level->Displacements.size; y++)
{
FDisplacement &disp = Level->Displacements(x, y);
Printf("%c%c(%6d, %6d)", TEXTCOLOR_ESCAPE, 'C' + disp.indirect, int(disp.pos.X), int(disp.pos.Y));
}
Printf("\n");
}
Printf("\n");
}
});
}

View file

@ -167,7 +167,7 @@ void FModelRenderer::RenderModel(float x, float y, float z, FSpriteModelFrame *s
objectToWorldMatrix.rotate(-smf->rolloffset, 1, 0, 0);
// consider the pixel stretching. For non-voxels this must be factored out here
float stretch = (smf->modelIDs[0] != -1 ? Models[smf->modelIDs[0]]->getAspectFactor() : 1.f) / level.info->pixelstretch;
float stretch = (smf->modelIDs[0] != -1 ? Models[smf->modelIDs[0]]->getAspectFactor() : 1.f) / actor->__GetLevel()->info->pixelstretch;
objectToWorldMatrix.scale(1, stretch, 1);
float orientation = scaleFactorX * scaleFactorY * scaleFactorZ;

View file

@ -876,7 +876,11 @@ void CreateSections(FLevelLocals *Level)
CCMD(printsections)
{
PrintSections(level.sections);
ForAllLevels([](FLevelLocals *Level)
{
Printf("%s - %s\n", Level->MapName.GetChars(), Level->LevelName.GetChars());
PrintSections(Level->sections);
});
}

View file

@ -919,7 +919,7 @@ void R_InitTranslationTables ()
// Each player corpse has its own translation so they won't change
// color if the player who created them changes theirs.
for (i = 0; i < level.BODYQUESIZE; ++i)
for (i = 0; i < FLevelLocals::BODYQUESIZE; ++i)
{
PushIdentityTable(TRANSLATION_PlayerCorpses);
}

View file

@ -145,6 +145,7 @@ void ModActorFlag(AActor *actor, FFlagDef *fd, bool set)
bool ModActorFlag(AActor *actor, const FString &flagname, bool set, bool printerror)
{
bool found = false;
auto Level = actor->__GetLevel();
if (actor != NULL)
{
@ -166,9 +167,9 @@ bool ModActorFlag(AActor *actor, const FString &flagname, bool set, bool printer
{
found = true;
if (actor->CountsAsKill() && actor->health > 0) --level.total_monsters;
if (actor->flags & MF_COUNTITEM) --level.total_items;
if (actor->flags5 & MF5_COUNTSECRET) --level.total_secrets;
if (actor->CountsAsKill() && actor->health > 0) --Level->total_monsters;
if (actor->flags & MF_COUNTITEM) --Level->total_items;
if (actor->flags5 & MF5_COUNTSECRET) --Level->total_secrets;
if (fd->structoffset == -1)
{
@ -187,9 +188,9 @@ bool ModActorFlag(AActor *actor, const FString &flagname, bool set, bool printer
if (linkchange) actor->LinkToWorld(&ctx);
}
if (actor->CountsAsKill() && actor->health > 0) ++level.total_monsters;
if (actor->flags & MF_COUNTITEM) ++level.total_items;
if (actor->flags5 & MF5_COUNTSECRET) ++level.total_secrets;
if (actor->CountsAsKill() && actor->health > 0) ++Level->total_monsters;
if (actor->flags & MF_COUNTITEM) ++Level->total_items;
if (actor->flags5 & MF5_COUNTSECRET) ++Level->total_secrets;
}
else if (printerror)
{

View file

@ -1165,7 +1165,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, RemoveForceField, RemoveForceField)
static void SetEnvironmentID(sector_t *self, int envnum)
{
level.Zones[self->ZoneNumber].Environment = S_FindEnvironment(envnum);
self->Level->Zones[self->ZoneNumber].Environment = S_FindEnvironment(envnum);
}
DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetEnvironmentID, SetEnvironmentID)
@ -1178,7 +1178,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, RemoveForceField, RemoveForceField)
static void SetEnvironment(sector_t *self, const FString &env)
{
level.Zones[self->ZoneNumber].Environment = S_FindEnvironment(env);
self->Level->Zones[self->ZoneNumber].Environment = S_FindEnvironment(env);
}
DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetEnvironment, SetEnvironment)
@ -2349,51 +2349,57 @@ DEFINE_ACTION_FUNCTION_NATIVE(DBaseStatusBar, SetClipRect, SBar_SetClipRect)
return 0;
}
static void GetGlobalACSString(int index, FString *result)
static void GetGlobalACSString(DBaseStatusBar *self, int index, FString *result)
{
*result = level.Behaviors.LookupString(ACS_GlobalVars[index]);
if (self->Level == nullptr) ThrowAbortException(X_OTHER, "BaseStatusBar.GetGlobalACSString called from outside the status bar code.");
*result = self->Level->Behaviors.LookupString(ACS_GlobalVars[index]);
}
DEFINE_ACTION_FUNCTION_NATIVE(DBaseStatusBar, GetGlobalACSString, GetGlobalACSString)
{
PARAM_PROLOGUE;
PARAM_SELF_PROLOGUE(DBaseStatusBar);
PARAM_INT(index);
ACTION_RETURN_STRING(level.Behaviors.LookupString(ACS_GlobalVars[index]));
FString result;
GetGlobalACSString(self, index, &result);
ACTION_RETURN_STRING(result);
}
static void GetGlobalACSArrayString(int arrayno, int index, FString *result)
static void GetGlobalACSArrayString(DBaseStatusBar *self, int arrayno, int index, FString *result)
{
*result = level.Behaviors.LookupString(ACS_GlobalVars[index]);
if (self->Level == nullptr) ThrowAbortException(X_OTHER, "BaseStatusBar.GetGlobalACSArrayString called from outside the status bar code.");
*result = self->Level->Behaviors.LookupString(ACS_GlobalVars[index]);
}
DEFINE_ACTION_FUNCTION_NATIVE(DBaseStatusBar, GetGlobalACSArrayString, GetGlobalACSArrayString)
{
PARAM_PROLOGUE;
PARAM_SELF_PROLOGUE(DBaseStatusBar);
PARAM_INT(arrayno);
PARAM_INT(index);
ACTION_RETURN_STRING(level.Behaviors.LookupString(ACS_GlobalArrays[arrayno][index]));
FString result;
GetGlobalACSArrayString(self, arrayno, index, &result);
ACTION_RETURN_STRING(result);
}
static int GetGlobalACSValue(int index)
static int GetGlobalACSValue(DBaseStatusBar *self, int index)
{
return (ACS_GlobalVars[index]);
}
DEFINE_ACTION_FUNCTION_NATIVE(DBaseStatusBar, GetGlobalACSValue, GetGlobalACSValue)
{
PARAM_PROLOGUE;
PARAM_SELF_PROLOGUE(DBaseStatusBar);
PARAM_INT(index);
ACTION_RETURN_INT(ACS_GlobalVars[index]);
}
static int GetGlobalACSArrayValue(int arrayno, int index)
static int GetGlobalACSArrayValue(DBaseStatusBar *self, int arrayno, int index)
{
return (ACS_GlobalArrays[arrayno][index]);
}
DEFINE_ACTION_FUNCTION_NATIVE(DBaseStatusBar, GetGlobalACSArrayValue, GetGlobalACSArrayValue)
{
PARAM_PROLOGUE;
PARAM_SELF_PROLOGUE(DBaseStatusBar);
PARAM_INT(arrayno);
PARAM_INT(index);
ACTION_RETURN_INT(ACS_GlobalArrays[arrayno][index]);
@ -2571,7 +2577,7 @@ DEFINE_ACTION_FUNCTION(FLevelLocals, GetChecksum)
for (int j = 0; j < 16; ++j)
{
sprintf(md5string + j * 2, "%02x", level.md5[j]);
sprintf(md5string + j * 2, "%02x", self->md5[j]);
}
ACTION_RETURN_STRING((const char*)md5string);

View file

@ -459,7 +459,7 @@ void ZCCCompiler::MessageV(ZCC_TreeNode *node, const char *txtcolor, const char
//
// ZCCCompiler :: Compile
//
// Compile everything defined at this level.
// Compile everything defined at this level
//
//==========================================================================

View file

@ -545,10 +545,10 @@ class BaseStatusBar native ui
}
// These cannot be done in ZScript.
native static String GetGlobalACSString(int index);
native static String GetGlobalACSArrayString(int arrayno, int index);
native static int GetGlobalACSValue(int index);
native static int GetGlobalACSArrayValue(int arrayno, int index);
native String GetGlobalACSString(int index);
native String GetGlobalACSArrayString(int arrayno, int index);
native int GetGlobalACSValue(int index);
native int GetGlobalACSArrayValue(int arrayno, int index);
//============================================================================
//