mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-02-17 17:11:19 +00:00
Merge branch 'new_level_refactor' into localization
This commit is contained in:
commit
88e227f1f3
59 changed files with 222 additions and 22367 deletions
|
@ -33,7 +33,7 @@ build_script:
|
||||||
- md build
|
- md build
|
||||||
- cd build
|
- cd build
|
||||||
- cmake -G "%GENERATOR%" -T "%TOOLSET%" -DPK3_QUIET_ZIPDIR=YES ..
|
- cmake -G "%GENERATOR%" -T "%TOOLSET%" -DPK3_QUIET_ZIPDIR=YES ..
|
||||||
- cmake --build . --config "%CONFIGURATION%" -- /verbosity:minimal
|
- cmake --build . --config "%CONFIGURATION%" -- -maxcpucount -verbosity:minimal
|
||||||
|
|
||||||
after_build:
|
after_build:
|
||||||
- set OUTPUT_DIR=%APPVEYOR_BUILD_FOLDER%\build\%CONFIGURATION%\
|
- set OUTPUT_DIR=%APPVEYOR_BUILD_FOLDER%\build\%CONFIGURATION%\
|
||||||
|
|
|
@ -108,11 +108,11 @@ matrix:
|
||||||
|
|
||||||
- os: windows
|
- os: windows
|
||||||
env:
|
env:
|
||||||
- CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=Release -A Win32"
|
- CMAKE_OPTIONS="-A Win32"
|
||||||
|
|
||||||
- os: windows
|
- os: windows
|
||||||
env:
|
env:
|
||||||
- CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=Release -A x64"
|
- CMAKE_OPTIONS="-A x64"
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- if [ -n "$GCC_VERSION" ]; then export CC="gcc-${GCC_VERSION}" CXX="g++-${GCC_VERSION}"; fi
|
- if [ -n "$GCC_VERSION" ]; then export CC="gcc-${GCC_VERSION}" CXX="g++-${GCC_VERSION}"; fi
|
||||||
|
@ -132,8 +132,8 @@ script:
|
||||||
-DFORCE_INTERNAL_GME=YES \
|
-DFORCE_INTERNAL_GME=YES \
|
||||||
-DPK3_QUIET_ZIPDIR=YES \
|
-DPK3_QUIET_ZIPDIR=YES \
|
||||||
..
|
..
|
||||||
- if [[ $TRAVIS_OS_NAME == 'windows' ]]; then cmake --build . -- -m; fi
|
- if [[ $TRAVIS_OS_NAME == 'windows' ]]; then cmake --build . --config Release -- -maxcpucount -verbosity:minimal; fi
|
||||||
- if [[ $TRAVIS_OS_NAME != 'windows' ]]; then cmake --build . -- -j2; fi
|
- if [[ $TRAVIS_OS_NAME != 'windows' ]]; then cmake --build . -- --jobs=2 --keep-going; fi
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
email: false
|
email: false
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
{
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"name": "x64-Release",
|
|
||||||
"generator": "Ninja",
|
|
||||||
"configurationType": "Release",
|
|
||||||
"inheritEnvironments": [ "msvc_x64_x64" ],
|
|
||||||
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
|
|
||||||
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
|
|
||||||
"cmakeCommandArgs": "",
|
|
||||||
"buildCommandArgs": "-v",
|
|
||||||
"ctestCommandArgs": "",
|
|
||||||
"variables": [
|
|
||||||
{
|
|
||||||
"name": "ZDOOM_GENERATE_ASM",
|
|
||||||
"value": "True",
|
|
||||||
"type": "BOOL"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ZDOOM_GENERATE_MAPFILE",
|
|
||||||
"value": "True",
|
|
||||||
"type": "BOOL"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ZDOOM_OUTPUT_OLDSTYLE",
|
|
||||||
"value": "True",
|
|
||||||
"type": "BOOL"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "JPEG_INCLUDE_DIR",
|
|
||||||
"value": "c:\\Programming\\vcpkg\\packages\\libjpeg-turbo_x64-windows-static\\include\\",
|
|
||||||
"type": "PATH"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "JPEG_LIBRARY_DEBUG",
|
|
||||||
"value": "c:\\Programming\\vcpkg\\packages\\libjpeg-turbo_x64-windows-static\\lib\\jpeg.lib",
|
|
||||||
"type": "FILEPATH"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "JPEG_LIBRARY_RELEASE",
|
|
||||||
"value": "c:\\Programming\\vcpkg\\packages\\libjpeg-turbo_x64-windows-static\\lib\\jpeg.lib",
|
|
||||||
"type": "FILEPATH"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
21073
externs.txt
21073
externs.txt
File diff suppressed because it is too large
Load diff
BIN
externs.zip
BIN
externs.zip
Binary file not shown.
1073
p_destructible.cpp
1073
p_destructible.cpp
File diff suppressed because it is too large
Load diff
|
@ -1,43 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "tarray.h"
|
|
||||||
#include "r_defs.h"
|
|
||||||
#include "p_trace.h"
|
|
||||||
|
|
||||||
// [ZZ] Destructible geometry related
|
|
||||||
struct FHealthGroup
|
|
||||||
{
|
|
||||||
TArray<sector_t*> sectors;
|
|
||||||
TArray<line_t*> lines;
|
|
||||||
int health;
|
|
||||||
int id;
|
|
||||||
};
|
|
||||||
|
|
||||||
// for P_DamageSector
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
SECPART_Floor = 0,
|
|
||||||
SECPART_Ceiling = 1,
|
|
||||||
SECPART_3D = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void P_SetHealthGroupHealth(FHealthGroup* group, int health);
|
|
||||||
void P_SetHealthGroupHealth(FLevelLocals *Level, int group, int health);
|
|
||||||
|
|
||||||
void P_InitHealthGroups(FLevelLocals *Level);
|
|
||||||
FHealthGroup* P_GetHealthGroup(FLevelLocals *Level, int id);
|
|
||||||
FHealthGroup* P_GetHealthGroupOrNew(FLevelLocals *Level, int id, int startinghealth);
|
|
||||||
|
|
||||||
void P_DamageSector(sector_t* sector, AActor* source, int damage, FName damagetype, int part, DVector3 position, bool isradius, bool dogroups);
|
|
||||||
void P_DamageLinedef(line_t* line, AActor* source, int damage, FName damagetype, int side, DVector3 position, bool isradius, bool dogroups);
|
|
||||||
|
|
||||||
void P_GeometryLineAttack(FTraceResults& trace, AActor* thing, int damage, FName damageType);
|
|
||||||
void P_GeometryRadiusAttack(AActor* bombspot, AActor* bombsource, int bombdamage, int bombdistance, FName damagetype, int fulldamagedistance);
|
|
||||||
bool P_ProjectileHitLinedef(AActor* projectile, line_t* line);
|
|
||||||
bool P_ProjectileHitPlane(AActor* projectile, int part);
|
|
||||||
|
|
||||||
bool P_CheckLinedefVulnerable(line_t* line, int side, int part = -1);
|
|
||||||
bool P_CheckSectorVulnerable(sector_t* sector, int part);
|
|
||||||
|
|
||||||
void P_SerializeHealthGroups(FSerializer& arc);
|
|
|
@ -1422,7 +1422,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
int ApplyDamageFactor(FName damagetype, int damage) const;
|
int ApplyDamageFactor(FName damagetype, int damage) const;
|
||||||
int GetModifiedDamage(FName damagetype, int damage, bool passive);
|
int GetModifiedDamage(FName damagetype, int damage, bool passive, AActor *inflictor, AActor *source, int flags = 0);
|
||||||
void DeleteAttachedLights();
|
void DeleteAttachedLights();
|
||||||
bool isFrozen();
|
bool isFrozen();
|
||||||
|
|
||||||
|
|
|
@ -217,7 +217,7 @@ void EventManager::InitHandler(PClass* type)
|
||||||
RegisterHandler(handler);
|
RegisterHandler(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventManager::InitStaticHandlers(bool map)
|
void EventManager::InitStaticHandlers(FLevelLocals *l, bool map)
|
||||||
{
|
{
|
||||||
// don't initialize map handlers if restoring from savegame.
|
// don't initialize map handlers if restoring from savegame.
|
||||||
if (savegamerestore)
|
if (savegamerestore)
|
||||||
|
@ -225,6 +225,7 @@ void EventManager::InitStaticHandlers(bool map)
|
||||||
|
|
||||||
// just make sure
|
// just make sure
|
||||||
Shutdown();
|
Shutdown();
|
||||||
|
Level = l;
|
||||||
|
|
||||||
// initialize event handlers from gameinfo
|
// initialize event handlers from gameinfo
|
||||||
for (const FString& typeName : gameinfo.EventHandlers)
|
for (const FString& typeName : gameinfo.EventHandlers)
|
||||||
|
@ -241,7 +242,7 @@ void EventManager::InitStaticHandlers(bool map)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// initialize event handlers from mapinfo
|
// initialize event handlers from mapinfo
|
||||||
for (const FString& typeName : level.info->EventHandlers)
|
for (const FString& typeName : Level->info->EventHandlers)
|
||||||
{
|
{
|
||||||
PClass* type = GetHandlerClass(typeName);
|
PClass* type = GetHandlerClass(typeName);
|
||||||
if (IsStaticType(type))
|
if (IsStaticType(type))
|
||||||
|
@ -257,6 +258,7 @@ void EventManager::Shutdown()
|
||||||
{
|
{
|
||||||
handler->Destroy();
|
handler->Destroy();
|
||||||
}
|
}
|
||||||
|
FirstEventHandler = LastEventHandler = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFINE_EVENT_LOOPER(name, play) void EventManager::name() \
|
#define DEFINE_EVENT_LOOPER(name, play) void EventManager::name() \
|
||||||
|
|
|
@ -249,7 +249,7 @@ struct EventManager
|
||||||
// check type
|
// check type
|
||||||
bool IsStaticType(PClass* type);
|
bool IsStaticType(PClass* type);
|
||||||
// init static handlers
|
// init static handlers
|
||||||
void InitStaticHandlers(bool map);
|
void InitStaticHandlers(FLevelLocals *l, bool map);
|
||||||
// shutdown handlers
|
// shutdown handlers
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,7 @@ CCMD (countdecals)
|
||||||
while (iterator.Next())
|
while (iterator.Next())
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
Printf("%s: Counted %d impact decals\n", Level->MapName.GetChars(), count);
|
Printf("%s: Counted %d impact decals, level counter is at %d\n", Level->MapName.GetChars(), count, Level->ImpactDecalCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -573,7 +573,7 @@ static bool unloading;
|
||||||
|
|
||||||
EXTERN_CVAR(Bool, sv_singleplayerrespawn)
|
EXTERN_CVAR(Bool, sv_singleplayerrespawn)
|
||||||
|
|
||||||
void FLevelLocals::ChangeLevel(const char *levelname, int position, int flags, int nextSkill)
|
void FLevelLocals::ChangeLevel(const char *levelname, int position, int inflags, int nextSkill)
|
||||||
{
|
{
|
||||||
if (!isPrimaryLevel()) return; // only the primary level may exit.
|
if (!isPrimaryLevel()) return; // only the primary level may exit.
|
||||||
|
|
||||||
|
@ -630,7 +630,7 @@ void FLevelLocals::ChangeLevel(const char *levelname, int position, int flags, i
|
||||||
if (nextSkill != -1)
|
if (nextSkill != -1)
|
||||||
NextSkill = nextSkill;
|
NextSkill = nextSkill;
|
||||||
|
|
||||||
if (flags & CHANGELEVEL_NOINTERMISSION)
|
if (inflags & CHANGELEVEL_NOINTERMISSION)
|
||||||
{
|
{
|
||||||
flags |= LEVEL_NOINTERMISSION;
|
flags |= LEVEL_NOINTERMISSION;
|
||||||
}
|
}
|
||||||
|
@ -647,15 +647,15 @@ void FLevelLocals::ChangeLevel(const char *levelname, int position, int flags, i
|
||||||
{
|
{
|
||||||
if (nextinfo->flags2 & LEVEL2_RESETINVENTORY)
|
if (nextinfo->flags2 & LEVEL2_RESETINVENTORY)
|
||||||
{
|
{
|
||||||
flags |= CHANGELEVEL_RESETINVENTORY;
|
inflags |= CHANGELEVEL_RESETINVENTORY;
|
||||||
}
|
}
|
||||||
if (nextinfo->flags2 & LEVEL2_RESETHEALTH)
|
if (nextinfo->flags2 & LEVEL2_RESETHEALTH)
|
||||||
{
|
{
|
||||||
flags |= CHANGELEVEL_RESETHEALTH;
|
inflags |= CHANGELEVEL_RESETHEALTH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
changeflags = flags;
|
changeflags = inflags;
|
||||||
|
|
||||||
BotInfo.End(); //Added by MC:
|
BotInfo.End(); //Added by MC:
|
||||||
|
|
||||||
|
|
|
@ -618,7 +618,7 @@ public:
|
||||||
bool FromSnapshot; // The current map was restored from a snapshot
|
bool FromSnapshot; // The current map was restored from a snapshot
|
||||||
bool HasHeightSecs; // true if some Transfer_Heights effects are present in the map. If this is false, some checks in the renderer can be shortcut.
|
bool HasHeightSecs; // true if some Transfer_Heights effects are present in the map. If this is false, some checks in the renderer can be shortcut.
|
||||||
bool HasDynamicLights; // Another render optimization for maps with no lights at all.
|
bool HasDynamicLights; // Another render optimization for maps with no lights at all.
|
||||||
uint8_t frozenstate;
|
int frozenstate;
|
||||||
|
|
||||||
double teamdamage;
|
double teamdamage;
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ void DDecalFader::Tick ()
|
||||||
}
|
}
|
||||||
else if (Level->maptime >= TimeToEndDecay)
|
else if (Level->maptime >= TimeToEndDecay)
|
||||||
{
|
{
|
||||||
|
TheDecal->Expired(); // for impact decal bookkeeping.
|
||||||
TheDecal->Destroy (); // remove the decal
|
TheDecal->Destroy (); // remove the decal
|
||||||
Destroy (); // remove myself
|
Destroy (); // remove myself
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -666,6 +666,8 @@ DBaseDecal *DBaseDecal::CloneSelf (const FDecalTemplate *tpl, double ix, double
|
||||||
|
|
||||||
void DImpactDecal::CheckMax ()
|
void DImpactDecal::CheckMax ()
|
||||||
{
|
{
|
||||||
|
static int SpawnCounter;
|
||||||
|
|
||||||
if (++Level->ImpactDecalCount >= cl_maxdecals)
|
if (++Level->ImpactDecalCount >= cl_maxdecals)
|
||||||
{
|
{
|
||||||
DThinker *thinker = Level->FirstThinker (STAT_AUTODECAL);
|
DThinker *thinker = Level->FirstThinker (STAT_AUTODECAL);
|
||||||
|
@ -683,6 +685,17 @@ void DImpactDecal::CheckMax ()
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void DImpactDecal::Expired()
|
||||||
|
{
|
||||||
|
Level->ImpactDecalCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
DImpactDecal *DImpactDecal::StaticCreate (FLevelLocals *Level, const char *name, const DVector3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color)
|
DImpactDecal *DImpactDecal::StaticCreate (FLevelLocals *Level, const char *name, const DVector3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color)
|
||||||
{
|
{
|
||||||
if (cl_maxdecals > 0)
|
if (cl_maxdecals > 0)
|
||||||
|
|
|
@ -26,6 +26,7 @@ public:
|
||||||
|
|
||||||
void Serialize(FSerializer &arc);
|
void Serialize(FSerializer &arc);
|
||||||
void OnDestroy() override;
|
void OnDestroy() override;
|
||||||
|
virtual void Expired() {} // For thinkers that can remove their decal. For impact decal bookkeeping.
|
||||||
FTextureID StickToWall(side_t *wall, double x, double y, F3DFloor * ffloor);
|
FTextureID StickToWall(side_t *wall, double x, double y, F3DFloor * ffloor);
|
||||||
double GetRealZ (const side_t *wall) const;
|
double GetRealZ (const side_t *wall) const;
|
||||||
void SetShade (uint32_t rgb);
|
void SetShade (uint32_t rgb);
|
||||||
|
@ -71,6 +72,7 @@ public:
|
||||||
static DImpactDecal *StaticCreate(FLevelLocals *Level, const FDecalTemplate *tpl, const DVector3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color = 0);
|
static DImpactDecal *StaticCreate(FLevelLocals *Level, const FDecalTemplate *tpl, const DVector3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color = 0);
|
||||||
|
|
||||||
void BeginPlay ();
|
void BeginPlay ();
|
||||||
|
void Expired() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DBaseDecal *CloneSelf(const FDecalTemplate *tpl, double x, double y, double z, side_t *wall, F3DFloor * ffloor) const;
|
DBaseDecal *CloneSelf(const FDecalTemplate *tpl, double x, double y, double z, side_t *wall, F3DFloor * ffloor) const;
|
||||||
|
|
|
@ -62,13 +62,12 @@
|
||||||
Only one selector of each type can be used.
|
Only one selector of each type can be used.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
AActor *COPY_AAPTR(AActor *origin, int selector)
|
AActor *COPY_AAPTREX(FLevelLocals *Level, AActor *origin, int selector)
|
||||||
{
|
{
|
||||||
if (selector == AAPTR_DEFAULT) return origin;
|
if (selector == AAPTR_DEFAULT) return origin;
|
||||||
|
|
||||||
FTranslatedLineTarget t;
|
FTranslatedLineTarget t;
|
||||||
|
|
||||||
auto Level = origin->Level;
|
|
||||||
auto AAPTR_RESOLVE_PLAYERNUM = [=](int playernum) -> AActor*
|
auto AAPTR_RESOLVE_PLAYERNUM = [=](int playernum) -> AActor*
|
||||||
{
|
{
|
||||||
return (Level->PlayerInGame(playernum) ? Level->Players[playernum]->mo : nullptr);
|
return (Level->PlayerInGame(playernum) ? Level->Players[playernum]->mo : nullptr);
|
||||||
|
@ -119,6 +118,11 @@ AActor *COPY_AAPTR(AActor *origin, int selector)
|
||||||
return origin;
|
return origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AActor *COPY_AAPTR(AActor *origin, int selector)
|
||||||
|
{
|
||||||
|
if (origin == nullptr) return nullptr;
|
||||||
|
return COPY_AAPTREX(origin->Level, origin, selector);
|
||||||
|
}
|
||||||
|
|
||||||
// [FDARI] Exported logic for guarding against loops in Target (for missiles) and Master (for all) chains.
|
// [FDARI] Exported logic for guarding against loops in Target (for missiles) and Master (for all) chains.
|
||||||
// It is called from multiple locations.
|
// It is called from multiple locations.
|
||||||
|
|
|
@ -64,8 +64,9 @@ enum AAPTR
|
||||||
Only one selector of each type can be used.
|
Only one selector of each type can be used.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct FLevelLocals;
|
||||||
AActor *COPY_AAPTR(AActor *origin, int selector);
|
AActor *COPY_AAPTR(AActor *origin, int selector);
|
||||||
|
AActor *COPY_AAPTREX(FLevelLocals *Level, AActor *origin, int selector);
|
||||||
enum PTROP
|
enum PTROP
|
||||||
{
|
{
|
||||||
PTROP_UNSAFETARGET = 1,
|
PTROP_UNSAFETARGET = 1,
|
||||||
|
|
|
@ -692,6 +692,7 @@ void P_LineOpening_XFloors (FLineOpening &open, AActor * thing, const line_t *li
|
||||||
double lowestfloor[2] = {
|
double lowestfloor[2] = {
|
||||||
linedef->frontsector->floorplane.ZatPoint(x, y),
|
linedef->frontsector->floorplane.ZatPoint(x, y),
|
||||||
linedef->backsector->floorplane.ZatPoint(x, y) };
|
linedef->backsector->floorplane.ZatPoint(x, y) };
|
||||||
|
bool lowestfloorset[2] = { false, false };
|
||||||
FTextureID highestfloorpic;
|
FTextureID highestfloorpic;
|
||||||
int highestfloorterrain = -1;
|
int highestfloorterrain = -1;
|
||||||
FTextureID lowestceilingpic;
|
FTextureID lowestceilingpic;
|
||||||
|
@ -741,7 +742,11 @@ void P_LineOpening_XFloors (FLineOpening &open, AActor * thing, const line_t *li
|
||||||
highestfloorplanes[j] = rover->top.plane;
|
highestfloorplanes[j] = rover->top.plane;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(ff_top > lowestfloor[j] && ff_top <= thing->Z() + thing->MaxStepHeight) lowestfloor[j] = ff_top;
|
if (ff_top > lowestfloor[j] && ff_top <= thing->Z() + thing->MaxStepHeight)
|
||||||
|
{
|
||||||
|
lowestfloor[j] = ff_top;
|
||||||
|
lowestfloorset[j] = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -771,8 +776,14 @@ void P_LineOpening_XFloors (FLineOpening &open, AActor * thing, const line_t *li
|
||||||
open.topsec = lowestceilingsec;
|
open.topsec = lowestceilingsec;
|
||||||
open.topffloor = lowestceilingffloor;
|
open.topffloor = lowestceilingffloor;
|
||||||
}
|
}
|
||||||
|
|
||||||
open.lowfloor = MIN(lowestfloor[0], lowestfloor[1]);
|
// Don't overwrite still valid info from portals here.
|
||||||
|
if ((open.lowfloorthroughportal & 1) && lowestfloorset[0]) open.lowfloorthroughportal &= ~1;
|
||||||
|
if ((open.lowfloorthroughportal & 2) && lowestfloorset[1]) open.lowfloorthroughportal &= ~2;
|
||||||
|
|
||||||
|
double low1 = (open.lowfloorthroughportal & 1) ? open.lowfloor : lowestfloor[0];
|
||||||
|
double low2 = (open.lowfloorthroughportal & 2) ? open.lowfloor : lowestfloor[1];
|
||||||
|
open.lowfloor = MIN(low1, low2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ struct FCheckPosition
|
||||||
TMap<AActor*, bool> LastRipped;
|
TMap<AActor*, bool> LastRipped;
|
||||||
bool DoRipping;
|
bool DoRipping;
|
||||||
bool portalstep;
|
bool portalstep;
|
||||||
|
bool dropoffisportal;
|
||||||
int portalgroup;
|
int portalgroup;
|
||||||
|
|
||||||
int PushTime;
|
int PushTime;
|
||||||
|
|
|
@ -195,7 +195,7 @@ DHUDMessage::DHUDMessage (FFont *font, const char *text, float x, float y, int h
|
||||||
HandleAspect = true;
|
HandleAspect = true;
|
||||||
Top = y;
|
Top = y;
|
||||||
HoldTics = (int)(holdTime * TICRATE);
|
HoldTics = (int)(holdTime * TICRATE);
|
||||||
Tics = 0;
|
Tics = -1; // -1 to compensate for one additional Tick the message will receive.
|
||||||
TextColor = textColor;
|
TextColor = textColor;
|
||||||
State = 0;
|
State = 0;
|
||||||
SourceText = copystring (text);
|
SourceText = copystring (text);
|
||||||
|
|
|
@ -201,7 +201,7 @@ enum ELevelFlags : unsigned int
|
||||||
LEVEL2_LAXACTIVATIONMAPINFO = 0x00000008, // LEVEL_LAXMONSTERACTIVATION is not a default.
|
LEVEL2_LAXACTIVATIONMAPINFO = 0x00000008, // LEVEL_LAXMONSTERACTIVATION is not a default.
|
||||||
|
|
||||||
LEVEL2_MISSILESACTIVATEIMPACT=0x00000010, // Missiles are the activators of SPAC_IMPACT events, not their shooters
|
LEVEL2_MISSILESACTIVATEIMPACT=0x00000010, // Missiles are the activators of SPAC_IMPACT events, not their shooters
|
||||||
LEVEL2_FROZEN = 0x00000020, // Game is frozen by a TimeFreezer
|
// = 0x00000020, // unused
|
||||||
|
|
||||||
LEVEL2_KEEPFULLINVENTORY = 0x00000040, // doesn't reduce the amount of inventory items to 1
|
LEVEL2_KEEPFULLINVENTORY = 0x00000040, // doesn't reduce the amount of inventory items to 1
|
||||||
|
|
||||||
|
|
|
@ -395,7 +395,7 @@ void PClassActor::StaticInit()
|
||||||
InitBotStuff();
|
InitBotStuff();
|
||||||
|
|
||||||
// reinit GLOBAL static stuff from gameinfo, once classes are loaded.
|
// reinit GLOBAL static stuff from gameinfo, once classes are loaded.
|
||||||
staticEventManager.InitStaticHandlers(false);
|
staticEventManager.InitStaticHandlers(primaryLevel, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -1034,7 +1034,7 @@ void MapLoader::SpawnLights(sector_t *sector)
|
||||||
|
|
||||||
// [RH] Hexen-like phased lighting
|
// [RH] Hexen-like phased lighting
|
||||||
case LightSequenceStart:
|
case LightSequenceStart:
|
||||||
Level->CreateThinker<DPhased>(sector);
|
Level->CreateThinker<DPhased>(sector)->Propagate();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case dLight_Flicker:
|
case dLight_Flicker:
|
||||||
|
|
|
@ -3247,7 +3247,7 @@ const char *FBehavior::LookupString (uint32_t index, bool forprint) const
|
||||||
token.Substitute(" ", "");
|
token.Substitute(" ", "");
|
||||||
token.Truncate(5);
|
token.Truncate(5);
|
||||||
|
|
||||||
FStringf label("TXT_ACS_%s_%d_%.5s", Level->MapName.GetChars(), index, token);
|
FStringf label("TXT_ACS_%s_%d_%.5s", Level->MapName.GetChars(), index, token.GetChars());
|
||||||
auto p = GStrings[label];
|
auto p = GStrings[label];
|
||||||
if (p) return p;
|
if (p) return p;
|
||||||
}
|
}
|
||||||
|
@ -5352,7 +5352,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args)
|
||||||
AActor *ptr = Level->SingleActorFromTID(args[1], activator);
|
AActor *ptr = Level->SingleActorFromTID(args[1], activator);
|
||||||
if (argCount > 2)
|
if (argCount > 2)
|
||||||
{
|
{
|
||||||
ptr = COPY_AAPTR(ptr, args[2]);
|
ptr = COPY_AAPTREX(Level, ptr, args[2]);
|
||||||
}
|
}
|
||||||
if (ptr == activator) ptr = NULL;
|
if (ptr == activator) ptr = NULL;
|
||||||
ASSIGN_AAPTR(activator, args[0], ptr, (argCount > 3) ? args[3] : 0);
|
ASSIGN_AAPTR(activator, args[0], ptr, (argCount > 3) ? args[3] : 0);
|
||||||
|
@ -6326,7 +6326,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
||||||
actor = Level->SingleActorFromTID(tid1, activator);
|
actor = Level->SingleActorFromTID(tid1, activator);
|
||||||
AActor * actor2 = tid2 == tid1 ? actor : Level->SingleActorFromTID(tid2, activator);
|
AActor * actor2 = tid2 == tid1 ? actor : Level->SingleActorFromTID(tid2, activator);
|
||||||
|
|
||||||
return COPY_AAPTR(actor, args[0]) == COPY_AAPTR(actor2, args[1]);
|
return COPY_AAPTREX(Level, actor, args[0]) == COPY_AAPTREX(Level, actor2, args[1]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -6504,7 +6504,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
||||||
int count = argCount >= 4 ? args[3] : 1;
|
int count = argCount >= 4 ? args[3] : 1;
|
||||||
int flags = argCount >= 5 ? args[4] : 0;
|
int flags = argCount >= 5 ? args[4] : 0;
|
||||||
int ptr = argCount >= 6 ? args[5] : AAPTR_DEFAULT;
|
int ptr = argCount >= 6 ? args[5] : AAPTR_DEFAULT;
|
||||||
return P_Thing_CheckProximity(actor, classname, distance, count, flags, ptr);
|
return P_Thing_CheckProximity(Level, actor, classname, distance, count, flags, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
case ACSF_CheckActorState:
|
case ACSF_CheckActorState:
|
||||||
|
@ -6528,8 +6528,8 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
||||||
case ACSF_DamageActor: // [arookas] wrapper around P_DamageMobj
|
case ACSF_DamageActor: // [arookas] wrapper around P_DamageMobj
|
||||||
{
|
{
|
||||||
// (target, ptr_select1, inflictor, ptr_select2, amount, damagetype)
|
// (target, ptr_select1, inflictor, ptr_select2, amount, damagetype)
|
||||||
AActor* target = COPY_AAPTR(Level->SingleActorFromTID(args[0], activator), args[1]);
|
AActor* target = COPY_AAPTREX(Level, Level->SingleActorFromTID(args[0], activator), args[1]);
|
||||||
AActor* inflictor = COPY_AAPTR(Level->SingleActorFromTID(args[2], activator), args[3]);
|
AActor* inflictor = COPY_AAPTREX(Level, Level->SingleActorFromTID(args[2], activator), args[3]);
|
||||||
FName damagetype(Level->Behaviors.LookupString(args[5]));
|
FName damagetype(Level->Behaviors.LookupString(args[5]));
|
||||||
return P_DamageMobj(target, inflictor, inflictor, args[4], damagetype);
|
return P_DamageMobj(target, inflictor, inflictor, args[4], damagetype);
|
||||||
}
|
}
|
||||||
|
|
|
@ -485,7 +485,7 @@ DEFINE_ACTION_FUNCTION(AActor, CountProximity)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret->SetInt(P_Thing_CheckProximity(self, classname, distance, 0, flags, ptr, true));
|
ret->SetInt(P_Thing_CheckProximity(self->Level, self, classname, distance, 0, flags, ptr, true));
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -4520,7 +4520,7 @@ DEFINE_ACTION_FUNCTION(AActor, CheckProximity)
|
||||||
PARAM_INT(flags);
|
PARAM_INT(flags);
|
||||||
PARAM_INT(ptr);
|
PARAM_INT(ptr);
|
||||||
|
|
||||||
ACTION_RETURN_BOOL(!!P_Thing_CheckProximity(self, classname, distance, count, flags, ptr));
|
ACTION_RETURN_BOOL(!!P_Thing_CheckProximity(self->Level, self, classname, distance, count, flags, ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================
|
/*===========================================================================
|
||||||
|
|
|
@ -351,7 +351,7 @@ static FStrifeDialogueNode *ReadRetailNode (FLevelLocals *Level, const char *nam
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
{
|
{
|
||||||
FStringf label("$TXT_DLG_%s_d%d_%s", name, int(pos), TokenFromString(speech.Dialogue));
|
FStringf label("$TXT_DLG_%s_d%d_%s", name, int(pos), TokenFromString(speech.Dialogue).GetChars());
|
||||||
node->Dialogue = label;
|
node->Dialogue = label;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -435,7 +435,7 @@ static FStrifeDialogueNode *ReadTeaserNode (FLevelLocals *Level, const char *nam
|
||||||
// Convert the rest of the data to our own internal format.
|
// Convert the rest of the data to our own internal format.
|
||||||
if (name)
|
if (name)
|
||||||
{
|
{
|
||||||
FStringf label("$TXT_DLG_%s_d%d_%s", name, pos, TokenFromString(speech.Dialogue));
|
FStringf label("$TXT_DLG_%s_d%d_%s", name, pos, TokenFromString(speech.Dialogue).GetChars());
|
||||||
node->Dialogue = label;
|
node->Dialogue = label;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -545,7 +545,7 @@ static void ParseReplies (const char *name, int pos, FStrifeDialogueReply **repl
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
{
|
{
|
||||||
FStringf label("$TXT_RPLY%d_%s_d%d_%s", j, name, pos, TokenFromString(rsp->Reply));
|
FStringf label("$TXT_RPLY%d_%s_d%d_%s", j, name, pos, TokenFromString(rsp->Reply).GetChars());
|
||||||
reply->Reply = label;
|
reply->Reply = label;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -569,7 +569,7 @@ static void ParseReplies (const char *name, int pos, FStrifeDialogueReply **repl
|
||||||
{
|
{
|
||||||
if (name)
|
if (name)
|
||||||
{
|
{
|
||||||
FStringf label("$TXT_RYES%d_%s_d%d_%s", j, name, pos, TokenFromString(rsp->Yes));
|
FStringf label("$TXT_RYES%d_%s_d%d_%s", j, name, pos, TokenFromString(rsp->Yes).GetChars());
|
||||||
reply->QuickYes = label;
|
reply->QuickYes = label;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -581,7 +581,7 @@ static void ParseReplies (const char *name, int pos, FStrifeDialogueReply **repl
|
||||||
{
|
{
|
||||||
if (name && strncmp(rsp->No, "NO. ", 4)) // All 'no' nodes starting with 'NO.' won't ever be shown and they all contain broken text.
|
if (name && strncmp(rsp->No, "NO. ", 4)) // All 'no' nodes starting with 'NO.' won't ever be shown and they all contain broken text.
|
||||||
{
|
{
|
||||||
FStringf label("$TXT_RNO%d_%s_d%d_%s", j, name, pos, TokenFromString(rsp->No));
|
FStringf label("$TXT_RNO%d_%s_d%d_%s", j, name, pos, TokenFromString(rsp->No).GetChars());
|
||||||
reply->QuickNo = label;
|
reply->QuickNo = label;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -1150,13 +1150,13 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da
|
||||||
// Handle active damage modifiers (e.g. PowerDamage)
|
// Handle active damage modifiers (e.g. PowerDamage)
|
||||||
if (damage > 0 && !(flags & DMG_NO_ENHANCE))
|
if (damage > 0 && !(flags & DMG_NO_ENHANCE))
|
||||||
{
|
{
|
||||||
damage = source->GetModifiedDamage(mod, damage, false);
|
damage = source->GetModifiedDamage(mod, damage, false, inflictor, source, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Handle passive damage modifiers (e.g. PowerProtection), provided they are not afflicted with protection penetrating powers.
|
// Handle passive damage modifiers (e.g. PowerProtection), provided they are not afflicted with protection penetrating powers.
|
||||||
if (damage > 0 && !(flags & DMG_NO_PROTECT))
|
if (damage > 0 && !(flags & DMG_NO_PROTECT))
|
||||||
{
|
{
|
||||||
damage = target->GetModifiedDamage(mod, damage, true);
|
damage = target->GetModifiedDamage(mod, damage, true, inflictor, source, flags);
|
||||||
}
|
}
|
||||||
if (damage > 0 && !(flags & DMG_NO_FACTOR))
|
if (damage > 0 && !(flags & DMG_NO_FACTOR))
|
||||||
{
|
{
|
||||||
|
@ -1747,7 +1747,7 @@ void P_PoisonDamage (player_t *player, AActor *source, int damage, bool playPain
|
||||||
// Take half damage in trainer mode
|
// Take half damage in trainer mode
|
||||||
damage = int(damage * G_SkillProperty(SKILLP_DamageFactor) * sv_damagefactorplayer);
|
damage = int(damage * G_SkillProperty(SKILLP_DamageFactor) * sv_damagefactorplayer);
|
||||||
// Handle passive damage modifiers (e.g. PowerProtection)
|
// Handle passive damage modifiers (e.g. PowerProtection)
|
||||||
damage = target->GetModifiedDamage(player->poisontype, damage, true);
|
damage = target->GetModifiedDamage(player->poisontype, damage, true, nullptr, source);
|
||||||
// Modify with damage factors
|
// Modify with damage factors
|
||||||
damage = target->ApplyDamageFactor(player->poisontype, damage);
|
damage = target->ApplyDamageFactor(player->poisontype, damage);
|
||||||
|
|
||||||
|
|
|
@ -148,7 +148,8 @@ PClassActor *P_GetSpawnableType(int spawnnum);
|
||||||
void InitSpawnablesFromMapinfo();
|
void InitSpawnablesFromMapinfo();
|
||||||
int P_Thing_CheckInputNum(player_t *p, int inputnum);
|
int P_Thing_CheckInputNum(player_t *p, int inputnum);
|
||||||
int P_Thing_Warp(AActor *caller, AActor *reference, double xofs, double yofs, double zofs, DAngle angle, int flags, double heightoffset, double radiusoffset, DAngle pitch);
|
int P_Thing_Warp(AActor *caller, AActor *reference, double xofs, double yofs, double zofs, DAngle angle, int flags, double heightoffset, double radiusoffset, DAngle pitch);
|
||||||
int P_Thing_CheckProximity(AActor *self, PClass *classname, double distance, int count, int flags, int ptr, bool counting = false);
|
struct FLevelLocals;
|
||||||
|
int P_Thing_CheckProximity(FLevelLocals *Level, AActor *self, PClass *classname, double distance, int count, int flags, int ptr, bool counting = false);
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
|
|
@ -280,6 +280,7 @@ void P_GetFloorCeilingZ(FCheckPosition &tmf, int flags)
|
||||||
|
|
||||||
tmf.ceilingz = NextHighestCeilingAt(sec, tmf.pos.X, tmf.pos.Y, tmf.pos.Z, tmf.pos.Z + tmf.thing->Height, flags, &tmf.ceilingsector, &ffc);
|
tmf.ceilingz = NextHighestCeilingAt(sec, tmf.pos.X, tmf.pos.Y, tmf.pos.Z, tmf.pos.Z + tmf.thing->Height, flags, &tmf.ceilingsector, &ffc);
|
||||||
tmf.floorz = tmf.dropoffz = NextLowestFloorAt(sec, tmf.pos.X, tmf.pos.Y, tmf.pos.Z, flags, tmf.thing->MaxStepHeight, &tmf.floorsector, &fff);
|
tmf.floorz = tmf.dropoffz = NextLowestFloorAt(sec, tmf.pos.X, tmf.pos.Y, tmf.pos.Z, flags, tmf.thing->MaxStepHeight, &tmf.floorsector, &fff);
|
||||||
|
tmf.dropoffisportal = tmf.floorsector != sec;
|
||||||
|
|
||||||
if (fff)
|
if (fff)
|
||||||
{
|
{
|
||||||
|
@ -1018,7 +1019,12 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
|
||||||
|
|
||||||
if (open.lowfloor < tm.dropoffz)
|
if (open.lowfloor < tm.dropoffz)
|
||||||
{
|
{
|
||||||
tm.dropoffz = open.lowfloor;
|
// Do not alter the dropoff if the previous portal layer got it solely from its own data.
|
||||||
|
if (!(cres.portalflags & FFCF_NOCEILING) || tm.dropoffisportal)
|
||||||
|
{
|
||||||
|
tm.dropoffz = open.lowfloor;
|
||||||
|
tm.dropoffisportal = open.lowfloorthroughportal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1680,6 +1686,7 @@ bool P_CheckPosition(AActor *thing, const DVector2 &pos, FCheckPosition &tm, boo
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tm.floorz = tm.dropoffz = newsec->floorplane.ZatPoint(pos);
|
tm.floorz = tm.dropoffz = newsec->floorplane.ZatPoint(pos);
|
||||||
|
tm.dropoffisportal = false;
|
||||||
tm.floorpic = newsec->GetTexture(sector_t::floor);
|
tm.floorpic = newsec->GetTexture(sector_t::floor);
|
||||||
tm.ceilingz = newsec->ceilingplane.ZatPoint(pos);
|
tm.ceilingz = newsec->ceilingplane.ZatPoint(pos);
|
||||||
tm.ceilingpic = newsec->GetTexture(sector_t::ceiling);
|
tm.ceilingpic = newsec->GetTexture(sector_t::ceiling);
|
||||||
|
@ -1704,6 +1711,7 @@ bool P_CheckPosition(AActor *thing, const DVector2 &pos, FCheckPosition &tm, boo
|
||||||
if (ff_top > tm.floorz && fabs(delta1) < fabs(delta2))
|
if (ff_top > tm.floorz && fabs(delta1) < fabs(delta2))
|
||||||
{
|
{
|
||||||
tm.floorz = tm.dropoffz = ff_top;
|
tm.floorz = tm.dropoffz = ff_top;
|
||||||
|
tm.dropoffisportal = false;
|
||||||
tm.floorpic = *rover->top.texture;
|
tm.floorpic = *rover->top.texture;
|
||||||
tm.floorterrain = rover->model->GetTerrain(rover->top.isceiling);
|
tm.floorterrain = rover->model->GetTerrain(rover->top.isceiling);
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,12 +177,17 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, co
|
||||||
|
|
||||||
bool usefront;
|
bool usefront;
|
||||||
|
|
||||||
|
// Store portal state to avoid registering false dropoffs.
|
||||||
|
open.lowfloorthroughportal = 0;
|
||||||
|
if (ff == LINEOPEN_MIN) open.lowfloorthroughportal |= 1;
|
||||||
|
if (bf == LINEOPEN_MIN) open.lowfloorthroughportal |= 2;
|
||||||
|
|
||||||
// [RH] fudge a bit for actors that are moving across lines
|
// [RH] fudge a bit for actors that are moving across lines
|
||||||
// bordering a slope/non-slope that meet on the floor. Note
|
// bordering a slope/non-slope that meet on the floor. Note
|
||||||
// that imprecisions in the plane equation mean there is a
|
// that imprecisions in the plane equation mean there is a
|
||||||
// good chance that even if a slope and non-slope look like
|
// good chance that even if a slope and non-slope look like
|
||||||
// they line up, they won't be perfectly aligned.
|
// they line up, they won't be perfectly aligned.
|
||||||
if (ff == -FLT_MIN || bf == -FLT_MIN || ref == NULL || fabs (ff-bf) > 1./256)
|
if (ff == LINEOPEN_MIN || bf == LINEOPEN_MIN || ref == NULL || fabs (ff-bf) > 1./256)
|
||||||
{
|
{
|
||||||
usefront = (ff > bf);
|
usefront = (ff > bf);
|
||||||
}
|
}
|
||||||
|
@ -196,6 +201,7 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, co
|
||||||
usefront = !P_PointOnLineSide (*ref, linedef);
|
usefront = !P_PointOnLineSide (*ref, linedef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open.lowfloorthroughportal = false;
|
||||||
if (usefront)
|
if (usefront)
|
||||||
{
|
{
|
||||||
open.bottom = ff;
|
open.bottom = ff;
|
||||||
|
|
|
@ -111,6 +111,7 @@ struct FLineOpening
|
||||||
int floorterrain;
|
int floorterrain;
|
||||||
bool touchmidtex;
|
bool touchmidtex;
|
||||||
bool abovemidtex;
|
bool abovemidtex;
|
||||||
|
uint8_t lowfloorthroughportal;
|
||||||
F3DFloor *topffloor;
|
F3DFloor *topffloor;
|
||||||
F3DFloor *bottomffloor;
|
F3DFloor *bottomffloor;
|
||||||
};
|
};
|
||||||
|
|
|
@ -4977,7 +4977,7 @@ AActor *FLevelLocals::SpawnPlayer (FPlayerStart *mthing, int playernum, int flag
|
||||||
|
|
||||||
mobj = Spawn (this, p->cls, spawn, NO_REPLACE);
|
mobj = Spawn (this, p->cls, spawn, NO_REPLACE);
|
||||||
|
|
||||||
if (flags & LEVEL_USEPLAYERSTARTZ)
|
if (this->flags & LEVEL_USEPLAYERSTARTZ)
|
||||||
{
|
{
|
||||||
if (spawn.Z == ONFLOORZ)
|
if (spawn.Z == ONFLOORZ)
|
||||||
mobj->AddZ(mthing->pos.Z);
|
mobj->AddZ(mthing->pos.Z);
|
||||||
|
@ -7217,15 +7217,15 @@ void AActor::ClearCounters()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int AActor::GetModifiedDamage(FName damagetype, int damage, bool passive)
|
int AActor::GetModifiedDamage(FName damagetype, int damage, bool passive, AActor *inflictor, AActor *source, int flags)
|
||||||
{
|
{
|
||||||
auto inv = Inventory;
|
auto inv = Inventory;
|
||||||
while (inv != nullptr)
|
while (inv != nullptr)
|
||||||
{
|
{
|
||||||
IFVIRTUALPTRNAME(inv, NAME_Inventory, ModifyDamage)
|
IFVIRTUALPTRNAME(inv, NAME_Inventory, ModifyDamage)
|
||||||
{
|
{
|
||||||
VMValue params[5] = { (DObject*)inv, damage, int(damagetype), &damage, passive };
|
VMValue params[8] = { (DObject*)inv, damage, int(damagetype), &damage, passive, inflictor, source, flags };
|
||||||
VMCall(func, params, 5, nullptr, 0);
|
VMCall(func, params, 8, nullptr, 0);
|
||||||
}
|
}
|
||||||
inv = inv->Inventory;
|
inv = inv->Inventory;
|
||||||
}
|
}
|
||||||
|
|
|
@ -964,7 +964,6 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload)
|
||||||
("spotstate", SpotState)
|
("spotstate", SpotState)
|
||||||
("fragglethinker", FraggleScriptThinker)
|
("fragglethinker", FraggleScriptThinker)
|
||||||
("acsthinker", ACSThinker)
|
("acsthinker", ACSThinker)
|
||||||
("impactdecalcount", ImpactDecalCount)
|
|
||||||
("scrolls", Scrolls)
|
("scrolls", Scrolls)
|
||||||
("automap", automap)
|
("automap", automap)
|
||||||
("interpolator", interpolator)
|
("interpolator", interpolator)
|
||||||
|
@ -1015,7 +1014,7 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload)
|
||||||
if (arc.isReading())
|
if (arc.isReading())
|
||||||
{
|
{
|
||||||
for (auto &sec : sectors)
|
for (auto &sec : sectors)
|
||||||
{
|
{
|
||||||
P_Recalculate3DFloors(&sec);
|
P_Recalculate3DFloors(&sec);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < MAXPLAYERS; ++i)
|
for (int i = 0; i < MAXPLAYERS; ++i)
|
||||||
|
@ -1029,6 +1028,10 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload)
|
||||||
RecreateAllAttachedLights();
|
RecreateAllAttachedLights();
|
||||||
InitPortalGroups(this);
|
InitPortalGroups(this);
|
||||||
|
|
||||||
|
auto it = GetThinkerIterator<DImpactDecal>(NAME_None, STAT_AUTODECAL);
|
||||||
|
ImpactDecalCount = 0;
|
||||||
|
while (it.Next()) ImpactDecalCount++;
|
||||||
|
|
||||||
automap->UpdateShowAllLines();
|
automap->UpdateShowAllLines();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -423,7 +423,7 @@ void P_SetupLevel(FLevelLocals *Level, int position, bool newGame)
|
||||||
|
|
||||||
// [ZZ] init per-map static handlers. we need to call this before everything is set up because otherwise scripts don't receive PlayerEntered event
|
// [ZZ] init per-map static handlers. we need to call this before everything is set up because otherwise scripts don't receive PlayerEntered event
|
||||||
// (which happens at god-knows-what stage in this function, but definitely not the last part, because otherwise it'd work to put E_InitStaticHandlers before the player spawning)
|
// (which happens at god-knows-what stage in this function, but definitely not the last part, because otherwise it'd work to put E_InitStaticHandlers before the player spawning)
|
||||||
Level->localEventManager->InitStaticHandlers(true);
|
Level->localEventManager->InitStaticHandlers(Level, true);
|
||||||
|
|
||||||
// generate a checksum for the level, to be included and checked with savegames.
|
// generate a checksum for the level, to be included and checked with savegames.
|
||||||
map->GetChecksum(Level->md5);
|
map->GetChecksum(Level->md5);
|
||||||
|
|
|
@ -567,9 +567,9 @@ int P_Thing_CheckInputNum(player_t *p, int inputnum)
|
||||||
}
|
}
|
||||||
return renum;
|
return renum;
|
||||||
}
|
}
|
||||||
int P_Thing_CheckProximity(AActor *self, PClass *classname, double distance, int count, int flags, int ptr, bool counting)
|
int P_Thing_CheckProximity(FLevelLocals *Level, AActor *self, PClass *classname, double distance, int count, int flags, int ptr, bool counting)
|
||||||
{
|
{
|
||||||
AActor *ref = COPY_AAPTR(self, ptr);
|
AActor *ref = COPY_AAPTREX(Level, self, ptr);
|
||||||
|
|
||||||
// We need these to check out.
|
// We need these to check out.
|
||||||
if (!ref || !classname || distance <= 0)
|
if (!ref || !classname || distance <= 0)
|
||||||
|
|
|
@ -858,29 +858,41 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor
|
||||||
if (DEarthquake::StaticGetQuakeIntensities(viewpoint.TicFrac, viewpoint.camera, jiggers) > 0)
|
if (DEarthquake::StaticGetQuakeIntensities(viewpoint.TicFrac, viewpoint.camera, jiggers) > 0)
|
||||||
{
|
{
|
||||||
double quakefactor = r_quakeintensity;
|
double quakefactor = r_quakeintensity;
|
||||||
DAngle an;
|
DVector3 pos; pos.Zero();
|
||||||
|
|
||||||
if (jiggers.RollIntensity != 0 || jiggers.RollWave != 0)
|
if (jiggers.RollIntensity != 0 || jiggers.RollWave != 0)
|
||||||
{
|
{
|
||||||
viewpoint.Angles.Roll += QuakePower(quakefactor, jiggers.RollIntensity, jiggers.RollWave);
|
viewpoint.Angles.Roll += QuakePower(quakefactor, jiggers.RollIntensity, jiggers.RollWave);
|
||||||
}
|
}
|
||||||
if (jiggers.RelIntensity.X != 0 || jiggers.RelOffset.X != 0)
|
if (jiggers.RelIntensity.X != 0 || jiggers.RelOffset.X != 0)
|
||||||
{
|
{
|
||||||
an = viewpoint.camera->Angles.Yaw;
|
pos.X += QuakePower(quakefactor, jiggers.RelIntensity.X, jiggers.RelOffset.X);
|
||||||
double power = QuakePower(quakefactor, jiggers.RelIntensity.X, jiggers.RelOffset.X);
|
|
||||||
viewpoint.Pos += an.ToVector(power);
|
|
||||||
}
|
}
|
||||||
if (jiggers.RelIntensity.Y != 0 || jiggers.RelOffset.Y != 0)
|
if (jiggers.RelIntensity.Y != 0 || jiggers.RelOffset.Y != 0)
|
||||||
{
|
{
|
||||||
an = viewpoint.camera->Angles.Yaw + 90;
|
pos.Y += QuakePower(quakefactor, jiggers.RelIntensity.Y, jiggers.RelOffset.Y);
|
||||||
double power = QuakePower(quakefactor, jiggers.RelIntensity.Y, jiggers.RelOffset.Y);
|
|
||||||
viewpoint.Pos += an.ToVector(power);
|
|
||||||
}
|
}
|
||||||
// FIXME: Relative Z is not relative
|
|
||||||
if (jiggers.RelIntensity.Z != 0 || jiggers.RelOffset.Z != 0)
|
if (jiggers.RelIntensity.Z != 0 || jiggers.RelOffset.Z != 0)
|
||||||
{
|
{
|
||||||
viewpoint.Pos.Z += QuakePower(quakefactor, jiggers.RelIntensity.Z, jiggers.RelOffset.Z);
|
pos.Z += QuakePower(quakefactor, jiggers.RelIntensity.Z, jiggers.RelOffset.Z);
|
||||||
}
|
}
|
||||||
|
// [MC] Tremendous thanks to Marisa Kirisame for helping me with this.
|
||||||
|
// Use a rotation matrix to make the view relative.
|
||||||
|
if (!pos.isZero())
|
||||||
|
{
|
||||||
|
DAngle yaw = viewpoint.camera->Angles.Yaw;
|
||||||
|
DAngle pitch = viewpoint.camera->Angles.Pitch;
|
||||||
|
DAngle roll = viewpoint.camera->Angles.Roll;
|
||||||
|
DVector3 relx, rely, relz;
|
||||||
|
DMatrix3x3 rot =
|
||||||
|
DMatrix3x3(DVector3(0., 0., 1.), yaw.Cos(), yaw.Sin()) *
|
||||||
|
DMatrix3x3(DVector3(0., 1., 0.), pitch.Cos(), pitch.Sin()) *
|
||||||
|
DMatrix3x3(DVector3(1., 0., 0.), roll.Cos(), roll.Sin());
|
||||||
|
relx = DVector3(1., 0., 0.)*rot;
|
||||||
|
rely = DVector3(0., 1., 0.)*rot;
|
||||||
|
relz = DVector3(0., 0., 1.)*rot;
|
||||||
|
viewpoint.Pos += relx * pos.X + rely * pos.Y + relz * pos.Z;
|
||||||
|
}
|
||||||
|
|
||||||
if (jiggers.Intensity.X != 0 || jiggers.Offset.X != 0)
|
if (jiggers.Intensity.X != 0 || jiggers.Offset.X != 0)
|
||||||
{
|
{
|
||||||
viewpoint.Pos.X += QuakePower(quakefactor, jiggers.Intensity.X, jiggers.Offset.X);
|
viewpoint.Pos.X += QuakePower(quakefactor, jiggers.Intensity.X, jiggers.Offset.X);
|
||||||
|
|
|
@ -95,7 +95,7 @@ namespace swrenderer
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Changes how rapidly things get dark with distance
|
// Changes how rapidly things get dark with distance
|
||||||
void LightVisibility::SetVisibility(RenderViewport *viewport, double vis)
|
void LightVisibility::SetVisibility(RenderViewport *viewport, double vis, bool nolightfade)
|
||||||
{
|
{
|
||||||
vis = R_ClampVisibility(vis);
|
vis = R_ClampVisibility(vis);
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ namespace swrenderer
|
||||||
|
|
||||||
TiltVisibility = float(vis * viewport->viewwindow.FocalTangent * (16.f * 320.f) / viewwidth);
|
TiltVisibility = float(vis * viewport->viewwindow.FocalTangent * (16.f * 320.f) / viewwidth);
|
||||||
|
|
||||||
NoLightFade = !!(viewport->Level()->flags3 & LEVEL3_NOLIGHTFADE);
|
NoLightFade = nolightfade;
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed_t LightVisibility::LightLevelToShadeImpl(RenderViewport *viewport, int lightlevel, bool foggy)
|
fixed_t LightVisibility::LightLevelToShadeImpl(RenderViewport *viewport, int lightlevel, bool foggy)
|
||||||
|
|
|
@ -77,7 +77,7 @@ namespace swrenderer
|
||||||
class LightVisibility
|
class LightVisibility
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void SetVisibility(RenderViewport *viewport, double visibility);
|
void SetVisibility(RenderViewport *viewport, double visibility, bool nolightfade);
|
||||||
double GetVisibility() const { return CurrentVisibility; }
|
double GetVisibility() const { return CurrentVisibility; }
|
||||||
|
|
||||||
// The vis value to pass into the GETPALOOKUP or LIGHTSCALE macros
|
// The vis value to pass into the GETPALOOKUP or LIGHTSCALE macros
|
||||||
|
|
|
@ -118,6 +118,7 @@ namespace swrenderer
|
||||||
double savedvisibility = Thread->Light->GetVisibility();
|
double savedvisibility = Thread->Light->GetVisibility();
|
||||||
AActor *savedcamera = Thread->Viewport->viewpoint.camera;
|
AActor *savedcamera = Thread->Viewport->viewpoint.camera;
|
||||||
sector_t *savedsector = Thread->Viewport->viewpoint.sector;
|
sector_t *savedsector = Thread->Viewport->viewpoint.sector;
|
||||||
|
auto Level = Thread->Viewport->Level();
|
||||||
|
|
||||||
for (VisiblePlane *pl = planes->PopFirstPortalPlane(); pl != nullptr; pl = planes->PopFirstPortalPlane())
|
for (VisiblePlane *pl = planes->PopFirstPortalPlane(); pl != nullptr; pl = planes->PopFirstPortalPlane())
|
||||||
{
|
{
|
||||||
|
@ -137,7 +138,7 @@ namespace swrenderer
|
||||||
// Don't let gun flashes brighten the sky box
|
// Don't let gun flashes brighten the sky box
|
||||||
AActor *sky = port->mSkybox;
|
AActor *sky = port->mSkybox;
|
||||||
Thread->Viewport->viewpoint.extralight = 0;
|
Thread->Viewport->viewpoint.extralight = 0;
|
||||||
Thread->Light->SetVisibility(Thread->Viewport.get(), sky->args[0] * 0.25f);
|
Thread->Light->SetVisibility(Thread->Viewport.get(), sky->args[0] * 0.25f, !!(Level->flags3 & LEVEL3_NOLIGHTFADE));
|
||||||
|
|
||||||
Thread->Viewport->viewpoint.Pos = sky->InterpolatedPosition(Thread->Viewport->viewpoint.TicFrac);
|
Thread->Viewport->viewpoint.Pos = sky->InterpolatedPosition(Thread->Viewport->viewpoint.TicFrac);
|
||||||
Thread->Viewport->viewpoint.Angles.Yaw = savedangles.Yaw + (sky->PrevAngles.Yaw + deltaangle(sky->PrevAngles.Yaw, sky->Angles.Yaw) * Thread->Viewport->viewpoint.TicFrac);
|
Thread->Viewport->viewpoint.Angles.Yaw = savedangles.Yaw + (sky->PrevAngles.Yaw + deltaangle(sky->PrevAngles.Yaw, sky->Angles.Yaw) * Thread->Viewport->viewpoint.TicFrac);
|
||||||
|
@ -150,7 +151,7 @@ namespace swrenderer
|
||||||
case PORTS_PORTAL:
|
case PORTS_PORTAL:
|
||||||
case PORTS_LINKEDPORTAL:
|
case PORTS_LINKEDPORTAL:
|
||||||
Thread->Viewport->viewpoint.extralight = pl->extralight;
|
Thread->Viewport->viewpoint.extralight = pl->extralight;
|
||||||
Thread->Light->SetVisibility(Thread->Viewport.get(), pl->visibility);
|
Thread->Light->SetVisibility(Thread->Viewport.get(), pl->visibility, !!(Level->flags3 & LEVEL3_NOLIGHTFADE));
|
||||||
Thread->Viewport->viewpoint.Pos.X = pl->viewpos.X + port->mDisplacement.X;
|
Thread->Viewport->viewpoint.Pos.X = pl->viewpos.X + port->mDisplacement.X;
|
||||||
Thread->Viewport->viewpoint.Pos.Y = pl->viewpos.Y + port->mDisplacement.Y;
|
Thread->Viewport->viewpoint.Pos.Y = pl->viewpos.Y + port->mDisplacement.Y;
|
||||||
Thread->Viewport->viewpoint.Pos.Z = pl->viewpos.Z;
|
Thread->Viewport->viewpoint.Pos.Z = pl->viewpos.Z;
|
||||||
|
@ -167,8 +168,6 @@ namespace swrenderer
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Level = Thread->Viewport->Level();
|
|
||||||
|
|
||||||
SetInSkyBox(port);
|
SetInSkyBox(port);
|
||||||
if (port->mPartner > 0) SetInSkyBox(&Level->sectorPortals[port->mPartner]);
|
if (port->mPartner > 0) SetInSkyBox(&Level->sectorPortals[port->mPartner]);
|
||||||
Thread->Viewport->viewpoint.camera = nullptr;
|
Thread->Viewport->viewpoint.camera = nullptr;
|
||||||
|
@ -256,7 +255,7 @@ namespace swrenderer
|
||||||
Thread->Viewport->viewpoint.camera = savedcamera;
|
Thread->Viewport->viewpoint.camera = savedcamera;
|
||||||
Thread->Viewport->viewpoint.sector = savedsector;
|
Thread->Viewport->viewpoint.sector = savedsector;
|
||||||
Thread->Viewport->viewpoint.Pos = savedpos;
|
Thread->Viewport->viewpoint.Pos = savedpos;
|
||||||
Thread->Light->SetVisibility(Thread->Viewport.get(), savedvisibility);
|
Thread->Light->SetVisibility(Thread->Viewport.get(), savedvisibility, !!(Level->flags3 & LEVEL3_NOLIGHTFADE));
|
||||||
Thread->Viewport->viewpoint.extralight = savedextralight;
|
Thread->Viewport->viewpoint.extralight = savedextralight;
|
||||||
Thread->Viewport->viewpoint.Angles = savedangles;
|
Thread->Viewport->viewpoint.Angles = savedangles;
|
||||||
Thread->Viewport->viewpoint.SetViewAngle(Thread->Viewport->viewwindow);
|
Thread->Viewport->viewpoint.SetViewAngle(Thread->Viewport->viewwindow);
|
||||||
|
|
|
@ -102,7 +102,7 @@ namespace swrenderer
|
||||||
int height = SCREENHEIGHT;
|
int height = SCREENHEIGHT;
|
||||||
float trueratio;
|
float trueratio;
|
||||||
ActiveRatio(width, height, &trueratio);
|
ActiveRatio(width, height, &trueratio);
|
||||||
viewport->SetViewport(MainThread(), width, height, trueratio);
|
viewport->SetViewport(player->camera->Level, MainThread(), width, height, trueratio);
|
||||||
|
|
||||||
r_modelscene = r_models && Models.Size() > 0;
|
r_modelscene = r_models && Models.Size() > 0;
|
||||||
if (r_modelscene)
|
if (r_modelscene)
|
||||||
|
@ -379,7 +379,7 @@ namespace swrenderer
|
||||||
viewwindowx = x;
|
viewwindowx = x;
|
||||||
viewwindowy = y;
|
viewwindowy = y;
|
||||||
viewactive = true;
|
viewactive = true;
|
||||||
viewport->SetViewport(MainThread(), width, height, MainThread()->Viewport->viewwindow.WidescreenRatio);
|
viewport->SetViewport(actor->Level, MainThread(), width, height, MainThread()->Viewport->viewwindow.WidescreenRatio);
|
||||||
if (r_modelscene)
|
if (r_modelscene)
|
||||||
PolyTriangleDrawer::ResizeBuffers(viewport->RenderTarget);
|
PolyTriangleDrawer::ResizeBuffers(viewport->RenderTarget);
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ namespace swrenderer
|
||||||
return Mat4f::Frustum(-width, width, -height + offset, height + offset, near, far, Handedness::Right, ClipZRange::NegativePositiveW);
|
return Mat4f::Frustum(-width, width, -height + offset, height + offset, near, far, Handedness::Right, ClipZRange::NegativePositiveW);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderViewport::SetViewport(RenderThread *thread, int fullWidth, int fullHeight, float trueratio)
|
void RenderViewport::SetViewport(FLevelLocals *Level, RenderThread *thread, int fullWidth, int fullHeight, float trueratio)
|
||||||
{
|
{
|
||||||
int virtheight, virtwidth, virtwidth2, virtheight2;
|
int virtheight, virtwidth, virtwidth2, virtheight2;
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ namespace swrenderer
|
||||||
virtwidth = virtwidth * AspectMultiplier(viewwindow.WidescreenRatio) / 48;
|
virtwidth = virtwidth * AspectMultiplier(viewwindow.WidescreenRatio) / 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
double ypixelstretch = (Level()->info) ? Level()->info->pixelstretch : 1.2;
|
double ypixelstretch = (Level->info) ? Level->info->pixelstretch : 1.2;
|
||||||
|
|
||||||
BaseYaspectMul = 320.0 * virtheight2 / (r_Yaspect * virtwidth2);
|
BaseYaspectMul = 320.0 * virtheight2 / (r_Yaspect * virtwidth2);
|
||||||
YaspectMul = 320.0 * virtheight / (r_Yaspect * virtwidth) * ypixelstretch / 1.2;
|
YaspectMul = 320.0 * virtheight / (r_Yaspect * virtwidth) * ypixelstretch / 1.2;
|
||||||
|
@ -150,7 +150,7 @@ namespace swrenderer
|
||||||
InitTextureMapping();
|
InitTextureMapping();
|
||||||
|
|
||||||
// Reset r_*Visibility vars
|
// Reset r_*Visibility vars
|
||||||
thread->Light->SetVisibility(this, r_visibility);
|
thread->Light->SetVisibility(this, r_visibility, !!(Level->flags3 & LEVEL3_NOLIGHTFADE));
|
||||||
|
|
||||||
SetupBuffer();
|
SetupBuffer();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace swrenderer
|
||||||
RenderViewport();
|
RenderViewport();
|
||||||
~RenderViewport();
|
~RenderViewport();
|
||||||
|
|
||||||
void SetViewport(RenderThread *thread, int width, int height, float trueratio);
|
void SetViewport(FLevelLocals *Level, RenderThread *thread, int width, int height, float trueratio);
|
||||||
void SetupFreelook();
|
void SetupFreelook();
|
||||||
|
|
||||||
void SetupPolyViewport(RenderThread *thread);
|
void SetupPolyViewport(RenderThread *thread);
|
||||||
|
|
|
@ -2106,7 +2106,7 @@ public:
|
||||||
: FxExpression(EFX_Nop, p)
|
: FxExpression(EFX_Nop, p)
|
||||||
{
|
{
|
||||||
isresolved = true;
|
isresolved = true;
|
||||||
ValueType = TypeError;
|
ValueType = TypeVoid;
|
||||||
}
|
}
|
||||||
ExpEmit Emit(VMFunctionBuilder *build)
|
ExpEmit Emit(VMFunctionBuilder *build)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2797,9 +2797,6 @@ DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, isFrozen, isFrozen)
|
||||||
void setFrozen(FLevelLocals *self, int on)
|
void setFrozen(FLevelLocals *self, int on)
|
||||||
{
|
{
|
||||||
self->frozenstate = (self->frozenstate & ~1) | !!on;
|
self->frozenstate = (self->frozenstate & ~1) | !!on;
|
||||||
// For compatibility. The engine itself never checks this.
|
|
||||||
if (on) self->flags2 |= LEVEL2_FROZEN;
|
|
||||||
else self->flags2 &= ~LEVEL2_FROZEN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, setFrozen, setFrozen)
|
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, setFrozen, setFrozen)
|
||||||
|
@ -2889,6 +2886,9 @@ DEFINE_FIELD(FLevelLocals, outsidefogdensity)
|
||||||
DEFINE_FIELD(FLevelLocals, skyfog)
|
DEFINE_FIELD(FLevelLocals, skyfog)
|
||||||
DEFINE_FIELD(FLevelLocals, pixelstretch)
|
DEFINE_FIELD(FLevelLocals, pixelstretch)
|
||||||
DEFINE_FIELD(FLevelLocals, deathsequence)
|
DEFINE_FIELD(FLevelLocals, deathsequence)
|
||||||
|
DEFINE_FIELD_BIT(FLevelLocals, frozenstate, frozen, 1) // still needed for backwards compatibility.
|
||||||
|
DEFINE_FIELD_NAMED(FLevelLocals, i_compatflags, compatflags)
|
||||||
|
DEFINE_FIELD_NAMED(FLevelLocals, i_compatflags2, compatflags2)
|
||||||
|
|
||||||
DEFINE_FIELD_BIT(FLevelLocals, flags, noinventorybar, LEVEL_NOINVENTORYBAR)
|
DEFINE_FIELD_BIT(FLevelLocals, flags, noinventorybar, LEVEL_NOINVENTORYBAR)
|
||||||
DEFINE_FIELD_BIT(FLevelLocals, flags, monsterstelefrag, LEVEL_MONSTERSTELEFRAG)
|
DEFINE_FIELD_BIT(FLevelLocals, flags, monsterstelefrag, LEVEL_MONSTERSTELEFRAG)
|
||||||
|
@ -2901,7 +2901,6 @@ DEFINE_FIELD_BIT(FLevelLocals, flags2, checkswitchrange, LEVEL2_CHECKSWITCHRANGE
|
||||||
DEFINE_FIELD_BIT(FLevelLocals, flags2, polygrind, LEVEL2_POLYGRIND)
|
DEFINE_FIELD_BIT(FLevelLocals, flags2, polygrind, LEVEL2_POLYGRIND)
|
||||||
DEFINE_FIELD_BIT(FLevelLocals, flags2, allowrespawn, LEVEL2_ALLOWRESPAWN)
|
DEFINE_FIELD_BIT(FLevelLocals, flags2, allowrespawn, LEVEL2_ALLOWRESPAWN)
|
||||||
DEFINE_FIELD_BIT(FLevelLocals, flags2, nomonsters, LEVEL2_NOMONSTERS)
|
DEFINE_FIELD_BIT(FLevelLocals, flags2, nomonsters, LEVEL2_NOMONSTERS)
|
||||||
DEFINE_FIELD_BIT(FLevelLocals, flags2, frozen, LEVEL2_FROZEN)
|
|
||||||
DEFINE_FIELD_BIT(FLevelLocals, flags2, infinite_flight, LEVEL2_INFINITE_FLIGHT)
|
DEFINE_FIELD_BIT(FLevelLocals, flags2, infinite_flight, LEVEL2_INFINITE_FLIGHT)
|
||||||
DEFINE_FIELD_BIT(FLevelLocals, flags2, no_dlg_freeze, LEVEL2_CONV_SINGLE_UNFREEZE)
|
DEFINE_FIELD_BIT(FLevelLocals, flags2, no_dlg_freeze, LEVEL2_CONV_SINGLE_UNFREEZE)
|
||||||
DEFINE_FIELD_BIT(FLevelLocals, flags2, keepfullinventory, LEVEL2_KEEPFULLINVENTORY)
|
DEFINE_FIELD_BIT(FLevelLocals, flags2, keepfullinventory, LEVEL2_KEEPFULLINVENTORY)
|
||||||
|
|
|
@ -799,9 +799,9 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, ClearCounters, ClearCounters)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetModifiedDamage(AActor *self, int type, int damage, bool passive)
|
static int GetModifiedDamage(AActor *self, int type, int damage, bool passive, AActor *inflictor, AActor *source, int flags)
|
||||||
{
|
{
|
||||||
return self->GetModifiedDamage(ENamedName(type), damage, passive);
|
return self->GetModifiedDamage(ENamedName(type), damage, passive, inflictor, source, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetModifiedDamage, GetModifiedDamage)
|
DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetModifiedDamage, GetModifiedDamage)
|
||||||
|
@ -810,7 +810,10 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetModifiedDamage, GetModifiedDamage)
|
||||||
PARAM_NAME(type);
|
PARAM_NAME(type);
|
||||||
PARAM_INT(damage);
|
PARAM_INT(damage);
|
||||||
PARAM_BOOL(passive);
|
PARAM_BOOL(passive);
|
||||||
ACTION_RETURN_INT(self->GetModifiedDamage(type, damage, passive));
|
PARAM_OBJECT(inflictor, AActor);
|
||||||
|
PARAM_OBJECT(source, AActor);
|
||||||
|
PARAM_INT(flags);
|
||||||
|
ACTION_RETURN_INT(self->GetModifiedDamage(type, damage, passive, inflictor, source, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ApplyDamageFactor(AActor *self, int type, int damage)
|
static int ApplyDamageFactor(AActor *self, int type, int damage)
|
||||||
|
@ -1666,34 +1669,6 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, isFrozen, isFrozen)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//=====================================================================================
|
|
||||||
//
|
|
||||||
// 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// PlayerPawn functions
|
// PlayerPawn functions
|
||||||
|
|
|
@ -271,7 +271,7 @@ bool DInterBackground::LoadBackground(bool isenterpic)
|
||||||
texture.SetInvalid();
|
texture.SetInvalid();
|
||||||
|
|
||||||
level_info_t * li = FindLevelInfo(wbs->current);
|
level_info_t * li = FindLevelInfo(wbs->current);
|
||||||
if (li != nullptr) exitpic = li->EnterPic;
|
if (li != nullptr) exitpic = li->ExitPic;
|
||||||
lumpname = exitpic;
|
lumpname = exitpic;
|
||||||
|
|
||||||
if (isenterpic)
|
if (isenterpic)
|
||||||
|
|
|
@ -651,7 +651,7 @@ class Actor : Thinker native
|
||||||
native void SpawnTeleportFog(Vector3 pos, bool beforeTele, bool setTarget);
|
native void SpawnTeleportFog(Vector3 pos, bool beforeTele, bool setTarget);
|
||||||
native Actor RoughMonsterSearch(int distance, bool onlyseekable = false, bool frontonly = false);
|
native Actor RoughMonsterSearch(int distance, bool onlyseekable = false, bool frontonly = false);
|
||||||
native int ApplyDamageFactor(Name damagetype, int damage);
|
native int ApplyDamageFactor(Name damagetype, int damage);
|
||||||
native int GetModifiedDamage(Name damagetype, int damage, bool passive);
|
native int GetModifiedDamage(Name damagetype, int damage, bool passive, Actor inflictor = null, Actor source = null, int flags = 0);
|
||||||
native bool CheckBossDeath();
|
native bool CheckBossDeath();
|
||||||
|
|
||||||
void A_Light(int extralight) { if (player) player.extralight = clamp(extralight, -20, 20); }
|
void A_Light(int extralight) { if (player) player.extralight = clamp(extralight, -20, 20); }
|
||||||
|
|
|
@ -630,7 +630,7 @@ extend class Actor
|
||||||
Actor mo;
|
Actor mo;
|
||||||
double spawnz = 0;
|
double spawnz = 0;
|
||||||
|
|
||||||
if (!compat_notossdrops)
|
if (!(Level.compatflags & COMPATF_NOTOSSDROPS))
|
||||||
{
|
{
|
||||||
int style = sv_dropstyle;
|
int style = sv_dropstyle;
|
||||||
if (style == 0)
|
if (style == 0)
|
||||||
|
@ -651,7 +651,7 @@ extend class Actor
|
||||||
{
|
{
|
||||||
mo.bDropped = true;
|
mo.bDropped = true;
|
||||||
mo.bNoGravity = false; // [RH] Make sure it is affected by gravity
|
mo.bNoGravity = false; // [RH] Make sure it is affected by gravity
|
||||||
if (!compat_notossdrops)
|
if (!(Level.compatflags & COMPATF_NOTOSSDROPS))
|
||||||
{
|
{
|
||||||
mo.TossItem ();
|
mo.TossItem ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -691,6 +691,8 @@ struct LevelLocals native
|
||||||
native readonly int skyfog;
|
native readonly int skyfog;
|
||||||
native readonly float pixelstretch;
|
native readonly float pixelstretch;
|
||||||
native name deathsequence;
|
native name deathsequence;
|
||||||
|
native readonly int compatflags;
|
||||||
|
native readonly int compatflags2;
|
||||||
// level_info_t *info cannot be done yet.
|
// level_info_t *info cannot be done yet.
|
||||||
|
|
||||||
native String GetUDMFString(int type, int index, Name key);
|
native String GetUDMFString(int type, int index, Name key);
|
||||||
|
|
|
@ -1295,3 +1295,47 @@ enum EChangeLevelFlags
|
||||||
CHANGELEVEL_PRERAISEWEAPON = 64,
|
CHANGELEVEL_PRERAISEWEAPON = 64,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// [RH] Compatibility flags.
|
||||||
|
enum ECompatFlags
|
||||||
|
{
|
||||||
|
COMPATF_SHORTTEX = 1 << 0, // Use Doom's shortest texture around behavior?
|
||||||
|
COMPATF_STAIRINDEX = 1 << 1, // Don't fix loop index for stair building?
|
||||||
|
COMPATF_LIMITPAIN = 1 << 2, // Pain elemental is limited to 20 lost souls?
|
||||||
|
COMPATF_SILENTPICKUP = 1 << 3, // Pickups are only heard locally?
|
||||||
|
COMPATF_NO_PASSMOBJ = 1 << 4, // Pretend every actor is infinitely tall?
|
||||||
|
COMPATF_MAGICSILENCE = 1 << 5, // Limit actors to one sound at a time?
|
||||||
|
COMPATF_WALLRUN = 1 << 6, // Enable buggier wall clipping so players can wallrun?
|
||||||
|
COMPATF_NOTOSSDROPS = 1 << 7, // Spawn dropped items directly on the floor?
|
||||||
|
COMPATF_USEBLOCKING = 1 << 8, // Any special line can block a use line
|
||||||
|
COMPATF_NODOORLIGHT = 1 << 9, // Don't do the BOOM local door light effect
|
||||||
|
COMPATF_RAVENSCROLL = 1 << 10, // Raven's scrollers use their original carrying speed
|
||||||
|
COMPATF_SOUNDTARGET = 1 << 11, // Use sector based sound target code.
|
||||||
|
COMPATF_DEHHEALTH = 1 << 12, // Limit deh.MaxHealth to the health bonus (as in Doom2.exe)
|
||||||
|
COMPATF_TRACE = 1 << 13, // Trace ignores lines with the same sector on both sides
|
||||||
|
COMPATF_DROPOFF = 1 << 14, // Monsters cannot move when hanging over a dropoff
|
||||||
|
COMPATF_BOOMSCROLL = 1 << 15, // Scrolling sectors are additive like in Boom
|
||||||
|
COMPATF_INVISIBILITY = 1 << 16, // Monsters can see semi-invisible players
|
||||||
|
COMPATF_SILENT_INSTANT_FLOORS = 1<<17, // Instantly moving floors are not silent
|
||||||
|
COMPATF_SECTORSOUNDS = 1 << 18, // Sector sounds use original method for sound origin.
|
||||||
|
COMPATF_MISSILECLIP = 1 << 19, // Use original Doom heights for clipping against projectiles
|
||||||
|
COMPATF_CROSSDROPOFF = 1 << 20, // monsters can't be pushed over dropoffs
|
||||||
|
COMPATF_ANYBOSSDEATH = 1 << 21, // [GZ] Any monster which calls BOSSDEATH counts for level specials
|
||||||
|
COMPATF_MINOTAUR = 1 << 22, // Minotaur's floor flame is exploded immediately when feet are clipped
|
||||||
|
COMPATF_MUSHROOM = 1 << 23, // Force original velocity calculations for A_Mushroom in Dehacked mods.
|
||||||
|
COMPATF_MBFMONSTERMOVE = 1 << 24, // Monsters are affected by friction and pushers/pullers.
|
||||||
|
COMPATF_CORPSEGIBS = 1 << 25, // Crushed monsters are turned into gibs, rather than replaced by gibs.
|
||||||
|
COMPATF_NOBLOCKFRIENDS = 1 << 26, // Friendly monsters aren't blocked by monster-blocking lines.
|
||||||
|
COMPATF_SPRITESORT = 1 << 27, // Invert sprite sorting order for sprites of equal distance
|
||||||
|
COMPATF_HITSCAN = 1 << 28, // Hitscans use original blockmap anf hit check code.
|
||||||
|
COMPATF_LIGHT = 1 << 29, // Find neighboring light level like Doom
|
||||||
|
COMPATF_POLYOBJ = 1 << 30, // Draw polyobjects the old fashioned way
|
||||||
|
COMPATF_MASKEDMIDTEX = 1 << 31, // Ignore compositing when drawing masked midtextures
|
||||||
|
|
||||||
|
COMPATF2_BADANGLES = 1 << 0, // It is impossible to face directly NSEW.
|
||||||
|
COMPATF2_FLOORMOVE = 1 << 1, // Use the same floor motion behavior as Doom.
|
||||||
|
COMPATF2_SOUNDCUTOFF = 1 << 2, // Cut off sounds when an actor vanishes instead of making it owner-less
|
||||||
|
COMPATF2_POINTONLINE = 1 << 3, // Use original but buggy P_PointOnLineSide() and P_PointOnDivlineSideCompat()
|
||||||
|
COMPATF2_MULTIEXIT = 1 << 4, // Level exit can be triggered multiple times (required by Daedalus's travel tubes, thanks to a faulty script)
|
||||||
|
COMPATF2_TELEPORT = 1 << 5, // Don't let indirect teleports trigger sector actions
|
||||||
|
COMPATF2_PUSHWINDOW = 1 << 6, // Disable the window check in CheckForPushSpecial()
|
||||||
|
};
|
||||||
|
|
|
@ -105,8 +105,6 @@ extend class Actor
|
||||||
{
|
{
|
||||||
const FATSPREAD = 90./8;
|
const FATSPREAD = 90./8;
|
||||||
|
|
||||||
private native bool compat_mushroom();
|
|
||||||
|
|
||||||
void A_FatRaise()
|
void A_FatRaise()
|
||||||
{
|
{
|
||||||
A_FaceTarget();
|
A_FaceTarget();
|
||||||
|
@ -196,7 +194,7 @@ extend class Actor
|
||||||
aimtarget.Height = Height;
|
aimtarget.Height = Height;
|
||||||
|
|
||||||
bool shootmode = ((flags & MSF_Classic) || // Flag explicitly set, or no flags and compat options
|
bool shootmode = ((flags & MSF_Classic) || // Flag explicitly set, or no flags and compat options
|
||||||
(flags == 0 && CurState.bDehacked && compat_mushroom()));
|
(flags == 0 && CurState.bDehacked && (Level.compatflags & COMPATF_MUSHROOM)));
|
||||||
|
|
||||||
for (i = -numspawns; i <= numspawns; i += 8)
|
for (i = -numspawns; i <= numspawns; i += 8)
|
||||||
{
|
{
|
||||||
|
|
|
@ -62,8 +62,6 @@ class PainElemental : Actor
|
||||||
|
|
||||||
extend class Actor
|
extend class Actor
|
||||||
{
|
{
|
||||||
private native bool compat_limitpain();
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// A_PainShootSkull
|
// A_PainShootSkull
|
||||||
// Spawn a lost soul and launch it at the target
|
// Spawn a lost soul and launch it at the target
|
||||||
|
@ -88,7 +86,7 @@ extend class Actor
|
||||||
}
|
}
|
||||||
|
|
||||||
// [RH] make this optional
|
// [RH] make this optional
|
||||||
if (limit < 0 && compat_limitpain())
|
if (limit < 0 && (Level.compatflags & COMPATF_LIMITPAIN))
|
||||||
limit = 21;
|
limit = 21;
|
||||||
|
|
||||||
if (limit > 0)
|
if (limit > 0)
|
||||||
|
|
|
@ -1002,7 +1002,7 @@ class Inventory : Actor
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
virtual void ModifyDamage(int damage, Name damageType, out int newdamage, bool passive) {}
|
virtual void ModifyDamage(int damage, Name damageType, out int newdamage, bool passive, Actor inflictor = null, Actor source = null, int flags = 0) {}
|
||||||
|
|
||||||
|
|
||||||
virtual bool Use (bool pickup) { return false; }
|
virtual bool Use (bool pickup) { return false; }
|
||||||
|
|
|
@ -1655,7 +1655,7 @@ class PowerDamage : Powerup
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
override void ModifyDamage(int damage, Name damageType, out int newdamage, bool passive)
|
override void ModifyDamage(int damage, Name damageType, out int newdamage, bool passive, Actor inflictor, Actor source, int flags)
|
||||||
{
|
{
|
||||||
if (!passive && damage > 0)
|
if (!passive && damage > 0)
|
||||||
{
|
{
|
||||||
|
@ -1749,7 +1749,7 @@ class PowerProtection : Powerup
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
override void ModifyDamage(int damage, Name damageType, out int newdamage, bool passive)
|
override void ModifyDamage(int damage, Name damageType, out int newdamage, bool passive, Actor inflictor, Actor source, int flags)
|
||||||
{
|
{
|
||||||
if (passive && damage > 0)
|
if (passive && damage > 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -217,7 +217,7 @@ class StateProvider : Inventory
|
||||||
// Temporarily adjusts the pitch
|
// Temporarily adjusts the pitch
|
||||||
double saved_player_pitch = self.Pitch;
|
double saved_player_pitch = self.Pitch;
|
||||||
self.Pitch += pitch;
|
self.Pitch += pitch;
|
||||||
let misl = SpawnPlayerMissile (missiletype, shootangle, ofs.X, ofs.Y, spawnheight, t, NULL, false, (flags & FPF_NOAUTOAIM) != 0);
|
let misl = SpawnPlayerMissile (missiletype, shootangle, ofs.X, ofs.Y, spawnheight, t, false, (flags & FPF_NOAUTOAIM) != 0);
|
||||||
self.Pitch = saved_player_pitch;
|
self.Pitch = saved_player_pitch;
|
||||||
|
|
||||||
// automatic handling of seeker missiles
|
// automatic handling of seeker missiles
|
||||||
|
|
|
@ -373,6 +373,7 @@ class LevelCompatibility native play
|
||||||
SetWallTexture(1027, Line.back, Side.top, "SP_HOT1");
|
SetWallTexture(1027, Line.back, Side.top, "SP_HOT1");
|
||||||
// Replace tag for eastern secret at level start to not
|
// Replace tag for eastern secret at level start to not
|
||||||
// cause any action to the two-Baron trap
|
// cause any action to the two-Baron trap
|
||||||
|
ClearSectorTags(127);
|
||||||
AddSectorTag(127, 100);
|
AddSectorTag(127, 100);
|
||||||
SetLineSpecial(382, Door_Open, 100, 16);
|
SetLineSpecial(382, Door_Open, 100, 16);
|
||||||
SetLineSpecial(388, Door_Open, 100, 16);
|
SetLineSpecial(388, Door_Open, 100, 16);
|
||||||
|
@ -997,7 +998,7 @@ class LevelCompatibility native play
|
||||||
SetLineSectorRef(328, Line.front, 74);
|
SetLineSectorRef(328, Line.front, 74);
|
||||||
SetLineSectorRef(329, Line.front, 74);
|
SetLineSectorRef(329, Line.front, 74);
|
||||||
AddSectorTag(74, 4);
|
AddSectorTag(74, 4);
|
||||||
SetLineSpecial(357, Transfer_Heights, 6);
|
SetLineSpecial(357, Transfer_Heights, 4, 6);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1220,6 +1221,15 @@ class LevelCompatibility native play
|
||||||
// Fix the soulsphere in a secret area (sector 324)
|
// Fix the soulsphere in a secret area (sector 324)
|
||||||
// so that it doesn't end up in an unreachable position.
|
// so that it doesn't end up in an unreachable position.
|
||||||
SetThingXY(516, -934, 48);
|
SetThingXY(516, -934, 48);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case '11EA5B8357DEB70A8F00900117831191': // kdizd_12.pk3 z1m3
|
||||||
|
{
|
||||||
|
// Fix incorrectly tagged underwater sector which causes render glitches.
|
||||||
|
ClearSectorTags(7857);
|
||||||
|
AddSectorTag(7857, 82);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -347,7 +347,7 @@ class Minotaur : Actor
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Floorclip > 0 && compat_minotaur)
|
if (Floorclip > 0 && (Level.compatflags & COMPAT_MINOTAUR))
|
||||||
{
|
{
|
||||||
// only play the sound.
|
// only play the sound.
|
||||||
A_PlaySound ("minotaur/fx2hit", CHAN_WEAPON);
|
A_PlaySound ("minotaur/fx2hit", CHAN_WEAPON);
|
||||||
|
|
|
@ -1930,7 +1930,7 @@ class PlayerPawn : Actor
|
||||||
|
|
||||||
override int GetMaxHealth(bool withupgrades) const
|
override int GetMaxHealth(bool withupgrades) const
|
||||||
{
|
{
|
||||||
int ret = MaxHealth > 0? MaxHealth : (compat_dehhealth? 100 : deh.MaxHealth);
|
int ret = MaxHealth > 0? MaxHealth : ((Level.compatflags & COMPATF_DEHHEALTH)? 100 : deh.MaxHealth);
|
||||||
if (withupgrades) ret += stamina + BonusHealth;
|
if (withupgrades) ret += stamina + BonusHealth;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue