Merge branch 'floatcvt' of https://github.com/rheit/zdoom into floatcvt

# Conflicts:
#	src/p_saveg.cpp
#	src/r_defs.h
This commit is contained in:
Christoph Oelckers 2016-04-03 22:16:06 +02:00
commit 447ce0abe7
32 changed files with 395 additions and 872 deletions

View file

@ -1086,7 +1086,7 @@ CCMD(currentpos)
if(mo) if(mo)
{ {
Printf("Current player position: (%1.3f,%1.3f,%1.3f), angle: %1.3f, floorheight: %1.3f, sector:%d, lightlevel: %d\n", Printf("Current player position: (%1.3f,%1.3f,%1.3f), angle: %1.3f, floorheight: %1.3f, sector:%d, lightlevel: %d\n",
mo->X(), mo->Y(), mo->Z(), mo->Angles.Yaw, mo->floorz, mo->Sector->sectornum, mo->Sector->lightlevel); mo->X(), mo->Y(), mo->Z(), mo->Angles.Yaw.Normalized360().Degrees, mo->floorz, mo->Sector->sectornum, mo->Sector->lightlevel);
} }
else else
{ {

View file

@ -1929,13 +1929,6 @@ void G_DoLoadGame ()
BYTE *vars_p = (BYTE *)text; BYTE *vars_p = (BYTE *)text;
C_ReadCVars (&vars_p); C_ReadCVars (&vars_p);
delete[] text; delete[] text;
if (SaveVersion <= 4509)
{
// account for the flag shuffling for making freelook a 3-state option
INTBOOL flag = dmflags & DF_YES_FREELOOK;
dmflags = dmflags & ~DF_YES_FREELOOK;
if (flag) dmflags2 = dmflags2 | DF2_RESPAWN_SUPER;
}
} }
// dearchive all the modifications // dearchive all the modifications

View file

@ -1495,26 +1495,11 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad)
<< level.maptime << level.maptime
<< i; << i;
if (SaveVersion >= 3313)
{
// This is a player property now
int nextmusic;
arc << nextmusic;
}
// Hub transitions must keep the current total time // Hub transitions must keep the current total time
if (!hubLoad) if (!hubLoad)
level.totaltime = i; level.totaltime = i;
if (SaveVersion >= 4507) arc << level.skytexture1 << level.skytexture2;
{
arc << level.skytexture1 << level.skytexture2;
}
else
{
level.skytexture1 = TexMan.GetTexture(arc.ReadName(), FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst);
level.skytexture2 = TexMan.GetTexture(arc.ReadName(), FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst);
}
if (arc.IsLoading()) if (arc.IsLoading())
{ {
sky1texture = level.skytexture1; sky1texture = level.skytexture1;
@ -1555,12 +1540,7 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad)
P_SerializeSubsectors(arc); P_SerializeSubsectors(arc);
StatusBar->Serialize (arc); StatusBar->Serialize (arc);
if (SaveVersion >= 4222) arc << level.DefaultSkybox << level.total_monsters << level.total_items << level.total_secrets;
{ // This must be done *after* thinkers are serialized.
arc << level.DefaultSkybox;
}
arc << level.total_monsters << level.total_items << level.total_secrets;
// Does this level have custom translations? // Does this level have custom translations?
FRemapTable *trans; FRemapTable *trans;
@ -1790,8 +1770,6 @@ void G_WriteSnapshots (FILE *file)
void G_ReadSnapshots (PNGHandle *png) void G_ReadSnapshots (PNGHandle *png)
{ {
DWORD chunkLen; DWORD chunkLen;
BYTE namelen;
char mapname[256];
FString MapName; FString MapName;
level_info_t *i; level_info_t *i;
@ -1804,14 +1782,7 @@ void G_ReadSnapshots (PNGHandle *png)
DWORD snapver; DWORD snapver;
arc << snapver; arc << snapver;
if (SaveVersion < 4508) arc << MapName;
{
arc << namelen;
arc.Read(mapname, namelen);
mapname[namelen] = 0;
MapName = mapname;
}
else arc << MapName;
i = FindLevelInfo (MapName); i = FindLevelInfo (MapName);
i->snapshotVer = snapver; i->snapshotVer = snapver;
i->snapshot = new FCompressedMemFile; i->snapshot = new FCompressedMemFile;
@ -1826,14 +1797,7 @@ void G_ReadSnapshots (PNGHandle *png)
DWORD snapver; DWORD snapver;
arc << snapver; arc << snapver;
if (SaveVersion < 4508) arc << MapName;
{
arc << namelen;
arc.Read(mapname, namelen);
mapname[namelen] = 0;
MapName = mapname;
}
else arc << MapName;
TheDefaultLevelInfo.snapshotVer = snapver; TheDefaultLevelInfo.snapshotVer = snapver;
TheDefaultLevelInfo.snapshot = new FCompressedMemFile; TheDefaultLevelInfo.snapshot = new FCompressedMemFile;
TheDefaultLevelInfo.snapshot->Serialize (arc); TheDefaultLevelInfo.snapshot->Serialize (arc);
@ -1844,25 +1808,10 @@ void G_ReadSnapshots (PNGHandle *png)
{ {
FPNGChunkArchive arc (png->File->GetFile(), VIST_ID, chunkLen); FPNGChunkArchive arc (png->File->GetFile(), VIST_ID, chunkLen);
if (SaveVersion < 4508) while (arc << MapName, MapName.Len() > 0)
{ {
arc << namelen; i = FindLevelInfo(MapName);
while (namelen != 0) i->flags |= LEVEL_VISITED;
{
arc.Read(mapname, namelen);
mapname[namelen] = 0;
i = FindLevelInfo(mapname);
i->flags |= LEVEL_VISITED;
arc << namelen;
}
}
else
{
while (arc << MapName, MapName.Len() > 0)
{
i = FindLevelInfo(MapName);
i->flags |= LEVEL_VISITED;
}
} }
} }
@ -1958,8 +1907,6 @@ void P_WriteACSDefereds (FILE *file)
void P_ReadACSDefereds (PNGHandle *png) void P_ReadACSDefereds (PNGHandle *png)
{ {
BYTE namelen;
char mapname[256];
FString MapName; FString MapName;
size_t chunklen; size_t chunklen;
@ -1969,33 +1916,14 @@ void P_ReadACSDefereds (PNGHandle *png)
{ {
FPNGChunkArchive arc (png->File->GetFile(), ACSD_ID, chunklen); FPNGChunkArchive arc (png->File->GetFile(), ACSD_ID, chunklen);
if (SaveVersion < 4508) while (arc << MapName, MapName.Len() > 0)
{ {
arc << namelen; level_info_t *i = FindLevelInfo(MapName);
while (namelen != 0) if (i == NULL)
{ {
arc.Read(mapname, namelen); I_Error("Unknown map '%s' in savegame", MapName.GetChars());
mapname[namelen] = 0;
level_info_t *i = FindLevelInfo(mapname);
if (i == NULL)
{
I_Error("Unknown map '%s' in savegame", mapname);
}
arc << i->defered;
arc << namelen;
}
}
else
{
while (arc << MapName, MapName.Len() > 0)
{
level_info_t *i = FindLevelInfo(MapName);
if (i == NULL)
{
I_Error("Unknown map '%s' in savegame", MapName.GetChars());
}
arc << i->defered;
} }
arc << i->defered;
} }
} }
png->File->ResetFilePtr(); png->File->ResetFilePtr();

View file

@ -24,12 +24,7 @@ IMPLEMENT_CLASS (AHexenArmor)
void ABasicArmor::Serialize (FArchive &arc) void ABasicArmor::Serialize (FArchive &arc)
{ {
Super::Serialize (arc); Super::Serialize (arc);
arc << SavePercent << BonusCount << MaxAbsorb << MaxFullAbsorb << AbsorbCount << ArmorType; arc << SavePercent << BonusCount << MaxAbsorb << MaxFullAbsorb << AbsorbCount << ArmorType << ActualSaveAmount;
if (SaveVersion >= 4511)
{
arc << ActualSaveAmount;
}
} }
//=========================================================================== //===========================================================================

View file

@ -1205,14 +1205,7 @@ IMPLEMENT_CLASS (APowerSpeed)
void APowerSpeed::Serialize(FArchive &arc) void APowerSpeed::Serialize(FArchive &arc)
{ {
Super::Serialize (arc); Super::Serialize (arc);
if (SaveVersion < 4146) arc << SpeedFlags;
{
SpeedFlags = 0;
}
else
{
arc << SpeedFlags;
}
} }
//=========================================================================== //===========================================================================

View file

@ -44,26 +44,6 @@ void DLightningThinker::Serialize (FArchive &arc)
arc << Stopped << NextLightningFlash << LightningFlashCount; arc << Stopped << NextLightningFlash << LightningFlashCount;
if (SaveVersion < 3243)
{
// Do nothing with old savegames and just keep whatever the constructor made
// but read the obsolete data from the savegame
for (i = (numsectors + (numsectors+7)/8); i > 0; --i)
{
if (SaveVersion < 3223)
{
BYTE bytelight;
arc << bytelight;
}
else
{
short shortlight;
arc << shortlight;
}
}
return;
}
if (arc.IsLoading ()) if (arc.IsLoading ())
{ {
if (LightningLightLevels != NULL) if (LightningLightLevels != NULL)

View file

@ -90,16 +90,11 @@ void AWeapon::Serialize (FArchive &arc)
<< MoveCombatDist << MoveCombatDist
<< Ammo1 << Ammo2 << SisterWeapon << GivenAsMorphWeapon << Ammo1 << Ammo2 << SisterWeapon << GivenAsMorphWeapon
<< bAltFire << bAltFire
<< ReloadCounter; << ReloadCounter
if (SaveVersion >= 3615) { << BobStyle << BobSpeed << BobRangeX << BobRangeY
arc << BobStyle << BobSpeed << BobRangeX << BobRangeY; << FOVScale
} << Crosshair
arc << FOVScale << MinSelAmmo1 << MinSelAmmo2;
<< Crosshair;
if (SaveVersion >= 4203)
{
arc << MinSelAmmo1 << MinSelAmmo2;
}
} }
//=========================================================================== //===========================================================================
@ -731,10 +726,7 @@ IMPLEMENT_CLASS(AWeaponGiver)
void AWeaponGiver::Serialize(FArchive &arc) void AWeaponGiver::Serialize(FArchive &arc)
{ {
Super::Serialize(arc); Super::Serialize(arc);
if (SaveVersion >= 4246) arc << DropAmmoFactor;
{
arc << DropAmmoFactor;
}
} }
bool AWeaponGiver::TryPickup(AActor *&toucher) bool AWeaponGiver::TryPickup(AActor *&toucher)

View file

@ -179,53 +179,23 @@ DHUDMessage::~DHUDMessage ()
// //
//============================================================================ //============================================================================
void DHUDMessage::Serialize (FArchive &arc) void DHUDMessage::Serialize(FArchive &arc)
{ {
Super::Serialize (arc); Super::Serialize(arc);
arc << Left << Top << CenterX << HoldTics arc << Left << Top << CenterX << HoldTics
<< Tics << State << TextColor << Tics << State << TextColor
<< SBarID << SourceText << Font << Next << SBarID << SourceText << Font << Next
<< HUDWidth << HUDHeight; << HUDWidth << HUDHeight
if (SaveVersion >= 3960) << NoWrap
{ << ClipX << ClipY << ClipWidth << ClipHeight
arc << NoWrap; << WrapWidth
arc << ClipX << ClipY << ClipWidth << ClipHeight; << HandleAspect
arc << WrapWidth; << VisibilityFlags
} << Style << Alpha;
else if (arc.IsLoading())
{
NoWrap = false;
ClipX = ClipY = ClipWidth = ClipHeight = WrapWidth = 0;
}
if (SaveVersion >= 4525)
{
arc << HandleAspect;
}
else
{
HandleAspect = true;
}
if (arc.IsLoading ())
{ {
Lines = NULL; Lines = NULL;
ResetText (SourceText); ResetText(SourceText);
}
if (SaveVersion < 3821)
{
VisibilityFlags = 0;
}
else
{
arc << VisibilityFlags;
}
if (SaveVersion < 3824)
{
Style = STYLE_Translucent;
Alpha = 1.;
}
else
{
arc << Style << Alpha;
} }
} }

View file

@ -207,67 +207,31 @@ class SBarInfoCommandFlowControl : public SBarInfoCommand
{ {
public: public:
SBarInfoCommandFlowControl(SBarInfo *script) : SBarInfoCommand(script), truth(false) {} SBarInfoCommandFlowControl(SBarInfo *script) : SBarInfoCommand(script), truth(false) {}
~SBarInfoCommandFlowControl()
{
for(unsigned int i = 0;i < 2;i++)
{
for(unsigned int j = 0;j < commands[i].Size();j++)
delete commands[i][j];
}
}
void Draw(const SBarInfoMainBlock *block, const DSBarInfo *statusBar) void Draw(const SBarInfoMainBlock *block, const DSBarInfo *statusBar)
{ {
for(unsigned int i = 0;i < commands[truth].Size();i++) for(auto command : commands[truth])
commands[truth][i]->Draw(block, statusBar); command->Draw(block, statusBar);
} }
int NumCommands() const { return commands[truth].Size(); } int NumCommands() const { return commands[truth].Size(); }
void Parse(FScanner &sc, bool fullScreenOffsets) void Parse(FScanner &sc, bool fullScreenOffsets)
{ {
bool elseBlock = false; ParseBlock(commands[1], sc, fullScreenOffsets);
SBarInfoCommand *cmd = NULL; if(sc.CheckToken(TK_Else))
// Should loop no more than twice. ParseBlock(commands[0], sc, fullScreenOffsets);
while(true)
{
if(sc.CheckToken('{'))
{
while((cmd = NextCommand(sc)) != NULL)
{
cmd->Parse(sc, fullScreenOffsets);
commands[!elseBlock].Push(cmd);
}
}
else
{
if((cmd = NextCommand(sc)) != NULL)
{
cmd->Parse(sc, fullScreenOffsets);
commands[!elseBlock].Push(cmd);
}
else
sc.ScriptError("Missing command for flow control statement.");
}
if(!elseBlock && sc.CheckToken(TK_Else))
{
elseBlock = true;
continue;
}
break;
}
} }
void Reset() void Reset()
{ {
for(unsigned int i = 0;i < 2;i++) for(unsigned int i = 0;i < 2;i++)
{ {
for(unsigned int j = 0;j < commands[i].Size();j++) for(auto command : commands[i])
commands[i][j]->Reset(); command->Reset();
} }
} }
void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged) void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged)
{ {
for(unsigned int i = 0;i < commands[truth].Size();i++) for(auto command : commands[truth])
commands[truth][i]->Tick(block, statusBar, hudChanged); command->Tick(block, statusBar, hudChanged);
} }
protected: protected:
@ -284,11 +248,65 @@ class SBarInfoCommandFlowControl : public SBarInfoCommand
Tick(block, statusBar, true); Tick(block, statusBar, true);
} }
void Negate()
{
swapvalues(commands[0], commands[1]);
}
private: private:
void ParseBlock(TDeletingArray<SBarInfoCommand *> &commands, FScanner &sc, bool fullScreenOffsets)
{
if(sc.CheckToken('{'))
{
while(SBarInfoCommand *cmd = NextCommand(sc))
{
cmd->Parse(sc, fullScreenOffsets);
commands.Push(cmd);
}
}
else
{
if(SBarInfoCommand *cmd = NextCommand(sc))
{
cmd->Parse(sc, fullScreenOffsets);
commands.Push(cmd);
}
else
sc.ScriptError("Missing command for flow control statement.");
}
}
SBarInfoCommand *NextCommand(FScanner &sc); SBarInfoCommand *NextCommand(FScanner &sc);
bool truth; TDeletingArray<SBarInfoCommand *> commands[2];
TArray<SBarInfoCommand *> commands[2]; bool truth;
};
class SBarInfoNegatableFlowControl : public SBarInfoCommandFlowControl
{
public:
SBarInfoNegatableFlowControl(SBarInfo *script) : SBarInfoCommandFlowControl(script) {}
void Parse(FScanner &sc, bool fullScreenOffsets)
{
bool negate = false;
if(sc.CheckToken(TK_Identifier))
{
if(sc.Compare("not"))
negate = true;
else
sc.UnGet();
}
ParseNegatable(sc, fullScreenOffsets);
SBarInfoCommandFlowControl::Parse(sc, fullScreenOffsets);
if(negate)
Negate();
}
virtual void ParseNegatable(FScanner &sc, bool fullScreenOffsets) {}
}; };
class SBarInfoMainBlock : public SBarInfoCommandFlowControl class SBarInfoMainBlock : public SBarInfoCommandFlowControl

View file

@ -1828,33 +1828,17 @@ const char* const CommandGameMode::modeNames[] =
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class CommandUsesAmmo : public SBarInfoCommandFlowControl class CommandUsesAmmo : public SBarInfoNegatableFlowControl
{ {
public: public:
CommandUsesAmmo(SBarInfo *script) : SBarInfoCommandFlowControl(script), CommandUsesAmmo(SBarInfo *script) : SBarInfoNegatableFlowControl(script) {}
negate(false)
{
}
void Parse(FScanner &sc, bool fullScreenOffsets)
{
if(sc.CheckToken(TK_Identifier))
{
if(sc.Compare("not"))
negate = true;
else
sc.ScriptError("Expected 'not', but got '%s' instead.", sc.String);
}
SBarInfoCommandFlowControl::Parse(sc, fullScreenOffsets);
}
void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged) void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged)
{ {
SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged); SBarInfoNegatableFlowControl::Tick(block, statusBar, hudChanged);
SetTruth((statusBar->CPlayer->ReadyWeapon != NULL && (statusBar->CPlayer->ReadyWeapon->AmmoType1 != NULL || statusBar->CPlayer->ReadyWeapon->AmmoType2 != NULL)) ^ negate, block, statusBar); SetTruth(statusBar->CPlayer->ReadyWeapon != NULL && (statusBar->CPlayer->ReadyWeapon->AmmoType1 != NULL || statusBar->CPlayer->ReadyWeapon->AmmoType2 != NULL), block, statusBar);
} }
protected:
bool negate;
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -1870,7 +1854,7 @@ class CommandUsesSecondaryAmmo : public CommandUsesAmmo
{ {
SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged); SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged);
SetTruth((statusBar->CPlayer->ReadyWeapon != NULL && statusBar->CPlayer->ReadyWeapon->AmmoType2 != NULL && statusBar->CPlayer->ReadyWeapon->AmmoType1 != statusBar->CPlayer->ReadyWeapon->AmmoType2) ^ negate, block, statusBar); SetTruth(statusBar->CPlayer->ReadyWeapon != NULL && statusBar->CPlayer->ReadyWeapon->AmmoType2 != NULL && statusBar->CPlayer->ReadyWeapon->AmmoType1 != statusBar->CPlayer->ReadyWeapon->AmmoType2, block, statusBar);
} }
}; };
@ -2887,28 +2871,18 @@ class CommandDrawBar : public SBarInfoCommand
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class CommandIsSelected : public SBarInfoCommandFlowControl class CommandIsSelected : public SBarInfoNegatableFlowControl
{ {
public: public:
CommandIsSelected(SBarInfo *script) : SBarInfoCommandFlowControl(script), CommandIsSelected(SBarInfo *script) : SBarInfoNegatableFlowControl(script)
negate(false)
{ {
weapon[0] = NULL; weapon[0] = NULL;
weapon[1] = NULL; weapon[1] = NULL;
} }
void Parse(FScanner &sc, bool fullScreenOffsets) void ParseNegatable(FScanner &sc, bool fullScreenOffsets)
{ {
if(sc.CheckToken(TK_Identifier)) if(!sc.CheckToken(TK_Identifier))
{
if(sc.Compare("not"))
{
negate = true;
if(!sc.CheckToken(TK_StringConst))
sc.MustGetToken(TK_Identifier);
}
}
else
sc.MustGetToken(TK_StringConst); sc.MustGetToken(TK_StringConst);
for(int i = 0;i < 2;i++) for(int i = 0;i < 2;i++)
{ {
@ -2927,24 +2901,18 @@ class CommandIsSelected : public SBarInfoCommandFlowControl
else else
break; break;
} }
SBarInfoCommandFlowControl::Parse(sc, fullScreenOffsets);
} }
void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged) void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged)
{ {
SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged); SBarInfoNegatableFlowControl::Tick(block, statusBar, hudChanged);
if(statusBar->CPlayer->ReadyWeapon != NULL) if(statusBar->CPlayer->ReadyWeapon != NULL)
{ {
const PClass *readyWeapon = statusBar->CPlayer->ReadyWeapon->GetClass(); const PClass *readyWeapon = statusBar->CPlayer->ReadyWeapon->GetClass();
SetTruth(((weapon[1] != NULL) && SetTruth(weapon[0] == readyWeapon || (weapon[1] && weapon[1] == readyWeapon), block, statusBar);
((negate && (weapon[0] != readyWeapon && weapon[1] != readyWeapon)) ||
(!negate && (weapon[0] == readyWeapon || weapon[1] == readyWeapon)))) ||
((weapon[1] == NULL) &&
((!negate && weapon[0] == readyWeapon) || (negate && weapon[0] != readyWeapon))), block, statusBar);
} }
} }
protected: protected:
bool negate;
const PClass *weapon[2]; const PClass *weapon[2];
}; };
@ -3242,26 +3210,20 @@ FRandom CommandDrawGem::pr_chainwiggle; //use the same method of chain wiggling
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class CommandWeaponAmmo : public SBarInfoCommandFlowControl class CommandWeaponAmmo : public SBarInfoNegatableFlowControl
{ {
public: public:
CommandWeaponAmmo(SBarInfo *script) : SBarInfoCommandFlowControl(script), CommandWeaponAmmo(SBarInfo *script) : SBarInfoNegatableFlowControl(script),
conditionAnd(false), negate(false) conditionAnd(false)
{ {
ammo[0] = NULL; ammo[0] = NULL;
ammo[1] = NULL; ammo[1] = NULL;
} }
void Parse(FScanner &sc, bool fullScreenOffsets) void ParseNegatable(FScanner &sc, bool fullScreenOffsets)
{ {
if(!sc.CheckToken(TK_StringConst)) if(!sc.CheckToken(TK_StringConst))
sc.MustGetToken(TK_Identifier); sc.MustGetToken(TK_Identifier);
if(sc.Compare("not") && sc.TokenType == TK_Identifier)
{
negate = true;
if(!sc.CheckToken(TK_StringConst))
sc.MustGetToken(TK_Identifier);
}
for(int i = 0;i < 2;i++) for(int i = 0;i < 2;i++)
{ {
ammo[i] = PClass::FindClass(sc.String); ammo[i] = PClass::FindClass(sc.String);
@ -3286,11 +3248,10 @@ class CommandWeaponAmmo : public SBarInfoCommandFlowControl
else else
break; break;
} }
SBarInfoCommandFlowControl::Parse(sc, fullScreenOffsets);
} }
void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged) void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged)
{ {
SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged); SBarInfoNegatableFlowControl::Tick(block, statusBar, hudChanged);
if(statusBar->CPlayer->ReadyWeapon != NULL) if(statusBar->CPlayer->ReadyWeapon != NULL)
{ {
@ -3298,41 +3259,25 @@ class CommandWeaponAmmo : public SBarInfoCommandFlowControl
const PClass *AmmoType2 = statusBar->CPlayer->ReadyWeapon->AmmoType2; const PClass *AmmoType2 = statusBar->CPlayer->ReadyWeapon->AmmoType2;
bool usesammo1 = (AmmoType1 != NULL); bool usesammo1 = (AmmoType1 != NULL);
bool usesammo2 = (AmmoType2 != NULL); bool usesammo2 = (AmmoType2 != NULL);
if(negate && !usesammo1 && !usesammo2) //if the weapon doesn't use ammo don't go though the trouble. //if(!usesammo1 && !usesammo2) //if the weapon doesn't use ammo don't go though the trouble.
{ //{
SetTruth(true, block, statusBar); // SetTruth(false, block, statusBar);
return; // return;
} //}
//Or means only 1 ammo type needs to match and means both need to match. //Or means only 1 ammo type needs to match and means both need to match.
if(ammo[1] != NULL) if(ammo[1] != NULL)
{ {
bool match1 = ((usesammo1 && (AmmoType1 == ammo[0] || AmmoType1 == ammo[1])) || !usesammo1); bool match1 = ((usesammo1 && (AmmoType1 == ammo[0] || AmmoType1 == ammo[1])) || !usesammo1);
bool match2 = ((usesammo2 && (AmmoType2 == ammo[0] || AmmoType2 == ammo[1])) || !usesammo2); bool match2 = ((usesammo2 && (AmmoType2 == ammo[0] || AmmoType2 == ammo[1])) || !usesammo2);
if((!conditionAnd && (match1 || match2)) || (conditionAnd && (match1 && match2))) if((!conditionAnd && (match1 || match2)) || (conditionAnd && (match1 && match2)))
{
if(!negate)
{
SetTruth(true, block, statusBar);
return;
}
}
else if(negate)
{ {
SetTruth(true, block, statusBar); SetTruth(true, block, statusBar);
return; return;
} }
} }
else //Every thing here could probably be one long if statement but then it would be more confusing. else
{ {
if((usesammo1 && (AmmoType1 == ammo[0])) || (usesammo2 && (AmmoType2 == ammo[0]))) if((usesammo1 && (AmmoType1 == ammo[0])) || (usesammo2 && (AmmoType2 == ammo[0])))
{
if(!negate)
{
SetTruth(true, block, statusBar);
return;
}
}
else if(negate)
{ {
SetTruth(true, block, statusBar); SetTruth(true, block, statusBar);
return; return;
@ -3342,33 +3287,26 @@ class CommandWeaponAmmo : public SBarInfoCommandFlowControl
SetTruth(false, block, statusBar); SetTruth(false, block, statusBar);
} }
protected: protected:
bool conditionAnd;
bool negate;
const PClass *ammo[2]; const PClass *ammo[2];
bool conditionAnd;
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class CommandInInventory : public SBarInfoCommandFlowControl class CommandInInventory : public SBarInfoNegatableFlowControl
{ {
public: public:
CommandInInventory(SBarInfo *script) : SBarInfoCommandFlowControl(script), CommandInInventory(SBarInfo *script) : SBarInfoNegatableFlowControl(script),
conditionAnd(false), negate(false) conditionAnd(false)
{ {
item[0] = item[1] = NULL; item[0] = item[1] = NULL;
amount[0] = amount[1] = 0; amount[0] = amount[1] = 0;
} }
void Parse(FScanner &sc, bool fullScreenOffsets) void ParseNegatable(FScanner &sc, bool fullScreenOffsets)
{ {
if(!sc.CheckToken(TK_StringConst)) if(!sc.CheckToken(TK_StringConst))
sc.MustGetToken(TK_Identifier); sc.MustGetToken(TK_Identifier);
if(sc.Compare("not") && sc.TokenType == TK_Identifier)
{
negate = true;
if(!sc.CheckToken(TK_StringConst))
sc.MustGetToken(TK_Identifier);
}
for(int i = 0;i < 2;i++) for(int i = 0;i < 2;i++)
{ {
item[i] = PClass::FindActor(sc.String); item[i] = PClass::FindActor(sc.String);
@ -3399,11 +3337,10 @@ class CommandInInventory : public SBarInfoCommandFlowControl
else else
break; break;
} }
SBarInfoCommandFlowControl::Parse(sc, fullScreenOffsets);
} }
void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged) void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged)
{ {
SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged); SBarInfoNegatableFlowControl::Tick(block, statusBar, hudChanged);
AInventory *invItem[2] = { statusBar->CPlayer->mo->FindInventory(item[0]), statusBar->CPlayer->mo->FindInventory(item[1]) }; AInventory *invItem[2] = { statusBar->CPlayer->mo->FindInventory(item[0]), statusBar->CPlayer->mo->FindInventory(item[1]) };
if (invItem[0] != NULL && amount[0] > 0 && invItem[0]->Amount < amount[0]) invItem[0] = NULL; if (invItem[0] != NULL && amount[0] > 0 && invItem[0]->Amount < amount[0]) invItem[0] = NULL;
@ -3412,16 +3349,15 @@ class CommandInInventory : public SBarInfoCommandFlowControl
if (item[1]) if (item[1])
{ {
if (conditionAnd) if (conditionAnd)
SetTruth((invItem[0] && invItem[1]) != negate, block, statusBar); SetTruth(invItem[0] && invItem[1], block, statusBar);
else else
SetTruth((invItem[0] || invItem[1]) != negate, block, statusBar); SetTruth(invItem[0] || invItem[1], block, statusBar);
} }
else else
SetTruth((invItem[0] != NULL) != negate, block, statusBar); SetTruth(invItem[0] != NULL, block, statusBar);
} }
protected: protected:
bool conditionAnd; bool conditionAnd;
bool negate;
PClassActor *item[2]; PClassActor *item[2];
int amount[2]; int amount[2];
}; };
@ -3456,42 +3392,48 @@ class CommandAlpha : public SBarInfoMainBlock
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class CommandIfHealth : public SBarInfoCommandFlowControl class CommandIfHealth : public SBarInfoNegatableFlowControl
{ {
public: public:
CommandIfHealth(SBarInfo *script) : SBarInfoCommandFlowControl(script), CommandIfHealth(SBarInfo *script) : SBarInfoNegatableFlowControl(script),
negate(false), percentage(false) percentage(false)
{ {
} }
void Parse(FScanner &sc, bool fullScreenOffsets) void ParseNegatable(FScanner &sc, bool fullScreenOffsets)
{ {
if (sc.CheckToken(TK_Identifier))
{
if (sc.Compare("not"))
negate = true;
else
sc.ScriptError("Expected 'not', but got '%s' instead.", sc.String);
}
sc.MustGetToken(TK_IntConst); sc.MustGetToken(TK_IntConst);
percentage = sc.CheckToken('%'); percentage = sc.CheckToken('%');
hpamount = sc.Number; hpamount = sc.Number;
SBarInfoCommandFlowControl::Parse(sc, fullScreenOffsets);
} }
void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged) void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged)
{ {
SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged); SBarInfoNegatableFlowControl::Tick(block, statusBar, hudChanged);
int phealth = percentage ? statusBar->CPlayer->mo->health * 100 / statusBar->CPlayer->mo->GetMaxHealth() : statusBar->CPlayer->mo->health; int phealth = percentage ? statusBar->CPlayer->mo->health * 100 / statusBar->CPlayer->mo->GetMaxHealth() : statusBar->CPlayer->mo->health;
SetTruth((phealth >= hpamount) ^ negate, block, statusBar); SetTruth(phealth >= hpamount, block, statusBar);
} }
protected: protected:
bool negate;
bool percentage;
int hpamount; int hpamount;
bool percentage;
};
////////////////////////////////////////////////////////////////////////////////
class CommandIfInvulnerable : public SBarInfoNegatableFlowControl
{
public:
CommandIfInvulnerable(SBarInfo *script) : SBarInfoNegatableFlowControl(script)
{
}
void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged)
{
SBarInfoNegatableFlowControl::Tick(block, statusBar, hudChanged);
SetTruth((statusBar->CPlayer->mo->flags2 & MF2_INVULNERABLE) || (statusBar->CPlayer->cheats & (CF_GODMODE | CF_GODMODE2)), block, statusBar);
}
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -3506,6 +3448,7 @@ static const char *SBarInfoCommandNames[] =
"isselected", "usesammo", "usessecondaryammo", "isselected", "usesammo", "usessecondaryammo",
"hasweaponpiece", "inventorybarnotvisible", "hasweaponpiece", "inventorybarnotvisible",
"weaponammo", "ininventory", "alpha", "ifhealth", "weaponammo", "ininventory", "alpha", "ifhealth",
"ifinvulnerable",
NULL NULL
}; };
@ -3519,6 +3462,7 @@ enum SBarInfoCommands
SBARINFO_ISSELECTED, SBARINFO_USESAMMO, SBARINFO_USESSECONDARYAMMO, SBARINFO_ISSELECTED, SBARINFO_USESAMMO, SBARINFO_USESSECONDARYAMMO,
SBARINFO_HASWEAPONPIECE, SBARINFO_INVENTORYBARNOTVISIBLE, SBARINFO_HASWEAPONPIECE, SBARINFO_INVENTORYBARNOTVISIBLE,
SBARINFO_WEAPONAMMO, SBARINFO_ININVENTORY, SBARINFO_ALPHA, SBARINFO_IFHEALTH, SBARINFO_WEAPONAMMO, SBARINFO_ININVENTORY, SBARINFO_ALPHA, SBARINFO_IFHEALTH,
SBARINFO_IFINVULNERABLE,
}; };
SBarInfoCommand *SBarInfoCommandFlowControl::NextCommand(FScanner &sc) SBarInfoCommand *SBarInfoCommandFlowControl::NextCommand(FScanner &sc)
@ -3552,6 +3496,7 @@ SBarInfoCommand *SBarInfoCommandFlowControl::NextCommand(FScanner &sc)
case SBARINFO_ININVENTORY: return new CommandInInventory(script); case SBARINFO_ININVENTORY: return new CommandInInventory(script);
case SBARINFO_ALPHA: return new CommandAlpha(script); case SBARINFO_ALPHA: return new CommandAlpha(script);
case SBARINFO_IFHEALTH: return new CommandIfHealth(script); case SBARINFO_IFHEALTH: return new CommandIfHealth(script);
case SBARINFO_IFINVULNERABLE: return new CommandIfInvulnerable(script);
} }
sc.ScriptError("Unknown command '%s'.\n", sc.String); sc.ScriptError("Unknown command '%s'.\n", sc.String);

View file

@ -1651,17 +1651,9 @@ void DBaseStatusBar::ReceivedWeapon (AWeapon *weapon)
void DBaseStatusBar::Serialize (FArchive &arc) void DBaseStatusBar::Serialize (FArchive &arc)
{ {
if (SaveVersion < 3821) for (size_t i = 0; i < countof(Messages); ++i)
{ {
memset(Messages, 0, sizeof(Messages)); arc << Messages[i];
arc << Messages[HUDMSGLayer_Default];
}
else
{
for (size_t i = 0; i < countof(Messages); ++i)
{
arc << Messages[i];
}
} }
} }

View file

@ -1654,13 +1654,13 @@ void FBehavior::StaticSerializeModuleStates (FArchive &arc)
if (arc.IsStoring()) if (arc.IsStoring())
{ {
arc.WriteString (module->ModuleName); arc.WriteString (module->ModuleName);
if (SaveVersion >= 4516) arc << ModSize; arc << ModSize;
} }
else else
{ {
char *modname = NULL; char *modname = NULL;
arc << modname; arc << modname;
if (SaveVersion >= 4516) arc << ModSize; arc << ModSize;
if (stricmp (modname, module->ModuleName) != 0) if (stricmp (modname, module->ModuleName) != 0)
{ {
delete[] modname; delete[] modname;
@ -2899,35 +2899,19 @@ void FBehavior::StaticStopMyScripts (AActor *actor)
void P_SerializeACSScriptNumber(FArchive &arc, int &scriptnum, bool was2byte) void P_SerializeACSScriptNumber(FArchive &arc, int &scriptnum, bool was2byte)
{ {
if (SaveVersion < 3359) arc << scriptnum;
// If the script number is negative, then it's really a name.
// So read/store the name after it.
if (scriptnum < 0)
{ {
if (was2byte) if (arc.IsStoring())
{ {
WORD oldver; arc.WriteName(FName(ENamedName(-scriptnum)).GetChars());
arc << oldver;
scriptnum = oldver;
} }
else else
{ {
arc << scriptnum; const char *nam = arc.ReadName();
} scriptnum = -FName(nam);
}
else
{
arc << scriptnum;
// If the script number is negative, then it's really a name.
// So read/store the name after it.
if (scriptnum < 0)
{
if (arc.IsStoring())
{
arc.WriteName(FName(ENamedName(-scriptnum)).GetChars());
}
else
{
const char *nam = arc.ReadName();
scriptnum = -FName(nam);
}
} }
} }
} }
@ -2969,52 +2953,47 @@ void DACSThinker::Serialize (FArchive &arc)
int scriptcount = 0; int scriptcount = 0;
Super::Serialize (arc); Super::Serialize (arc);
if (SaveVersion < 4515) if (arc.IsStoring())
arc << Scripts << LastScript; {
DLevelScript *script;
script = Scripts;
while (script)
{
scriptcount++;
// We want to store this list backwards, so we can't loose the last pointer
if (script->next == NULL)
break;
script = script->next;
}
arc << scriptcount;
while (script)
{
arc << script;
script = script->prev;
}
}
else else
{ {
if (arc.IsStoring()) // We are running through this list backwards, so the next entry is the last processed
DLevelScript *next = NULL;
arc << scriptcount;
Scripts = NULL;
LastScript = NULL;
for (int i = 0; i < scriptcount; i++)
{ {
DLevelScript *script; arc << Scripts;
script = Scripts;
while (script)
{
scriptcount++;
// We want to store this list backwards, so we can't loose the last pointer Scripts->next = next;
if (script->next == NULL) Scripts->prev = NULL;
break; if (next != NULL)
script = script->next; next->prev = Scripts;
}
arc << scriptcount;
while (script) next = Scripts;
{
arc << script;
script = script->prev;
}
}
else
{
// We are running through this list backwards, so the next entry is the last processed
DLevelScript *next = NULL;
arc << scriptcount;
Scripts = NULL;
LastScript = NULL;
for (int i = 0; i < scriptcount; i++)
{
arc << Scripts;
Scripts->next = next; if (i == 0)
Scripts->prev = NULL; LastScript = Scripts;
if (next != NULL)
next->prev = Scripts;
next = Scripts;
if (i == 0)
LastScript = Scripts;
}
} }
} }
if (arc.IsStoring ()) if (arc.IsStoring ())
@ -3102,8 +3081,6 @@ void DLevelScript::Serialize (FArchive &arc)
DWORD i; DWORD i;
Super::Serialize (arc); Super::Serialize (arc);
if (SaveVersion < 4515)
arc << next << prev;
P_SerializeACSScriptNumber(arc, script, false); P_SerializeACSScriptNumber(arc, script, false);
@ -3140,23 +3117,9 @@ void DLevelScript::Serialize (FArchive &arc)
arc << activefont arc << activefont
<< hudwidth << hudheight; << hudwidth << hudheight;
if (SaveVersion >= 3960) arc << ClipRectLeft << ClipRectTop << ClipRectWidth << ClipRectHeight
{ << WrapWidth;
arc << ClipRectLeft << ClipRectTop << ClipRectWidth << ClipRectHeight arc << InModuleScriptNumber;
<< WrapWidth;
}
else
{
ClipRectLeft = ClipRectTop = ClipRectWidth = ClipRectHeight = WrapWidth = 0;
}
if (SaveVersion >= 4058)
{
arc << InModuleScriptNumber;
}
else
{ // Don't worry about locating profiling info for old saves.
InModuleScriptNumber = -1;
}
} }
DLevelScript::DLevelScript () DLevelScript::DLevelScript ()

View file

@ -2122,8 +2122,10 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
// it slopes or the player's eyes are bobbing in and out. // it slopes or the player's eyes are bobbing in and out.
bool oldAboveFakeFloor, oldAboveFakeCeiling; bool oldAboveFakeFloor, oldAboveFakeCeiling;
double viewheight = thing->player ? thing->player->viewheight : thing->Height / 2; double viewheight;
oldAboveFakeFloor = oldAboveFakeCeiling = false; // pacify GCC // pacify GCC
viewheight = thing->player ? thing->player->viewheight : thing->Height / 2;
oldAboveFakeFloor = oldAboveFakeCeiling = false;
if (oldsec->heightsec) if (oldsec->heightsec)
{ {
@ -2943,7 +2945,7 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, DVector2 &move)
double t; double t;
dest = actor->Pos() + move; dest = actor->Pos() + move;
t = plane->fA() * dest.X + plane->fB() * dest.Y + plane->fC() * actor->Z() + plane->fD(); t = (plane->Normal() | DVector3(dest, actor->Z())) + plane->fD();
if (t < 0) if (t < 0)
{ // Desired location is behind (below) the plane { // Desired location is behind (below) the plane
// (i.e. Walking up the plane) // (i.e. Walking up the plane)
@ -2977,16 +2979,16 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, DVector2 &move)
} }
if (dopush) if (dopush)
{ {
actor->Vel.X = move.X = plane->fA() * 2; move = plane->Normal() * 2;
actor->Vel.Y = move.Y = plane->fB() * 2; actor->Vel.X = move.X;
actor->Vel.Y = move.Y;
} }
return (actor->floorsector == actor->Sector) ? plane : NULL; return (actor->floorsector == actor->Sector) ? plane : NULL;
} }
} }
// Slide the desired location along the plane's normal // Slide the desired location along the plane's normal
// so that it lies on the plane's surface // so that it lies on the plane's surface
dest.X -= plane->fA() * t; dest -= plane->Normal() * t;
dest.Y -= plane->fB() * t;
move = dest - actor->Pos().XY(); move = dest - actor->Pos().XY();
return (actor->floorsector == actor->Sector) ? plane : NULL; return (actor->floorsector == actor->Sector) ? plane : NULL;
} }
@ -2996,8 +2998,7 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, DVector2 &move)
{ {
// Actor's current spot is on/in the plane, so walk down it // Actor's current spot is on/in the plane, so walk down it
// Same principle as walking up, except reversed // Same principle as walking up, except reversed
dest.X += plane->fA() * t; dest += plane->Normal() * t;
dest.Y += plane->fB() * t;
move = dest - actor->Pos().XY(); move = dest - actor->Pos().XY();
return (actor->floorsector == actor->Sector) ? plane : NULL; return (actor->floorsector == actor->Sector) ? plane : NULL;
} }

View file

@ -1545,7 +1545,7 @@ void FPathTraverse::init(double x1, double y1, double x2, double y2, int flags,
// we want to use one list of checked actors for the entire operation // we want to use one list of checked actors for the entire operation
FBlockThingsIterator btit; FBlockThingsIterator btit;
for (count = 0 ; count < 100 ; count++) for (count = 0 ; count < 1000 ; count++)
{ {
if (flags & PT_ADDLINES) if (flags & PT_ADDLINES)
{ {
@ -1557,26 +1557,30 @@ void FPathTraverse::init(double x1, double y1, double x2, double y2, int flags,
AddThingIntercepts(mapx, mapy, btit, compatible); AddThingIntercepts(mapx, mapy, btit, compatible);
} }
if (mapx == xt2 && mapy == yt2) // both coordinates reached the end, so end the traversing.
{ if ((mapxstep | mapystep) == 0)
break; break;
}
// [RH] Handle corner cases properly instead of pretending they don't exist. // [RH] Handle corner cases properly instead of pretending they don't exist.
switch (((xs_FloorToInt(yintercept) == mapy) << 1) | (xs_FloorToInt(xintercept) == mapx)) switch (((xs_FloorToInt(yintercept) == mapy) << 1) | (xs_FloorToInt(xintercept) == mapx))
{ {
case 0: // neither xintercept nor yintercept match! case 0: // neither xintercept nor yintercept match!
count = 100; // Stop traversing, because somebody screwed up. count = 1000; // Stop traversing, because somebody screwed up.
break; break;
case 1: // xintercept matches case 1: // xintercept matches
xintercept += xstep; xintercept += xstep;
mapy += mapystep; mapy += mapystep;
if (mapy == mapey)
mapystep = 0;
break; break;
case 2: // yintercept matches case 2: // yintercept matches
yintercept += ystep; yintercept += ystep;
mapx += mapxstep; mapx += mapxstep;
if (mapx == mapex)
mapxstep = 0;
break; break;
case 3: // xintercept and yintercept both match case 3: // xintercept and yintercept both match
@ -1584,6 +1588,7 @@ void FPathTraverse::init(double x1, double y1, double x2, double y2, int flags,
// being entered need to be checked (which will happen when this loop // being entered need to be checked (which will happen when this loop
// continues), but the other two blocks adjacent to the corner also need to // continues), but the other two blocks adjacent to the corner also need to
// be checked. // be checked.
// Since Doom.exe did not do this, this code won't either if run in compatibility mode.
if (!compatible) if (!compatible)
{ {
if (flags & PT_ADDLINES) if (flags & PT_ADDLINES)
@ -1601,10 +1606,14 @@ void FPathTraverse::init(double x1, double y1, double x2, double y2, int flags,
yintercept += ystep; yintercept += ystep;
mapx += mapxstep; mapx += mapxstep;
mapy += mapystep; mapy += mapystep;
if (mapx == mapex)
mapxstep = 0;
if (mapy == mapey)
mapystep = 0;
} }
else else
{ {
count = 100; // Doom originally did not handle this case so do the same in compatibility mode. count = 1000; // Doom originally did not handle this case so do the same in compatibility mode.
} }
break; break;
} }

View file

@ -38,12 +38,12 @@ struct intercept_t
inline int P_PointOnLineSidePrecise(double x, double y, const line_t *line) inline int P_PointOnLineSidePrecise(double x, double y, const line_t *line)
{ {
return (y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - x) * line->Delta().Y > EQUAL_EPSILON; return (y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - x) * line->Delta().Y > -EQUAL_EPSILON;
} }
inline int P_PointOnLineSidePrecise(const DVector2 &pt, const line_t *line) inline int P_PointOnLineSidePrecise(const DVector2 &pt, const line_t *line)
{ {
return (pt.Y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - pt.X) * line->Delta().Y > EQUAL_EPSILON; return (pt.Y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - pt.X) * line->Delta().Y > -EQUAL_EPSILON;
} }
inline int P_PointOnLineSide (double x, double y, const line_t *line) inline int P_PointOnLineSide (double x, double y, const line_t *line)
@ -73,12 +73,12 @@ inline int P_PointOnLineSide(const DVector2 & p, const line_t *line)
inline int P_PointOnDivlineSide(double x, double y, const divline_t *line) inline int P_PointOnDivlineSide(double x, double y, const divline_t *line)
{ {
return (y - line->y) * line->dx + (line->x - x) * line->dy > EQUAL_EPSILON; return (y - line->y) * line->dx + (line->x - x) * line->dy > -EQUAL_EPSILON;
} }
inline int P_PointOnDivlineSide(const DVector2 &pos, const divline_t *line) inline int P_PointOnDivlineSide(const DVector2 &pos, const divline_t *line)
{ {
return (pos.Y - line->y) * line->dx + (line->x - pos.X) * line->dy > EQUAL_EPSILON; return (pos.Y - line->y) * line->dx + (line->x - pos.X) * line->dy > -EQUAL_EPSILON;
} }
//========================================================================== //==========================================================================

View file

@ -275,29 +275,17 @@ void AActor::Serialize(FArchive &arc)
arc << dmg; arc << dmg;
Damage = UncalcDamageValue(dmg, GetDefault()->Damage); Damage = UncalcDamageValue(dmg, GetDefault()->Damage);
} }
if (SaveVersion >= 4530) P_SerializeTerrain(arc, floorterrain);
{ arc << projectileKickback
P_SerializeTerrain(arc, floorterrain); << flags
}
if (SaveVersion >= 3227)
{
arc << projectileKickback;
}
arc << flags
<< flags2 << flags2
<< flags3 << flags3
<< flags4 << flags4
<< flags5 << flags5
<< flags6; << flags6
if (SaveVersion >= 4504) << flags7
{ << weaponspecial
arc << flags7; << special1
}
if (SaveVersion >= 4512)
{
arc << weaponspecial;
}
arc << special1
<< special2 << special2
<< specialf1 << specialf1
<< specialf2 << specialf2
@ -313,12 +301,9 @@ void AActor::Serialize(FArchive &arc)
<< threshold << threshold
<< player << player
<< SpawnPoint << SpawnPoint
<< SpawnAngle; << SpawnAngle
if (SaveVersion >= 4506) << StartHealth
{ << skillrespawncount
arc << StartHealth;
}
arc << skillrespawncount
<< tracer << tracer
<< Floorclip << Floorclip
<< tid << tid
@ -332,21 +317,13 @@ void AActor::Serialize(FArchive &arc)
arc << args[0]; arc << args[0];
} }
arc << args[1] << args[2] << args[3] << args[4]; arc << args[1] << args[2] << args[3] << args[4];
if (SaveVersion >= 3427) arc << accuracy << stamina;
{
arc << accuracy << stamina;
}
arc << goal arc << goal
<< waterlevel << waterlevel
<< MinMissileChance << MinMissileChance
<< SpawnFlags << SpawnFlags
<< Inventory << Inventory
<< InventoryID; << InventoryID;
if (SaveVersion < 4513)
{
SDWORD id;
arc << id;
}
arc << FloatBobPhase arc << FloatBobPhase
<< Translation << Translation
<< SeeSound << SeeSound
@ -376,16 +353,9 @@ void AActor::Serialize(FArchive &arc)
<< meleethreshold << meleethreshold
<< meleerange << meleerange
<< DamageType; << DamageType;
if (SaveVersion >= 4501) arc << DamageTypeReceived;
{ arc << PainType
arc << DamageTypeReceived;
}
if (SaveVersion >= 3237)
{
arc
<< PainType
<< DeathType; << DeathType;
}
arc << Gravity arc << Gravity
<< FastChaseStrafeCount << FastChaseStrafeCount
<< master << master
@ -396,48 +366,23 @@ void AActor::Serialize(FArchive &arc)
<< pushfactor << pushfactor
<< Species << Species
<< Score; << Score;
if (SaveVersion >= 3113) arc << DesignatedTeam;
{
arc << DesignatedTeam;
}
arc << lastpush << lastbump arc << lastpush << lastbump
<< PainThreshold << PainThreshold
<< DamageFactor; << DamageFactor;
if (SaveVersion >= 4516) arc << DamageMultiply;
{
arc << DamageMultiply;
}
else
{
DamageMultiply = 1.;
}
arc << WeaveIndexXY << WeaveIndexZ arc << WeaveIndexXY << WeaveIndexZ
<< PoisonDamageReceived << PoisonDurationReceived << PoisonPeriodReceived << Poisoner << PoisonDamageReceived << PoisonDurationReceived << PoisonPeriodReceived << Poisoner
<< PoisonDamage << PoisonDuration << PoisonPeriod; << PoisonDamage << PoisonDuration << PoisonPeriod;
if (SaveVersion >= 3235) arc << PoisonDamageType << PoisonDamageTypeReceived;
{
arc << PoisonDamageType << PoisonDamageTypeReceived;
}
arc << ConversationRoot << Conversation; arc << ConversationRoot << Conversation;
if (SaveVersion >= 4509) arc << FriendPlayer;
{ arc << TeleFogSourceType
arc << FriendPlayer; << TeleFogDestType;
} arc << RipperLevel
if (SaveVersion >= 4517) << RipLevelMin
{ << RipLevelMax;
arc << TeleFogSourceType arc << DefThreshold;
<< TeleFogDestType;
}
if (SaveVersion >= 4518)
{
arc << RipperLevel
<< RipLevelMin
<< RipLevelMax;
}
if (SaveVersion >= 4533)
{
arc << DefThreshold;
}
{ {
FString tagstr; FString tagstr;

View file

@ -341,22 +341,8 @@ void P_SerializeWorld (FArchive &arc)
{ {
arc << sec->floorplane arc << sec->floorplane
<< sec->ceilingplane; << sec->ceilingplane;
if (SaveVersion < 3223)
{
BYTE bytelight;
arc << bytelight;
sec->lightlevel = bytelight;
}
else
{
arc << sec->lightlevel; arc << sec->lightlevel;
}
arc << sec->special; arc << sec->special;
if (SaveVersion < 4523)
{
short tag;
arc << tag;
}
arc << sec->soundtraversed arc << sec->soundtraversed
<< sec->seqType << sec->seqType
<< sec->friction << sec->friction
@ -372,49 +358,12 @@ void P_SerializeWorld (FArchive &arc)
<< sec->heightsec << sec->heightsec
<< sec->bottommap << sec->midmap << sec->topmap << sec->bottommap << sec->midmap << sec->topmap
<< sec->gravity; << sec->gravity;
if (SaveVersion >= 4530)
{
P_SerializeTerrain(arc, sec->terrainnum[0]); P_SerializeTerrain(arc, sec->terrainnum[0]);
P_SerializeTerrain(arc, sec->terrainnum[1]); P_SerializeTerrain(arc, sec->terrainnum[1]);
}
if (SaveVersion >= 4529)
{
arc << sec->damageamount; arc << sec->damageamount;
}
else
{
short dmg;
arc << dmg;
sec->damageamount = dmg;
}
if (SaveVersion >= 4528)
{
arc << sec->damageinterval arc << sec->damageinterval
<< sec->leakydamage << sec->leakydamage
<< sec->damagetype; << sec->damagetype;
}
else
{
short damagemod;
arc << damagemod;
sec->damagetype = MODtoDamageType(damagemod);
if (sec->damageamount < 20)
{
sec->leakydamage = 0;
sec->damageinterval = 32;
}
else if (sec->damageamount < 50)
{
sec->leakydamage = 5;
sec->damageinterval = 32;
}
else
{
sec->leakydamage = 256;
sec->damageinterval = 1;
}
}
arc << sec->SoundTarget arc << sec->SoundTarget
<< sec->SecActTarget << sec->SecActTarget
<< sec->sky << sec->sky
@ -422,13 +371,6 @@ void P_SerializeWorld (FArchive &arc)
<< sec->Flags << sec->Flags
<< sec->SkyBoxes[sector_t::floor] << sec->SkyBoxes[sector_t::ceiling] << sec->SkyBoxes[sector_t::floor] << sec->SkyBoxes[sector_t::ceiling]
<< sec->ZoneNumber; << sec->ZoneNumber;
if (SaveVersion < 4529)
{
short secretsector;
arc << secretsector;
if (secretsector) sec->Flags |= SECF_WASSECRET;
P_InitSectorSpecial(sec, sec->special, true);
}
arc << sec->interpolations[0] arc << sec->interpolations[0]
<< sec->interpolations[1] << sec->interpolations[1]
<< sec->interpolations[2] << sec->interpolations[2]
@ -464,11 +406,6 @@ void P_SerializeWorld (FArchive &arc)
<< li->special << li->special
<< li->Alpha; << li->Alpha;
if (SaveVersion < 4523)
{
int id;
arc << id;
}
if (P_IsACSSpecial(li->special)) if (P_IsACSSpecial(li->special))
{ {
P_SerializeACSScriptNumber(arc, li->args[0], false); P_SerializeACSScriptNumber(arc, li->args[0], false);
@ -479,12 +416,7 @@ void P_SerializeWorld (FArchive &arc)
} }
arc << li->args[1] << li->args[2] << li->args[3] << li->args[4]; arc << li->args[1] << li->args[2] << li->args[3] << li->args[4];
if (SaveVersion >= 4532)
{
arc << li->portalindex; arc << li->portalindex;
}
else li->portalindex = UINT_MAX;
if (SaveVersion >= 4531) if (SaveVersion >= 4531)
{ {
arc << li->skybox; arc << li->skybox;
@ -525,14 +457,7 @@ void P_SerializeWorld (FArchive &arc)
arc << zn->Environment; arc << zn->Environment;
} }
if (SaveVersion >= 4532)
{
arc << linePortals; arc << linePortals;
}
else
{
linePortals.Clear();
}
P_CollectLinkedPortals(); P_CollectLinkedPortals();
} }

View file

@ -1052,24 +1052,12 @@ double sector_t::NextLowestFloorAt(double x, double y, double z, int flags, doub
FArchive &operator<< (FArchive &arc, secspecial_t &p) FArchive &operator<< (FArchive &arc, secspecial_t &p)
{ {
if (SaveVersion < 4529) arc << p.special
{ << p.damageamount
int special; << p.damagetype
arc << special; << p.damageinterval
sector_t sec; << p.leakydamage
memset(&sec, 0, sizeof(sec)); << p.Flags;
P_InitSectorSpecial(&sec, special, true);
sec.GetSpecial(&p);
}
else
{
arc << p.special
<< p.damageamount
<< p.damagetype
<< p.damageinterval
<< p.leakydamage
<< p.Flags;
}
return arc; return arc;
} }
@ -1086,11 +1074,11 @@ bool secplane_t::CopyPlaneIfValid (secplane_t *dest, const secplane_t *opp) cons
// If the planes do not have matching slopes, then always copy them // If the planes do not have matching slopes, then always copy them
// because clipping would require creating new sectors. // because clipping would require creating new sectors.
if (fA() != dest->fA() || fB() != dest->fB() || fC() != dest->fC()) if (Normal() != dest->Normal())
{ {
copy = true; copy = true;
} }
else if (opp->fA() != -dest->fA() || opp->fB() != -dest->fB() || opp->fC() != -dest->fC()) else if (opp->Normal() != -dest->Normal())
{ {
if (fD() < dest->fD()) if (fD() < dest->fD())
{ {
@ -1112,11 +1100,11 @@ bool secplane_t::CopyPlaneIfValid (secplane_t *dest, const secplane_t *opp) cons
FArchive &operator<< (FArchive &arc, secplane_t &plane) FArchive &operator<< (FArchive &arc, secplane_t &plane)
{ {
arc << plane.a << plane.b << plane.c << plane.d; arc << plane.normal << plane.D;
//if (plane.c != 0) if (plane.normal.Z != 0)
{ // plane.c should always be non-0. Otherwise, the plane { // plane.c should always be non-0. Otherwise, the plane
// would be perfectly vertical. // would be perfectly vertical. (But then, don't let this crash on a broken savegame...)
plane.ic = DivScale32 (1, plane.c); plane.negiC = -1 / plane.normal.Z;
} }
return arc; return arc;
} }

View file

@ -713,7 +713,7 @@ bool SightCheck::P_SightPathTraverse ()
// step through map blocks // step through map blocks
// Count is present to prevent a round off error from skipping the break // Count is present to prevent a round off error from skipping the break
for (count = 0 ; count < 100 ; count++) for (count = 0 ; count < 1000 ; count++)
{ {
// end traversing when reaching the end of the blockmap // end traversing when reaching the end of the blockmap
// an early out is not possible because with portals a trace can easily land outside the map's bounds. // an early out is not possible because with portals a trace can easily land outside the map's bounds.
@ -737,7 +737,7 @@ bool SightCheck::P_SightPathTraverse ()
case 0: // neither xintercept nor yintercept match! case 0: // neither xintercept nor yintercept match!
sightcounts[5]++; sightcounts[5]++;
// Continuing won't make things any better, so we might as well stop right here // Continuing won't make things any better, so we might as well stop right here
count = 100; count = 1000;
break; break;
case 1: // xintercept matches case 1: // xintercept matches

View file

@ -665,16 +665,7 @@ IMPLEMENT_CLASS (DLightTransfer)
void DLightTransfer::Serialize (FArchive &arc) void DLightTransfer::Serialize (FArchive &arc)
{ {
Super::Serialize (arc); Super::Serialize (arc);
if (SaveVersion < 3223) arc << LastLight;
{
BYTE bytelight;
arc << bytelight;
LastLight = bytelight;
}
else
{
arc << LastLight;
}
arc << Source << TargetTag << CopyFloor; arc << Source << TargetTag << CopyFloor;
} }
@ -762,16 +753,7 @@ IMPLEMENT_CLASS (DWallLightTransfer)
void DWallLightTransfer::Serialize (FArchive &arc) void DWallLightTransfer::Serialize (FArchive &arc)
{ {
Super::Serialize (arc); Super::Serialize (arc);
if (SaveVersion < 3223) arc << LastLight;
{
BYTE bytelight;
arc << bytelight;
LastLight = bytelight;
}
else
{
arc << LastLight;
}
arc << Source << TargetID << Flags; arc << Source << TargetID << Flags;
} }
@ -1075,7 +1057,7 @@ static void P_SetupSectorDamage(sector_t *sector, int damage, int interval, int
// ('fromload' is necessary to allow conversion upon savegame load.) // ('fromload' is necessary to allow conversion upon savegame load.)
// //
void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers) void P_InitSectorSpecial(sector_t *sector, int special)
{ {
// [RH] All secret sectors are marked with a BOOM-ish bitfield // [RH] All secret sectors are marked with a BOOM-ish bitfield
if (sector->special & SECRET_MASK) if (sector->special & SECRET_MASK)
@ -1110,28 +1092,28 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers)
switch (sector->special) switch (sector->special)
{ {
case Light_Phased: case Light_Phased:
if (!nothinkers) new DPhased (sector, 48, 63 - (sector->lightlevel & 63)); new DPhased (sector, 48, 63 - (sector->lightlevel & 63));
break; break;
// [RH] Hexen-like phased lighting // [RH] Hexen-like phased lighting
case LightSequenceStart: case LightSequenceStart:
if (!nothinkers) new DPhased (sector); new DPhased (sector);
break; break;
case dLight_Flicker: case dLight_Flicker:
if (!nothinkers) new DLightFlash (sector); new DLightFlash (sector);
break; break;
case dLight_StrobeFast: case dLight_StrobeFast:
if (!nothinkers) new DStrobe (sector, STROBEBRIGHT, FASTDARK, false); new DStrobe (sector, STROBEBRIGHT, FASTDARK, false);
break; break;
case dLight_StrobeSlow: case dLight_StrobeSlow:
if (!nothinkers) new DStrobe (sector, STROBEBRIGHT, SLOWDARK, false); new DStrobe (sector, STROBEBRIGHT, SLOWDARK, false);
break; break;
case dLight_Strobe_Hurt: case dLight_Strobe_Hurt:
if (!nothinkers) new DStrobe (sector, STROBEBRIGHT, FASTDARK, false); new DStrobe (sector, STROBEBRIGHT, FASTDARK, false);
P_SetupSectorDamage(sector, 20, 32, 5, NAME_Slime, 0); P_SetupSectorDamage(sector, 20, 32, 5, NAME_Slime, 0);
break; break;
@ -1144,7 +1126,7 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers)
break; break;
case dLight_Glow: case dLight_Glow:
if (!nothinkers) new DGlow (sector); new DGlow (sector);
break; break;
case dSector_DoorCloseIn30: case dSector_DoorCloseIn30:
@ -1156,11 +1138,11 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers)
break; break;
case dLight_StrobeSlowSync: case dLight_StrobeSlowSync:
if (!nothinkers) new DStrobe (sector, STROBEBRIGHT, SLOWDARK, true); new DStrobe (sector, STROBEBRIGHT, SLOWDARK, true);
break; break;
case dLight_StrobeFastSync: case dLight_StrobeFastSync:
if (!nothinkers) new DStrobe (sector, STROBEBRIGHT, FASTDARK, true); new DStrobe (sector, STROBEBRIGHT, FASTDARK, true);
break; break;
case dSector_DoorRaiseIn5Mins: case dSector_DoorRaiseIn5Mins:
@ -1178,7 +1160,7 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers)
break; break;
case dLight_FireFlicker: case dLight_FireFlicker:
if (!nothinkers) new DFireFlicker (sector); new DFireFlicker (sector);
break; break;
case dDamage_LavaWimpy: case dDamage_LavaWimpy:
@ -1191,11 +1173,8 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers)
case dScroll_EastLavaDamage: case dScroll_EastLavaDamage:
P_SetupSectorDamage(sector, 5, 32, 256, NAME_Fire, SECF_DMGTERRAINFX); P_SetupSectorDamage(sector, 5, 32, 256, NAME_Fire, SECF_DMGTERRAINFX);
if (!nothinkers) new DStrobe(sector, STROBEBRIGHT, FASTDARK, false);
{ P_CreateScroller(EScroll::sc_floor, -4., 0, -1, int(sector - sectors), 0);
new DStrobe(sector, STROBEBRIGHT, FASTDARK, false);
P_CreateScroller(EScroll::sc_floor, -4., 0, -1, int(sector - sectors), 0);
}
keepspecial = true; keepspecial = true;
break; break;
@ -1205,7 +1184,7 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers)
case sLight_Strobe_Hurt: case sLight_Strobe_Hurt:
P_SetupSectorDamage(sector, 5, 32, 0, NAME_Slime, 0); P_SetupSectorDamage(sector, 5, 32, 0, NAME_Slime, 0);
if (!nothinkers) new DStrobe (sector, STROBEBRIGHT, FASTDARK, false); new DStrobe (sector, STROBEBRIGHT, FASTDARK, false);
break; break;
case sDamage_Hellslime: case sDamage_Hellslime:
@ -1254,13 +1233,13 @@ void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers)
int i = sector->special - Scroll_North_Slow; int i = sector->special - Scroll_North_Slow;
double dx = hexenScrollies[i][0] / 2.; double dx = hexenScrollies[i][0] / 2.;
double dy = hexenScrollies[i][1] / 2.; double dy = hexenScrollies[i][1] / 2.;
if (!nothinkers) P_CreateScroller(EScroll::sc_floor, dx, dy, -1, int(sector-sectors), 0); P_CreateScroller(EScroll::sc_floor, dx, dy, -1, int(sector-sectors), 0);
} }
else if (sector->special >= Carry_East5 && else if (sector->special >= Carry_East5 &&
sector->special <= Carry_East35) sector->special <= Carry_East35)
{ // Heretic scroll special { // Heretic scroll special
// Only east scrollers also scroll the texture // Only east scrollers also scroll the texture
if (!nothinkers) P_CreateScroller(EScroll::sc_floor, P_CreateScroller(EScroll::sc_floor,
-0.5 * (1 << ((sector->special & 0xff) - Carry_East5)), 0, -1, int(sector-sectors), 0); -0.5 * (1 << ((sector->special & 0xff) - Carry_East5)), 0, -1, int(sector-sectors), 0);
} }
keepspecial = true; keepspecial = true;
@ -1290,7 +1269,7 @@ void P_SpawnSpecials (void)
if (sector->special == 0) if (sector->special == 0)
continue; continue;
P_InitSectorSpecial(sector, sector->special, false); P_InitSectorSpecial(sector, sector->special);
} }
#ifndef NO_EDATA #ifndef NO_EDATA

View file

@ -87,7 +87,7 @@ const double CARRYFACTOR = 3 / 32.;
bool CheckIfExitIsGood (AActor *self, level_info_t *info); bool CheckIfExitIsGood (AActor *self, level_info_t *info);
// at map load // at map load
void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers); void P_InitSectorSpecial(sector_t *sector, int special);
void P_SpawnSpecials (void); void P_SpawnSpecials (void);
// every tic // every tic

View file

@ -877,11 +877,11 @@ bool FTraceInfo::TraceTraverse (int ptflags)
bool FTraceInfo::CheckPlane (const secplane_t &plane) bool FTraceInfo::CheckPlane (const secplane_t &plane)
{ {
double den = plane.fA() * Vec.X + plane.fB() * Vec.Y + plane.fC() * Vec.Z; double den = plane.Normal() | Vec;
if (den != 0) if (den != 0)
{ {
double num = plane.fA() * Start.X + plane.fB() * Start.Y + plane.fC() * Start.Z + plane.fD(); double num = (plane.Normal() | Start) + plane.fD();
double hitdist = -num / den; double hitdist = -num / den;

View file

@ -643,28 +643,10 @@ void APlayerPawn::Serialize (FArchive &arc)
<< DamageFade << DamageFade
<< PlayerFlags << PlayerFlags
<< FlechetteType; << FlechetteType;
if (SaveVersion < 3829) arc << GruntSpeed << FallingScreamMinSpeed << FallingScreamMaxSpeed;
{ arc << UseRange;
GruntSpeed = 12; arc << AirCapacity;
FallingScreamMinSpeed = 35; arc << ViewHeight;
FallingScreamMaxSpeed = 40;
}
else
{
arc << GruntSpeed << FallingScreamMinSpeed << FallingScreamMaxSpeed;
}
if (SaveVersion >= 4502)
{
arc << UseRange;
}
if (SaveVersion >= 4503)
{
arc << AirCapacity;
}
if (SaveVersion >= 4526)
{
arc << ViewHeight;
}
} }
//=========================================================================== //===========================================================================
@ -3039,11 +3021,6 @@ void player_t::Serialize (FArchive &arc)
<< centering << centering
<< health << health
<< inventorytics; << inventorytics;
if (SaveVersion < 4513)
{
bool backpack;
arc << backpack;
}
arc << fragcount arc << fragcount
<< spreecount << spreecount
<< multicount << multicount
@ -3074,50 +3051,14 @@ void player_t::Serialize (FArchive &arc)
<< air_finished << air_finished
<< turnticks << turnticks
<< oldbuttons; << oldbuttons;
if (SaveVersion >= 4929) arc << hazardtype
{ << hazardinterval;
arc << hazardtype arc << Bot;
<< hazardinterval;
}
bool IsBot = false;
if (SaveVersion >= 4514)
{
arc << Bot;
}
else
{
arc << IsBot;
}
arc << BlendR arc << BlendR
<< BlendG << BlendG
<< BlendB << BlendB
<< BlendA; << BlendA;
if (SaveVersion < 3427) arc << WeaponState;
{
WORD oldaccuracy, oldstamina;
arc << oldaccuracy << oldstamina;
if (mo != NULL)
{
mo->accuracy = oldaccuracy;
mo->stamina = oldstamina;
}
}
if (SaveVersion < 4041)
{
// Move weapon state flags from cheats and into WeaponState.
WeaponState = ((cheats >> 14) & 1) | ((cheats & (0x37 << 24)) >> (24 - 1));
cheats &= ~((1 << 14) | (0x37 << 24));
}
if (SaveVersion < 4527)
{
BYTE oldWeaponState;
arc << oldWeaponState;
WeaponState = oldWeaponState;
}
else
{
arc << WeaponState;
}
arc << LogText arc << LogText
<< ConversationNPC << ConversationNPC
<< ConversationPC << ConversationPC
@ -3137,45 +3078,10 @@ void player_t::Serialize (FArchive &arc)
<< crouchviewdelta << crouchviewdelta
<< original_cmd << original_cmd
<< original_oldbuttons; << original_oldbuttons;
arc << poisontype << poisonpaintype;
if (SaveVersion >= 3475) arc << timefreezer;
{ arc << settings_controller;
arc << poisontype << poisonpaintype; arc << onground;
}
else if (poisoner != NULL)
{
poisontype = poisoner->DamageType;
poisonpaintype = poisoner->PainType != NAME_None ? poisoner->PainType : poisoner->DamageType;
}
if (SaveVersion >= 3599)
{
arc << timefreezer;
}
else
{
cheats &= ~(1 << 15); // make sure old CF_TIMEFREEZE bit is cleared
}
if (SaveVersion < 3640)
{
cheats &= ~(1 << 17); // make sure old CF_REGENERATION bit is cleared
}
if (SaveVersion >= 3780)
{
arc << settings_controller;
}
else
{
settings_controller = (this - players == Net_Arbitrator);
}
if (SaveVersion >= 4505)
{
arc << onground;
}
else
{
onground = (mo->Z() <= mo->floorz) || (mo->flags2 & MF2_ONMOBJ) || (mo->BounceFlags & BOUNCE_MBF) || (cheats & CF_NOCLIP2);
}
if (arc.IsLoading ()) if (arc.IsLoading ())
{ {
@ -3188,10 +3094,7 @@ void player_t::Serialize (FArchive &arc)
{ {
userinfo.SkinChanged(skinname, CurrentPlayerClass); userinfo.SkinChanged(skinname, CurrentPlayerClass);
} }
if (SaveVersion >= 4522) arc << MUSINFOactor << MUSINFOtics;
{
arc << MUSINFOactor << MUSINFOtics;
}
} }
bool P_IsPlayerTotallyFrozen(const player_t *player) bool P_IsPlayerTotallyFrozen(const player_t *player)

View file

@ -1054,7 +1054,7 @@ void P_CreateLinkedPortals()
if (cz < fz) if (cz < fz)
{ {
// This is a fatal condition. We have to remove one of the two portals. Choose the one that doesn't match the current plane // This is a fatal condition. We have to remove one of the two portals. Choose the one that doesn't match the current plane
Printf("Error in sector %d: Ceiling portal at z=%d is below floor portal at z=%d\n", i, cz, fz); Printf("Error in sector %d: Ceiling portal at z=%f is below floor portal at z=%f\n", i, cz, fz);
double cp = -sectors[i].ceilingplane.fD(); double cp = -sectors[i].ceilingplane.fD();
double fp = -sectors[i].ceilingplane.fD(); double fp = -sectors[i].ceilingplane.fD();
if (cp < fp || fz == fp) if (cp < fp || fz == fp)

View file

@ -308,80 +308,59 @@ struct secplane_t
// ic is 1/c, for faster Z calculations // ic is 1/c, for faster Z calculations
private: private:
fixed_t a, b, c, d, ic; DVector3 normal;
double D, negiC; // negative iC because that also saves a negation in all methods using this.
public: public:
void set(double aa, double bb, double cc, double dd) void set(double aa, double bb, double cc, double dd)
{ {
a = FLOAT2FIXED(aa); normal.X = aa;
b = FLOAT2FIXED(bb); normal.Y = bb;
c = FLOAT2FIXED(cc); normal.Z = cc;
d = FLOAT2FIXED(dd); D = dd;
ic = FixedDiv(FRACUNIT, c); negiC = -1 / cc;
}
void setD(fixed_t dd)
{
d = dd;
}
void changeD(fixed_t dd)
{
d += dd;
} }
void setD(double dd) void setD(double dd)
{ {
d = FLOAT2FIXED(dd); D = dd;
} }
double fA() const
{
return FIXED2DBL(a);
}
double fB() const
{
return FIXED2DBL(b);
}
double fC() const double fC() const
{ {
return FIXED2DBL(c); return normal.Z;
} }
double fD() const double fD() const
{ {
return FIXED2DBL(d); return D;
} }
double fiC() const
{
return FIXED2DBL(ic);
}
bool isSlope() const bool isSlope() const
{ {
return a != 0 || b != 0; return !normal.XY().isZero();
} }
DVector3 Normal() const DVector3 Normal() const
{ {
return{ fA(), fB(), fC() }; return normal;
} }
// Returns < 0 : behind; == 0 : on; > 0 : in front // Returns < 0 : behind; == 0 : on; > 0 : in front
int PointOnSide (fixed_t x, fixed_t y, fixed_t z) const int PointOnSide (fixed_t x, fixed_t y, fixed_t z) const
{ {
return TMulScale16(a,x, b,y, c,z) + d; return PointOnSide(DVector3(FIXED2DBL(x), FIXED2DBL(y), FIXED2DBL(z)));
} }
int PointOnSide(const DVector3 &pos) const int PointOnSide(const DVector3 &pos) const
{ {
double v = a * pos.X + b * pos.Y + c * pos.Z + d; double v = (normal | pos) + D;
return v < -EQUAL_EPSILON ? -1 : v > EQUAL_EPSILON ? 1 : 0; return v < -EQUAL_EPSILON ? -1 : v > EQUAL_EPSILON ? 1 : 0;
} }
// Returns the value of z at (0,0) This is used by the 3D floor code which does not handle slopes // Returns the value of z at (0,0) This is used by the 3D floor code which does not handle slopes
fixed_t Zat0 () const fixed_t Zat0 () const
{ {
return ic < 0 ? d : -d; return FLOAT2FIXED(negiC*D);
} }
// Returns the value of z at (x,y) // Returns the value of z at (x,y)
@ -389,7 +368,7 @@ public:
fixed_t ZatPointFixed(fixed_t x, fixed_t y) const fixed_t ZatPointFixed(fixed_t x, fixed_t y) const
{ {
return FixedMul (ic, -d - DMulScale16 (a, x, b, y)); return FLOAT2FIXED(ZatPoint(FIXED2DBL(x), FIXED2DBL(y)));
} }
// This is for the software renderer // This is for the software renderer
@ -407,106 +386,101 @@ public:
// Returns the value of z at (x,y) as a double // Returns the value of z at (x,y) as a double
double ZatPoint (double x, double y) const double ZatPoint (double x, double y) const
{ {
return (d + a*x + b*y) * ic / (-65536.0 * 65536.0); return (D + normal.X*x + normal.Y*y) * negiC;
} }
double ZatPoint(const DVector2 &pos) const double ZatPoint(const DVector2 &pos) const
{ {
return (d + a*pos.X + b*pos.Y) * ic / (-65536.0 * 65536.0); return (D + normal.X*pos.X + normal.Y*pos.Y) * negiC;
} }
double ZatPoint(const vertex_t *v) const double ZatPoint(const vertex_t *v) const
{ {
return (d + a*v->fX() + b*v->fY()) * ic / (-65536.0 * 65536.0); return (D + normal.X*v->fX() + normal.Y*v->fY()) * negiC;
} }
double ZatPoint(const AActor *ac) const double ZatPoint(const AActor *ac) const
{ {
return (d + a*ac->X() + b*ac->Y()) * ic / (-65536.0 * 65536.0); return (D + normal.X*ac->X() + normal.Y*ac->Y()) * negiC;
} }
// Returns the value of z at vertex v if d is equal to dist // Returns the value of z at vertex v if d is equal to dist
double ZatPointDist(const vertex_t *v, double dist) double ZatPointDist(const vertex_t *v, double dist)
{ {
return (dist + a*v->fX() + b*v->fY()) * ic / (-65536.0 * 65536.0); return (dist + normal.X*v->fX() + normal.Y*v->fY()) * negiC;
} }
// Flips the plane's vertical orientiation, so that if it pointed up, // Flips the plane's vertical orientiation, so that if it pointed up,
// it will point down, and vice versa. // it will point down, and vice versa.
void FlipVert () void FlipVert ()
{ {
a = -a; normal = -normal;
b = -b; D = -D;
c = -c; negiC = -negiC;
d = -d;
ic = -ic;
} }
// Returns true if 2 planes are the same // Returns true if 2 planes are the same
bool operator== (const secplane_t &other) const bool operator== (const secplane_t &other) const
{ {
return a == other.a && b == other.b && c == other.c && d == other.d; return normal == other.normal && D == other.D;
} }
// Returns true if 2 planes are different // Returns true if 2 planes are different
bool operator!= (const secplane_t &other) const bool operator!= (const secplane_t &other) const
{ {
return a != other.a || b != other.b || c != other.c || d != other.d; return normal != other.normal || D != other.D;
} }
// Moves a plane up/down by hdiff units // Moves a plane up/down by hdiff units
void ChangeHeight(double hdiff) void ChangeHeight(double hdiff)
{ {
d = d - fixed_t(hdiff * c); D = D - hdiff * normal.Z;
} }
// Moves a plane up/down by hdiff units // Moves a plane up/down by hdiff units
double GetChangedHeight(double hdiff) double GetChangedHeight(double hdiff)
{ {
return fD() - hdiff * fC(); return D - hdiff * normal.Z;
} }
// Returns how much this plane's height would change if d were set to oldd // Returns how much this plane's height would change if d were set to oldd
double HeightDiff(double oldd) const double HeightDiff(double oldd) const
{ {
return (oldd - fD()) * fiC(); return (D - oldd) * negiC;
} }
// Returns how much this plane's height would change if d were set to oldd // Returns how much this plane's height would change if d were set to oldd
double HeightDiff(double oldd, double newd) const double HeightDiff(double oldd, double newd) const
{ {
return (oldd - newd) * fiC(); return (newd - oldd) * negiC;
} }
double PointToDist(const DVector2 &xy, double z) const double PointToDist(const DVector2 &xy, double z) const
{ {
return -(a * xy.X + b * xy.Y + c * z) / 65536.; return -(normal.X * xy.X + normal.Y * xy.Y + normal.Z * z);
} }
double PointToDist(const vertex_t *v, double z) const double PointToDist(const vertex_t *v, double z) const
{ {
return -(a * v->fX() + b * v->fY() + c * z) / 65536.; return -(normal.X * v->fX() + normal.Y * v->fY() + normal.Z * z);
} }
void SetAtHeight(fixed_t height, int ceiling) void SetAtHeight(double height, int ceiling)
{ {
a = b = 0; normal.X = normal.Y = 0;
if (ceiling) if (ceiling)
{ {
c = ic = -FRACUNIT; normal.Z = negiC = 1;
d = height; D = height;
} }
else else
{ {
c = ic = FRACUNIT; normal.Z = negiC = -1;
d = -height; D = -height;
} }
} }
inline void SetAtHeight(double height, int ceiling) inline void SetAtHeight(fixed_t height, int ceiling) = delete;
{
SetAtHeight(FLOAT2FIXED(clamp(height, -32767., 32767.)), ceiling);
}
bool CopyPlaneIfValid (secplane_t *dest, const secplane_t *opp) const; bool CopyPlaneIfValid (secplane_t *dest, const secplane_t *opp) const;

View file

@ -1568,7 +1568,7 @@ void R_DrawNormalPlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske
basexfrac = FixedMul (xscale, finecosine[planeang]) + x*xstepscale; basexfrac = FixedMul (xscale, finecosine[planeang]) + x*xstepscale;
baseyfrac = FixedMul (yscale, -finesine[planeang]) + x*ystepscale; baseyfrac = FixedMul (yscale, -finesine[planeang]) + x*ystepscale;
planeheight = abs (int(pl->height.fD() * -pl->height.fiC() * 65536) - viewz); planeheight = abs (pl->height.Zat0() - viewz);
GlobVis = FixedDiv (r_FloorVisibility, planeheight); GlobVis = FixedDiv (r_FloorVisibility, planeheight);
if (fixedlightlev >= 0) if (fixedlightlev >= 0)

View file

@ -3169,7 +3169,8 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
break; break;
} }
fixed_t fzpos = FLOAT2FIXED(zpos); fixed_t fzpos;
fzpos = FLOAT2FIXED(zpos); // pacify GCC
topoff = WallSpriteTile->TopOffset << FRACBITS; topoff = WallSpriteTile->TopOffset << FRACBITS;
dc_texturemid = topoff + FixedDiv (fzpos - viewz, yscale); dc_texturemid = topoff + FixedDiv (fzpos - viewz, yscale);

View file

@ -728,7 +728,6 @@ void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop
// //
void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling) void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling)
{ {
fixed_t fx, fy, fz;
fixed_t tr_x; fixed_t tr_x;
fixed_t tr_y; fixed_t tr_y;
@ -768,9 +767,9 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
// [RH] Interpolate the sprite's position to make it look smooth // [RH] Interpolate the sprite's position to make it look smooth
DVector3 pos = thing->InterpolatedPosition(r_TicFracF); DVector3 pos = thing->InterpolatedPosition(r_TicFracF);
fx = FLOAT2FIXED(pos.X); const fixed_t fx = FLOAT2FIXED(pos.X);
fy = FLOAT2FIXED(pos.Y); const fixed_t fy = FLOAT2FIXED(pos.Y);
fz = FLOAT2FIXED(pos.Z + thing->GetBobOffset(r_TicFracF)); fixed_t fz = FLOAT2FIXED(pos.Z + thing->GetBobOffset(r_TicFracF));
tex = NULL; tex = NULL;
voxel = NULL; voxel = NULL;
@ -937,19 +936,19 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
{ {
if (fakeside == FAKED_AboveCeiling) if (fakeside == FAKED_AboveCeiling)
{ {
if (gzt < heightsec->ceilingplane.ZatPointFixed(fx, fy)) if (gzt < heightsec->ceilingplane.ZatPointFixed(pos))
return; return;
} }
else if (fakeside == FAKED_BelowFloor) else if (fakeside == FAKED_BelowFloor)
{ {
if (gzb >= heightsec->floorplane.ZatPointFixed(fx, fy)) if (gzb >= heightsec->floorplane.ZatPointFixed(pos))
return; return;
} }
else else
{ {
if (gzt < heightsec->floorplane.ZatPointFixed(fx, fy)) if (gzt < heightsec->floorplane.ZatPointFixed(pos))
return; return;
if (!(heightsec->MoreFlags & SECF_FAKEFLOORONLY) && gzb >= heightsec->ceilingplane.ZatPointFixed(fx, fy)) if (!(heightsec->MoreFlags & SECF_FAKEFLOORONLY) && gzb >= heightsec->ceilingplane.ZatPointFixed(pos))
return; return;
} }
} }

View file

@ -39,6 +39,7 @@
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include <new> #include <new>
#include <utility>
#if !defined(_WIN32) #if !defined(_WIN32)
#include <inttypes.h> // for intptr_t #include <inttypes.h> // for intptr_t
@ -137,11 +138,17 @@ public:
Count = 0; Count = 0;
Array = (T *)M_Malloc (sizeof(T)*max); Array = (T *)M_Malloc (sizeof(T)*max);
} }
TArray (const TArray<T> &other) TArray (const TArray<T,TT> &other)
{ {
DoCopy (other); DoCopy (other);
} }
TArray<T> &operator= (const TArray<T> &other) TArray (TArray<T,TT> &&other)
{
Array = other.Array; other.Array = NULL;
Most = other.Most; other.Most = 0;
Count = other.Count; other.Count = 0;
}
TArray<T,TT> &operator= (const TArray<T,TT> &other)
{ {
if (&other != this) if (&other != this)
{ {
@ -157,6 +164,21 @@ public:
} }
return *this; return *this;
} }
TArray<T,TT> &operator= (TArray<T,TT> &&other)
{
if (Array)
{
if (Count > 0)
{
DoDelete (0, Count-1);
}
M_Free (Array);
}
Array = other.Array; other.Array = NULL;
Most = other.Most; other.Most = 0;
Count = other.Count; other.Count = 0;
return *this;
}
~TArray () ~TArray ()
{ {
if (Array) if (Array)
@ -417,6 +439,14 @@ template<class T, class TT=T>
class TDeletingArray : public TArray<T, TT> class TDeletingArray : public TArray<T, TT>
{ {
public: public:
TDeletingArray() : TArray<T,TT>() {}
TDeletingArray(TDeletingArray<T,TT> &&other) : TArray<T,TT>(std::move(other)) {}
TDeletingArray<T,TT> &operator=(TDeletingArray<T,TT> &&other)
{
TArray<T,TT>::operator=(std::move(other));
return *this;
}
~TDeletingArray<T, TT> () ~TDeletingArray<T, TT> ()
{ {
for (unsigned int i = 0; i < TArray<T,TT>::Size(); ++i) for (unsigned int i = 0; i < TArray<T,TT>::Size(); ++i)

View file

@ -40,6 +40,7 @@
#endif #endif
#include <stdlib.h> #include <stdlib.h>
#include <utility>
//========================================================================== //==========================================================================
// //
@ -204,7 +205,7 @@ template<class T>
inline inline
void swapvalues (T &a, T &b) void swapvalues (T &a, T &b)
{ {
T temp = a; a = b; b = temp; T temp = std::move(a); a = std::move(b); b = std::move(temp);
} }
#endif //__TEMPLATES_H__ #endif //__TEMPLATES_H__

View file

@ -3038,7 +3038,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnParticle)
acc.X = accelx * c + accely * s; acc.X = accelx * c + accely * s;
acc.Y = accelx * s - accely * c; acc.Y = accelx * s - accely * c;
} }
pos = self->Vec3Offset(xoff, yoff, zoff);
P_SpawnParticle(self->Vec3Offset(pos), vel, acc, color, !!(flags & SPF_FULLBRIGHT), startalpha, lifetime, size, fadestep); P_SpawnParticle(self->Vec3Offset(pos), vel, acc, color, !!(flags & SPF_FULLBRIGHT), startalpha, lifetime, size, fadestep);
} }
return 0; return 0;
@ -3706,7 +3705,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF)
{ {
offsetforward *= self->radius; offsetforward *= self->radius;
offsetwidth *= self->radius; offsetwidth *= self->radius;
} }
pos = self->PosPlusZ(offsetheight - self->Floorclip); pos = self->PosPlusZ(offsetheight - self->Floorclip);
@ -3763,7 +3762,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF)
} }
else else
{ {
pitch -= VecToAngle(xydist, target->Center()); pitch -= VecToAngle(xydist, target->Center() - pos.Z);
} }
} }
else if (flags & CLOFF_ALLOWNULL) else if (flags & CLOFF_ALLOWNULL)

View file

@ -72,11 +72,11 @@ const char *GetVersionString();
// SAVESIG should match SAVEVER. // SAVESIG should match SAVEVER.
// MINSAVEVER is the minimum level snapshot version that can be loaded. // MINSAVEVER is the minimum level snapshot version that can be loaded.
#define MINSAVEVER 4535 #define MINSAVEVER 4536
// Use 4500 as the base git save version, since it's higher than the // Use 4500 as the base git save version, since it's higher than the
// SVN revision ever got. // SVN revision ever got.
#define SAVEVER 4535 #define SAVEVER 4536
#define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY2(x) #x
#define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)