From 724e625f16d3a5fb3b5fb0d0105370c79da5da8e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Jan 2016 09:20:27 +0100 Subject: [PATCH 01/14] - fixed: Loading an old savegame from before the sector damage refactoring cleared the extended Boom sector flags before processing them. --- src/p_saveg.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 7623104d7..31eb76c7a 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -425,7 +425,6 @@ void P_SerializeWorld (FArchive &arc) short secretsector; arc << secretsector; if (secretsector) sec->Flags |= SECF_WASSECRET; - sec->special &= ~(SECRET_MASK|FRICTION_MASK|PUSH_MASK); P_InitSectorSpecial(sec, sec->special, true); } arc << sec->interpolations[0] From dfcee625db09c9a03d630a36e8c9d04d2104afb3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Jan 2016 11:56:47 +0100 Subject: [PATCH 02/14] - fixed: The ACS String garbage collector only looked at the active script's stack but never considered a recursive call from another script. Fixing this required adding an external list of active stack objects that the garbage collector can access. A nice side effect: It's no longer necessary to pass around the stack info to various functions that might end up triggering a garbage collection. --- src/p_acs.cpp | 150 +++++++++++++++++++++++++++++++++----------------- src/p_acs.h | 12 ++-- 2 files changed, 105 insertions(+), 57 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 3aab261f4..da76408ed 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -217,6 +217,52 @@ FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS]; SDWORD ACS_GlobalVars[NUM_GLOBALVARS]; FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS]; +//---------------------------------------------------------------------------- +// +// ACS stack management +// +// This is needed so that the garbage collector has access to all active +// script stacks +// +//---------------------------------------------------------------------------- + +struct FACSStack +{ + SDWORD buffer[STACK_SIZE]; + int sp; + FACSStack *next; + FACSStack *prev; + static FACSStack *head; + + FACSStack(); + ~FACSStack(); +}; + +FACSStack *FACSStack::head; + +FACSStack::FACSStack() +{ + sp = 0; + next = head; + prev = NULL; + head = this; + + Printf("Adding stack %08d\n", this); +} + +FACSStack::~FACSStack() +{ + if (next != NULL) next->prev = prev; + if (prev == NULL) + { + head = next; + } + else + { + prev->next = next; + } + Printf("Removing stack %08d\n", this); +} //---------------------------------------------------------------------------- // @@ -290,7 +336,7 @@ void ACSStringPool::Clear() // //============================================================================ -int ACSStringPool::AddString(const char *str, const SDWORD *stack, int stackdepth) +int ACSStringPool::AddString(const char *str) { size_t len = strlen(str); unsigned int h = SuperFastHash(str, len); @@ -301,10 +347,10 @@ int ACSStringPool::AddString(const char *str, const SDWORD *stack, int stackdept return i | STRPOOL_LIBRARYID_OR; } FString fstr(str); - return InsertString(fstr, h, bucketnum, stack, stackdepth); + return InsertString(fstr, h, bucketnum); } -int ACSStringPool::AddString(FString &str, const SDWORD *stack, int stackdepth) +int ACSStringPool::AddString(FString &str) { unsigned int h = SuperFastHash(str.GetChars(), str.Len()); unsigned int bucketnum = h % NUM_BUCKETS; @@ -313,7 +359,7 @@ int ACSStringPool::AddString(FString &str, const SDWORD *stack, int stackdepth) { return i | STRPOOL_LIBRARYID_OR; } - return InsertString(str, h, bucketnum, stack, stackdepth); + return InsertString(str, h, bucketnum); } //============================================================================ @@ -583,12 +629,12 @@ int ACSStringPool::FindString(const char *str, size_t len, unsigned int h, unsig // //============================================================================ -int ACSStringPool::InsertString(FString &str, unsigned int h, unsigned int bucketnum, const SDWORD *stack, int stackdepth) +int ACSStringPool::InsertString(FString &str, unsigned int h, unsigned int bucketnum) { unsigned int index = FirstFreeEntry; if (index >= MIN_GC_SIZE && index == Pool.Max()) { // We will need to grow the array. Try a garbage collection first. - P_CollectACSGlobalStrings(stack, stackdepth); + P_CollectACSGlobalStrings(); index = FirstFreeEntry; } if (FirstFreeEntry >= STRPOOL_LIBRARYID_OR) @@ -772,11 +818,11 @@ void P_MarkGlobalVarStrings() // //============================================================================ -void P_CollectACSGlobalStrings(const SDWORD *stack, int stackdepth) +void P_CollectACSGlobalStrings() { - if (stack != NULL && stackdepth != 0) + for (FACSStack *stack = FACSStack::head; stack != NULL; stack = stack->next) { - GlobalACSStrings.MarkStringArray(stack, stackdepth); + GlobalACSStrings.MarkStringArray(stack->buffer, stack->sp); } FBehavior::StaticMarkLevelVarStrings(); P_MarkWorldVarStrings(); @@ -787,7 +833,7 @@ void P_CollectACSGlobalStrings(const SDWORD *stack, int stackdepth) #ifdef _DEBUG CCMD(acsgc) { - P_CollectACSGlobalStrings(NULL, 0); + P_CollectACSGlobalStrings(); } CCMD(globstr) { @@ -1995,7 +2041,7 @@ bool FBehavior::Init(int lumpnum, FileReader * fr, int len) const char *str = LookupString(MapVarStore[LittleLong(chunk[i+2])]); if (str != NULL) { - MapVarStore[LittleLong(chunk[i+2])] = GlobalACSStrings.AddString(str, NULL, 0); + MapVarStore[LittleLong(chunk[i+2])] = GlobalACSStrings.AddString(str); } } } @@ -2015,7 +2061,7 @@ bool FBehavior::Init(int lumpnum, FileReader * fr, int len) const char *str = LookupString(*elems); if (str != NULL) { - *elems = GlobalACSStrings.AddString(str, NULL, 0); + *elems = GlobalACSStrings.AddString(str); } } } @@ -2049,7 +2095,7 @@ bool FBehavior::Init(int lumpnum, FileReader * fr, int len) const char *str = LookupString(*elems); if (str != NULL) { - *elems = GlobalACSStrings.AddString(str, NULL, 0); + *elems = GlobalACSStrings.AddString(str); } } } @@ -3949,7 +3995,7 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) } } -int DLevelScript::GetActorProperty (int tid, int property, const SDWORD *stack, int stackdepth) +int DLevelScript::GetActorProperty (int tid, int property) { AActor *actor = SingleActorFromTID (tid, activator); @@ -4034,13 +4080,13 @@ int DLevelScript::GetActorProperty (int tid, int property, const SDWORD *stack, return 0; } - case APROP_SeeSound: return GlobalACSStrings.AddString(actor->SeeSound, stack, stackdepth); - case APROP_AttackSound: return GlobalACSStrings.AddString(actor->AttackSound, stack, stackdepth); - case APROP_PainSound: return GlobalACSStrings.AddString(actor->PainSound, stack, stackdepth); - case APROP_DeathSound: return GlobalACSStrings.AddString(actor->DeathSound, stack, stackdepth); - case APROP_ActiveSound: return GlobalACSStrings.AddString(actor->ActiveSound, stack, stackdepth); - case APROP_Species: return GlobalACSStrings.AddString(actor->GetSpecies(), stack, stackdepth); - case APROP_NameTag: return GlobalACSStrings.AddString(actor->GetTag(), stack, stackdepth); + case APROP_SeeSound: return GlobalACSStrings.AddString(actor->SeeSound); + case APROP_AttackSound: return GlobalACSStrings.AddString(actor->AttackSound); + case APROP_PainSound: return GlobalACSStrings.AddString(actor->PainSound); + case APROP_DeathSound: return GlobalACSStrings.AddString(actor->DeathSound); + case APROP_ActiveSound: return GlobalACSStrings.AddString(actor->ActiveSound); + case APROP_Species: return GlobalACSStrings.AddString(actor->GetSpecies()); + case APROP_NameTag: return GlobalACSStrings.AddString(actor->GetTag()); case APROP_StencilColor:return actor->fillcolor; case APROP_Friction: return actor->Friction; @@ -4090,7 +4136,7 @@ int DLevelScript::CheckActorProperty (int tid, int property, int value) case APROP_ViewHeight: case APROP_AttackZOffset: case APROP_StencilColor: - return (GetActorProperty(tid, property, NULL, 0) == value); + return (GetActorProperty(tid, property) == value); // Boolean values need to compare to a binary version of value case APROP_Ambush: @@ -4102,7 +4148,7 @@ int DLevelScript::CheckActorProperty (int tid, int property, int value) case APROP_Notarget: case APROP_Notrigger: case APROP_Dormant: - return (GetActorProperty(tid, property, NULL, 0) == (!!value)); + return (GetActorProperty(tid, property) == (!!value)); // Strings are covered by GetActorProperty, but they're fairly // heavy-duty, so make the check here. @@ -4614,14 +4660,14 @@ static void DoSetCVar(FBaseCVar *cvar, int value, bool is_string, bool force=fal } // Converts floating- to fixed-point as required. -static int DoGetCVar(FBaseCVar *cvar, bool is_string, const SDWORD *stack, int stackdepth) +static int DoGetCVar(FBaseCVar *cvar, bool is_string) { UCVarValue val; if (is_string) { val = cvar->GetGenericRep(CVAR_String); - return GlobalACSStrings.AddString(val.String, stack, stackdepth); + return GlobalACSStrings.AddString(val.String); } else if (cvar->GetRealType() == CVAR_Float) { @@ -4635,7 +4681,7 @@ static int DoGetCVar(FBaseCVar *cvar, bool is_string, const SDWORD *stack, int s } } -static int GetUserCVar(int playernum, const char *cvarname, bool is_string, const SDWORD *stack, int stackdepth) +static int GetUserCVar(int playernum, const char *cvarname, bool is_string) { if ((unsigned)playernum >= MAXPLAYERS || !playeringame[playernum]) { @@ -4647,10 +4693,10 @@ static int GetUserCVar(int playernum, const char *cvarname, bool is_string, cons { return 0; } - return DoGetCVar(cvar, is_string, stack, stackdepth); + return DoGetCVar(cvar, is_string); } -static int GetCVar(AActor *activator, const char *cvarname, bool is_string, const SDWORD *stack, int stackdepth) +static int GetCVar(AActor *activator, const char *cvarname, bool is_string) { FBaseCVar *cvar = FindCVar(cvarname, NULL); // Either the cvar doesn't exist, or it's for a mod that isn't loaded, so return 0. @@ -4667,9 +4713,9 @@ static int GetCVar(AActor *activator, const char *cvarname, bool is_string, cons { return 0; } - return GetUserCVar(int(activator->player - players), cvarname, is_string, stack, stackdepth); + return GetUserCVar(int(activator->player - players), cvarname, is_string); } - return DoGetCVar(cvar, is_string, stack, stackdepth); + return DoGetCVar(cvar, is_string); } } @@ -4860,7 +4906,7 @@ static int SwapActorTeleFog(AActor *activator, int tid) -int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const SDWORD *stack, int stackdepth) +int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) { AActor *actor; switch(funcIndex) @@ -5031,7 +5077,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const switch(args[0]) { case ARMORINFO_CLASSNAME: - return GlobalACSStrings.AddString(equippedarmor->ArmorType.GetChars(), stack, stackdepth); + return GlobalACSStrings.AddString(equippedarmor->ArmorType.GetChars()); case ARMORINFO_SAVEAMOUNT: return equippedarmor->MaxAmount; @@ -5052,7 +5098,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const return 0; } } - return args[0] == ARMORINFO_CLASSNAME ? GlobalACSStrings.AddString("None", stack, stackdepth) : 0; + return args[0] == ARMORINFO_CLASSNAME ? GlobalACSStrings.AddString("None") : 0; } case ACSF_SpawnSpotForced: @@ -5171,7 +5217,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const case ACSF_GetActorClass: { AActor *a = SingleActorFromTID(args[0], activator); - return GlobalACSStrings.AddString(a == NULL ? "None" : a->GetClass()->TypeName.GetChars(), stack, stackdepth); + return GlobalACSStrings.AddString(a == NULL ? "None" : a->GetClass()->TypeName.GetChars()); } case ACSF_SoundSequenceOnActor: @@ -5349,7 +5395,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const case ACSF_GetCVarString: if (argCount == 1) { - return GetCVar(activator, FBehavior::StaticLookupString(args[0]), true, stack, stackdepth); + return GetCVar(activator, FBehavior::StaticLookupString(args[0]), true); } break; @@ -5370,14 +5416,14 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const case ACSF_GetUserCVar: if (argCount == 2) { - return GetUserCVar(args[0], FBehavior::StaticLookupString(args[1]), false, stack, stackdepth); + return GetUserCVar(args[0], FBehavior::StaticLookupString(args[1]), false); } break; case ACSF_GetUserCVarString: if (argCount == 2) { - return GetUserCVar(args[0], FBehavior::StaticLookupString(args[1]), true, stack, stackdepth); + return GetUserCVar(args[0], FBehavior::StaticLookupString(args[1]), true); } break; @@ -5564,7 +5610,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) const char *oldstr = FBehavior::StaticLookupString(args[0]); if (oldstr == NULL || *oldstr == '\0') { - return GlobalACSStrings.AddString("", stack, stackdepth); + return GlobalACSStrings.AddString(""); } size_t oldlen = strlen(oldstr); size_t newlen = args[1]; @@ -5574,7 +5620,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) newlen = oldlen; } FString newstr(funcIndex == ACSF_StrLeft ? oldstr : oldstr + oldlen - newlen, newlen); - return GlobalACSStrings.AddString(newstr, stack, stackdepth); + return GlobalACSStrings.AddString(newstr); } break; @@ -5584,7 +5630,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) const char *oldstr = FBehavior::StaticLookupString(args[0]); if (oldstr == NULL || *oldstr == '\0') { - return GlobalACSStrings.AddString("", stack, stackdepth); + return GlobalACSStrings.AddString(""); } size_t oldlen = strlen(oldstr); size_t pos = args[1]; @@ -5592,13 +5638,13 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) if (pos >= oldlen) { - return GlobalACSStrings.AddString("", stack, stackdepth); + return GlobalACSStrings.AddString(""); } if (pos + newlen > oldlen || pos + newlen < pos) { newlen = oldlen - pos; } - return GlobalACSStrings.AddString(FString(oldstr + pos, newlen), stack, stackdepth); + return GlobalACSStrings.AddString(FString(oldstr + pos, newlen)); } break; @@ -5606,11 +5652,11 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) if (activator == NULL || activator->player == NULL || // Non-players do not have weapons activator->player->ReadyWeapon == NULL) { - return GlobalACSStrings.AddString("None", stack, stackdepth); + return GlobalACSStrings.AddString("None"); } else { - return GlobalACSStrings.AddString(activator->player->ReadyWeapon->GetClass()->TypeName.GetChars(), stack, stackdepth); + return GlobalACSStrings.AddString(activator->player->ReadyWeapon->GetClass()->TypeName.GetChars()); } case ACSF_SpawnDecal: @@ -6157,8 +6203,10 @@ int DLevelScript::RunScript () break; } - SDWORD Stack[STACK_SIZE]; - int sp = 0; + FACSStack stackobj; + SDWORD *Stack = stackobj.buffer; + int &sp = stackobj.sp; + int *pc = this->pc; ACSFormat fmt = activeBehavior->GetFormat(); FBehavior* const savedActiveBehavior = activeBehavior; @@ -6211,7 +6259,7 @@ int DLevelScript::RunScript () case PCD_TAGSTRING: //Stack[sp-1] |= activeBehavior->GetLibraryID(); - Stack[sp-1] = GlobalACSStrings.AddString(activeBehavior->LookupString(Stack[sp-1]), Stack, sp); + Stack[sp-1] = GlobalACSStrings.AddString(activeBehavior->LookupString(Stack[sp-1])); break; case PCD_PUSHNUMBER: @@ -6409,7 +6457,7 @@ int DLevelScript::RunScript () int argCount = NEXTBYTE; int funcIndex = NEXTSHORT; - int retval = CallFunction(argCount, funcIndex, &STACK(argCount), Stack, sp); + int retval = CallFunction(argCount, funcIndex, &STACK(argCount)); sp -= argCount-1; STACK(1) = retval; } @@ -8933,7 +8981,7 @@ scriptwait: break; case PCD_GETACTORPROPERTY: - STACK(2) = GetActorProperty (STACK(2), STACK(1), Stack, sp); + STACK(2) = GetActorProperty (STACK(2), STACK(1)); sp -= 1; break; @@ -9030,7 +9078,7 @@ scriptwait: break; case PCD_GETCVAR: - STACK(1) = GetCVar(activator, FBehavior::StaticLookupString(STACK(1)), false, Stack, sp); + STACK(1) = GetCVar(activator, FBehavior::StaticLookupString(STACK(1)), false); break; case PCD_SETHUDSIZE: @@ -9384,7 +9432,7 @@ scriptwait: case PCD_SAVESTRING: // Saves the string { - const int str = GlobalACSStrings.AddString(work, Stack, sp); + const int str = GlobalACSStrings.AddString(work); PushToStack(str); STRINGBUILDER_FINISH(work); } diff --git a/src/p_acs.h b/src/p_acs.h index 3188e46aa..858364e2f 100644 --- a/src/p_acs.h +++ b/src/p_acs.h @@ -80,8 +80,8 @@ class ACSStringPool { public: ACSStringPool(); - int AddString(const char *str, const SDWORD *stack, int stackdepth); - int AddString(FString &str, const SDWORD *stack, int stackdepth); + int AddString(const char *str); + int AddString(FString &str); const char *GetString(int strnum); void LockString(int strnum); void UnlockString(int strnum); @@ -99,7 +99,7 @@ public: private: int FindString(const char *str, size_t len, unsigned int h, unsigned int bucketnum); - int InsertString(FString &str, unsigned int h, unsigned int bucketnum, const SDWORD *stack, int stackdepth); + int InsertString(FString &str, unsigned int h, unsigned int bucketnum); void FindFirstFreeEntry(unsigned int base); enum { NUM_BUCKETS = 251 }; @@ -119,7 +119,7 @@ private: }; extern ACSStringPool GlobalACSStrings; -void P_CollectACSGlobalStrings(const SDWORD *stack, int stackdepth); +void P_CollectACSGlobalStrings(); void P_ReadACSVars(PNGHandle *); void P_WriteACSVars(FILE*); void P_ClearACSVars(bool); @@ -910,7 +910,7 @@ protected: int DoSpawnSpot (int type, int spot, int tid, int angle, bool forced); int DoSpawnSpotFacing (int type, int spot, int tid, bool forced); int DoClassifyActor (int tid); - int CallFunction(int argCount, int funcIndex, SDWORD *args, const SDWORD *stack, int stackdepth); + int CallFunction(int argCount, int funcIndex, SDWORD *args); void DoFadeTo (int r, int g, int b, int a, fixed_t time); void DoFadeRange (int r1, int g1, int b1, int a1, @@ -918,7 +918,7 @@ protected: void DoSetFont (int fontnum); void SetActorProperty (int tid, int property, int value); void DoSetActorProperty (AActor *actor, int property, int value); - int GetActorProperty (int tid, int property, const SDWORD *stack, int stackdepth); + int GetActorProperty (int tid, int property); int CheckActorProperty (int tid, int property, int value); int GetPlayerInput (int playernum, int inputnum); From 6715a97d6e344de563441e23bbf0e424cd3ba25a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Jan 2016 12:04:47 +0100 Subject: [PATCH 03/14] - removed debug output from previous commit. --- src/p_acs.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index da76408ed..9737f8aa9 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -219,7 +219,7 @@ FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS]; //---------------------------------------------------------------------------- // -// ACS stack management +// ACS stack manager // // This is needed so that the garbage collector has access to all active // script stacks @@ -246,8 +246,6 @@ FACSStack::FACSStack() next = head; prev = NULL; head = this; - - Printf("Adding stack %08d\n", this); } FACSStack::~FACSStack() @@ -261,7 +259,6 @@ FACSStack::~FACSStack() { prev->next = next; } - Printf("Removing stack %08d\n", this); } //---------------------------------------------------------------------------- From 772f086a5efe9037c284ee171a132304471a5008 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Thu, 28 Jan 2016 12:24:40 -0600 Subject: [PATCH 04/14] Fixed broken aiming with A_CheckLOF. --- src/thingdef/thingdef_codeptr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 1764717f5..85f0c4675 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -3448,11 +3448,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF) } else if (flags & CLOFF_AIM_VERT_NOOFFSET) { - pitch += R_PointToAngle2 (0,0, xydist, target->Z() - pos.z + offsetheight + target->height / 2); + pitch -= R_PointToAngle2 (0,0, xydist, target->Z() - pos.z + offsetheight + target->height / 2); } else { - pitch += R_PointToAngle2 (0,0, xydist, target->Z() - pos.z + target->height / 2); + pitch -= R_PointToAngle2 (0,0, xydist, target->Z() - pos.z + target->height / 2); } } else if (flags & CLOFF_ALLOWNULL) From c5161ee7480fc4f35549873dd6e5b1750577d860 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Jan 2016 20:44:10 +0100 Subject: [PATCH 05/14] - fixed: A_Face* mixed angle and distance values in the same parameter. Fixed by separating these into two. - removed the intermediate A_Face* functions, except a bare-bones A_FaceTarget as needed by the monster AI code. --- src/p_enemy.cpp | 37 +++++++++++++++---------------------- src/p_enemy.h | 4 ++-- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 0fd23f73e..fa2804593 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -2724,9 +2724,9 @@ enum FAF_Flags FAF_BOTTOM = 1, FAF_MIDDLE = 2, FAF_TOP = 4, - FAF_NODISTFACTOR = 8, + FAF_NODISTFACTOR = 8, // deprecated }; -void A_Face (AActor *self, AActor *other, angle_t max_turn, angle_t max_pitch, angle_t ang_offset, angle_t pitch_offset, int flags) +void A_Face (AActor *self, AActor *other, angle_t max_turn, angle_t max_pitch, angle_t ang_offset, angle_t pitch_offset, int flags, fixed_t z_add) { if (!other) return; @@ -2799,8 +2799,8 @@ void A_Face (AActor *self, AActor *other, angle_t max_turn, angle_t max_pitch, a target_z = other->Z() + (other->height / 2) + other->GetBobOffset(); if (flags & FAF_TOP) target_z = other->Z() + (other->height) + other->GetBobOffset(); - if (!(flags & FAF_NODISTFACTOR)) - target_z += pitch_offset; + + target_z += z_add; double dist_z = target_z - source_z; double ddist = sqrt(dist.X*dist.X + dist.Y*dist.Y + dist_z*dist_z); @@ -2836,55 +2836,48 @@ void A_Face (AActor *self, AActor *other, angle_t max_turn, angle_t max_pitch, a } } -void A_FaceTarget(AActor *self, angle_t max_turn, angle_t max_pitch, angle_t ang_offset, angle_t pitch_offset, int flags) +void A_FaceTarget(AActor *self) { - A_Face(self, self->target, max_turn, max_pitch, ang_offset, pitch_offset, flags); -} - -void A_FaceMaster(AActor *self, angle_t max_turn, angle_t max_pitch, angle_t ang_offset, angle_t pitch_offset, int flags) -{ - A_Face(self, self->master, max_turn, max_pitch, ang_offset, pitch_offset, flags); -} - -void A_FaceTracer(AActor *self, angle_t max_turn, angle_t max_pitch, angle_t ang_offset, angle_t pitch_offset, int flags) -{ - A_Face(self, self->tracer, max_turn, max_pitch, ang_offset, pitch_offset, flags); + A_Face(self, self->target); } DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceTarget) { - ACTION_PARAM_START(5); + ACTION_PARAM_START(6); ACTION_PARAM_ANGLE(max_turn, 0); ACTION_PARAM_ANGLE(max_pitch, 1); ACTION_PARAM_ANGLE(ang_offset, 2); ACTION_PARAM_ANGLE(pitch_offset, 3); ACTION_PARAM_INT(flags, 4); + ACTION_PARAM_FIXED(z_add, 5); - A_FaceTarget(self, max_turn, max_pitch, ang_offset, pitch_offset, flags); + A_Face(self, self->target, max_turn, max_pitch, ang_offset, pitch_offset, flags, z_add); } DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMaster) { - ACTION_PARAM_START(5); + ACTION_PARAM_START(6); ACTION_PARAM_ANGLE(max_turn, 0); ACTION_PARAM_ANGLE(max_pitch, 1); ACTION_PARAM_ANGLE(ang_offset, 2); ACTION_PARAM_ANGLE(pitch_offset, 3); ACTION_PARAM_INT(flags, 4); + ACTION_PARAM_FIXED(z_add, 5); - A_FaceMaster(self, max_turn, max_pitch, ang_offset, pitch_offset, flags); + A_Face(self, self->master, max_turn, max_pitch, ang_offset, pitch_offset, flags, z_add); } DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceTracer) { - ACTION_PARAM_START(5); + ACTION_PARAM_START(6); ACTION_PARAM_ANGLE(max_turn, 0); ACTION_PARAM_ANGLE(max_pitch, 1); ACTION_PARAM_ANGLE(ang_offset, 2); ACTION_PARAM_ANGLE(pitch_offset, 3); ACTION_PARAM_INT(flags, 4); + ACTION_PARAM_FIXED(z_add, 5); - A_FaceTracer(self, max_turn, max_pitch, ang_offset, pitch_offset, flags); + A_Face(self, self->tracer, max_turn, max_pitch, ang_offset, pitch_offset, flags, z_add); } //=========================================================================== diff --git a/src/p_enemy.h b/src/p_enemy.h index 799b4c0ff..9ee77caed 100644 --- a/src/p_enemy.h +++ b/src/p_enemy.h @@ -72,8 +72,8 @@ DECLARE_ACTION(A_FreezeDeathChunks) DECLARE_ACTION(A_BossDeath) void A_Chase(AActor *self); -void A_FaceTarget(AActor *actor, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270, angle_t ang_offset = 0, angle_t pitch_offset = 0, int flags = 0); -void A_Face(AActor *self, AActor *other, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270, angle_t ang_offset = 0, angle_t pitch_offset = 0, int flags = 0); +void A_FaceTarget(AActor *actor); +void A_Face(AActor *self, AActor *other, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270, angle_t ang_offset = 0, angle_t pitch_offset = 0, int flags = 0, fixed_t pitch_add = 0); bool A_RaiseMobj (AActor *, fixed_t speed); bool A_SinkMobj (AActor *, fixed_t speed); From 058bfdea264ccd5744b01f173c04fa6ae498ff24 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Jan 2016 00:58:18 +0100 Subject: [PATCH 06/14] - forgot to commit this with the source changes for A_Face*. --- wadsrc/static/actors/actor.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index fab9ebd9f..08e376e61 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -82,9 +82,9 @@ ACTOR Actor native //: Thinker action native A_XScream(); action native A_Look(); action native A_Chase(state melee = "*", state missile = "none", int flags = 0); - action native A_FaceTarget(float max_turn = 0, float max_pitch = 270, float ang_offset = 0, float pitch_offset = 0, int flags = 0); - action native A_FaceTracer(float max_turn = 0, float max_pitch = 270, float ang_offset = 0, float pitch_offset = 0, int flags = 0); - action native A_FaceMaster(float max_turn = 0, float max_pitch = 270, float ang_offset = 0, float pitch_offset = 0, int flags = 0); + action native A_FaceTarget(float max_turn = 0, float max_pitch = 270, float ang_offset = 0, float pitch_offset = 0, int flags = 0, float z_ofs = 0); + action native A_FaceTracer(float max_turn = 0, float max_pitch = 270, float ang_offset = 0, float pitch_offset = 0, int flags = 0, float z_ofs = 0); + action native A_FaceMaster(float max_turn = 0, float max_pitch = 270, float ang_offset = 0, float pitch_offset = 0, int flags = 0, float z_ofs = 0); action native A_PosAttack(); action native A_Scream(); action native A_SPosAttack(); From 87dee5c611ee87bbdc84c761587d3324fd9ab9c3 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 28 Jan 2016 20:08:09 -0600 Subject: [PATCH 07/14] Fixed: Co-op players could spawn at (0,0) if no start spots for them - Check if a co-op start exists. If not, pick one at random. - Don't telefrag other players when spawning in co-op games, since you're allowed to move out of other players now. --- src/g_game.cpp | 12 +++++++----- src/p_local.h | 2 +- src/p_map.cpp | 5 ++++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/g_game.cpp b/src/g_game.cpp index 799a4e7aa..c97ea2198 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1557,7 +1557,7 @@ void G_DeathMatchSpawnPlayer (int playernum) if (spot == NULL) { // We have a player 1 start, right? spot = &playerstarts[0]; - if (spot == NULL) + if (spot->type == 0) { // Fine, whatever. spot = &deathmatchstarts[0]; } @@ -1573,7 +1573,8 @@ void G_DeathMatchSpawnPlayer (int playernum) // FPlayerStart *G_PickPlayerStart(int playernum, int flags) { - if ((level.flags2 & LEVEL2_RANDOMPLAYERSTARTS) || (flags & PPS_FORCERANDOM)) + if ((level.flags2 & LEVEL2_RANDOMPLAYERSTARTS) || (flags & PPS_FORCERANDOM) || + playerstarts[playernum].type == 0) { if (!(flags & PPS_NOBLOCKINGCHECK)) { @@ -1592,7 +1593,7 @@ FPlayerStart *G_PickPlayerStart(int playernum, int flags) { // Pick an open spot at random. return good_starts[pr_pspawn(good_starts.Size())]; } - } + } // Pick a spot at random, whether it's open or not. return &AllPlayerStarts[pr_pspawn(AllPlayerStarts.Size())]; } @@ -1665,16 +1666,17 @@ void G_DoReborn (int playernum, bool freshbot) } if (!(level.flags2 & LEVEL2_RANDOMPLAYERSTARTS) && + playerstarts[playernum].type != 0 && G_CheckSpot (playernum, &playerstarts[playernum])) { AActor *mo = P_SpawnPlayer(&playerstarts[playernum], playernum); - if (mo != NULL) P_PlayerStartStomp(mo); + if (mo != NULL) P_PlayerStartStomp(mo, true); } else { // try to spawn at any random player's spot FPlayerStart *start = G_PickPlayerStart(playernum, PPS_FORCERANDOM); AActor *mo = P_SpawnPlayer(start, playernum); - if (mo != NULL) P_PlayerStartStomp(mo); + if (mo != NULL) P_PlayerStartStomp(mo, true); } } } diff --git a/src/p_local.h b/src/p_local.h index 420fff565..c39bcef78 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -485,7 +485,7 @@ inline bool P_TeleportMove(AActor* thing, const fixedvec3 &pos, bool telefrag, b { return P_TeleportMove(thing, pos.x, pos.y, pos.z, telefrag, modifyactor); } -void P_PlayerStartStomp (AActor *actor); // [RH] Stomp on things for a newly spawned player +void P_PlayerStartStomp (AActor *actor, bool mononly=false); // [RH] Stomp on things for a newly spawned player void P_SlideMove (AActor* mo, fixed_t tryx, fixed_t tryy, int numsteps); bool P_BounceWall (AActor *mo); bool P_BounceActor (AActor *mo, AActor *BlockingMobj, bool ontop); diff --git a/src/p_map.cpp b/src/p_map.cpp index d096beb0d..7fd0ece38 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -504,7 +504,7 @@ bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefra // //========================================================================== -void P_PlayerStartStomp(AActor *actor) +void P_PlayerStartStomp(AActor *actor, bool mononly) { AActor *th; FBlockThingsIterator it(FBoundingBox(actor->X(), actor->Y(), actor->radius)); @@ -525,6 +525,9 @@ void P_PlayerStartStomp(AActor *actor) if (th->player == NULL && !(th->flags3 & MF3_ISMONSTER)) continue; + if (th->player != NULL && mononly) + continue; + if (actor->Z() > th->Top()) continue; // overhead if (actor->Top() < th->Z()) From 674b81a6b1c74d6e281d08c84eef7b8d7af0efb8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Jan 2016 10:54:44 +0100 Subject: [PATCH 08/14] - fixed: The 3D floor light list should use the last light starting above the ceiling, not the first one. - fixed: ExtraFloor_LightOnly type 2 was behaving like type 0. Instead anything interrupting it should reset to the sector's own light level. --- src/p_3dfloors.cpp | 40 +++++++++++++++++++++++----------------- src/p_3dfloors.h | 1 + 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index e294dec69..37ecaed27 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -290,6 +290,7 @@ static int P_Set3DFloor(line_t * line, int param, int param2, int alpha) // if flooding is used the floor must be non-solid and is automatically made shootthrough and seethrough if ((param2&128) && !(flags & FF_SOLID)) flags |= FF_FLOOD|FF_SEETHROUGH|FF_SHOOTTHROUGH; if (param2&512) flags |= FF_FADEWALLS; + if (param2&1024) flags |= FF_RESET; FTextureID tex = line->sidedef[0]->GetTexture(side_t::top); if (!tex.Exists() && alpha<255) { @@ -434,6 +435,7 @@ void P_Recalculate3DFloors(sector_t * sector) fixed_t maxheight, minheight; unsigned i, j; lightlist_t newlight; + lightlist_t resetlight; // what it goes back to after FF_DOUBLESHADOW TArray & ffloors=sector->e->XFloor.ffloors; TArray & lightlist = sector->e->XFloor.lightlist; @@ -588,7 +590,9 @@ void P_Recalculate3DFloors(sector_t * sector) lightlist[0].extra_colormap = sector->ColorMap; lightlist[0].blend = 0; lightlist[0].flags = 0; - + + resetlight = lightlist[0]; + maxheight = sector->CenterCeiling(); minheight = sector->CenterFloor(); for(i = 0; i < ffloors.Size(); i++) @@ -611,7 +615,7 @@ void P_Recalculate3DFloors(sector_t * sector) newlight.flags = rover->flags; lightlist.Push(newlight); } - else if (i==0) + else //if (i==0) { fixed_t ff_bottom=rover->bottom.plane->ZatPoint(CenterSpot(sector)); if (ff_bottomflags; } } + if (!(rover->flags & (FF_DOUBLESHADOW | FF_RESET))) + { + resetlight = lightlist.Last(); + } + else if (rover->flags & FF_RESET) + { + resetlight.p_lightlevel = §or->lightlevel; + resetlight.lightsource = NULL; + resetlight.extra_colormap = sector->ColorMap; + resetlight.blend = 0; + } + if (rover->flags&FF_DOUBLESHADOW) { fixed_t ff_bottom=rover->bottom.plane->ZatPoint(CenterSpot(sector)); @@ -632,20 +648,10 @@ void P_Recalculate3DFloors(sector_t * sector) { newlight.caster = rover; newlight.plane = *rover->bottom.plane; - if (lightlist.Size()>1) - { - newlight.lightsource = lightlist[lightlist.Size()-2].lightsource; - newlight.p_lightlevel = lightlist[lightlist.Size()-2].p_lightlevel; - newlight.extra_colormap = lightlist[lightlist.Size()-2].extra_colormap; - newlight.blend = lightlist[lightlist.Size()-2].blend; - } - else - { - newlight.lightsource = NULL; - newlight.p_lightlevel = §or->lightlevel; - newlight.extra_colormap = sector->ColorMap; - newlight.blend = 0; - } + newlight.lightsource = resetlight.lightsource; + newlight.p_lightlevel = resetlight.p_lightlevel; + newlight.extra_colormap = resetlight.extra_colormap; + newlight.blend = resetlight.blend; newlight.flags = rover->flags; lightlist.Push(newlight); } @@ -825,7 +831,7 @@ void P_LineOpening_XFloors (FLineOpening &open, AActor * thing, const line_t *li //========================================================================== void P_Spawn3DFloors (void) { - static int flagvals[] = {128+512, 2+512, 512}; + static int flagvals[] = {512, 2+512, 512+1024}; int i; line_t * line; diff --git a/src/p_3dfloors.h b/src/p_3dfloors.h index 0dfdf872c..5ddded3d3 100644 --- a/src/p_3dfloors.h +++ b/src/p_3dfloors.h @@ -35,6 +35,7 @@ typedef enum FF_ADDITIVETRANS = 0x10000000, // Render this floor with additive translucency FF_FLOOD = 0x20000000, // extends towards the next lowest flooding or solid 3D floor or the bottom of the sector FF_THISINSIDE = 0x40000000, // hack for software 3D with FF_BOTHPLANES + FF_RESET = 0x80000000, // light effect is completely reset, once interrupted } ffloortype_e; // This is for the purpose of Sector_SetContents: From f8d5430c06b3e0936e14acf0cdf491c4173e8d3b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Jan 2016 11:11:10 +0100 Subject: [PATCH 09/14] - fixed: When changing 'noclip2' some minor lateral velocity should be set to ensure that all internal variables contain proper values. --- src/m_cheat.cpp | 1 + src/p_3dfloors.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 3bab8f7e5..b6316f732 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -136,6 +136,7 @@ void cht_DoCheat (player_t *player, int cheat) player->cheats &= ~CF_NOCLIP; msg = GStrings("STSTR_NCOFF"); } + player->mo->velx = 1; // force some lateral movement so that internal variables are up to date break; case CHT_NOVELOCITY: diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index 37ecaed27..b60c69e11 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -615,7 +615,7 @@ void P_Recalculate3DFloors(sector_t * sector) newlight.flags = rover->flags; lightlist.Push(newlight); } - else //if (i==0) + else { fixed_t ff_bottom=rover->bottom.plane->ZatPoint(CenterSpot(sector)); if (ff_bottom Date: Fri, 29 Jan 2016 11:29:47 +0100 Subject: [PATCH 10/14] - fixed: P_TeleportMove was missing checks for THRUACTORS and THRUSPECIES flags. --- src/p_map.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/p_map.cpp b/src/p_map.cpp index 7fd0ece38..1aacff982 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -430,6 +430,12 @@ bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefra if (abs(th->X() - tmf.x) >= blockdist || abs(th->Y() - tmf.y) >= blockdist) continue; + if ((th->flags2 | tmf.thing->flags2) & MF2_THRUACTORS) + continue; + + if (tmf.thing->flags6 & MF6_THRUSPECIES && tmf.thing->GetSpecies() == th->GetSpecies()) + continue; + // [RH] Z-Check // But not if not MF2_PASSMOBJ or MF3_DONTOVERLAP are set! // Otherwise those things would get stuck inside each other. From fe271b4e78db1c619b28fbac752a59ef23811095 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Jan 2016 12:21:35 +0100 Subject: [PATCH 11/14] - fixed: A_MaceBallImpact2 was missing a check for hitting some liquid terrain. --- src/g_heretic/a_hereticweaps.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index ba216a8ba..d4a63c144 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -505,6 +505,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact2) AActor *tiny; angle_t angle; + if ((self->Z() <= self->floorz) && P_HitFloor (self)) + { // Landed in some sort of liquid + self->Destroy (); + return; + } if (self->flags & MF_INBOUNCE) { fixed_t floordist = self->Z() - self->floorz; From 08e5e1c145e8bd7d02a16013115ae1f5c38fa5bb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Jan 2016 12:44:38 +0100 Subject: [PATCH 12/14] - restored the velocity threshold checks in A_MaceBallImpact2 and A_DeathBallImpact to their original Heretic form, minus the check for floorz, to account for potential positioning issues with slopes. These checks had some major issues: * they calculated incorrect positive values for hitting a ceiling * the way they used the plane equations made some incorrect assumptions. * velz has the velocity reduction from bouncing already factored in from the calling code so doing it here again is not necessary. --- src/g_heretic/a_hereticweaps.cpp | 32 ++------------------------------ 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index d4a63c144..899514139 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -512,21 +512,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact2) } if (self->flags & MF_INBOUNCE) { - fixed_t floordist = self->Z() - self->floorz; - fixed_t ceildist = self->ceilingz - self->Z(); - fixed_t vel; - - // NOTE: The assumptions being made here about the plane to use for bouncing off are dead wrong. - // http://forum.zdoom.org/viewtopic.php?f=2&t=50449 - if (floordist <= ceildist) - { - vel = MulScale32 (self->velz, self->Sector->floorplane.c); - } - else - { - vel = MulScale32 (self->velz, self->Sector->ceilingplane.c); - } - if (vel < 2) + if (self->velz < 2*FRACUNIT) { goto boom; } @@ -624,21 +610,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact) } if (self->flags & MF_INBOUNCE) { - fixed_t floordist = self->Z() - self->floorz; - fixed_t ceildist = self->ceilingz - self->Z(); - fixed_t vel; - - // NOTE: The assumptions being made here about the plane to use for bouncing off are dead wrong. - // http://forum.zdoom.org/viewtopic.php?f=2&t=50449 - if (floordist <= ceildist) - { - vel = MulScale32 (self->velz, self->Sector->floorplane.c); - } - else - { - vel = MulScale32 (self->velz, self->Sector->ceilingplane.c); - } - if (vel < 2) + if (self->velz < 2*FRACUNIT) { goto boom; } From c6c15fe83c0b7e7fc24f14f86bb685a1711af9dd Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Jan 2016 13:40:37 +0100 Subject: [PATCH 13/14] - fixed: AActor::SpawnPoint[2] must store the actor's height above the sector's floor, not above floorz. floorz will represent the current floor the actor is standing on, which may be a 3D floor or a 3D midtexture, but both respawn functions which use this value work from the actual sector floor. --- src/p_mobj.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 67f7d1685..c9693ba47 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4084,7 +4084,7 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t } else { - actor->SpawnPoint[2] = (actor->Z() - actor->floorz); + actor->SpawnPoint[2] = (actor->Z() - actor->Sector->floorplane.ZatPoint(actor)); } if (actor->FloatBobPhase == (BYTE)-1) actor->FloatBobPhase = rng(); // Don't make everything bob in sync (unless deliberately told to do) From a41dc24086c673dd975965f2dbeb188f7307796b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Jan 2016 14:55:31 +0100 Subject: [PATCH 14/14] - fixed: 3D lights should override the sidedef's regular light completely, that includes relative light added by UDMF's 'light' property. - Renamed the 'noabsolute' parameter in side_t::GetLightLevel to 'is3dlight', what it actually is, to avoid the confusion that caused the abovementioned error. - fixed: The Down2Up render path for sides of 3D floors had the 'is3dlight' check inverted. --- src/p_sectors.cpp | 6 +++--- src/r_segs.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 8ee5c280b..a1cf2077f 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -1024,9 +1024,9 @@ CUSTOM_CVAR(Int, r_fakecontrast, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // //========================================================================== -int side_t::GetLightLevel (bool foggy, int baselight, bool noabsolute, int *pfakecontrast) const +int side_t::GetLightLevel (bool foggy, int baselight, bool is3dlight, int *pfakecontrast) const { - if (!noabsolute && (Flags & WALLF_ABSLIGHTING)) + if (!is3dlight && (Flags & WALLF_ABSLIGHTING)) { baselight = Light; } @@ -1066,7 +1066,7 @@ int side_t::GetLightLevel (bool foggy, int baselight, bool noabsolute, int *pfak } } } - if (!(Flags & WALLF_ABSLIGHTING) && (!foggy || (Flags & WALLF_LIGHT_FOG))) + if (!is3dlight && !(Flags & WALLF_ABSLIGHTING) && (!foggy || (Flags & WALLF_LIGHT_FOG))) { baselight += this->Light; } diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 7bcfec13a..ebf525569 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -829,7 +829,7 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2) { lightlist_t *lit = &backsector->e->XFloor.lightlist[j]; basecolormap = lit->extra_colormap; - wallshade = LIGHT2SHADE(curline->sidedef->GetLightLevel(foggy, *lit->p_lightlevel, lit->lightsource == NULL) + r_actualextralight); + wallshade = LIGHT2SHADE(curline->sidedef->GetLightLevel(foggy, *lit->p_lightlevel, lit->lightsource != NULL) + r_actualextralight); break; } } @@ -842,7 +842,7 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2) { lightlist_t *lit = &frontsector->e->XFloor.lightlist[j]; basecolormap = lit->extra_colormap; - wallshade = LIGHT2SHADE(curline->sidedef->GetLightLevel(foggy, *lit->p_lightlevel, lit->lightsource == NULL) + r_actualextralight); + wallshade = LIGHT2SHADE(curline->sidedef->GetLightLevel(foggy, *lit->p_lightlevel, lit->lightsource != NULL) + r_actualextralight); break; } }