- fixed: A powered up weapon which shares its ready state with the parent but is currently in a firing sequence may not force-switch the weapon, because that will cause the sequence to run in the wrong weapon's context.

This commit is contained in:
Christoph Oelckers 2018-12-18 20:38:25 +01:00
parent 6342e85c26
commit 462fe891bd
5 changed files with 26 additions and 11 deletions

View file

@ -1259,7 +1259,6 @@ public:
void LinkToWorld (FLinkContext *ctx, bool spawningmapthing=false, sector_t *sector = NULL);
void UnlinkFromWorld(FLinkContext *ctx);
void AdjustFloorClip ();
bool InStateSequence(FState * newstate, FState * basestate);
bool IsMapActor();
int GetTics(FState * newstate);
bool SetState (FState *newstate, bool nofunction=false);

View file

@ -425,7 +425,7 @@ AActor &AActor::operator= (const AActor &other)
//
//==========================================================================
bool AActor::InStateSequence(FState * newstate, FState * basestate)
static int InStateSequence(FState * newstate, FState * basestate)
{
if (basestate == NULL) return false;
@ -440,12 +440,19 @@ bool AActor::InStateSequence(FState * newstate, FState * basestate)
return false;
}
DEFINE_ACTION_FUNCTION(AActor, InStateSequence)
DEFINE_ACTION_FUNCTION(AActor, InStateSequence, InStateSequence)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_PROLOGUE;
PARAM_POINTER(newstate, FState);
PARAM_POINTER(basestate, FState);
ACTION_RETURN_BOOL(self->InStateSequence(newstate, basestate));
ACTION_RETURN_BOOL(InStateSequence(newstate, basestate));
}
DEFINE_ACTION_FUNCTION(FState, InStateSequence, InStateSequence)
{
PARAM_SELF_STRUCT_PROLOGUE(FState);
PARAM_POINTER(basestate, FState);
ACTION_RETURN_BOOL(InStateSequence(self, basestate));
}

View file

@ -680,7 +680,7 @@ class Actor : Thinker native
native void FindFloorCeiling(int flags = 0);
native double, double GetFriction();
native bool, Actor TestMobjZ(bool quick = false);
native bool InStateSequence(State newstate, State basestate);
native static bool InStateSequence(State newstate, State basestate);
bool TryWalk ()
{

View file

@ -747,6 +747,7 @@ struct State native
native int DistanceTo(state other);
native bool ValidateSpriteFrame();
native TextureID, bool, Vector2 GetSpriteTexture(int rotation, int skin = 0, Vector2 scale = (0,0));
native bool InStateSequence(State base);
}
struct F3DFloor native

View file

@ -811,24 +811,32 @@ class Weapon : StateProvider
let player = Owner.player;
if (SisterWeapon != NULL && bPowered_Up)
{
if (GetReadyState() != SisterWeapon.GetReadyState())
let ready = GetReadyState();
if (ready != SisterWeapon.GetReadyState())
{
if (player.PendingWeapon == NULL || player.PendingWeapon == WP_NOCHANGE)
{
player.PendingWeapon = SisterWeapon;
}
player.WeaponState |= WF_REFIRESWITCHOK;
}
else
{
let psp = player.FindPSprite(PSP_WEAPON);
if (psp != null && psp.Caller == player.ReadyWeapon)
if (psp != null && psp.Caller == player.ReadyWeapon && psp.CurState.InStateSequence(ready))
{
// If the weapon changes but the state does not, we have to manually change the PSprite's caller here.
psp.Caller = SisterWeapon;
player.ReadyWeapon = SisterWeapon;
}
else
else
{
// Something went wrong. Initiate a regular weapon change.
player.PendingWeapon = SisterWeapon;
if (player.PendingWeapon == NULL || player.PendingWeapon == WP_NOCHANGE)
{
// Something went wrong. Initiate a regular weapon change.
player.PendingWeapon = SisterWeapon;
}
player.WeaponState |= WF_REFIRESWITCHOK;
}
}
}