Merge remote-tracking branch 'remotes/origin/master' into new_level_refactor

This commit is contained in:
Christoph Oelckers 2019-01-31 20:43:24 +01:00
commit ff903da19a
7 changed files with 106 additions and 10 deletions

View file

@ -536,6 +536,14 @@ bool E_CheckReplacement( PClassActor *replacee, PClassActor **replacement )
return final;
}
bool E_CheckReplacee(PClassActor **replacee, PClassActor *replacement)
{
bool final = false;
for (DStaticEventHandler *handler = E_FirstEventHandler; handler; handler = handler->next)
handler->CheckReplacee(replacee, replacement, &final);
return final;
}
void E_NewGame(EventHandlerType handlerType)
{
bool isStatic = handlerType == EventHandlerType::Global;
@ -627,6 +635,10 @@ DEFINE_FIELD_X(ReplaceEvent, FReplaceEvent, Replacee)
DEFINE_FIELD_X(ReplaceEvent, FReplaceEvent, Replacement)
DEFINE_FIELD_X(ReplaceEvent, FReplaceEvent, IsFinal)
DEFINE_FIELD_X(ReplacedEvent, FReplacedEvent, Replacee)
DEFINE_FIELD_X(ReplacedEvent, FReplacedEvent, Replacement)
DEFINE_FIELD_X(ReplacedEvent, FReplacedEvent, IsFinal)
DEFINE_ACTION_FUNCTION(DStaticEventHandler, SetOrder)
{
PARAM_SELF_PROLOGUE(DStaticEventHandler);
@ -1193,6 +1205,21 @@ void DStaticEventHandler::CheckReplacement( PClassActor *replacee, PClassActor *
}
}
void DStaticEventHandler::CheckReplacee(PClassActor **replacee, PClassActor *replacement, bool *final)
{
IFVIRTUAL(DStaticEventHandler, CheckReplacee)
{
// don't create excessive DObjects if not going to be processed anyway
if (isEmpty(func)) return;
FReplacedEvent e = { *replacee, replacement, *final };
VMValue params[2] = { (DStaticEventHandler*)this, &e };
VMCall(func, params, 2, nullptr, 0);
if (e.Replacee != replacement) // prevent infinite recursion
*replacee = e.Replacee;
*final = e.IsFinal;
}
}
void DStaticEventHandler::NewGame()
{
IFVIRTUAL(DStaticEventHandler, NewGame)

View file

@ -81,6 +81,8 @@ void E_Console(int player, FString name, int arg1, int arg2, int arg3, bool manu
// called when looking up the replacement for an actor class
bool E_CheckReplacement(PClassActor* replacee, PClassActor** replacement);
// called when looking up the replaced for an actor class
bool E_CheckReplacee(PClassActor** replacee, PClassActor* replacement);
// called on new game
void E_NewGame(EventHandlerType handlerType);
@ -187,6 +189,7 @@ public:
//
void CheckReplacement(PClassActor* replacee, PClassActor** replacement, bool* final);
void CheckReplacee(PClassActor** replacee, PClassActor* replacement, bool* final);
//
void NewGame();
@ -301,4 +304,11 @@ struct FReplaceEvent
bool IsFinal;
};
struct FReplacedEvent
{
PClassActor* Replacee;
PClassActor* Replacement;
bool IsFinal;
};
#endif

View file

@ -834,15 +834,18 @@ void FLevelLocals::RecreateAllAttachedLights()
while ((a=it.Next()))
{
if (a->IsKindOf(NAME_DynamicLight))
{
::AttachLight(a);
::ActivateLight(a);
}
else
if (!a->IsKindOf(NAME_DynamicLight))
{
a->SetDynamicLights();
}
else if (a->AttachedLights.Size() == 0)
{
::AttachLight(a);
if (!(a->flags2 & MF2_DORMANT))
{
::ActivateLight(a);
}
}
}
}

View file

@ -593,6 +593,16 @@ PClassActor *PClassActor::GetReplacee(bool lookskill)
}
}
PClassActor *savedrep = ActorInfo()->Replacee;
// [MC] Same code as CheckReplacement but turned around so modders can indicate
// what monsters spawn from which entity. I.e. instead of a randomspawner
// showing up, one can assign an Arachnotron as the one being replaced
// so functions like CheckReplacee and A_BossDeath can actually work, given
// modders set it up that way.
if (E_CheckReplacee(&savedrep, this))
{
// [MK] the replacement is final, so don't continue with the chain
return savedrep ? savedrep : this;
}
if (savedrep == nullptr && (!lookskill || skillrepname == NAME_None))
{
return this;