This commit is contained in:
Rachael Alexanderson 2018-02-10 07:08:57 -05:00
commit f2673747c2
11 changed files with 75 additions and 47 deletions

View file

@ -283,6 +283,7 @@ Note: All <bool> fields default to false unless mentioned otherwise.
For things with ACS specials (80-86 and 226), if arg0str is present and non-null, it
will be used as the name of the script to execute, and arg0 will be ignored.
On dynamic lights, arg0str can be used to set a color by name, this will supersede all args which are normally used to define a color.
}
@ -426,6 +427,9 @@ floor_reflect and ceiling_reflect.
1.28 28.01.2017
sector material colors.
1.29 04.02.2018
arg0str in dynamic lights.
===============================================================================
EOF
===============================================================================

View file

@ -648,7 +648,8 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill
// If this is co-op, respawn any dead players now so they can
// keep their inventory on the next map.
if ((multiplayer || level.flags2 & LEVEL2_ALLOWRESPAWN || sv_singleplayerrespawn) && !deathmatch && player->playerstate == PST_DEAD)
if ((multiplayer || level.flags2 & LEVEL2_ALLOWRESPAWN || sv_singleplayerrespawn || !!G_SkillProperty(SKILLP_PlayerRespawn))
&& !deathmatch && player->playerstate == PST_DEAD)
{
// Copied from the end of P_DeathThink [[
player->cls = NULL; // Force a new class if the player is using a random class

View file

@ -289,7 +289,7 @@ void GLWall::DrawDecal(DBaseDecal *decal)
// Note: This should be replaced with proper shader based lighting.
double x, y;
decal->GetXY(seg->sidedef, x, y);
gl_SetDynSpriteLight(NULL, x, y, zpos, sub);
gl_SetDynSpriteLight(nullptr, x, y, zpos - decalheight * 0.5f, sub);
}
// alpha color only has an effect when using an alpha texture.

View file

@ -842,7 +842,7 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, f
stereo3dMode.SetUp();
for (int eye_ix = 0; eye_ix < stereo3dMode.eye_count(); ++eye_ix)
{
if (eye_ix > 0)
if (eye_ix > 0 && camera->player)
SetFixedColormap(camera->player); // reiterate color map for each eye, so night vision goggles work in both eyes
const s3d::EyePose * eye = stereo3dMode.getEyePose(eye_ix);
eye->SetUp();

View file

@ -75,7 +75,7 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *
while (node)
{
light=node->lightsource;
if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->lightflags&LF_DONTLIGHTSELF) || light->target != self) && !(light->lightflags&LF_DONTLIGHTACTORS))
if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->lightflags&LF_DONTLIGHTSELF) || light->target != self || !self) && !(light->lightflags&LF_DONTLIGHTACTORS))
{
float dist;
FVector3 L;

View file

@ -835,12 +835,12 @@ inline int uallong(const int &foo)
//============================================================================
// ACS variables with world scope
int32_t ACS_WorldVars[NUM_WORLDVARS];
FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS];
static BoundsCheckingArray<int32_t, NUM_WORLDVARS> ACS_WorldVars;
static BoundsCheckingArray<FWorldGlobalArray, NUM_WORLDVARS> ACS_WorldArrays;
// ACS variables with global scope
int32_t ACS_GlobalVars[NUM_GLOBALVARS];
FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
BoundsCheckingArray<int32_t, NUM_GLOBALVARS> ACS_GlobalVars;
BoundsCheckingArray<FWorldGlobalArray, NUM_GLOBALVARS> ACS_GlobalArrays;
//----------------------------------------------------------------------------
//
@ -851,21 +851,7 @@ FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
//
//----------------------------------------------------------------------------
struct FACSStackMemory
{
int32_t& operator[](const size_t index)
{
if (index >= STACK_SIZE)
{
I_Error("Corrupted stack pointer in ACS VM");
}
return buffer[index];
}
private:
int32_t buffer[STACK_SIZE];
};
using FACSStackMemory = BoundsCheckingArray<int32_t, STACK_SIZE>;
struct FACSStack
{
@ -1470,10 +1456,10 @@ void ACSStringPool::UnlockForLevel(int lnum)
void P_MarkWorldVarStrings()
{
GlobalACSStrings.MarkStringArray(ACS_WorldVars, countof(ACS_WorldVars));
for (size_t i = 0; i < countof(ACS_WorldArrays); ++i)
GlobalACSStrings.MarkStringArray(ACS_WorldVars.Pointer(), ACS_WorldVars.Size());
for (size_t i = 0; i < ACS_WorldArrays.Size(); ++i)
{
GlobalACSStrings.MarkStringMap(ACS_WorldArrays[i]);
GlobalACSStrings.MarkStringMap(ACS_WorldArrays.Pointer()[i]);
}
}
@ -1485,10 +1471,10 @@ void P_MarkWorldVarStrings()
void P_MarkGlobalVarStrings()
{
GlobalACSStrings.MarkStringArray(ACS_GlobalVars, countof(ACS_GlobalVars));
for (size_t i = 0; i < countof(ACS_GlobalArrays); ++i)
GlobalACSStrings.MarkStringArray(ACS_GlobalVars.Pointer(), ACS_GlobalVars.Size());
for (size_t i = 0; i < ACS_GlobalArrays.Size(); ++i)
{
GlobalACSStrings.MarkStringMap(ACS_GlobalArrays[i]);
GlobalACSStrings.MarkStringMap(ACS_GlobalArrays.Pointer()[i]);
}
}
@ -1571,14 +1557,14 @@ void P_ClearACSVars(bool alsoglobal)
{
int i;
memset (ACS_WorldVars, 0, sizeof(ACS_WorldVars));
ACS_WorldVars.Fill(0);
for (i = 0; i < NUM_WORLDVARS; ++i)
{
ACS_WorldArrays[i].Clear ();
}
if (alsoglobal)
{
memset (ACS_GlobalVars, 0, sizeof(ACS_GlobalVars));
ACS_GlobalVars.Fill(0);
for (i = 0; i < NUM_GLOBALVARS; ++i)
{
ACS_GlobalArrays[i].Clear ();
@ -1726,10 +1712,10 @@ static void ReadArrayVars (FSerializer &file, FWorldGlobalArray *vars, size_t co
void P_ReadACSVars(FSerializer &arc)
{
ReadVars (arc, ACS_WorldVars, NUM_WORLDVARS, "acsworldvars");
ReadVars (arc, ACS_GlobalVars, NUM_GLOBALVARS, "acsglobalvars");
ReadArrayVars (arc, ACS_WorldArrays, NUM_WORLDVARS, "acsworldarrays");
ReadArrayVars (arc, ACS_GlobalArrays, NUM_GLOBALVARS, "acsglobalarrays");
ReadVars (arc, ACS_WorldVars.Pointer(), NUM_WORLDVARS, "acsworldvars");
ReadVars (arc, ACS_GlobalVars.Pointer(), NUM_GLOBALVARS, "acsglobalvars");
ReadArrayVars (arc, ACS_WorldArrays.Pointer(), NUM_WORLDVARS, "acsworldarrays");
ReadArrayVars (arc, ACS_GlobalArrays.Pointer(), NUM_GLOBALVARS, "acsglobalarrays");
GlobalACSStrings.ReadStrings(arc, "acsglobalstrings");
}
@ -1741,10 +1727,10 @@ void P_ReadACSVars(FSerializer &arc)
void P_WriteACSVars(FSerializer &arc)
{
WriteVars (arc, ACS_WorldVars, NUM_WORLDVARS, "acsworldvars");
WriteVars (arc, ACS_GlobalVars, NUM_GLOBALVARS, "acsglobalvars");
WriteArrayVars (arc, ACS_WorldArrays, NUM_WORLDVARS, "acsworldarrays");
WriteArrayVars (arc, ACS_GlobalArrays, NUM_GLOBALVARS, "acsglobalarrays");
WriteVars (arc, ACS_WorldVars.Pointer(), NUM_WORLDVARS, "acsworldvars");
WriteVars (arc, ACS_GlobalVars.Pointer(), NUM_GLOBALVARS, "acsglobalvars");
WriteArrayVars (arc, ACS_WorldArrays.Pointer(), NUM_WORLDVARS, "acsworldarrays");
WriteArrayVars (arc, ACS_GlobalArrays.Pointer(), NUM_GLOBALVARS, "acsglobalarrays");
GlobalACSStrings.WriteStrings(arc, "acsglobalstrings");
}

View file

@ -60,13 +60,32 @@ struct InitIntToZero
};
typedef TMap<int32_t, int32_t, THashTraits<int32_t>, InitIntToZero> FWorldGlobalArray;
// ACS variables with world scope
extern int32_t ACS_WorldVars[NUM_WORLDVARS];
extern FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS];
// Type of elements count is unsigned int instead of size_t to match ACSStringPool interface
template <typename T, unsigned int N>
struct BoundsCheckingArray
{
T &operator[](const unsigned int index)
{
if (index >= N)
{
I_Error("Out of bounds memory access in ACS VM");
}
return buffer[index];
}
T *Pointer() { return buffer; }
unsigned int Size() const { return N; }
void Fill(const T &value) { std::fill(std::begin(buffer), std::end(buffer), value); }
private:
T buffer[N];
};
// ACS variables with global scope
extern int32_t ACS_GlobalVars[NUM_GLOBALVARS];
extern FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
extern BoundsCheckingArray<int32_t, NUM_GLOBALVARS> ACS_GlobalVars;
extern BoundsCheckingArray<FWorldGlobalArray, NUM_GLOBALVARS> ACS_GlobalArrays;
#define LIBRARYID_MASK 0xFFF00000
#define LIBRARYID_SHIFT 20
@ -359,7 +378,7 @@ public:
ACSProfileInfo *GetFunctionProfileData(ScriptFunction *func) { return GetFunctionProfileData((int)(func - (ScriptFunction *)Functions)); }
const char *LookupString (uint32_t index) const;
int32_t *MapVars[NUM_MAPVARS];
BoundsCheckingArray<int32_t *, NUM_MAPVARS> MapVars;
static FBehavior *StaticLoadModule (int lumpnum, FileReader * fr=NULL, int len=0);
static void StaticLoadDefaultModules ();

View file

@ -6101,6 +6101,9 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
if (mthing->arg0str != NAME_None)
{
PalEntry color = V_GetColor(nullptr, mthing->arg0str);
light->args[0] = color.r;
light->args[1] = color.g;
light->args[2] = color.b;
}
else if (light->lightflags & LF_SPOT)
{

View file

@ -376,6 +376,14 @@ F481922F4881F74760F3C0437FD5EDD0 // map03
setlinespecial 1008 Door_Open 0 64 0 0 0
}
7ED9800213C00D6E7FB98652AB48B3DE // Ultimate Simplicity, map04
{
// Add missing map spots on easy and medium skills
// Demons will teleport into starting room making 100% kills possible
setthingskills 31 31
setthingskills 32 31
}
1891E029994B023910CFE0B3209C3CDB // Ultimate Simplicity, map07
{
// It is possible to get stuck on skill 0 or 1 when no shots have been fired
@ -386,6 +394,13 @@ F481922F4881F74760F3C0437FD5EDD0 // map03
setlinespecial 411 NoiseAlert 0 0 0 0 0
}
F0E6F30F57B0425F17E43600AA813E80 // Ultimate Simplicity, map11
{
// If door (sector #309) is closed it cannot be open again
// from one side potentially blocking level progression
clearlinespecial 2445
}
952CC8D03572E17BA550B01B366EFBB9 // Cheogsh map01
{
// make the blue key spawn above the 3D floor

View file

@ -118,7 +118,7 @@ DoomEdNums
9851 = SpotLightPulseAdditive
9852 = SpotLightFlickerAdditive
9853 = SectorSpotLightAdditive
9854 = SpotLightFlickerRandomSubtractive
9854 = SpotLightFlickerRandomAdditive
9860 = SpotLightSubtractive
9861 = SpotLightPulseSubtractive
9862 = SpotLightFlickerSubtractive

View file

@ -528,7 +528,7 @@ class PlayerPawn : Actor native
if (level.time >= player.respawn_time || ((player.cmd.buttons & BT_USE) && player.Bot == NULL))
{
player.cls = NULL; // Force a new class if the player is using a random class
player.playerstate = (multiplayer || (level.AllowRespawn) || sv_singleplayerrespawn)? PST_REBORN : PST_ENTER;
player.playerstate = (multiplayer || level.AllowRespawn || sv_singleplayerrespawn || G_SkillPropertyInt(SKILLP_PlayerRespawn)) ? PST_REBORN : PST_ENTER;
if (special1 > 2)
{
special1 = 0;