- moved the non-map timers out of LevelLocals into GameSession and moved the composite compatibility flags into FLevelLocals, because they are level specific.

This commit is contained in:
Christoph Oelckers 2019-01-10 23:08:35 +01:00
parent 3b59afae31
commit 229dde1e67
54 changed files with 248 additions and 196 deletions

View file

@ -182,9 +182,9 @@ static FRandom pr_bbannounce ("BBAnnounce");
void DoVoiceAnnounce (const char *sound)
{
// Don't play announcements too close together
if (LastAnnounceTime == 0 || LastAnnounceTime <= level.time-5)
if (LastAnnounceTime == 0 || LastAnnounceTime <= currentSession->time-5)
{
LastAnnounceTime = level.time;
LastAnnounceTime = currentSession->time;
S_Sound (CHAN_VOICE, sound, 1, ATTN_NONE);
}
}

View file

@ -502,9 +502,6 @@ CVAR (Flag, sv_respawnsuper, dmflags2, DF2_RESPAWN_SUPER);
//
//==========================================================================
int i_compatflags, i_compatflags2; // internal compatflags composed from the compatflags CVAR and MAPINFO settings
int ii_compatflags, ii_compatflags2, ib_compatflags;
EXTERN_CVAR(Int, compatmode)
static int GetCompatibility(FLevelLocals *Level, int mask)
@ -521,17 +518,23 @@ static int GetCompatibility2(FLevelLocals *Level, int mask)
CUSTOM_CVAR (Int, compatflags, 0, CVAR_ARCHIVE|CVAR_SERVERINFO)
{
int old = i_compatflags;
i_compatflags = GetCompatibility(&level, self) | ii_compatflags;
if ((old ^ i_compatflags) & COMPATF_POLYOBJ)
ForAllLevels([&](FLevelLocals *Level)
{
level.ClearAllSubsectorLinks();
}
int old = Level->i_compatflags;
Level->i_compatflags = GetCompatibility(Level, self) | Level->ii_compatflags;
if ((old ^ Level->i_compatflags) & COMPATF_POLYOBJ)
{
Level->ClearAllSubsectorLinks();
}
});
}
CUSTOM_CVAR (Int, compatflags2, 0, CVAR_ARCHIVE|CVAR_SERVERINFO)
{
i_compatflags2 = GetCompatibility2(&level, self) | ii_compatflags2;
ForAllLevels([&](FLevelLocals *Level)
{
Level->i_compatflags2 = GetCompatibility2(Level, self) | Level->ii_compatflags2;
});
}
CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL)

View file

@ -2226,8 +2226,11 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
s = ReadString (stream);
// Using LEVEL_NOINTERMISSION tends to throw the game out of sync.
// That was a long time ago. Maybe it works now?
level.flags |= LEVEL_CHANGEMAPCHEAT;
G_ChangeLevel(s, pos, 0);
if (currentSession)
{
currentSession->Levelinfo[0]->flags |= LEVEL_CHANGEMAPCHEAT;
G_ChangeLevel(s, pos, 0);
}
break;
case DEM_SUICIDE:

View file

@ -248,7 +248,6 @@ EXTERN_CVAR (Int, dmflags2); // [BC]
EXTERN_CVAR (Int, compatflags);
EXTERN_CVAR (Int, compatflags2);
extern int i_compatflags, i_compatflags2, ii_compatflags, ii_compatflags2, ib_compatflags;
// Filters from AddAutoloadFiles(). Used to filter files from archives.
extern FString LumpFilterIWAD;

View file

@ -221,7 +221,7 @@ EMoveResult sector_t::MoveFloor(double speed, double dest, int crush, int direct
//destheight = (dest < ceilingheight) ? dest : ceilingheight;
if (!ceilingplane.isSlope() && !floorplane.isSlope() &&
!PortalIsLinked(sector_t::ceiling) &&
(!(i_compatflags2 & COMPATF2_FLOORMOVE) && -dest > ceilingplane.fD()))
(!(Level->i_compatflags2 & COMPATF2_FLOORMOVE) && -dest > ceilingplane.fD()))
{
dest = -ceilingplane.fD();
}
@ -311,7 +311,7 @@ EMoveResult sector_t::MoveCeiling(double speed, double dest, int crush, int dire
//destheight = (dest > floorheight) ? dest : floorheight;
if (!ceilingplane.isSlope() && !floorplane.isSlope() &&
!PortalIsLinked(sector_t::floor) &&
(!(i_compatflags2 & COMPATF2_FLOORMOVE) && dest < -floorplane.fD()))
(!(Level->i_compatflags2 & COMPATF2_FLOORMOVE) && dest < -floorplane.fD()))
{
dest = -floorplane.fD();
}

View file

@ -1685,11 +1685,11 @@ void G_DoPlayerPop(int playernum)
}
// [RH] Make the player disappear
level.Behaviors.StopMyScripts(players[playernum].mo);
players[playernum].mo->Level->Behaviors.StopMyScripts(players[playernum].mo);
// [ZZ] fire player disconnect hook
E_PlayerDisconnected(playernum);
// [RH] Let the scripts know the player left
level.Behaviors.StartTypedScripts(&level, SCRIPT_Disconnect, players[playernum].mo, true, playernum, true);
players[playernum].mo->Level->Behaviors.StartTypedScripts(&level, SCRIPT_Disconnect, players[playernum].mo, true, playernum, true);
if (players[playernum].mo != NULL)
{
P_DisconnectEffect(players[playernum].mo);
@ -1902,7 +1902,7 @@ void G_DoLoadGame ()
arc("ticrate", time[0])
("leveltime", time[1]);
// dearchive all the modifications
level.time = Scale(time[1], TICRATE, time[0]);
currentSession->time = Scale(time[1], TICRATE, time[0]);
G_ReadSnapshots(resfile.get());
resfile.reset(nullptr); // we no longer need the resource file below this point
@ -2081,9 +2081,8 @@ static void PutSaveComment (FSerializer &arc)
});
// Append elapsed time
levelTime = level.time / TICRATE;
comment.AppendFormat("time: %02d:%02d:%02d",
levelTime/3600, (levelTime%3600)/60, levelTime%60);
levelTime = currentSession->time / TICRATE;
comment.AppendFormat("time: %02d:%02d:%02d", levelTime/3600, (levelTime%3600)/60, levelTime%60);
// Write out the comment
arc.AddString("Comment", comment);
@ -2196,11 +2195,11 @@ void G_DoSaveGame (bool okForQuicksave, FString filename, const char *descriptio
savegameglobals.AddString("importantcvars", vars.GetChars());
}
if (level.time != 0 || level.maptime != 0)
if (currentSession->time != 0)
{
int tic = TICRATE;
savegameglobals("ticrate", tic);
savegameglobals("leveltime", level.time);
savegameglobals("leveltime", currentSession->time);
}
STAT_Serialize(savegameglobals);

View file

@ -540,9 +540,10 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
}
FRandom::StaticClearRandom ();
P_ClearACSVars(true);
level.time = 0;
currentSession->time = 0;
currentSession->totaltime = 0;
level.maptime = 0;
level.totaltime = 0;
level.spawnindex = 0;
if (!multiplayer || !deathmatch)
@ -610,7 +611,7 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill
Printf (TEXTCOLOR_RED "Unloading scripts cannot exit the level again.\n");
return;
}
if (gameaction == ga_completed && !(i_compatflags2 & COMPATF2_MULTIEXIT)) // do not exit multiple times.
if (gameaction == ga_completed && !(currentSession->Levelinfo[0]->i_compatflags2 & COMPATF2_MULTIEXIT)) // do not exit multiple times.
{
return;
}
@ -665,7 +666,7 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill
startpos = position;
gameaction = ga_completed;
level.SetMusicVolume(1.0);
currentSession->SetMusicVolume(1.0);
if (nextinfo != NULL)
{
@ -738,18 +739,19 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill
const char *G_GetExitMap()
{
return level.NextMap;
return currentSession->Levelinfo[0]->NextMap;
}
const char *G_GetSecretExitMap()
{
const char *nextmap = level.NextMap;
auto Level = currentSession->Levelinfo[0];
const char *nextmap = Level->NextMap;
if (level.NextSecretMap.Len() > 0)
if (Level->NextSecretMap.Len() > 0)
{
if (P_CheckMapData(level.NextSecretMap))
if (P_CheckMapData(Level->NextSecretMap))
{
nextmap = level.NextSecretMap;
nextmap = Level->NextSecretMap;
}
}
return nextmap;
@ -757,18 +759,19 @@ const char *G_GetSecretExitMap()
//==========================================================================
//
// The flags here must always be on the primary level.
//
//==========================================================================
void G_ExitLevel (int position, bool keepFacing)
{
level.flags3 |= LEVEL3_EXITNORMALUSED;
currentSession->Levelinfo[0]->flags3 |= LEVEL3_EXITNORMALUSED;
G_ChangeLevel(G_GetExitMap(), position, keepFacing ? CHANGELEVEL_KEEPFACING : 0);
}
void G_SecretExitLevel (int position)
{
level.flags3 |= LEVEL3_EXITSECRETUSED;
currentSession->Levelinfo[0]->flags3 |= LEVEL3_EXITSECRETUSED;
G_ChangeLevel(G_GetSecretExitMap(), position, 0);
}
@ -847,14 +850,14 @@ void G_DoCompleted ()
wminfo.partime = TICRATE * Level->partime;
wminfo.sucktime = Level->sucktime;
wminfo.pnum = consoleplayer;
wminfo.totaltime = Level->totaltime;
wminfo.totaltime = currentSession->totaltime;
for (i=0 ; i<MAXPLAYERS ; i++)
{
wminfo.plyr[i].skills = players[i].killcount;
wminfo.plyr[i].sitems = players[i].itemcount;
wminfo.plyr[i].ssecret = players[i].secretcount;
wminfo.plyr[i].stime = level.time;
wminfo.plyr[i].stime = currentSession->time;
memcpy (wminfo.plyr[i].frags, players[i].frags
, sizeof(wminfo.plyr[i].frags));
wminfo.plyr[i].fragcount = players[i].fragcount;
@ -922,7 +925,7 @@ void G_DoCompleted ()
{ // Reset world variables for the new hub.
P_ClearACSVars(false);
}
level.time = 0;
currentSession->time = 0;
level.maptime = 0;
level.spawnindex = 0;
}
@ -1477,7 +1480,7 @@ int G_FinishTravel ()
VMCall(func, params, 1, nullptr, 0);
}
}
if (ib_compatflags & BCOMPATF_RESETPLAYERSPEED)
if (pawn->Level->ib_compatflags & BCOMPATF_RESETPLAYERSPEED)
{
pawn->Speed = pawn->GetDefault()->Speed;
}
@ -1505,6 +1508,8 @@ void FLevelLocals::InitLevelLocals ()
// Session data should be moved out of here later!
currentSession->F1Pic = info->F1Pic;
currentSession->MusicVolume = 1.f;
P_InitParticles(this);
P_ClearParticles(this);
@ -1560,7 +1565,6 @@ void FLevelLocals::InitLevelLocals ()
levelnum = info->levelnum;
Music = info->Music;
musicorder = info->musicorder;
MusicVolume = 1.f;
HasHeightSecs = false;
LevelName = info->LookupLevelName();
@ -2198,9 +2202,9 @@ void FLevelLocals::SetMusic()
//
//==========================================================================
void FLevelLocals::SetMusicVolume(float f)
void FGameSession::SetMusicVolume(float f)
{
MusicVolume = f;
if (currentSession) currentSession->MusicVolume = f;
I_SetMusicVolume(f);
}

View file

@ -115,6 +115,11 @@ struct FLevelData
FDialogueIDMap DialogueRoots;
FDialogueMap ClassRoots;
int ii_compatflags = 0;
int ii_compatflags2 = 0;
int ib_compatflags = 0;
int i_compatflags = 0;
int i_compatflags2 = 0;
};
@ -128,7 +133,6 @@ struct FLevelLocals : public FLevelData
void AddScroller(int secnum);
void SetInterMusic(const char *nextmap);
void SetMusic();
void SetMusicVolume(float v);
void ClearLevelData();
void ClearPortals();
bool CheckIfExitIsGood(AActor *self, level_info_t *newmap);
@ -162,9 +166,7 @@ struct FLevelLocals : public FLevelData
DSectorMarker *SectorMarker;
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
int maptime; // time in the map
int totaltime; // time in the game
int maptime; // time in the map
int starttime;
int partime;
int sucktime;
@ -257,7 +259,6 @@ struct FLevelLocals : public FLevelData
FName deathsequence;
float pixelstretch;
float MusicVolume;
// Hardware render stuff that can either be set via CVAR or MAPINFO
ELightMode lightMode;
@ -302,6 +303,12 @@ class FGameSession
public:
TArray<FLevelLocals *> Levelinfo;
FString F1Pic;
float MusicVolume;
int time; // time in the hub
int totaltime; // time in the game
void SetMusicVolume(float vol);
};
extern FGameSession *currentSession;

View file

@ -168,7 +168,7 @@ void DLightningThinker::LightningFlash ()
}
else
{
if (pr_lightning() < 128 && !(Level->time&32))
if (pr_lightning() < 128 && !(currentSession->time&32))
{
NextLightningFlash = ((pr_lightning()&7)+2)*35;
}

View file

@ -918,7 +918,7 @@ class CommandDrawString : public SBarInfoCommand
break;
case TIME:
{
int sec = Tics2Seconds(statusBar->Level->time);
int sec = Tics2Seconds(currentSession->time);
str.Format("%02d:%02d:%02d", sec / 3600, (sec % 3600) / 60, sec % 60);
break;
}
@ -1461,7 +1461,7 @@ class CommandDrawNumber : public CommandDrawString
if(statusBar->CPlayer->mo->waterlevel < 3)
num = statusBar->Level->airsupply/TICRATE;
else
num = clamp<int>((statusBar->CPlayer->air_finished - statusBar->Level->time + (TICRATE-1))/TICRATE, 0, INT_MAX);
num = clamp<int>((statusBar->CPlayer->air_finished - currentSession->time + (TICRATE-1))/TICRATE, 0, INT_MAX);
break;
}
case SELECTEDINVENTORY:
@ -1502,7 +1502,7 @@ class CommandDrawNumber : public CommandDrawString
}
default: break;
}
if(interpolationSpeed != 0 && (!hudChanged || statusBar->Level->time == 1))
if(interpolationSpeed != 0 && (!hudChanged || currentSession->time == 1))
{
if(num < drawValue)
drawValue -= clamp<int>((drawValue - num) >> 2, 1, interpolationSpeed);
@ -2751,7 +2751,7 @@ class CommandDrawBar : public SBarInfoCommand
break;
}
case AIRTIME:
value = clamp<int>(statusBar->CPlayer->air_finished - statusBar->Level->time, 0, INT_MAX);
value = clamp<int>(statusBar->CPlayer->air_finished - currentSession->time, 0, INT_MAX);
max = statusBar->Level->airsupply;
break;
case POWERUPTIME:
@ -2798,7 +2798,7 @@ class CommandDrawBar : public SBarInfoCommand
}
else
value = 0;
if(interpolationSpeed != 0 && (!hudChanged || statusBar->Level->time == 1))
if(interpolationSpeed != 0 && (!hudChanged || currentSession->time == 1))
{
// [BL] Since we used a percentage (in order to get the most fluid animation)
// we need to establish a cut off point so the last pixel won't hang as the animation slows
@ -3192,7 +3192,7 @@ class CommandDrawGem : public SBarInfoCommand
goalValue = reverse ? 100 - goalValue : goalValue;
if(interpolationSpeed != 0 && (!hudChanged || statusBar->Level->time == 1)) // At the start force an animation
if(interpolationSpeed != 0 && (!hudChanged || currentSession->time == 1)) // At the start force an animation
{
if(goalValue < drawValue)
drawValue -= clamp<int>((drawValue - goalValue) >> 2, 1, interpolationSpeed);
@ -3202,7 +3202,7 @@ class CommandDrawGem : public SBarInfoCommand
else
drawValue = goalValue;
if(wiggle && statusBar->Level->time & 1)
if(wiggle && currentSession->time & 1)
chainWiggle = pr_chainwiggle() & 1;
}
protected:

View file

@ -368,7 +368,7 @@ static void HU_DrawTimeRemaining (int y)
if (deathmatch && timelimit && gamestate == GS_LEVEL)
{
char str[80];
int timeleft = (int)(timelimit * TICRATE * 60) - level.maptime;
int timeleft = (int)(timelimit * TICRATE * 60) - currentSession->Levelinfo[0]->maptime;
int hours, minutes, seconds;
if (timeleft < 0)

View file

@ -588,7 +588,7 @@ inline int HWDrawList::CompareSprites(SortNode * a,SortNode * b)
int res = s1->depth - s2->depth;
if (res != 0) return -res;
else return (i_compatflags & COMPATF_SPRITESORT)? s2->index-s1->index : s1->index-s2->index;
else return reverseSort? s2->index-s1->index : s1->index-s2->index;
}
//==========================================================================
@ -702,6 +702,7 @@ SortNode * HWDrawList::DoSort(HWDrawInfo *di, SortNode * head)
//==========================================================================
void HWDrawList::Sort(HWDrawInfo *di)
{
reverseSort = !!(di->Level->i_compatflags & COMPATF_SPRITESORT);
SortZ = di->Viewpoint.Pos.Z;
MakeSortList();
sorted = DoSort(di, SortNodes[SortNodeStart]);

View file

@ -67,6 +67,7 @@ struct HWDrawList
int SortNodeStart;
float SortZ;
SortNode * sorted;
bool reverseSort;
public:
HWDrawList()

View file

@ -2063,7 +2063,7 @@ void GLWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
FTexture *tex = TexMan.GetTexture(seg->sidedef->GetTexture(side_t::mid), true);
if (tex != NULL)
{
if (i_compatflags & COMPATF_MASKEDMIDTEX)
if (di->Level->i_compatflags & COMPATF_MASKEDMIDTEX)
{
tex = tex->GetRawTexture();
}

View file

@ -279,17 +279,17 @@ FName MapLoader::CheckCompatibility(MapData *map)
if (BCompatMap.CountUsed() == 0) ParseCompatibility();
ii_compatflags = 0;
ii_compatflags2 = 0;
ib_compatflags = 0;
Level->ii_compatflags = 0;
Level->ii_compatflags2 = 0;
Level->ib_compatflags = 0;
// When playing Doom IWAD levels force COMPAT_SHORTTEX and COMPATF_LIGHT.
// I'm not sure if the IWAD maps actually need COMPATF_LIGHT but it certainly does not hurt.
// TNT's MAP31 also needs COMPATF_STAIRINDEX but that only gets activated for TNT.WAD.
if (Wads.GetLumpFile(map->lumpnum) == Wads.GetIwadNum() && (gameinfo.flags & GI_COMPATSHORTTEX) && Level->maptype == MAPTYPE_DOOM)
{
ii_compatflags = COMPATF_SHORTTEX|COMPATF_LIGHT;
if (gameinfo.flags & GI_COMPATSTAIRS) ii_compatflags |= COMPATF_STAIRINDEX;
Level->ii_compatflags = COMPATF_SHORTTEX|COMPATF_LIGHT;
if (gameinfo.flags & GI_COMPATSTAIRS) Level->ii_compatflags |= COMPATF_STAIRINDEX;
}
map->GetChecksum(md5.Bytes);
@ -319,18 +319,18 @@ FName MapLoader::CheckCompatibility(MapData *map)
if (flags != NULL)
{
ii_compatflags |= flags->CompatFlags[SLOT_COMPAT];
ii_compatflags2 |= flags->CompatFlags[SLOT_COMPAT2];
ib_compatflags |= flags->CompatFlags[SLOT_BCOMPAT];
Level->ii_compatflags |= flags->CompatFlags[SLOT_COMPAT];
Level->ii_compatflags2 |= flags->CompatFlags[SLOT_COMPAT2];
Level->ib_compatflags |= flags->CompatFlags[SLOT_BCOMPAT];
}
// Reset i_compatflags
// Reset Level->i_compatflags
compatflags.Callback();
compatflags2.Callback();
// Set floatbob compatibility for all maps with an original Hexen MAPINFO.
if (Level->flags2 & LEVEL2_HEXENHACK)
{
ib_compatflags |= BCOMPATF_FLOATBOB;
Level->ib_compatflags |= BCOMPATF_FLOATBOB;
}
return FName(hash, true); // if this returns NAME_None it means there is no scripted compatibility handler.
}
@ -556,6 +556,9 @@ CCMD (mapchecksum)
CCMD (hiddencompatflags)
{
Printf("%08x %08x %08x\n", ii_compatflags, ii_compatflags2, ib_compatflags);
ForAllLevels([](FLevelLocals *Level)
{
Printf("%s: %08x %08x %08x\n", Level->MapName.GetChars(), Level->ii_compatflags, Level->ii_compatflags2, Level->ib_compatflags);
});
}

View file

@ -1448,7 +1448,7 @@ void MapLoader::SetLineID (int i, line_t *ld)
break;
case Plane_Align:
if (!(ib_compatflags & BCOMPATF_NOSLOPEID)) setid = ld->args[2];
if (!(Level->ib_compatflags & BCOMPATF_NOSLOPEID)) setid = ld->args[2];
break;
case Static_Init:
@ -2948,7 +2948,7 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position)
Level->maptype = MAPTYPE_UDMF;
}
FName checksum = CheckCompatibility(map);
if (ib_compatflags & BCOMPATF_REBUILDNODES)
if (Level->ib_compatflags & BCOMPATF_REBUILDNODES)
{
ForceNodeBuild = true;
}

View file

@ -179,7 +179,7 @@ void MapLoader::SetSlope (secplane_t *plane, bool setCeil, int xyangi, int zangi
DVector3 norm;
if (ib_compatflags & BCOMPATF_SETSLOPEOVERFLOW)
if (Level->ib_compatflags & BCOMPATF_SETSLOPEOVERFLOW)
{
// We have to consider an integer multiplication overflow here.
norm[0] = FixedToFloat(FloatToFixed(zang.Cos()) * FloatToFixed(xyang.Cos())) / 65536.;

View file

@ -5428,7 +5428,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
}
else
{
return players[args[0]].air_finished - Level->time;
return players[args[0]].air_finished - currentSession->time;
}
}
@ -5440,7 +5440,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
}
else
{
players[args[0]].air_finished = args[1] + Level->time;
players[args[0]].air_finished = args[1] + currentSession->time;
return 1;
}
}
@ -6491,7 +6491,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
break;
case ACSF_SetMusicVolume:
Level->SetMusicVolume(ACSToFloat(args[0]));
currentSession->SetMusicVolume(ACSToFloat(args[0]));
break;
case ACSF_CheckProximity:
@ -8827,7 +8827,7 @@ scriptwait:
// [BC] End ST PCD's
case PCD_TIMER:
PushToStack (Level->time);
PushToStack (currentSession->time);
break;
case PCD_SECTORSOUND:

View file

@ -1077,7 +1077,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply
if (isconsole)
{
I_SetMusicVolume (player->mo->Level->MusicVolume);
I_SetMusicVolume (currentSession->MusicVolume);
}
}

View file

@ -350,7 +350,7 @@ DDoor::DDoor (sector_t *sec, EVlDoor type, double speed, int delay, int lightTag
vertex_t *spot;
double height;
if (i_compatflags & COMPATF_NODOORLIGHT)
if (Level->i_compatflags & COMPATF_NODOORLIGHT)
{
m_LightTag = 0;
}

View file

@ -864,7 +864,7 @@ void P_NewChaseDir(AActor * actor)
if (actor->floorz - actor->dropoffz > actor->MaxDropOffHeight &&
actor->Z() <= actor->floorz && !(actor->flags & MF_DROPOFF) &&
!(actor->flags2 & MF2_ONMOBJ) &&
!(actor->flags & MF_FLOAT) && !(i_compatflags & COMPATF_DROPOFF))
!(actor->flags & MF_FLOAT) && !(actor->Level->i_compatflags & COMPATF_DROPOFF))
{
FBoundingBox box(actor->X(), actor->Y(), actor->radius);
FBlockLinesIterator it(actor->Level, box);
@ -1717,7 +1717,7 @@ int P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params)
// the player then, eh?
if(!(actor->flags6 & MF6_SEEINVISIBLE))
{
if ((player->mo->flags & MF_SHADOW && !(i_compatflags & COMPATF_INVISIBILITY)) ||
if ((player->mo->flags & MF_SHADOW && !(actor->Level->i_compatflags & COMPATF_INVISIBILITY)) ||
player->mo->flags3 & MF3_GHOST)
{
if (player->mo->Distance2D (actor) > 128 && player->mo->Vel.XY().LengthSquared() < 5*5)
@ -1780,7 +1780,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Look)
}
else
{
targ = (i_compatflags & COMPATF_SOUNDTARGET || self->flags & MF_NOSECTOR)?
targ = (Level->i_compatflags & COMPATF_SOUNDTARGET || self->flags & MF_NOSECTOR)?
self->Sector->SoundTarget : self->LastHeard;
// [RH] If the soundtarget is dead, don't chase it
@ -1915,7 +1915,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LookEx)
{
if (!(flags & LOF_NOSOUNDCHECK))
{
targ = (i_compatflags & COMPATF_SOUNDTARGET || self->flags & MF_NOSECTOR)?
targ = (Level->i_compatflags & COMPATF_SOUNDTARGET || self->flags & MF_NOSECTOR)?
self->Sector->SoundTarget : self->LastHeard;
if (targ != NULL)
{
@ -2730,7 +2730,7 @@ bool P_CheckForResurrection(AActor *self, bool usevilestates)
{
corpsehit->Translation = info->Translation; // Clean up bloodcolor translation from crushed corpses
}
if (ib_compatflags & BCOMPATF_VILEGHOSTS)
if (self->Level->ib_compatflags & BCOMPATF_VILEGHOSTS)
{
corpsehit->Height *= 4;
// [GZ] This was a commented-out feature, so let's make use of it,
@ -3113,7 +3113,7 @@ void A_BossDeath(AActor *self)
LEVEL_SORCERER2SPECIAL)) == 0)
return;
if ((i_compatflags & COMPATF_ANYBOSSDEATH) || ( // [GZ] Added for UAC_DEAD
if ((Level->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)) ||

View file

@ -465,7 +465,7 @@ bool P_CreateFloor(sector_t *sec, DFloor::EFloor floortype, line_t *line,
// [Graf Zahl]
// Don't make sounds for instant movement hacks but make an exception for
// switches that activate their own back side.
if (!(i_compatflags & COMPATF_SILENT_INSTANT_FLOORS))
if (!(sec->Level->i_compatflags & COMPATF_SILENT_INSTANT_FLOORS))
{
if (!line || !(line->activation & (SPAC_Use | SPAC_Push)) || line->backsector != sec)
silent = true;
@ -622,7 +622,7 @@ bool EV_BuildStairs (FLevelLocals *Level, int tag, DFloor::EStair type, line_t *
FSectorTagIterator itr(Level->tagManager, tag, line);
// The compatibility mode doesn't work with a hashing algorithm.
// It needs the original linear search method. This was broken in Boom.
bool compatible = tag != 0 && (i_compatflags & COMPATF_STAIRINDEX);
bool compatible = tag != 0 && (Level->i_compatflags & COMPATF_STAIRINDEX);
while ((secnum = itr.NextCompat(compatible, secnum)) >= 0)
{
sec = &Level->sectors[secnum];
@ -711,14 +711,14 @@ bool EV_BuildStairs (FLevelLocals *Level, int tag, DFloor::EStair type, line_t *
// Doom bug: Height was changed before discarding the sector as part of the stairs.
// Needs to be compatibility optioned because some maps (Eternall MAP25) depend on it.
if (i_compatflags & COMPATF_STAIRINDEX) height += stairstep;
if (Level->i_compatflags & COMPATF_STAIRINDEX) height += stairstep;
// if sector's floor already moving, look for another
//jff 2/26/98 special lockout condition for retriggering
if (tsec->PlaneMoving(sector_t::floor) || tsec->stairlock)
continue;
if (!(i_compatflags & COMPATF_STAIRINDEX)) height += stairstep;
if (!(Level->i_compatflags & COMPATF_STAIRINDEX)) height += stairstep;
ok = true;
break;

View file

@ -492,7 +492,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 < currentSession->time - 3*TICRATE)
{
source->player->multicount = 1;
}
@ -535,7 +535,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOf
}
}
}
source->player->lastkilltime = Level->time;
source->player->lastkilltime = currentSession->time;
}
// [RH] Implement fraglimit
@ -566,7 +566,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOf
Level->Behaviors.StartTypedScripts (Level, SCRIPT_Death, this, true);
// [RH] Force a delay between death and respawn
player->respawn_time = Level->time + TICRATE;
player->respawn_time = currentSession->time + TICRATE;
//Added by MC: Respawn bots
if (bglobal.botnum && !demoplayback)
@ -1807,7 +1807,7 @@ void P_PoisonDamage (player_t *player, AActor *source, int damage, bool playPain
}
auto Level = player->mo->Level;
if (!(Level->time & 63) && playPainSound)
if (!(Level->maptime & 63) && playPainSound)
{
FState *painstate = target->FindState(NAME_Pain, player->poisonpaintype);
if (painstate != NULL)

View file

@ -594,7 +594,7 @@ void EV_LightTurnOn (FLevelLocals *Level, int tag, int bright)
//jff 5/17/98 unless compatibility optioned
//then maximum near ANY tagged sector
if (i_compatflags & COMPATF_LIGHT)
if (Level->i_compatflags & COMPATF_LIGHT)
{
bright = tbright;
}

View file

@ -3067,7 +3067,7 @@ FUNC(LS_SetPlayerProperty)
{
int i;
if ((ib_compatflags & BCOMPATF_LINKFROZENPROPS) && (mask & (CF_FROZEN | CF_TOTALLYFROZEN)))
if ((Level->ib_compatflags & BCOMPATF_LINKFROZENPROPS) && (mask & (CF_FROZEN | CF_TOTALLYFROZEN)))
{ // Clearing one of these properties clears both of them (if the compat flag is set.)
mask = CF_FROZEN | CF_TOTALLYFROZEN;
}

View file

@ -459,7 +459,7 @@ bool P_TeleportMove(AActor* thing, const DVector3 &pos, bool telefrag, bool modi
// [RH] Z-Check
// But not if not MF2_PASSMOBJ or MF3_DONTOVERLAP are set!
// Otherwise those things would get stuck inside each other.
if ((thing->flags2 & MF2_PASSMOBJ || th->flags4 & MF4_ACTLIKEBRIDGE) && !(i_compatflags & COMPATF_NO_PASSMOBJ))
if ((thing->flags2 & MF2_PASSMOBJ || th->flags4 & MF4_ACTLIKEBRIDGE) && !(thing->Level->i_compatflags & COMPATF_NO_PASSMOBJ))
{
if (!(th->flags3 & thing->flags3 & MF3_DONTOVERLAP))
{
@ -516,7 +516,7 @@ bool P_TeleportMove(AActor* thing, const DVector3 &pos, bool telefrag, bool modi
// If this teleport was caused by a move, P_TryMove() will handle the
// sector transition messages better than we can here.
// This needs to be compatibility optioned because some older maps exploited this missing feature.
if (!(thing->flags6 & MF6_INTRYMOVE) && !(i_compatflags2 & COMPATF2_TELEPORT))
if (!(thing->flags6 & MF6_INTRYMOVE) && !(thing->Level->i_compatflags2 & COMPATF2_TELEPORT))
{
thing->CheckSectorTransition(oldsec);
}
@ -850,7 +850,7 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
// into being friendly with the MBF flag automatically gain MF3_NOBLOCKMONST, so this
// just optionally generalizes the behavior to other friendly monsters.
bool NotBlocked = ((tm.thing->flags3 & MF3_NOBLOCKMONST)
|| ((i_compatflags & COMPATF_NOBLOCKFRIENDS) && (tm.thing->flags & MF_FRIENDLY)));
|| ((tm.thing->Level->i_compatflags & COMPATF_NOBLOCKFRIENDS) && (tm.thing->flags & MF_FRIENDLY)));
uint32_t ProjectileBlocking = ML_BLOCKEVERYTHING | ML_BLOCKPROJECTILE;
if ( tm.thing->flags8 & MF8_BLOCKASPLAYER ) ProjectileBlocking |= ML_BLOCK_PLAYERS | ML_BLOCKING;
@ -1263,7 +1263,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch
// walking on other actors and unblocking is too messy through restricted portal types so disable it.
if (!(cres.portalflags & FFCF_RESTRICTEDPORTAL))
{
if (!(i_compatflags & COMPATF_NO_PASSMOBJ) && !(tm.thing->flags & (MF_FLOAT | MF_MISSILE | MF_SKULLFLY | MF_NOGRAVITY)) &&
if (!(thing->Level->i_compatflags & COMPATF_NO_PASSMOBJ) && !(tm.thing->flags & (MF_FLOAT | MF_MISSILE | MF_SKULLFLY | MF_NOGRAVITY)) &&
(thing->flags & MF_SOLID) && (thing->flags4 & MF4_ACTLIKEBRIDGE))
{
// [RH] Let monsters walk on actors as well as floors
@ -1311,7 +1311,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch
// [RH] If the other thing is a bridge, then treat the moving thing as if it had MF2_PASSMOBJ, so
// you can use a scrolling floor to move scenery items underneath a bridge.
if ((tm.thing->flags2 & MF2_PASSMOBJ || thing->flags4 & MF4_ACTLIKEBRIDGE) && !(i_compatflags & COMPATF_NO_PASSMOBJ))
if ((tm.thing->flags2 & MF2_PASSMOBJ || thing->flags4 & MF4_ACTLIKEBRIDGE) && !(tm.thing->Level->i_compatflags & COMPATF_NO_PASSMOBJ))
{ // check if a mobj passed over/under another object
if (!(tm.thing->flags & MF_MISSILE) ||
!(tm.thing->flags2 & MF2_RIP) ||
@ -1442,7 +1442,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch
{
clipheight = thing->projectilepassheight;
}
else if (thing->projectilepassheight < 0 && (i_compatflags & COMPATF_MISSILECLIP))
else if (thing->projectilepassheight < 0 && (thing->Level->i_compatflags & COMPATF_MISSILECLIP))
{
clipheight = -thing->projectilepassheight;
}
@ -1764,7 +1764,7 @@ bool P_CheckPosition(AActor *thing, const DVector2 &pos, FCheckPosition &tm, boo
AActor *BlockingMobj = thing->BlockingMobj;
// If this blocks through a restricted line portal, it will always completely block.
if (BlockingMobj == NULL || (i_compatflags & COMPATF_NO_PASSMOBJ) || (tcres.portalflags & FFCF_RESTRICTEDPORTAL))
if (BlockingMobj == NULL || (thing->Level->i_compatflags & COMPATF_NO_PASSMOBJ) || (tcres.portalflags & FFCF_RESTRICTEDPORTAL))
{ // Thing slammed into something; don't let it move now.
thing->Height = realHeight;
return false;
@ -2070,7 +2070,7 @@ static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, DVector2 *
auto Level = mobj->Level;
if (line->special && !(mobj->flags6 & MF6_NOTRIGGER))
{
if (posforwindowcheck && !(i_compatflags2 & COMPATF2_PUSHWINDOW) && line->backsector != NULL)
if (posforwindowcheck && !(Level->i_compatflags2 & COMPATF2_PUSHWINDOW) && line->backsector != NULL)
{ // Make sure this line actually blocks us and is not a window
// or similar construct we are standing inside of.
DVector3 pos = mobj->PosRelative(line);
@ -2177,7 +2177,7 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
goto pushline;
}
}
if (!(tm.thing->flags2 & MF2_PASSMOBJ) || (i_compatflags & COMPATF_NO_PASSMOBJ))
if (!(tm.thing->flags2 & MF2_PASSMOBJ) || (tm.thing->Level->i_compatflags & COMPATF_NO_PASSMOBJ))
{
thing->SetZ(oldz);
thing->flags6 &= ~MF6_INTRYMOVE;
@ -2276,7 +2276,7 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
// compatibility check: Doom originally did not allow monsters to cross dropoffs at all.
// If the compatibility flag is on, only allow this when the velocity comes from a scroller
if ((i_compatflags & COMPATF_CROSSDROPOFF) && !(thing->flags4 & MF4_SCROLLMOVE))
if ((thing->Level->i_compatflags & COMPATF_CROSSDROPOFF) && !(thing->flags4 & MF4_SCROLLMOVE))
{
dropoff = false;
}
@ -2965,7 +2965,7 @@ void FSlide::SlideTraverse(const DVector2 &start, const DVector2 &end)
goto isblocking;
}
if (li->flags & ML_BLOCKMONSTERS && !((slidemo->flags3 & MF3_NOBLOCKMONST)
|| ((i_compatflags & COMPATF_NOBLOCKFRIENDS) && (slidemo->flags & MF_FRIENDLY))))
|| ((slidemo->Level->i_compatflags & COMPATF_NOBLOCKFRIENDS) && (slidemo->flags & MF_FRIENDLY))))
{
goto isblocking;
}
@ -4592,7 +4592,7 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
// Hit a thing, so it could be either a puff or blood
DVector3 bleedpos = trace.HitPos;
// position a bit closer for puffs/blood if using compatibility mode.
if (i_compatflags & COMPATF_HITSCAN)
if (Level->i_compatflags & COMPATF_HITSCAN)
{
DVector2 ofs = P_GetOffsetPosition(t1->Level, bleedpos.X, bleedpos.Y, -10 * trace.HitVector.X, -10 * trace.HitVector.Y);
bleedpos.X = ofs.X;
@ -4785,7 +4785,7 @@ int P_LineTrace(AActor *t1, DAngle angle, double distance,
if ( flags & TRF_BLOCKSELF )
{
bool Projectile = ( (t1->flags&MF_MISSILE) || (t1->BounceFlags&BOUNCE_MBF) );
bool NotBlocked = ( (t1->flags3&MF3_NOBLOCKMONST) || ( (i_compatflags&COMPATF_NOBLOCKFRIENDS) && (t1->flags&MF_FRIENDLY) ) );
bool NotBlocked = ( (t1->flags3&MF3_NOBLOCKMONST) || ( (t1->Level->i_compatflags&COMPATF_NOBLOCKFRIENDS) && (t1->flags&MF_FRIENDLY) ) );
if ( Projectile ) lflags |= ML_BLOCKPROJECTILE;
if ( !Projectile || (t1->flags8&MF8_BLOCKASPLAYER) ) lflags |= ML_BLOCKING;
if ( !NotBlocked ) lflags |= ML_BLOCKMONSTERS;
@ -5103,7 +5103,7 @@ static ETraceStatus ProcessRailHit(FTraceResults &res, void *userdata)
newhit.HitActor = res.Actor;
newhit.HitPos = res.HitPos;
newhit.HitAngle = res.SrcAngleFromTarget;
if (i_compatflags & COMPATF_HITSCAN)
if (res.Actor->Level->i_compatflags & COMPATF_HITSCAN)
{
DVector2 ofs = P_GetOffsetPosition(res.Actor->Level, newhit.HitPos.X, newhit.HitPos.Y, -10 * res.HitVector.X, -10 * res.HitVector.Y);
newhit.HitPos.X = ofs.X;
@ -5431,7 +5431,7 @@ bool P_UseTraverse(AActor *usething, const DVector2 &start, const DVector2 &end,
P_LineOpening(open, NULL, in->d.line, it.InterceptPoint(in));
}
if (open.range <= 0 ||
(in->d.line->special != 0 && (i_compatflags & COMPATF_USEBLOCKING)))
(in->d.line->special != 0 && (usething->Level->i_compatflags & COMPATF_USEBLOCKING)))
{
// [RH] Give sector a chance to intercept the use
@ -5491,7 +5491,7 @@ bool P_UseTraverse(AActor *usething, const DVector2 &start, const DVector2 &end,
//[RH] And now I've changed it again. If the line is of type
// SPAC_USE, then it eats the use. Everything else passes
// it through, including SPAC_USETHROUGH.
if (i_compatflags & COMPATF_USEBLOCKING)
if (usething->Level->i_compatflags & COMPATF_USEBLOCKING)
{
if (in->d.line->activation & SPAC_UseThrough) continue;
else return true;

View file

@ -1540,7 +1540,7 @@ void FPathTraverse::init(double x1, double y1, double x2, double y2, int flags,
// Count is present to prevent a round off error
// from skipping the break statement.
bool compatible = (flags & PT_COMPATIBLE) && (i_compatflags & COMPATF_HITSCAN);
bool compatible = (flags & PT_COMPATIBLE) && (Level->i_compatflags & COMPATF_HITSCAN);
// we want to use one list of checked actors for the entire operation
FBlockThingsIterator btit(Level);

View file

@ -5,6 +5,7 @@
#include "r_defs.h"
#include "doomstat.h"
#include "m_bbox.h"
#include "g_levellocals.h"
extern int validcount;
struct FBlockNode;
@ -50,7 +51,7 @@ inline int P_PointOnLineSidePrecise(const DVector2 &pt, const line_t *line)
inline int P_PointOnLineSide (double x, double y, const line_t *line)
{
extern int P_VanillaPointOnLineSide(double x, double y, const line_t* line);
return i_compatflags2 & COMPATF2_POINTONLINE
return line->GetLevel()->i_compatflags2 & COMPATF2_POINTONLINE
? P_VanillaPointOnLineSide(x, y, line) : P_PointOnLineSidePrecise(x, y, line);
}

View file

@ -1173,7 +1173,7 @@ bool AActor::Grind(bool items)
// see rh_log entry for February 21, 1999. Don't know if it is still relevant.
if (state == NULL // Only use the default crushed state if:
&& !(flags & MF_NOBLOOD) // 1. the monster bleeeds,
&& (i_compatflags & COMPATF_CORPSEGIBS) // 2. the compat setting is on,
&& (Level->i_compatflags & COMPATF_CORPSEGIBS) // 2. the compat setting is on,
&& player == NULL) // 3. and the thing isn't a player.
{
isgeneric = true;
@ -1829,7 +1829,7 @@ double P_XYMovement (AActor *mo, DVector2 scroll)
// [anon] When friction is turned off, turn off the crouching and water
// speed caps as well, since it is a sort of friction, and the modders
// most likely want to deal with that themselves.
if ((mo->player != NULL && (i_compatflags & COMPATF_WALLRUN)) || ((mo->waterlevel >= 1 ||
if ((mo->player != NULL && (Level->i_compatflags & COMPATF_WALLRUN)) || ((mo->waterlevel >= 1 ||
(mo->player != NULL && mo->player->crouchfactor < 0.75)) && !(mo->flags8 & MF8_NOFRICTION)))
{
// preserve the direction instead of clamping x and y independently.
@ -1951,7 +1951,7 @@ double P_XYMovement (AActor *mo, DVector2 scroll)
DAngle oldangle = mo->Angles.Yaw;
do
{
if (i_compatflags & COMPATF_WALLRUN) pushtime++;
if (Level->i_compatflags & COMPATF_WALLRUN) pushtime++;
tm.PushTime = pushtime;
ptry = start + move * step / steps;
@ -2002,7 +2002,7 @@ double P_XYMovement (AActor *mo, DVector2 scroll)
// actor's velocity, do not attempt to slide.
if (mo->Vel.XY() == startvel)
{
if (player && (i_compatflags & COMPATF_WALLRUN))
if (player && (Level->i_compatflags & COMPATF_WALLRUN))
{
// [RH] Here is the key to wall running: The move is clipped using its full speed.
// If the move is done a second time (because it was too fast for one move), it
@ -2020,7 +2020,7 @@ double P_XYMovement (AActor *mo, DVector2 scroll)
}
else
{
if (!player || !(i_compatflags & COMPATF_WALLRUN))
if (!player || !(Level->i_compatflags & COMPATF_WALLRUN))
{
move = mo->Vel;
onestep = move / steps;
@ -2464,7 +2464,7 @@ void P_ZMovement (AActor *mo, double oldfloorz)
// Hexen yanked all items to the floor, except those being spawned at map start in the air.
// Those were kept at their original height.
// Do this only if the item was actually spawned by the map above ground to avoid problems.
if (mo->specialf1 > 0 && (mo->flags2 & MF2_FLOATBOB) && (ib_compatflags & BCOMPATF_FLOATBOB))
if (mo->specialf1 > 0 && (mo->flags2 & MF2_FLOATBOB) && (mo->Level->ib_compatflags & BCOMPATF_FLOATBOB))
{
mo->SetZ(mo->floorz + mo->specialf1);
}
@ -3741,7 +3741,7 @@ void AActor::Tick ()
scrolltype <= Scroll_SouthWest_Fast)
{ // Hexen scroll special
scrolltype -= Scroll_North_Slow;
if (i_compatflags&COMPATF_RAVENSCROLL)
if (Level->i_compatflags&COMPATF_RAVENSCROLL)
{
scrollv.X -= HexenCompatSpeeds[HexenScrollies[scrolltype][0]+4] * (1. / (32 * CARRYFACTOR));
scrollv.Y += HexenCompatSpeeds[HexenScrollies[scrolltype][1]+4] * (1. / (32 * CARRYFACTOR));
@ -3760,7 +3760,7 @@ void AActor::Tick ()
scrolltype -= Carry_East5;
uint8_t dir = HereticScrollDirs[scrolltype / 5];
double carryspeed = HereticSpeedMuls[scrolltype % 5] * (1. / (32 * CARRYFACTOR));
if (scrolltype < 5 && !(i_compatflags&COMPATF_RAVENSCROLL))
if (scrolltype < 5 && !(Level->i_compatflags&COMPATF_RAVENSCROLL))
{
// Use speeds that actually match the scrolling textures!
carryspeed = (1 << ((scrolltype % 5) + 15)) / 65536.;
@ -3770,7 +3770,7 @@ void AActor::Tick ()
}
else if (scrolltype == dScroll_EastLavaDamage)
{ // Special Heretic scroll special
if (i_compatflags&COMPATF_RAVENSCROLL)
if (Level->i_compatflags&COMPATF_RAVENSCROLL)
{
scrollv.X += 28. / (32*CARRYFACTOR);
}
@ -3823,7 +3823,7 @@ void AActor::Tick ()
// Some levels designed with Boom in mind actually want things to accelerate
// at neighboring scrolling sector boundaries. But it is only important for
// non-player objects.
if (player != NULL || !(i_compatflags & COMPATF_BOOMSCROLL))
if (player != NULL || !(Level->i_compatflags & COMPATF_BOOMSCROLL))
{
if (countx > 1)
{
@ -3916,7 +3916,7 @@ void AActor::Tick ()
}
if (Vel.Z != 0 || BlockingMobj || Z() != floorz)
{ // Handle Z velocity and gravity
if (((flags2 & MF2_PASSMOBJ) || (flags & MF_SPECIAL)) && !(i_compatflags & COMPATF_NO_PASSMOBJ))
if (((flags2 & MF2_PASSMOBJ) || (flags & MF_SPECIAL)) && !(Level->i_compatflags & COMPATF_NO_PASSMOBJ))
{
if (!(onmo = P_CheckOnmobj (this)))
{
@ -4001,7 +4001,7 @@ void AActor::Tick ()
}
// Check for poison damage, but only once per PoisonPeriod tics (or once per second if none).
if (PoisonDurationReceived && (Level->time % (PoisonPeriodReceived ? PoisonPeriodReceived : TICRATE) == 0))
if (PoisonDurationReceived && (Level->maptime % (PoisonPeriodReceived ? PoisonPeriodReceived : TICRATE) == 0))
{
P_DamageMobj(this, NULL, Poisoner, PoisonDamageReceived, PoisonDamageTypeReceived ? PoisonDamageTypeReceived : (FName)NAME_Poison, 0);
@ -4055,7 +4055,7 @@ void AActor::Tick ()
if (movecount < respawn_monsters)
return;
if (Level->time & 31)
if (Level->maptime & 31)
return;
if (pr_nightmarerespawn() > 4)
@ -4348,7 +4348,7 @@ bool AActor::UpdateWaterLevel(bool dosplash)
else if (oldlevel == 3 && waterlevel < 3)
{
// Our head just came up.
if (player->air_finished > Level->time)
if (player->air_finished > currentSession->time)
{
// We hadn't run out of air yet.
S_Sound(this, CHAN_VOICE, "*surface", 1, ATTN_NORM);
@ -4388,7 +4388,7 @@ AActor *AActor::StaticSpawn (FLevelLocals *Level, PClassActor *type, const DVect
AActor *actor;
actor = static_cast<AActor *>(const_cast<PClassActor *>(type)->CreateNew ());
actor->SpawnTime = Level->totaltime;
actor->SpawnTime = currentSession->totaltime;
actor->SpawnOrder = Level->spawnindex++;
// Set default dialogue
@ -4972,7 +4972,7 @@ AActor *P_SpawnPlayer (FLevelLocals *Level, FPlayerStart *mthing, int playernum,
// Allow full angular precision
SpawnAngle = (double)mthing->angle;
if (i_compatflags2 & COMPATF2_BADANGLES)
if (Level->i_compatflags2 & COMPATF2_BADANGLES)
{
SpawnAngle += 0.01;
}
@ -5434,7 +5434,7 @@ AActor *P_SpawnMapThing (FLevelLocals *Level, FMapThing *mthing, int position)
if (sz == ONFLOORZ)
{
mobj->AddZ(mthing->pos.Z);
if ((mobj->flags2 & MF2_FLOATBOB) && (ib_compatflags & BCOMPATF_FLOATBOB))
if ((mobj->flags2 & MF2_FLOATBOB) && (mobj->Level->ib_compatflags & BCOMPATF_FLOATBOB))
{
mobj->specialf1 = mthing->pos.Z;
}
@ -5457,7 +5457,7 @@ AActor *P_SpawnMapThing (FLevelLocals *Level, FMapThing *mthing, int position)
}
// For Hexen floatbob 'compatibility' we do not really want to alter the floorz.
if (mobj->specialf1 == 0 || !(mobj->flags2 & MF2_FLOATBOB) || !(ib_compatflags & BCOMPATF_FLOATBOB))
if (mobj->specialf1 == 0 || !(mobj->flags2 & MF2_FLOATBOB) || !(mobj->Level->ib_compatflags & BCOMPATF_FLOATBOB))
{
P_FindFloorCeiling(mobj, FFCF_SAMESECTOR | FFCF_ONLY3DFLOORS | FFCF_3DRESTRICT);
}

View file

@ -890,8 +890,6 @@ static void SpawnExtraPlayers(FLevelLocals *Level)
void G_SerializeLevel(FSerializer &arc, FLevelLocals *Level, bool hubload)
{
int i = Level->totaltime;
if (arc.isWriting())
{
arc.Array("checksum", Level->md5, 16);
@ -937,7 +935,6 @@ void G_SerializeLevel(FSerializer &arc, FLevelLocals *Level, bool hubload)
("airfriction", Level->airfriction)
("teamdamage", Level->teamdamage)
("maptime", Level->maptime)
("totaltime", i)
("skytexture1", Level->skytexture1)
("skytexture2", Level->skytexture2)
("fogdensity", Level->fogdensity)
@ -957,10 +954,6 @@ void G_SerializeLevel(FSerializer &arc, FLevelLocals *Level, bool hubload)
("sndseqlisthead", Level->SequenceListHead);
// Hub transitions must keep the current total time
if (!hubload)
Level->totaltime = i;
if (arc.isReading())
{
sky1texture = Level->skytexture1;
@ -1000,13 +993,16 @@ void G_SerializeLevel(FSerializer &arc, FLevelLocals *Level, bool hubload)
{
order = S_GetMusic(&name);
}
arc.StringPtr("musicname", name)
("musicorder", order);
("musicorder", order)
("musicvolume", currentSession->MusicVolume);
if (!hubload) arc ("totaltime", currentSession->totaltime); // this must be skipped for hub transitions.
if (arc.isReading())
{
if (!S_ChangeMusic(name, order)) Level->SetMusic();
level.SetMusicVolume(Level->MusicVolume);
currentSession->SetMusicVolume(currentSession->MusicVolume);
}

View file

@ -473,9 +473,9 @@ double FindHighestCeilingSurrounding (const sector_t *sector, vertex_t **v)
// jff 02/03/98 Add routine to find shortest lower texture
//
static inline void CheckShortestTex (FTextureID texnum, double &minsize)
static inline void CheckShortestTex (FLevelLocals *Level, FTextureID texnum, double &minsize)
{
if (texnum.isValid() || (texnum.isNull() && (i_compatflags & COMPATF_SHORTTEX)))
if (texnum.isValid() || (texnum.isNull() && (Level->i_compatflags & COMPATF_SHORTTEX)))
{
FTexture *tex = TexMan.GetTexture(texnum);
if (tex != NULL)
@ -497,8 +497,8 @@ double FindShortestTextureAround (sector_t *sec)
{
if (check->flags & ML_TWOSIDED)
{
CheckShortestTex (check->sidedef[0]->GetTexture(side_t::bottom), minsize);
CheckShortestTex (check->sidedef[1]->GetTexture(side_t::bottom), minsize);
CheckShortestTex (sec->Level, check->sidedef[0]->GetTexture(side_t::bottom), minsize);
CheckShortestTex (sec->Level, check->sidedef[1]->GetTexture(side_t::bottom), minsize);
}
}
return minsize < FLT_MAX ? minsize : TexMan.ByIndex(0)->GetDisplayHeight();
@ -522,8 +522,8 @@ double FindShortestUpperAround (sector_t *sec)
{
if (check->flags & ML_TWOSIDED)
{
CheckShortestTex (check->sidedef[0]->GetTexture(side_t::top), minsize);
CheckShortestTex (check->sidedef[1]->GetTexture(side_t::top), minsize);
CheckShortestTex (sec->Level, check->sidedef[0]->GetTexture(side_t::top), minsize);
CheckShortestTex (sec->Level, check->sidedef[1]->GetTexture(side_t::top), minsize);
}
}
return minsize < FLT_MAX ? minsize : TexMan.ByIndex(0)->GetDisplayHeight();

View file

@ -378,7 +378,7 @@ void P_SetupLevel(FLevelLocals *Level, const char *lumpname, int position, bool
if (!savegamerestore)
{
Level->SetMusicVolume(Level->MusicVolume);
currentSession->SetMusicVolume(currentSession->MusicVolume);
for (i = 0; i < MAXPLAYERS; ++i)
{
players[i].killcount = players[i].secretcount

View file

@ -218,7 +218,7 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in)
//
// ignore self referencing sectors if COMPAT_TRACE is on
if ((i_compatflags & COMPATF_TRACE) && li->frontsector == li->backsector)
if ((Level->i_compatflags & COMPATF_TRACE) && li->frontsector == li->backsector)
return true;
double trX = Trace.x + Trace.dx * in->frac;

View file

@ -463,7 +463,7 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector)
player->hazardtype = sector->damagetype;
player->hazardinterval = sector->damageinterval;
}
else if (Level->time % sector->damageinterval == 0)
else if (Level->maptime % sector->damageinterval == 0)
{
if (!(player->cheats & (CF_GODMODE|CF_GODMODE2))) P_DamageMobj(player->mo, NULL, NULL, sector->damageamount, sector->damagetype);
if ((sector->Flags & SECF_ENDLEVEL) && player->health <= 10 && (!deathmatch || !(dmflags & DF_NO_EXIT)))
@ -479,7 +479,7 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector)
}
else if (sector->damageamount < 0)
{
if (Level->time % sector->damageinterval == 0)
if (Level->maptime % sector->damageinterval == 0)
{
P_GiveBody(player->mo, -sector->damageamount, 100);
}
@ -638,7 +638,7 @@ void P_PlayerOnSpecialFlat (player_t *player, int floorType)
auto Level = player->mo->Level;
if (Terrains[floorType].DamageAmount &&
!(Level->time & Terrains[floorType].DamageTimeMask))
!(Level->maptime & Terrains[floorType].DamageTimeMask))
{
AActor *ironfeet = NULL;

View file

@ -247,7 +247,7 @@ static AActor *SelectTeleDest (FLevelLocals *Level, int tid, int tag, bool noran
// sector).
// Compatibility hack for some maps that fell victim to a bug in the teleport code in 2.0.9x
if (ib_compatflags & BCOMPATF_BADTELEPORTERS) tag = 0;
if (Level->ib_compatflags & BCOMPATF_BADTELEPORTERS) tag = 0;
if (tid != 0)
{
@ -386,7 +386,7 @@ bool EV_Teleport (FLevelLocals *Level, int tid, int tag, line_t *line, int side,
{
z = ONFLOORZ;
}
if ((i_compatflags2 & COMPATF2_BADANGLES) && (thing->player != NULL))
if ((Level->i_compatflags2 & COMPATF2_BADANGLES) && (thing->player != NULL))
{
badangle = 0.01;
}

View file

@ -159,8 +159,8 @@ void P_Ticker (void)
}
// for par times
Level->time++;
Level->maptime++;
Level->totaltime++;
});
currentSession->time++;
currentSession->totaltime++;
}

View file

@ -420,7 +420,7 @@ bool FTraceInfo::LineCheck(intercept_t *in, double dist, DVector3 hit, bool spec
// For backwards compatibility: Ignore lines with the same sector on both sides.
// This is the way Doom.exe did it and some WADs (e.g. Alien Vendetta MAP15) need it.
if (i_compatflags & COMPATF_TRACE && in->d.line->backsector == in->d.line->frontsector && !special3dpass)
if (Level->i_compatflags & COMPATF_TRACE && in->d.line->backsector == in->d.line->frontsector && !special3dpass)
{
// We must check special activation here because the code below is never reached.
if (TraceFlags & TRACE_PCross)

View file

@ -1722,7 +1722,7 @@ void FPolyObj::CreateSubsectorLinks()
seg->v2 = side->V2();
seg->wall = side;
}
if (!(i_compatflags & COMPATF_POLYOBJ))
if (!(Level->i_compatflags & COMPATF_POLYOBJ))
{
SplitPoly(node, Level->HeadNode(), dummybbox);
}

View file

@ -861,7 +861,7 @@ static bool ValidatePosVel(const FSoundChan *const chan, const FVector3 &pos, co
static void CalcSectorSoundOrg(const DVector3 &listenpos, const sector_t *sec, int channum, FVector3 &pos)
{
if (!(i_compatflags & COMPATF_SECTORSOUNDS))
if (!(sec->Level->i_compatflags & COMPATF_SECTORSOUNDS))
{
// Are we inside the sector? If yes, the closest point is the one we're on.
if (P_PointInSector(sec->Level, listenpos.X, listenpos.Y) == sec)
@ -991,11 +991,11 @@ static FSoundChan *S_StartSound(FLevelLocals *Level, AActor *actor, const sector
return nullptr;
}
if (i_compatflags & COMPATF_MAGICSILENCE)
if (Level->i_compatflags & COMPATF_MAGICSILENCE)
{ // For people who just can't play without a silent BFG.
channel = CHAN_WEAPON;
}
else if ((chanflags & CHAN_MAYBE_LOCAL) && (i_compatflags & COMPATF_SILENTPICKUP))
else if ((chanflags & CHAN_MAYBE_LOCAL) && (Level->i_compatflags & COMPATF_SILENTPICKUP))
{
if (actor != NULL && actor != players[consoleplayer].camera)
{
@ -1679,7 +1679,7 @@ void S_StopSound (int channel)
{
FSoundChan *next = chan->NextChan;
if (chan->SourceType == SOURCE_None &&
(chan->EntChannel == channel || (i_compatflags & COMPATF_MAGICSILENCE)))
(chan->EntChannel == channel || (compatflags & COMPATF_MAGICSILENCE)))
{
S_StopChannel(chan);
}
@ -1703,7 +1703,7 @@ void S_StopSound (AActor *actor, int channel)
FSoundChan *next = chan->NextChan;
if (chan->SourceType == SOURCE_Actor &&
chan->Actor == actor &&
(chan->EntChannel == channel || (i_compatflags & COMPATF_MAGICSILENCE)))
(chan->EntChannel == channel || (compatflags & COMPATF_MAGICSILENCE)))
{
S_StopChannel(chan);
}
@ -1727,7 +1727,7 @@ void S_StopSound (const sector_t *sec, int channel)
FSoundChan *next = chan->NextChan;
if (chan->SourceType == SOURCE_Sector &&
chan->Sector == sec &&
(chan->EntChannel == channel || (i_compatflags & COMPATF_MAGICSILENCE)))
(chan->EntChannel == channel || (compatflags & COMPATF_MAGICSILENCE)))
{
S_StopChannel(chan);
}
@ -1751,7 +1751,7 @@ void S_StopSound (const FPolyObj *poly, int channel)
FSoundChan *next = chan->NextChan;
if (chan->SourceType == SOURCE_Polyobj &&
chan->Poly == poly &&
(chan->EntChannel == channel || (i_compatflags & COMPATF_MAGICSILENCE)))
(chan->EntChannel == channel || (compatflags & COMPATF_MAGICSILENCE)))
{
S_StopChannel(chan);
}
@ -1840,7 +1840,7 @@ void S_ChangeSoundVolume(AActor *actor, int channel, double dvolume)
{
if (chan->SourceType == SOURCE_Actor &&
chan->Actor == actor &&
(chan->EntChannel == channel || (i_compatflags & COMPATF_MAGICSILENCE)))
(chan->EntChannel == channel || (compatflags & COMPATF_MAGICSILENCE)))
{
GSnd->ChannelVolume(chan, volume);
chan->Volume = volume;
@ -1946,7 +1946,7 @@ static bool S_IsChannelUsed(AActor *actor, int channel, int *seen)
bool S_IsActorPlayingSomething (AActor *actor, int channel, int sound_id)
{
if (i_compatflags & COMPATF_MAGICSILENCE)
if (compatflags & COMPATF_MAGICSILENCE)
{
channel = 0;
}
@ -2200,7 +2200,7 @@ void S_UpdateSounds (AActor *listenactor)
GSnd->UpdateListener(&listener);
GSnd->UpdateSounds();
if (listenactor && listenactor->Level->time >= RestartEvictionsAt)
if (currentSession && currentSession->time >= RestartEvictionsAt)
{
RestartEvictionsAt = 0;
S_RestoreEvictedChannels();
@ -2506,7 +2506,7 @@ void S_SerializeSounds(FSerializer &arc, FLevelLocals *Level)
// playing before the wipe, and depending on the synchronization
// between the main thread and the mixer thread at the time, the
// sounds might be heard briefly before pausing for the wipe.
RestartEvictionsAt = Level->time + 2;
RestartEvictionsAt = currentSession->time + 2;
}
GSnd->Sync(false);
GSnd->UpdateSounds();

View file

@ -6836,9 +6836,7 @@ ExpEmit FxCVar::Emit(VMFunctionBuilder *build)
int *pVal;
auto cv = static_cast<FFlagCVar *>(CVar);
auto vcv = &cv->ValueVar;
if (vcv == &compatflags) pVal = &i_compatflags;
else if (vcv == &compatflags2) pVal = &i_compatflags2;
else pVal = &vcv->Value;
pVal = &vcv->Value;
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(pVal));
build->Emit(OP_LW, dest.RegNum, addr.RegNum, nul);
build->Emit(OP_SRL_RI, dest.RegNum, dest.RegNum, cv->BitNum);

View file

@ -2711,9 +2711,7 @@ DEFINE_FIELD(FLevelLocals, lines)
DEFINE_FIELD(FLevelLocals, sides)
DEFINE_FIELD(FLevelLocals, vertexes)
DEFINE_FIELD(FLevelLocals, sectorPortals)
DEFINE_FIELD(FLevelLocals, time)
DEFINE_FIELD(FLevelLocals, maptime)
DEFINE_FIELD(FLevelLocals, totaltime)
DEFINE_FIELD(FLevelLocals, starttime)
DEFINE_FIELD(FLevelLocals, partime)
DEFINE_FIELD(FLevelLocals, sucktime)
@ -2768,6 +2766,8 @@ DEFINE_FIELD_BIT(FLevelLocals, flags3, removeitems, LEVEL3_REMOVEITEMS)
DEFINE_FIELD(FGameSession, Levelinfo)
DEFINE_FIELD(FGameSession, F1Pic)
DEFINE_FIELD(FGameSession, time)
DEFINE_FIELD(FGameSession, totaltime)
DEFINE_GLOBAL(currentSession)
DEFINE_FIELD_X(Sector, sector_t, floorplane)

View file

@ -1652,7 +1652,33 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, CheckFor3DCeilingHit, CheckFor3DCeilingHit
ACTION_RETURN_BOOL(P_CheckFor3DCeilingHit(self, z, trigger));
}
//=====================================================================================
//
// compat flags. These two are the only ones that get checked in script code
// so anything more complex isn't really needed.
//
//=====================================================================================
static int compat_limitpain_(AActor *self)
{
return self->Level->i_compatflags & COMPATF_LIMITPAIN;
}
static int compat_mushroom_(AActor *self)
{
return self->Level->i_compatflags & COMPATF_MUSHROOM;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, compat_limitpain, compat_limitpain_)
{
PARAM_SELF_PROLOGUE(AActor);
ACTION_RETURN_INT(compat_limitpain_(self));
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, compat_mushroom, compat_mushroom_)
{
PARAM_SELF_PROLOGUE(AActor);
ACTION_RETURN_INT(compat_mushroom_(self));
}
//===========================================================================
//

View file

@ -481,7 +481,7 @@ void STAT_ChangeLevel(const char *newl, FLevelLocals *Level)
}
infostring.Format("%4d/%4d, %4d/%4d, %3d/%3d, %2d", statvals[0], statvals[1], statvals[2], statvals[3], statvals[4], statvals[5], validlevels);
FSessionStatistics *es = StatisticsEntry(sl, infostring, Level->totaltime);
FSessionStatistics *es = StatisticsEntry(sl, infostring, currentSession->totaltime);
for(unsigned i = 0; i < LevelData.Size(); i++)
{

View file

@ -591,7 +591,7 @@ namespace swrenderer
if (mFrontSector->e && mFrontSector->e->XFloor.lightlist.Size()) return true;
if (mBackSector->e && mBackSector->e->XFloor.lightlist.Size()) return true;
if (sidedef->GetTexture(side_t::mid).isValid() && ((ib_compatflags & BCOMPATF_CLIPMIDTEX) || (linedef->flags & (ML_CLIP_MIDTEX | ML_WRAP_MIDTEX)) || sidedef->Flags & (WALLF_CLIP_MIDTEX | WALLF_WRAP_MIDTEX))) return true;
if (sidedef->GetTexture(side_t::mid).isValid() && ((mFrontSector->Level->ib_compatflags & BCOMPATF_CLIPMIDTEX) || (linedef->flags & (ML_CLIP_MIDTEX | ML_WRAP_MIDTEX)) || sidedef->Flags & (WALLF_CLIP_MIDTEX | WALLF_WRAP_MIDTEX))) return true;
return false;
}
@ -653,7 +653,7 @@ namespace swrenderer
if (sidedef->GetTexture(side_t::mid).isValid())
{
if (ib_compatflags & BCOMPATF_CLIPMIDTEX) return true;
if (mFrontSector->Level->ib_compatflags & BCOMPATF_CLIPMIDTEX) return true;
if (linedef->flags & (ML_CLIP_MIDTEX | ML_WRAP_MIDTEX)) return true;
if (sidedef->Flags & (WALLF_CLIP_MIDTEX | WALLF_WRAP_MIDTEX)) return true;
}

View file

@ -150,7 +150,7 @@ namespace swrenderer
return false;
FTexture *ttex = TexMan.GetPalettedTexture(curline->sidedef->GetTexture(side_t::mid), true);
if (i_compatflags & COMPATF_MASKEDMIDTEX)
if (curline->frontsector->Level->i_compatflags & COMPATF_MASKEDMIDTEX)
{
ttex = ttex->GetRawTexture();
}
@ -294,7 +294,7 @@ namespace swrenderer
// this drawseg.
if ((curline->linedef->flags & ML_CLIP_MIDTEX) ||
(curline->sidedef->Flags & WALLF_CLIP_MIDTEX) ||
(ib_compatflags & BCOMPATF_CLIPMIDTEX))
(curline->frontsector->Level->ib_compatflags & BCOMPATF_CLIPMIDTEX))
{
ClipMidtex(x1, x2);
}
@ -356,7 +356,7 @@ namespace swrenderer
// this drawseg.
if ((curline->linedef->flags & ML_CLIP_MIDTEX) ||
(curline->sidedef->Flags & WALLF_CLIP_MIDTEX) ||
(ib_compatflags & BCOMPATF_CLIPMIDTEX))
(curline->frontsector->Level->ib_compatflags & BCOMPATF_CLIPMIDTEX))
{
ClipMidtex(x1, x2);
}

View file

@ -69,7 +69,7 @@ namespace swrenderer
if (count == 0)
return;
if (!(i_compatflags & COMPATF_SPRITESORT))
if (!(thread->Viewport->GetLevel()->i_compatflags & COMPATF_SPRITESORT))
{
for (unsigned int i = 0; i < count; i++)
SortedSprites[i] = Sprites[first + i];

View file

@ -769,7 +769,7 @@ class Actor : Thinker native
//==========================================================================
clearscope int GetLevelSpawnTime() const
{
return SpawnTime - Level.totaltime + Level.time;
return SpawnTime - currentSession.totaltime + currentSession.time;
}
//==========================================================================
@ -782,7 +782,7 @@ class Actor : Thinker native
clearscope int GetAge() const
{
return Level.totaltime - SpawnTime;
return currentSession.totaltime - SpawnTime;
}
double AccuracyFactor()

View file

@ -626,6 +626,8 @@ struct GameSession native
// all open levels. The first entry in this list is the primary one where gameplay takes place.
native Array<LevelLocals> LevelInfo;
native readonly String F1Pic;
native readonly int time;
native readonly int totaltime;
}
struct LevelLocals native
@ -645,6 +647,14 @@ struct LevelLocals native
{
return currentSession? currentSession.F1Pic : "";
}
deprecated("3.8") static int __getter__time__()
{
return currentSession? currentSession.time : 0;
}
deprecated("3.8") static int __getter__totaltime__()
{
return currentSession? currentSession.totaltime : 0;
}
@ -654,9 +664,7 @@ struct LevelLocals native
native readonly Array<@Vertex> Vertexes;
native internal Array<@SectorPortal> SectorPortals;
deprecated("3.8") native readonly int time;
native readonly int maptime;
deprecated("3.8") native readonly int totaltime;
native readonly int starttime;
native readonly int partime;
native readonly int sucktime;
@ -752,7 +760,7 @@ struct LevelLocals native
String TimeFormatted(bool totals = false)
{
int sec = Thinker.Tics2Seconds(totals? totaltime : time);
int sec = Thinker.Tics2Seconds(totals? currentSession.totaltime : currentSession.time);
return String.Format("%02d:%02d:%02d", sec / 3600, (sec % 3600) / 60, sec % 60);
}
}

View file

@ -105,6 +105,7 @@ extend class Actor
{
const FATSPREAD = 90./8;
private native bool compat_mushroom();
void A_FatRaise()
{
@ -195,7 +196,7 @@ extend class Actor
aimtarget.Height = Height;
bool shootmode = ((flags & MSF_Classic) || // Flag explicitly set, or no flags and compat options
(flags == 0 && CurState.bDehacked && compat_mushroom));
(flags == 0 && CurState.bDehacked && compat_mushroom()));
for (i = -numspawns; i <= numspawns; i += 8)
{

View file

@ -62,6 +62,8 @@ class PainElemental : Actor
extend class Actor
{
private native bool compat_limitpain();
//
// A_PainShootSkull
// Spawn a lost soul and launch it at the target
@ -86,7 +88,7 @@ extend class Actor
}
// [RH] make this optional
if (limit < 0 && compat_limitpain)
if (limit < 0 && compat_limitpain())
limit = 21;
if (limit > 0)

View file

@ -118,7 +118,7 @@ extend class Actor
morphed.RenderStyle = RenderStyle;
morphed.Score = Score;
morphed.UnmorphTime = Level.time + ((duration) ? duration : DEFMORPHTICS) + random[morphmonst]();
morphed.UnmorphTime = currentSession.time + ((duration) ? duration : DEFMORPHTICS) + random[morphmonst]();
morphed.MorphStyle = style;
morphed.MorphExitFlash = (exit_flash) ? exit_flash : (class<Actor>)("TeleportFog");
morphed.FlagsSave = bSolid * 2 + bShootable * 4 + bInvisible * 0x40; // The factors are for savegame compatibility
@ -656,7 +656,7 @@ class MorphedMonster : Actor
override void Tick ()
{
if (UnmorphTime > Level.time || !UndoMonsterMorph())
if (UnmorphTime > currentSession.time || !UndoMonsterMorph())
{
Super.Tick();
}
@ -687,7 +687,7 @@ class MorphedMonster : Actor
unmorphed.bSolid = false;
bSolid = true;
bTouchy = save;
UnmorphTime = Level.time + 5*TICRATE; // Next try in 5 seconds
UnmorphTime = currentSession.time + 5*TICRATE; // Next try in 5 seconds
return false;
}
unmorphed.Angle = Angle;

View file

@ -798,8 +798,8 @@ class AltHud ui
hud_showtime < 4
? Level.maptime
: (hud_showtime < 6
? Level.time
: Level.totaltime);
? currentSession.time
: currentSession.totaltime);
timeSeconds = Thinker.Tics2Seconds(timeTicks);
}
else
@ -818,7 +818,7 @@ class AltHud ui
if (showMillis)
{
int millis = (Level.time % Thinker.TICRATE) * (1000 / Thinker.TICRATE);
int millis = (currentSession.time % Thinker.TICRATE) * (1000 / Thinker.TICRATE);
timeString = String.Format("%02i:%02i:%02i.%03i", hours, minutes, seconds, millis);
}
else if (showSeconds)
@ -950,7 +950,7 @@ class AltHud ui
if (am_showtotaltime)
{
DrawTimeString(SmallFont, hudcolor_ttim, Level.totaltime, hudwidth-2, bottom, 1);
DrawTimeString(SmallFont, hudcolor_ttim, currentSession.totaltime, hudwidth-2, bottom, 1);
bottom -= fonth;
}
@ -958,7 +958,7 @@ class AltHud ui
{
if (Level.clusterflags & Level.CLUSTER_HUB)
{
DrawTimeString(SmallFont, hudcolor_time, Level.time, hudwidth-2, bottom, 1);
DrawTimeString(SmallFont, hudcolor_time, currentSession.time, hudwidth-2, bottom, 1);
bottom -= fonth;
}

View file

@ -43,7 +43,7 @@ class HereticStatusBar : BaseStatusBar
mHealthInterpolator.Update(CPlayer.health);
// wiggle the chain if it moves
if (Level.time & 1)
if (currentSession.time & 1)
{
wiggle = (mHealthInterpolator.GetValue() != CPlayer.health) && Random[ChainWiggle](0, 1);
}

View file

@ -600,7 +600,7 @@ class BaseStatusBar native ui
if(CPlayer.mo.waterlevel < 3)
return Level.airsupply;
else
return max(CPlayer.air_finished - Level.time, 0);
return max(CPlayer.air_finished - currentSession.time, 0);
}
int GetSelectedInventoryAmount()