mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-11 15:22:15 +00:00
This commit is contained in:
commit
6b2ddb0f3a
4 changed files with 84 additions and 41 deletions
|
@ -1288,7 +1288,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Explode)
|
||||||
// Comparing the results of a test wad with Eternity, it seems A_NailBomb does not aim
|
// Comparing the results of a test wad with Eternity, it seems A_NailBomb does not aim
|
||||||
P_LineAttack(self, ang, MISSILERANGE, 0.,
|
P_LineAttack(self, ang, MISSILERANGE, 0.,
|
||||||
//P_AimLineAttack (self, ang, MISSILERANGE),
|
//P_AimLineAttack (self, ang, MISSILERANGE),
|
||||||
naildamage, NAME_Hitscan, pufftype);
|
naildamage, NAME_Hitscan, pufftype, (self->flags & MF_MISSILE) ? LAF_TARGETISSOURCE : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -323,6 +323,7 @@ enum // P_LineAttack flags
|
||||||
LAF_NORANDOMPUFFZ = 2,
|
LAF_NORANDOMPUFFZ = 2,
|
||||||
LAF_NOIMPACTDECAL = 4,
|
LAF_NOIMPACTDECAL = 4,
|
||||||
LAF_NOINTERACT = 8,
|
LAF_NOINTERACT = 8,
|
||||||
|
LAF_TARGETISSOURCE = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL);
|
AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL);
|
||||||
|
|
115
src/p_map.cpp
115
src/p_map.cpp
|
@ -82,6 +82,56 @@ static FRandom pr_crunch("DoCrunch");
|
||||||
TArray<spechit_t> spechit;
|
TArray<spechit_t> spechit;
|
||||||
TArray<spechit_t> portalhit;
|
TArray<spechit_t> portalhit;
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// CanCollideWith
|
||||||
|
//
|
||||||
|
// Checks if an actor can collide with another one, calling virtual script functions to check.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(AActor, CanCollideWith)
|
||||||
|
{
|
||||||
|
// No need to check the parameters, as they are not even used.
|
||||||
|
ACTION_RETURN_BOOL(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool P_CanCollideWith(AActor *tmthing, AActor *thing)
|
||||||
|
{
|
||||||
|
static unsigned VIndex = ~0u;
|
||||||
|
if (VIndex == ~0u)
|
||||||
|
{
|
||||||
|
VIndex = GetVirtualIndex(RUNTIME_CLASS(AActor), "CanCollideWith");
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
GlobalVMStack.Call(func, params, 3, &ret, 1, nullptr);
|
||||||
|
if (!retval) return false;
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
GlobalVMStack.Call(func, params, 3, &ret, 1, nullptr);
|
||||||
|
if (!retval) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// FindRefPoint
|
// FindRefPoint
|
||||||
|
@ -402,6 +452,9 @@ bool P_TeleportMove(AActor* thing, const DVector3 &pos, bool telefrag, bool modi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!P_CanCollideWith(tmf.thing, th))
|
||||||
|
continue;
|
||||||
|
|
||||||
// monsters don't stomp things except on boss level
|
// monsters don't stomp things except on boss level
|
||||||
// [RH] Some Heretic/Hexen monsters can telestomp
|
// [RH] Some Heretic/Hexen monsters can telestomp
|
||||||
// ... and some items can never be telefragged while others will be telefragged by everything that teleports upon them.
|
// ... and some items can never be telefragged while others will be telefragged by everything that teleports upon them.
|
||||||
|
@ -1147,12 +1200,6 @@ static bool CanAttackHurt(AActor *victim, AActor *shooter)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(AActor, CanCollideWith)
|
|
||||||
{
|
|
||||||
// No need to check the parameters, as they are not even used.
|
|
||||||
ACTION_RETURN_BOOL(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::CheckResult &cres, const FBoundingBox &box, FCheckPosition &tm)
|
bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::CheckResult &cres, const FBoundingBox &box, FCheckPosition &tm)
|
||||||
{
|
{
|
||||||
AActor *thing = cres.thing;
|
AActor *thing = cres.thing;
|
||||||
|
@ -1257,36 +1304,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch
|
||||||
if (((thing->flags & MF_SOLID) || (thing->flags6 & (MF6_TOUCHY | MF6_BUMPSPECIAL))) &&
|
if (((thing->flags & MF_SOLID) || (thing->flags6 & (MF6_TOUCHY | MF6_BUMPSPECIAL))) &&
|
||||||
((tm.thing->flags & (MF_SOLID|MF_MISSILE)) || (tm.thing->flags2 & MF2_BLASTED) || (tm.thing->flags6 & MF6_BLOCKEDBYSOLIDACTORS) || (tm.thing->BounceFlags & BOUNCE_MBF)))
|
((tm.thing->flags & (MF_SOLID|MF_MISSILE)) || (tm.thing->flags2 & MF2_BLASTED) || (tm.thing->flags6 & MF6_BLOCKEDBYSOLIDACTORS) || (tm.thing->BounceFlags & BOUNCE_MBF)))
|
||||||
{
|
{
|
||||||
static unsigned VIndex = ~0u;
|
if (!P_CanCollideWith(tm.thing, thing)) return true;
|
||||||
if (VIndex == ~0u)
|
|
||||||
{
|
|
||||||
VIndex = GetVirtualIndex(RUNTIME_CLASS(AActor), "CanCollideWith");
|
|
||||||
assert(VIndex != ~0u);
|
|
||||||
}
|
|
||||||
|
|
||||||
VMValue params[3] = { tm.thing, thing, false };
|
|
||||||
VMReturn ret;
|
|
||||||
int retval;
|
|
||||||
ret.IntAt(&retval);
|
|
||||||
|
|
||||||
auto clss = tm.thing->GetClass();
|
|
||||||
VMFunction *func = clss->Virtuals.Size() > VIndex ? clss->Virtuals[VIndex] : nullptr;
|
|
||||||
if (func != nullptr)
|
|
||||||
{
|
|
||||||
GlobalVMStack.Call(func, params, 3, &ret, 1, nullptr);
|
|
||||||
if (!retval) 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)
|
|
||||||
{
|
|
||||||
GlobalVMStack.Call(func, params, 3, &ret, 1, nullptr);
|
|
||||||
if (!retval) return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1959,6 +1977,12 @@ bool P_TestMobjZ(AActor *actor, bool quick, AActor **pOnmobj)
|
||||||
{ // something higher is in the way
|
{ // something higher is in the way
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
else if (!P_CanCollideWith(actor, thing))
|
||||||
|
{ // If they cannot collide, they cannot block each other.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
onmobj = thing;
|
onmobj = thing;
|
||||||
if (quick) break;
|
if (quick) break;
|
||||||
}
|
}
|
||||||
|
@ -4476,7 +4500,9 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance,
|
||||||
puff = P_SpawnPuff(t1, pufftype, bleedpos, 0., 0., 2, puffFlags | PF_HITTHING | PF_TEMPORARY);
|
puff = P_SpawnPuff(t1, pufftype, bleedpos, 0., 0., 2, puffFlags | PF_HITTHING | PF_TEMPORARY);
|
||||||
killPuff = true;
|
killPuff = true;
|
||||||
}
|
}
|
||||||
newdam = P_DamageMobj(trace.Actor, puff ? puff : t1, t1, damage, damageType, dmgflags|DMG_USEANGLE, trace.SrcAngleFromTarget);
|
auto src = t1;
|
||||||
|
if ((flags & LAF_TARGETISSOURCE) && t1 && t1->target) src = t1->target;
|
||||||
|
newdam = P_DamageMobj(trace.Actor, puff ? puff : t1, src, damage, damageType, dmgflags|DMG_USEANGLE, trace.SrcAngleFromTarget);
|
||||||
if (actualdamage != NULL)
|
if (actualdamage != NULL)
|
||||||
{
|
{
|
||||||
*actualdamage = newdam;
|
*actualdamage = newdam;
|
||||||
|
@ -5943,6 +5969,9 @@ int P_PushUp(AActor *thing, FChangePosition *cpos)
|
||||||
continue;
|
continue;
|
||||||
if ((thing->flags & MF_MISSILE) && (intersect->flags2 & MF2_REFLECTIVE) && (intersect->flags7 & MF7_THRUREFLECT))
|
if ((thing->flags & MF_MISSILE) && (intersect->flags2 & MF2_REFLECTIVE) && (intersect->flags7 & MF7_THRUREFLECT))
|
||||||
continue;
|
continue;
|
||||||
|
if (!P_CanCollideWith(thing, intersect))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!(intersect->flags2 & MF2_PASSMOBJ) ||
|
if (!(intersect->flags2 & MF2_PASSMOBJ) ||
|
||||||
(!(intersect->flags3 & MF3_ISMONSTER) && intersect->Mass > mymass) ||
|
(!(intersect->flags3 & MF3_ISMONSTER) && intersect->Mass > mymass) ||
|
||||||
(intersect->flags4 & MF4_ACTLIKEBRIDGE)
|
(intersect->flags4 & MF4_ACTLIKEBRIDGE)
|
||||||
|
@ -5989,6 +6018,18 @@ int P_PushDown(AActor *thing, FChangePosition *cpos)
|
||||||
for (; firstintersect < lastintersect; firstintersect++)
|
for (; firstintersect < lastintersect; firstintersect++)
|
||||||
{
|
{
|
||||||
AActor *intersect = intersectors[firstintersect];
|
AActor *intersect = intersectors[firstintersect];
|
||||||
|
|
||||||
|
// [GZ] Skip this iteration for THRUSPECIES things
|
||||||
|
// Should there be MF2_THRUGHOST / MF3_GHOST checks there too for consistency?
|
||||||
|
// Or would that risk breaking established behavior? THRUGHOST, like MTHRUSPECIES,
|
||||||
|
// is normally for projectiles which would have exploded by now anyway...
|
||||||
|
if (thing->flags6 & MF6_THRUSPECIES && thing->GetSpecies() == intersect->GetSpecies())
|
||||||
|
continue;
|
||||||
|
if ((thing->flags & MF_MISSILE) && (intersect->flags2 & MF2_REFLECTIVE) && (intersect->flags7 & MF7_THRUREFLECT))
|
||||||
|
continue;
|
||||||
|
if (!P_CanCollideWith(thing, intersect))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!(intersect->flags2 & MF2_PASSMOBJ) ||
|
if (!(intersect->flags2 & MF2_PASSMOBJ) ||
|
||||||
(!(intersect->flags3 & MF3_ISMONSTER) && intersect->Mass > mymass) ||
|
(!(intersect->flags3 & MF3_ISMONSTER) && intersect->Mass > mymass) ||
|
||||||
(intersect->flags4 & MF4_ACTLIKEBRIDGE)
|
(intersect->flags4 & MF4_ACTLIKEBRIDGE)
|
||||||
|
|
|
@ -917,6 +917,7 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
|
||||||
// the referenced sound so some additional checks are required
|
// the referenced sound so some additional checks are required
|
||||||
int near_limit = sfx->NearLimit;
|
int near_limit = sfx->NearLimit;
|
||||||
float limit_range = sfx->LimitRange;
|
float limit_range = sfx->LimitRange;
|
||||||
|
auto pitchmask = sfx->PitchMask;
|
||||||
rolloff = &sfx->Rolloff;
|
rolloff = &sfx->Rolloff;
|
||||||
|
|
||||||
// Resolve player sounds, random sounds, and aliases
|
// Resolve player sounds, random sounds, and aliases
|
||||||
|
@ -1081,9 +1082,9 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vary the sfx pitches.
|
// Vary the sfx pitches.
|
||||||
if (sfx->PitchMask != 0)
|
if (pitchmask != 0)
|
||||||
{
|
{
|
||||||
pitch = NORM_PITCH - (M_Random() & sfx->PitchMask) + (M_Random() & sfx->PitchMask);
|
pitch = NORM_PITCH - (M_Random() & pitchmask) + (M_Random() & pitchmask);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue