mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 07:11:54 +00:00
- Splitting the pull request in half.
- Added THRUREFLECT, MIRRORREFLECT, and AIMREFLECT. All require REFLECTIVE to work. - THRUREFLECT prevents missiles from changing course if reflected, and takes precedence over all reflective flags. - MIRRORREFLECT causes missiles to perform a direct 180 turn-around. - AIMREFLECT turns the missile back to the original shooter, and does not slow the missile down.
This commit is contained in:
parent
b2452b806e
commit
e5340ad637
4 changed files with 78 additions and 20 deletions
|
@ -347,6 +347,11 @@ enum
|
|||
MF7_DONTTHRUST = 0x00000100, // Thrusting functions do not take, and do not give thrust (damage) to actors with this flag.
|
||||
MF7_ALLOWPAIN = 0x00000200, // Invulnerable or immune (via damagefactors) actors can still react to taking damage even if they don't.
|
||||
MF7_CAUSEPAIN = 0x00000400, // Damage sources with this flag can cause similar effects like ALLOWPAIN.
|
||||
MF7_THRUREFLECT = 0x00000800, // Actors who are reflective cause the missiles to not slow down or change angles.
|
||||
MF7_MIRRORREFLECT = 0x00001000, // Actor is turned directly 180 degrees around when reflected.
|
||||
MF7_AIMREFLECT = 0x00002000, // Actor is directly reflected straight back at the one who fired the projectile.
|
||||
|
||||
|
||||
|
||||
// --- mobj.renderflags ---
|
||||
|
||||
|
@ -859,7 +864,7 @@ public:
|
|||
DWORD flags4; // [RH] Even more flags!
|
||||
DWORD flags5; // OMG! We need another one.
|
||||
DWORD flags6; // Shit! Where did all the flags go?
|
||||
DWORD flags7; //
|
||||
DWORD flags7; // WHO WANTS TO BET ON 8!?
|
||||
|
||||
// [BB] If 0, everybody can see the actor, if > 0, only members of team (VisibleToTeam-1) can see it.
|
||||
DWORD VisibleToTeam;
|
||||
|
|
|
@ -1283,6 +1283,16 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm)
|
|||
{
|
||||
P_GiveBody(thing, -damage);
|
||||
}
|
||||
|
||||
if ((thing->flags7 & MF7_THRUREFLECT) && (thing->flags2 & MF2_REFLECTIVE) && (tm.thing->flags & MF_MISSILE))
|
||||
{
|
||||
if (tm.thing->flags2 & MF2_SEEKERMISSILE)
|
||||
{
|
||||
tm.thing->tracer = tm.thing->target;
|
||||
}
|
||||
tm.thing->target = thing;
|
||||
return true;
|
||||
}
|
||||
return false; // don't traverse any more
|
||||
}
|
||||
if (thing->flags2 & MF2_PUSHABLE && !(tm.thing->flags2 & MF2_CANNOTPUSH))
|
||||
|
@ -1643,7 +1653,7 @@ bool P_TestMobjZ(AActor *actor, bool quick, AActor **pOnmobj)
|
|||
{ // Don't clip against self
|
||||
continue;
|
||||
}
|
||||
if ((actor->flags & MF_MISSILE) && thing == actor->target)
|
||||
if ((actor->flags & MF_MISSILE) && (thing == actor->target))
|
||||
{ // Don't clip against whoever shot the missile.
|
||||
continue;
|
||||
}
|
||||
|
@ -2983,18 +2993,20 @@ bool P_BounceWall(AActor *mo)
|
|||
extern FRandom pr_bounce;
|
||||
bool P_BounceActor(AActor *mo, AActor *BlockingMobj, bool ontop)
|
||||
{
|
||||
//Don't go through all of this if the actor is reflective and wants things to pass through them.
|
||||
if (BlockingMobj && ((BlockingMobj->flags2 & MF2_REFLECTIVE) && (BlockingMobj->flags7 & MF7_THRUREFLECT))) return true;
|
||||
if (mo && BlockingMobj && ((mo->BounceFlags & BOUNCE_AllActors)
|
||||
|| ((mo->flags & MF_MISSILE) && (!(mo->flags2 & MF2_RIP) || (BlockingMobj->flags5 & MF5_DONTRIP) || ((mo->flags6 & MF6_NOBOSSRIP) && (BlockingMobj->flags2 & MF2_BOSS))) && (BlockingMobj->flags2 & MF2_REFLECTIVE))
|
||||
|| ((BlockingMobj->player == NULL) && (!(BlockingMobj->flags3 & MF3_ISMONSTER)))
|
||||
))
|
||||
|| ((mo->flags & MF_MISSILE) && (!(mo->flags2 & MF2_RIP)
|
||||
|| (BlockingMobj->flags5 & MF5_DONTRIP)
|
||||
|| ((mo->flags6 & MF6_NOBOSSRIP) && (BlockingMobj->flags2 & MF2_BOSS))) && (BlockingMobj->flags2 & MF2_REFLECTIVE))
|
||||
|| ((BlockingMobj->player == NULL) && (!(BlockingMobj->flags3 & MF3_ISMONSTER)))))
|
||||
{
|
||||
if (mo->bouncecount > 0 && --mo->bouncecount == 0) return false;
|
||||
|
||||
if (!ontop)
|
||||
{
|
||||
fixed_t speed;
|
||||
angle_t angle = R_PointToAngle2(BlockingMobj->x,
|
||||
BlockingMobj->y, mo->x, mo->y) + ANGLE_1*((pr_bounce() % 16) - 8);
|
||||
angle_t angle = R_PointToAngle2(BlockingMobj->x,BlockingMobj->y, mo->x, mo->y) + ANGLE_1*((pr_bounce() % 16) - 8);
|
||||
speed = P_AproxDistance(mo->velx, mo->vely);
|
||||
speed = FixedMul(speed, mo->wallbouncefactor); // [GZ] was 0.75, using wallbouncefactor seems more consistent
|
||||
mo->angle = angle;
|
||||
|
@ -5090,6 +5102,8 @@ int P_PushUp(AActor *thing, FChangePosition *cpos)
|
|||
// 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 (!(intersect->flags2 & MF2_PASSMOBJ) ||
|
||||
(!(intersect->flags3 & MF3_ISMONSTER) && intersect->Mass > mymass) ||
|
||||
(intersect->flags4 & MF4_ACTLIKEBRIDGE)
|
||||
|
@ -5098,7 +5112,8 @@ int P_PushUp(AActor *thing, FChangePosition *cpos)
|
|||
// Can't push bridges or things more massive than ourself
|
||||
return 2;
|
||||
}
|
||||
fixed_t oldz = intersect->z;
|
||||
fixed_t oldz;
|
||||
oldz = intersect->z;
|
||||
P_AdjustFloorCeil(intersect, cpos);
|
||||
intersect->z = thing->z + thing->height + 1;
|
||||
if (P_PushUp(intersect, cpos))
|
||||
|
|
|
@ -1660,6 +1660,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
|
|||
int steps, step, totalsteps;
|
||||
fixed_t startx, starty;
|
||||
fixed_t oldfloorz = mo->floorz;
|
||||
fixed_t oldz = mo->z;
|
||||
|
||||
fixed_t maxmove = (mo->waterlevel < 1) || (mo->flags & MF_MISSILE) ||
|
||||
(mo->player && mo->player->crouchoffset<-10*FRACUNIT) ? MAXMOVE : MAXMOVE/4;
|
||||
|
@ -1949,20 +1950,53 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
|
|||
}
|
||||
if (BlockingMobj && (BlockingMobj->flags2 & MF2_REFLECTIVE))
|
||||
{
|
||||
angle = R_PointToAngle2(BlockingMobj->x, BlockingMobj->y, mo->x, mo->y);
|
||||
|
||||
// Change angle for deflection/reflection
|
||||
if (mo->AdjustReflectionAngle (BlockingMobj, angle))
|
||||
bool seeker = (mo->flags2 & MF2_SEEKERMISSILE) ? true : false;
|
||||
// Don't change the angle if there's THRUREFLECT on the monster.
|
||||
if (!(BlockingMobj->flags7 & MF7_THRUREFLECT))
|
||||
{
|
||||
goto explode;
|
||||
}
|
||||
int dir;
|
||||
angle_t delta;
|
||||
|
||||
if (BlockingMobj->flags7 & MF7_MIRRORREFLECT)
|
||||
angle = mo->angle + ANG180;
|
||||
else
|
||||
angle = R_PointToAngle2(BlockingMobj->x, BlockingMobj->y, mo->x, mo->y);
|
||||
|
||||
// Reflect the missile along angle
|
||||
mo->angle = angle;
|
||||
angle >>= ANGLETOFINESHIFT;
|
||||
mo->velx = FixedMul (mo->Speed>>1, finecosine[angle]);
|
||||
mo->vely = FixedMul (mo->Speed>>1, finesine[angle]);
|
||||
mo->velz = -mo->velz/2;
|
||||
// Change angle for deflection/reflection
|
||||
// AIMREFLECT calls precedence so make sure not to bother with adjusting here if declared.
|
||||
if (!(BlockingMobj->flags7 & MF7_AIMREFLECT) && (mo->AdjustReflectionAngle(BlockingMobj, angle)))
|
||||
{
|
||||
goto explode;
|
||||
}
|
||||
|
||||
// Reflect the missile along angle
|
||||
if (BlockingMobj->flags7 & MF7_AIMREFLECT)
|
||||
{
|
||||
dir = P_FaceMobj(mo, mo->target, &delta);
|
||||
if (dir)
|
||||
{ // Turn clockwise
|
||||
mo->angle += delta;
|
||||
}
|
||||
else
|
||||
{ // Turn counter clockwise
|
||||
mo->angle -= delta;
|
||||
}
|
||||
angle = mo->angle >> ANGLETOFINESHIFT;
|
||||
mo->velx = FixedMul(mo->Speed, finecosine[angle]);
|
||||
mo->vely = FixedMul(mo->Speed, finesine[angle]);
|
||||
mo->velz = -mo->velz;
|
||||
}
|
||||
else
|
||||
{
|
||||
mo->angle = angle;
|
||||
angle >>= ANGLETOFINESHIFT;
|
||||
mo->velx = FixedMul(mo->Speed >> 1, finecosine[angle]);
|
||||
mo->vely = FixedMul(mo->Speed >> 1, finesine[angle]);
|
||||
mo->velz = -mo->velz / 2;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if (mo->flags2 & MF2_SEEKERMISSILE)
|
||||
{
|
||||
mo->tracer = mo->target;
|
||||
|
@ -2893,6 +2927,7 @@ int AActor::SpecialMissileHit (AActor *victim)
|
|||
bool AActor::AdjustReflectionAngle (AActor *thing, angle_t &angle)
|
||||
{
|
||||
if (flags2 & MF2_DONTREFLECT) return true;
|
||||
if (thing->flags7 & MF7_THRUREFLECT) return false;
|
||||
|
||||
// Change angle for reflection
|
||||
if (thing->flags4&MF4_SHIELDREFLECT)
|
||||
|
|
|
@ -247,6 +247,9 @@ static FFlagDef ActorFlags[]=
|
|||
DEFINE_FLAG(MF7, DONTTHRUST, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, ALLOWPAIN, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, CAUSEPAIN, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, THRUREFLECT, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, MIRRORREFLECT, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, AIMREFLECT, AActor, flags7),
|
||||
|
||||
// Effect flags
|
||||
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),
|
||||
|
|
Loading…
Reference in a new issue