Added CanResurrect(Actor other, bool passive)

- Works similarly to CanCollideWith.
- Passive means the caller is trying to be resurrected by 'other'.
- Non-passive means the caller is trying to resurrect 'other'.
This commit is contained in:
Major Cooke 2018-11-05 20:22:37 -06:00 committed by Christoph Oelckers
parent 9520a3c640
commit b553be153d
4 changed files with 64 additions and 2 deletions

View file

@ -2757,11 +2757,63 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi
actor->flags &= ~MF_INCHASE;
}
//==========================================================================
//
// CanResurrect
//
// Checks if an actor can resurrect with another one, calling virtual script
// functions to check.
//
//==========================================================================
// [MC] Code is almost a duplicate of CanCollideWith but with changes to
// accommodate checking of just one actor.
bool P_CanResurrect(AActor *tmthing, AActor *thing)
{
if (tmthing == nullptr)
return false;
static unsigned VIndex = ~0u;
if (VIndex == ~0u)
{
VIndex = GetVirtualIndex(RUNTIME_CLASS(AActor), "CanResurrect");
assert(VIndex != ~0u);
}
VMValue params[3] = { tmthing, thing, false };
VMReturn ret;
int retval;
ret.IntAt(&retval);
auto clss = tmthing->GetClass();
VMFunction *func = clss->Virtuals.Size() > VIndex ? clss->Virtuals[VIndex] : nullptr;
if (func != nullptr)
{
VMCall(func, params, 3, &ret, 1);
if (!retval) return false;
}
// Pointless to be running it again if it's just self.
if (thing == nullptr || thing == tmthing)
return true;
std::swap(params[0].a, params[1].a);
params[2].i = true;
// re-get for the other actor.
clss = thing->GetClass();
func = clss->Virtuals.Size() > VIndex ? clss->Virtuals[VIndex] : nullptr;
if (func != nullptr)
{
VMCall(func, params, 3, &ret, 1);
if (!retval) return false;
}
return true;
}
//==========================================================================
//
// P_CheckForResurrection (formerly part of A_VileChase)
// Check for ressurecting a body
// Check for resurrecting a body
//
//==========================================================================
@ -2834,7 +2886,7 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates)
corpsehit->flags = oldflags;
corpsehit->radius = oldradius;
corpsehit->Height = oldheight;
if (!check) continue;
if (!check || !P_CanResurrect(self, corpsehit)) continue;
// got one!
temp = self->target;

View file

@ -162,6 +162,7 @@ void P_Thing_SetVelocity(AActor *actor, const DVector3 &vec, bool add, bool setb
void P_RemoveThing(AActor * actor);
bool P_Thing_Raise(AActor *thing, AActor *raiser, int nocheck = false);
bool P_Thing_CanRaise(AActor *thing);
bool P_CanResurrect(AActor *ththing, AActor *thing);
PClassActor *P_GetSpawnableType(int spawnnum);
void InitSpawnablesFromMapinfo();
int P_Thing_CheckInputNum(player_t *p, int inputnum);

View file

@ -460,6 +460,8 @@ bool P_Thing_Raise(AActor *thing, AActor *raiser, int nocheck)
return false;
}
if (!P_CanResurrect(thing, raiser))
return false;
S_Sound (thing, CHAN_BODY, "vile/raise", 1, ATTN_IDLE);

View file

@ -445,6 +445,13 @@ class Actor : Thinker native
return true;
}
// Called by revival/resurrection to check if one can resurrect the other.
// "other" can be null when not passive.
virtual bool CanResurrect(Actor other, bool passive)
{
return true;
}
// Called when an actor is to be reflected by a disc of repulsion.
// Returns true to continue normal blast processing.
virtual bool SpecialBlastHandling (Actor source, double strength)