- 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:
MajorCooke 2014-12-09 12:09:36 -06:00
parent b2452b806e
commit e5340ad637
4 changed files with 78 additions and 20 deletions

View file

@ -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;

View file

@ -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))

View file

@ -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)

View file

@ -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),