- made adjustments to P_LineAttack and P_RailAttack to deal with altered angles by passing through a non-parallel portal.

- fixed: P_FindFloorCeiling set the floorsector for a new ceilingheight.

Note: P_DrawRailTrail still needs to be changed, at the moment rail trails through portals will not work correctly.
This commit is contained in:
Christoph Oelckers 2016-03-06 21:58:36 +01:00
parent 90553bb61c
commit 5175d56129
13 changed files with 187 additions and 168 deletions

View file

@ -829,6 +829,11 @@ public:
return R_PointToAngle2(X(), Y(), otherx, othery);
}
fixed_t AngleTo(fixedvec2 other)
{
return R_PointToAngle2(X(), Y(), other.x, other.y);
}
// 'absolute' is reserved for a linked portal implementation which needs
// to distinguish between portal-aware and portal-unaware distance calculation.
fixed_t AproxDistance(AActor *other, bool absolute = false)

View file

@ -112,30 +112,56 @@ struct fixedvec3
return *this;
}
fixedvec3 &operator -=(const fixedvec2 &other)
{
x -= other.x;
y -= other.y;
return *this;
}
fixedvec3 &operator -=(const fixedvec3 &other)
{
x -= other.x;
y -= other.y;
z -= other.z;
return *this;
}
operator fixedvec2()
{
fixedvec2 ret = { x, y };
return ret;
return { x, y };
}
};
inline fixedvec2 operator +(const fixedvec2 &v1, const fixedvec2 &v2)
{
fixedvec2 v = { v1.x + v2.x, v1.y + v2.y };
return v;
return { v1.x + v2.x, v1.y + v2.y };
}
inline fixedvec2 operator -(const fixedvec2 &v1, const fixedvec2 &v2)
{
return { v1.x - v2.x, v1.y - v2.y };
}
inline fixedvec3 operator +(const fixedvec3 &v1, const fixedvec3 &v2)
{
fixedvec3 v = { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z };
return v;
return { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z };
}
inline fixedvec3 operator +(const fixedvec3 &v1, const fixedvec2 &v2)
{
fixedvec3 v = { v1.x + v2.x, v1.y + v2.y, v1.z };
return v;
return { v1.x + v2.x, v1.y + v2.y, v1.z };
}
inline fixedvec3 operator -(const fixedvec3 &v1, const fixedvec2 &v2)
{
return{ v1.x - v2.x, v1.y - v2.y, v1.z };
}
inline fixedvec3 operator -(const fixedvec3 &v1, const fixedvec3 &v2)
{
return{ v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };
}
#define FIXED_MAX (signed)(0x7fffffff)

View file

@ -2382,9 +2382,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
{
if (trace.HitType == TRACE_HitWall)
{
DImpactDecal::StaticCreate (s,
trace.X, trace.Y, trace.Z,
trace.Line->sidedef[trace.Side], NULL);
DImpactDecal::StaticCreate (s, trace.HitPos, trace.Line->sidedef[trace.Side], NULL);
}
}
}

View file

@ -64,7 +64,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Tracer)
return 0;
// spawn a puff of smoke behind the rocket
P_SpawnPuff (self, PClass::FindActor(NAME_BulletPuff), self->X(), self->Y(), self->Z(), 0, 3);
P_SpawnPuff (self, PClass::FindActor(NAME_BulletPuff), self->Pos(), self->angle, self->angle, 3);
smoke = Spawn ("RevenantTracerSmoke", self->Vec3Offset(-self->velx, -self->vely, 0), ALLOW_REPLACE);

View file

@ -638,7 +638,7 @@ void DImpactDecal::CheckMax ()
}
}
DImpactDecal *DImpactDecal::StaticCreate (const char *name, fixed_t x, fixed_t y, fixed_t z, side_t *wall, F3DFloor * ffloor, PalEntry color)
DImpactDecal *DImpactDecal::StaticCreate (const char *name, const fixedvec3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color)
{
if (cl_maxdecals > 0)
{
@ -646,13 +646,13 @@ DImpactDecal *DImpactDecal::StaticCreate (const char *name, fixed_t x, fixed_t y
if (tpl != NULL && (tpl = tpl->GetDecal()) != NULL)
{
return StaticCreate (tpl, x, y, z, wall, ffloor, color);
return StaticCreate (tpl, pos, wall, ffloor, color);
}
}
return NULL;
}
DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, fixed_t x, fixed_t y, fixed_t z, side_t *wall, F3DFloor * ffloor, PalEntry color)
DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, const fixedvec3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color)
{
DImpactDecal *decal = NULL;
if (tpl != NULL && cl_maxdecals > 0 && !(wall->Flags & WALLF_NOAUTODECALS))
@ -666,16 +666,16 @@ DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, fixed_t x,
// apply the custom color as well.
if (tpl->ShadeColor != tpl_low->ShadeColor) lowercolor=0;
else lowercolor = color;
StaticCreate (tpl_low, x, y, z, wall, ffloor, lowercolor);
StaticCreate (tpl_low, pos, wall, ffloor, lowercolor);
}
DImpactDecal::CheckMax();
decal = new DImpactDecal (z);
decal = new DImpactDecal (pos.z);
if (decal == NULL)
{
return NULL;
}
if (!decal->StickToWall (wall, x, y, ffloor).isValid())
if (!decal->StickToWall (wall, pos.x, pos.y, ffloor).isValid())
{
return NULL;
}
@ -692,7 +692,7 @@ DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, fixed_t x,
}
// Spread decal to nearby walls if it does not all fit on this one
decal->Spread (tpl, wall, x, y, z, ffloor);
decal->Spread (tpl, wall, pos.x, pos.y, pos.z, ffloor);
}
return decal;
}
@ -779,22 +779,20 @@ DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t *
{
if (permanent)
{
decal = new DBaseDecal(trace.Z);
decal = new DBaseDecal(trace.HitPos.z);
wall = trace.Line->sidedef[trace.Side];
decal->StickToWall(wall, trace.X, trace.Y, trace.ffloor);
decal->StickToWall(wall, trace.HitPos.x, trace.HitPos.y, trace.ffloor);
tpl->ApplyToDecal(decal, wall);
// Spread decal to nearby walls if it does not all fit on this one
if (cl_spreaddecals)
{
decal->Spread(tpl, wall, trace.X, trace.Y, trace.Z, trace.ffloor);
decal->Spread(tpl, wall, trace.HitPos.x, trace.HitPos.y, trace.HitPos.z, trace.ffloor);
}
return decal;
}
else
{
return DImpactDecal::StaticCreate(tpl,
trace.X, trace.Y, trace.Z,
trace.Line->sidedef[trace.Side], NULL);
return DImpactDecal::StaticCreate(tpl, trace.HitPos, trace.Line->sidedef[trace.Side], NULL);
}
}
return NULL;

View file

@ -63,8 +63,8 @@ public:
DImpactDecal (fixed_t z);
DImpactDecal (side_t *wall, const FDecalTemplate *templ);
static DImpactDecal *StaticCreate (const char *name, fixed_t x, fixed_t y, fixed_t z, side_t *wall, F3DFloor * ffloor, PalEntry color=0);
static DImpactDecal *StaticCreate (const FDecalTemplate *tpl, fixed_t x, fixed_t y, fixed_t z, side_t *wall, F3DFloor * ffloor, PalEntry color=0);
static DImpactDecal *StaticCreate (const char *name, const fixedvec3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color=0);
static DImpactDecal *StaticCreate (const FDecalTemplate *tpl, const fixedvec3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color=0);
void BeginPlay ();
void Destroy ();

View file

@ -141,18 +141,18 @@ enum EPuffFlags
PF_NORANDOMZ = 16
};
AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags = 0, AActor *vict = NULL);
inline AActor *P_SpawnPuff(AActor *source, PClassActor *pufftype, const fixedvec3 &pos, angle_t dir, int updown, int flags = 0, AActor *vict = NULL)
AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t hitdir, angle_t particledir, int updown, int flags = 0, AActor *vict = NULL);
inline AActor *P_SpawnPuff(AActor *source, PClassActor *pufftype, const fixedvec3 &pos, angle_t hitdir, angle_t particledir, int updown, int flags = 0, AActor *vict = NULL)
{
return P_SpawnPuff(source, pufftype, pos.x, pos.y, pos.z, dir, updown, flags, vict);
return P_SpawnPuff(source, pufftype, pos.x, pos.y, pos.z, hitdir, particledir, updown, flags, vict);
}
void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AActor *originator);
inline void P_SpawnBlood(const fixedvec3 &pos, angle_t dir, int damage, AActor *originator)
{
P_SpawnBlood(pos.x, pos.y, pos.z, dir, damage, originator);
}
void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator);
void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator);
void P_BloodSplatter (fixedvec3 pos, AActor *originator);
void P_BloodSplatter2 (fixedvec3 pos, AActor *originator);
void P_RipperBlood (AActor *mo, AActor *bleeder);
int P_GetThingFloorType (AActor *thing);
void P_ExplodeMissile (AActor *missile, line_t *explodeline, AActor *target);
@ -328,12 +328,20 @@ enum // P_LineAttack flags
AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, PClassActor *pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL);
AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, FName pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL);
void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target, angle_t angle, int pitch);
inline void P_TraceBleed(int damage, const fixedvec3 &pos, AActor *target, angle_t angle, int pitch)
{
P_TraceBleed(damage, pos.x, pos.y, pos.z, target, angle, pitch);
}
void P_TraceBleed (int damage, AActor *target, angle_t angle, int pitch);
void P_TraceBleed (int damage, AActor *target, AActor *missile); // missile version
void P_TraceBleed(int damage, FTranslatedLineTarget *t, AActor *puff); // hitscan version
void P_TraceBleed (int damage, AActor *target); // random direction version
bool P_HitFloor (AActor *thing);
bool P_HitWater (AActor *thing, sector_t *sec, fixed_t splashx = FIXED_MIN, fixed_t splashy = FIXED_MIN, fixed_t splashz=FIXED_MIN, bool checkabove = false, bool alert = true, bool force = false);
inline bool P_HitWater(AActor *thing, sector_t *sec, const fixedvec3 &pos, bool checkabove = false, bool alert = true, bool force = false)
{
return P_HitWater(thing, sec, pos.x, pos.y, pos.z, checkabove, alert, force);
}
void P_CheckSplash(AActor *self, fixed_t distance);
void P_RailAttack (AActor *source, int damage, int offset_xy, fixed_t offset_z = 0, int color1 = 0, int color2 = 0, double maxdiff = 0, int flags = 0, PClassActor *puff = NULL, angle_t angleoffset = 0, angle_t pitchoffset = 0, fixed_t distance = 8192*FRACUNIT, int duration = 0, double sparsity = 1.0, double drift = 1.0, PClassActor *spawnclass = NULL, int SpiralOffset = 270); // [RH] Shoot a railgun

View file

@ -65,8 +65,7 @@ CVAR(Bool, cl_doautoaim, false, CVAR_ARCHIVE)
static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, fixedvec2 * posforwindowcheck = NULL);
static void SpawnShootDecal(AActor *t1, const FTraceResults &trace);
static void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff,
fixed_t vx, fixed_t vy, fixed_t vz, fixed_t shootz, bool ffloor = false);
static void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff);
static FRandom pr_tracebleed("TraceBleed");
static FRandom pr_checkthing("CheckThing");
@ -245,7 +244,7 @@ static bool PIT_FindFloorCeiling(FMultiBlockLinesIterator &mit, FMultiBlockLines
if (open.top < tmf.ceilingz)
{
tmf.ceilingz = open.top;
if (open.topsec != NULL) tmf.floorsector = open.topsec;
if (open.topsec != NULL) tmf.ceilingsector = open.topsec;
if (ffcf_verbose) Printf(" Adjust ceilingz to %f\n", FIXED2FLOAT(open.top));
mit.StopUp();
}
@ -1527,7 +1526,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch
!(tm.thing->flags3 & MF3_BLOODLESSIMPACT) &&
(pr_checkthing() < 192))
{
P_BloodSplatter(tm.thing->X(), tm.thing->Y(), tm.thing->Z(), thing);
P_BloodSplatter(tm.thing->Pos(), thing);
}
if (!(tm.thing->flags3 & MF3_BLOODLESSIMPACT))
{
@ -3667,7 +3666,7 @@ struct aim_t
void EnterSectorPortal(int position, fixed_t frac, sector_t *entersec, fixed_t newtoppitch, fixed_t newbottompitch)
{
AActor *portal = entersec->SkyBoxes[position];
if (portal == NULL)
if (position == sector_t::ceiling && portal->threshold < limitz) return;
else if (position == sector_t::floor && portal->threshold > limitz) return;
aim_t newtrace = Clone();
@ -3779,7 +3778,7 @@ struct aim_t
if (aimdebug)
Printf("Start AimTraverse, start = %f,%f,%f, vect = %f,%f,%f\n",
startpos.x / 65536., startpos.y / 65536., startpos.y / 65536.,
startpos.x / 65536., startpos.y / 65536., startpos.z / 65536.,
aimtrace.x / 65536., aimtrace.y / 65536.);
while ((in = it.Next()))
@ -4102,7 +4101,7 @@ fixed_t P_AimLineAttack(AActor *t1, angle_t angle, fixed_t distance, FTranslated
//==========================================================================
//
//
// Helper stuff for P_LineAttack
//
//==========================================================================
@ -4231,7 +4230,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
}
if (puffDefaults != NULL && puffDefaults->flags3 & MF3_ALWAYSPUFF)
{ // Spawn the puff anyway
puff = P_SpawnPuff(t1, pufftype, trace.X, trace.Y, trace.Z, angle - ANG180, 2, puffFlags);
puff = P_SpawnPuff(t1, pufftype, trace.HitPos, trace.SrcAngleToTarget, trace.SrcAngleToTarget, 2, puffFlags);
}
else
{
@ -4240,21 +4239,19 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
}
else
{
fixed_t hitx = 0, hity = 0, hitz = 0;
if (trace.HitType != TRACE_HitActor)
{
// position a bit closer for puffs
if (trace.HitType != TRACE_HitWall || trace.Line->special != Line_Horizon)
{
fixed_t closer = trace.Distance - 4 * FRACUNIT;
fixedvec2 pos = t1->Vec2Offset(FixedMul(vx, closer), FixedMul(vy, closer));
puff = P_SpawnPuff(t1, pufftype, pos.x, pos.y,
shootz + FixedMul(vz, closer), angle - ANG90, 0, puffFlags);
fixedvec2 pos = P_GetOffsetPosition(trace.HitPos.x, trace.HitPos.y, -trace.HitVector.x * 4, -trace.HitVector.y * 4);
puff = P_SpawnPuff(t1, pufftype, pos.x, pos.y, trace.HitPos.z - trace.HitVector.z * 4, trace.SrcAngleToTarget,
trace.SrcAngleToTarget - ANGLE_90, 0, puffFlags);
puff->radius = 1;
}
// [RH] Spawn a decal
if (trace.HitType == TRACE_HitWall && trace.Line->special != Line_Horizon && !(flags & LAF_NOIMPACTDECAL) && !(puffDefaults->flags7 & MF7_NODECAL))
if (trace.HitType == TRACE_HitWall && trace.Line->special != Line_Horizon && !trace.Line->isVisualPortal() && !(flags & LAF_NOIMPACTDECAL) && !(puffDefaults->flags7 & MF7_NODECAL))
{
// [TN] If the actor or weapon has a decal defined, use that one.
if (t1->DecalGenerator != NULL ||
@ -4283,7 +4280,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
trace.Sector->heightsec == NULL &&
trace.HitType == TRACE_HitFloor)
{
P_HitWater(puff, trace.Sector, trace.X, trace.Y, trace.Z);
P_HitWater(puff, trace.Sector, trace.HitPos);
}
}
else
@ -4297,14 +4294,13 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
(t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD));
// Hit a thing, so it could be either a puff or blood
fixed_t dist = trace.Distance;
fixedvec3 bleedpos = trace.HitPos;
// position a bit closer for puffs/blood if using compatibility mode.
if (i_compatflags & COMPATF_HITSCAN) dist -= 10 * FRACUNIT;
hitx = t1->X() + FixedMul(vx, dist);
hity = t1->Y() + FixedMul(vy, dist);
hitz = shootz + FixedMul(vz, dist);
if (i_compatflags & COMPATF_HITSCAN)
{
fixedvec2 ofs = P_GetOffsetPosition(bleedpos.x, bleedpos.y, -10 * trace.HitVector.x, -10 * trace.HitVector.y);
bleedpos -= { ofs.x, ofs.y, -10 * trace.HitVector.z};
}
// Spawn bullet puffs or blood spots, depending on target type.
if ((puffDefaults != NULL && puffDefaults->flags3 & MF3_PUFFONACTORS) ||
@ -4315,7 +4311,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
puffFlags |= PF_HITTHINGBLEED;
// We must pass the unreplaced puff type here
puff = P_SpawnPuff(t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, puffFlags | PF_HITTHING, trace.Actor);
puff = P_SpawnPuff(t1, pufftype, bleedpos, trace.SrcAngleToTarget, trace.SrcAngleToTarget - ANGLE_90, 2, puffFlags | PF_HITTHING, trace.Actor);
}
// Allow puffs to inflict poison damage, so that hitscans can poison, too.
@ -4341,11 +4337,10 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
{
// Since the puff is the damage inflictor we need it here
// regardless of whether it is displayed or not.
puff = P_SpawnPuff(t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, puffFlags | PF_HITTHING | PF_TEMPORARY);
puff = P_SpawnPuff(t1, pufftype, bleedpos, 0, 0, 2, puffFlags | PF_HITTHING | PF_TEMPORARY);
killPuff = true;
}
#pragma message("damage angle")
newdam = P_DamageMobj(trace.Actor, puff ? puff : t1, t1, damage, damageType, dmgflags);
newdam = P_DamageMobj(trace.Actor, puff ? puff : t1, t1, damage, damageType, dmgflags|DMG_USEANGLE, trace.SrcAngleToTarget);
if (actualdamage != NULL)
{
*actualdamage = newdam;
@ -4357,7 +4352,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
!(trace.Actor->flags & MF_NOBLOOD) &&
!(trace.Actor->flags2 & (MF2_INVULNERABLE | MF2_DORMANT)))
{
P_SpawnBlood(hitx, hity, hitz, angle - ANG180, newdam > 0 ? newdam : damage, trace.Actor);
P_SpawnBlood(bleedpos, trace.SrcAngleToTarget, newdam > 0 ? newdam : damage, trace.Actor);
}
if (damage)
@ -4369,35 +4364,34 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
{
if (axeBlood)
{
P_BloodSplatter2(hitx, hity, hitz, trace.Actor);
P_BloodSplatter2(bleedpos, trace.Actor);
}
if (pr_lineattack() < 192)
{
P_BloodSplatter(hitx, hity, hitz, trace.Actor);
P_BloodSplatter(bleedpos, trace.Actor);
}
}
}
// [RH] Stick blood to walls
P_TraceBleed(newdam > 0 ? newdam : damage, trace.X, trace.Y, trace.Z,
trace.Actor, srcangle, srcpitch);
P_TraceBleed(newdam > 0 ? newdam : damage, trace.HitPos,
trace.Actor, trace.SrcAngleToTarget, srcpitch);
}
}
if (victim != NULL)
{
victim->linetarget = trace.Actor;
victim->angleFromSource = R_PointToAngle2(t1->X(), t1->Y(), trace.Actor->X(), trace.Actor->Y());
victim->unlinked = false;
victim->angleFromSource = trace.SrcAngleToTarget;
victim->unlinked = trace.unlinked;
}
}
if (trace.Crossed3DWater || trace.CrossedWater)
{
if (puff == NULL)
{ // Spawn puff just to get a mass for the splash
puff = P_SpawnPuff(t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, puffFlags | PF_HITTHING | PF_TEMPORARY);
puff = P_SpawnPuff(t1, pufftype, trace.HitPos, 0, 0, 2, puffFlags | PF_HITTHING | PF_TEMPORARY);
killPuff = true;
}
SpawnDeepSplash(t1, trace, puff, vx, vy, vz, shootz, trace.Crossed3DWater != NULL);
SpawnDeepSplash(t1, trace, puff);
}
}
if (killPuff && puff != NULL)
@ -4553,11 +4547,8 @@ void P_TraceBleed(int damage, fixed_t x, fixed_t y, fixed_t z, AActor *actor, an
bloodcolor.a = 1;
}
DImpactDecal::StaticCreate(bloodType,
bleedtrace.X, bleedtrace.Y, bleedtrace.Z,
bleedtrace.Line->sidedef[bleedtrace.Side],
bleedtrace.ffloor,
bloodcolor);
DImpactDecal::StaticCreate(bloodType, bleedtrace.HitPos,
bleedtrace.Line->sidedef[bleedtrace.Side], bleedtrace.ffloor, bloodcolor);
}
}
}
@ -4645,7 +4636,8 @@ void P_TraceBleed(int damage, AActor *target)
struct SRailHit
{
AActor *HitActor;
fixed_t Distance;
fixedvec3 HitPos;
angle_t HitAngle;
};
struct RailData
{
@ -4679,7 +4671,13 @@ static ETraceStatus ProcessRailHit(FTraceResults &res, void *userdata)
// Save this thing for damaging later, and continue the trace
SRailHit newhit;
newhit.HitActor = res.Actor;
newhit.Distance = res.Distance - 10 * FRACUNIT; // put blood in front
newhit.HitPos = res.HitPos;
newhit.HitAngle = res.SrcAngleToTarget;
if (i_compatflags & COMPATF_HITSCAN)
{
fixedvec2 ofs = P_GetOffsetPosition(newhit.HitPos.x, newhit.HitPos.y, -10 * res.HitVector.x, -10 * res.HitVector.y);
newhit.HitPos = { ofs.x, ofs.y, -10 * res.HitVector.z};
}
data->RailHits.Push(newhit);
return data->StopAtOne ? TRACE_Stop : TRACE_Continue;
@ -4761,17 +4759,13 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
{
fixed_t x, y, z;
bool spawnpuff;
bool bleed = false;
int puffflags = PF_HITTHING;
AActor *hitactor = rail_data.RailHits[i].HitActor;
fixed_t hitdist = rail_data.RailHits[i].Distance;
x = xy.x + FixedMul(hitdist, vx);
y = xy.y + FixedMul(hitdist, vy);
z = shootz + FixedMul(hitdist, vz);
fixedvec3 &hitpos = rail_data.RailHits[i].HitPos;
angle_t hitangle = rail_data.RailHits[i].HitAngle;
if ((hitactor->flags & MF_NOBLOOD) ||
(hitactor->flags2 & MF2_DORMANT || ((hitactor->flags2 & MF2_INVULNERABLE) && !(puffDefaults->flags3 & MF3_FOILINVUL))))
@ -4789,7 +4783,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
}
if (spawnpuff)
{
P_SpawnPuff(source, puffclass, x, y, z, (source->angle + angleoffset) - ANG90, 1, puffflags, hitactor);
P_SpawnPuff(source, puffclass, hitpos, trace.SrcAngleToTarget, trace.SrcAngleToTarget - ANGLE_90, 1, puffflags, hitactor);
}
int dmgFlagPass = DMG_INFLICTOR_IS_PUFF;
@ -4802,13 +4796,12 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
if (puffDefaults->flags3 & MF3_FOILINVUL) dmgFlagPass |= DMG_FOILINVUL;
if (puffDefaults->flags7 & MF7_FOILBUDDHA) dmgFlagPass |= DMG_FOILBUDDHA;
}
#pragma message("damage angle")
int newdam = P_DamageMobj(hitactor, thepuff ? thepuff : source, source, damage, damagetype, dmgFlagPass);
int newdam = P_DamageMobj(hitactor, thepuff ? thepuff : source, source, damage, damagetype, dmgFlagPass|DMG_USEANGLE, hitangle);
if (bleed)
{
P_SpawnBlood(x, y, z, (source->angle + angleoffset) - ANG180, newdam > 0 ? newdam : damage, hitactor);
P_TraceBleed(newdam > 0 ? newdam : damage, x, y, z, hitactor, source->angle, pitch);
P_SpawnBlood(hitpos, hitangle, newdam > 0 ? newdam : damage, hitactor);
P_TraceBleed(newdam > 0 ? newdam : damage, hitpos, hitactor, source->angle, pitch);
}
}
@ -4819,7 +4812,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
if (puffclass != NULL && puffDefaults->flags3 & MF3_ALWAYSPUFF)
{
puff = P_SpawnPuff(source, puffclass, trace.X, trace.Y, trace.Z, (source->angle + angleoffset) - ANG90, 1, 0);
puff = P_SpawnPuff(source, puffclass, trace.HitPos, trace.SrcAngleToTarget, trace.SrcAngleToTarget - ANGLE_90, 1, 0);
if (puff && (trace.Line != NULL) && (trace.Line->special == Line_Horizon) && !(puff->flags3 & MF3_SKYEXPLODE))
puff->Destroy();
}
@ -4834,7 +4827,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
AActor* puff = NULL;
if (puffclass != NULL && puffDefaults->flags3 & MF3_ALWAYSPUFF)
{
puff = P_SpawnPuff(source, puffclass, trace.X, trace.Y, trace.Z, (source->angle + angleoffset) - ANG90, 1, 0);
puff = P_SpawnPuff(source, puffclass, trace.HitPos, trace.SrcAngleToTarget, trace.SrcAngleToTarget - ANGLE_90, 1, 0);
if (puff && !(puff->flags3 & MF3_SKYEXPLODE) &&
(((trace.HitType == TRACE_HitFloor) && (puff->floorpic == skyflatnum)) ||
((trace.HitType == TRACE_HitCeiling) && (puff->ceilingpic == skyflatnum))))
@ -4845,23 +4838,21 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
}
if (thepuff != NULL)
{
if (trace.HitType == TRACE_HitFloor &&
trace.CrossedWater == NULL &&
trace.Sector->heightsec == NULL)
{
P_HitWater(thepuff, trace.Sector, trace.X, trace.Y, trace.Z);
}
if (trace.Crossed3DWater || trace.CrossedWater)
{
SpawnDeepSplash(source, trace, thepuff, vx, vy, vz, shootz, trace.Crossed3DWater != NULL);
SpawnDeepSplash(source, trace, thepuff);
}
else if (trace.HitType == TRACE_HitFloor && trace.Sector->heightsec == NULL)
{
P_HitWater(thepuff, trace.Sector, trace.HitPos);
}
thepuff->Destroy();
}
// Draw the slug's trail.
end.X = FIXED2DBL(trace.X);
end.Y = FIXED2DBL(trace.Y);
end.Z = FIXED2DBL(trace.Z);
end.X = FIXED2DBL(trace.HitPos.x);
end.Y = FIXED2DBL(trace.HitPos.y);
end.Z = FIXED2DBL(trace.HitPos.z);
P_DrawRailTrail(source, start, end, color1, color2, maxdiff, railflags, spawnclass, source->angle + angleoffset, duration, sparsity, drift, SpiralOffset);
}
@ -4900,9 +4891,9 @@ void P_AimCamera(AActor *t1, fixed_t &CameraX, fixed_t &CameraY, fixed_t &Camera
}
else
{
CameraX = trace.X;
CameraY = trace.Y;
CameraZ = trace.Z;
CameraX = trace.HitPos.x;
CameraY = trace.HitPos.y;
CameraZ = trace.HitPos.z;
}
CameraSector = trace.Sector;
unlinked = trace.unlinked;
@ -6426,7 +6417,7 @@ void SpawnShootDecal(AActor *t1, const FTraceResults &trace)
if (decalbase != NULL)
{
DImpactDecal::StaticCreate(decalbase->GetDecal(),
trace.X, trace.Y, trace.Z, trace.Line->sidedef[trace.Side], trace.ffloor);
trace.HitPos, trace.Line->sidedef[trace.Side], trace.ffloor);
}
}
@ -6436,31 +6427,20 @@ void SpawnShootDecal(AActor *t1, const FTraceResults &trace)
//
//==========================================================================
static void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff,
fixed_t vx, fixed_t vy, fixed_t vz, fixed_t shootz, bool ffloor)
static void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff)
{
const secplane_t *plane;
if (ffloor && trace.Crossed3DWater)
plane = trace.Crossed3DWater->top.plane;
const fixedvec3 *hitpos;
if (trace.Crossed3DWater)
{
hitpos = &trace.Crossed3DWaterPos;
}
else if (trace.CrossedWater && trace.CrossedWater->heightsec)
plane = &trace.CrossedWater->heightsec->floorplane;
{
hitpos = &trace.CrossedWaterPos;
}
else return;
fixed_t num, den, hitdist;
den = TMulScale16(plane->a, vx, plane->b, vy, plane->c, vz);
if (den != 0)
{
num = TMulScale16(plane->a, t1->X(), plane->b, t1->Y(), plane->c, shootz) + plane->d;
hitdist = FixedDiv(-num, den);
if (hitdist >= 0 && hitdist <= trace.Distance)
{
fixedvec2 hitpos = t1->Vec2Offset(FixedMul(vx, hitdist), FixedMul(vy, hitdist));
fixed_t hitz = shootz + FixedMul(vz, hitdist);
P_HitWater(puff != NULL ? puff : t1, P_PointInSector(hitpos.x, hitpos.y), hitpos.x, hitpos.y, hitz);
}
}
P_HitWater(puff != NULL ? puff : t1, P_PointInSector(hitpos->x, hitpos->y), *hitpos);
}
//=============================================================================

View file

@ -1444,8 +1444,7 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target)
}
}
DImpactDecal::StaticCreate (base->GetDecal (),
x, y, z, line->sidedef[side], ffloor);
DImpactDecal::StaticCreate(base->GetDecal(), { x, y, z }, line->sidedef[side], ffloor);
}
}
}
@ -5228,7 +5227,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
// P_SpawnPuff
//
AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags, AActor *vict)
AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t hitdir, angle_t particledir, int updown, int flags, AActor *vict)
{
AActor *puff;
@ -5256,8 +5255,8 @@ AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y
if ( puff && (puff->flags5 & MF5_PUFFGETSOWNER))
puff->target = source;
if (source != NULL) puff->angle = puff->AngleTo(source);
// Angle is the opposite of the hit direction (i.e. the puff faces the source.)
puff->angle = hitdir + ANGLE_180;
// If a puff has a crash state and an actor was not hit,
// it will enter the crash state. This is used by the StrifeSpark
@ -5282,7 +5281,7 @@ AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y
{
if (cl_pufftype && updown != 3 && (puff->flags4 & MF4_ALLOWPARTICLES))
{
P_DrawSplash2 (32, x, y, z, dir, updown, 1);
P_DrawSplash2 (32, x, y, z, particledir, updown, 1);
puff->renderflags |= RF_INVISIBLE;
}
@ -5402,7 +5401,7 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc
//
//---------------------------------------------------------------------------
void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
void P_BloodSplatter (fixedvec3 pos, AActor *originator)
{
PalEntry bloodcolor = originator->GetBloodColor();
PClassActor *bloodcls = originator->GetBloodType(1);
@ -5416,7 +5415,7 @@ void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
{
AActor *mo;
mo = Spawn(bloodcls, x, y, z, NO_REPLACE); // GetBloodType already performed the replacement
mo = Spawn(bloodcls, pos, NO_REPLACE); // GetBloodType already performed the replacement
mo->target = originator;
mo->velx = pr_splatter.Random2 () << 10;
mo->vely = pr_splatter.Random2 () << 10;
@ -5432,7 +5431,7 @@ void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
}
if (bloodtype >= 1)
{
P_DrawSplash2 (40, x, y, z, 0u - originator->AngleTo(x, y), 2, bloodcolor);
P_DrawSplash2 (40, pos.x, pos.y, pos.z, 0u - originator->AngleTo(pos), 2, bloodcolor);
}
}
@ -5442,7 +5441,7 @@ void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
//
//===========================================================================
void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
void P_BloodSplatter2 (fixedvec3 pos, AActor *originator)
{
PalEntry bloodcolor = originator->GetBloodColor();
PClassActor *bloodcls = originator->GetBloodType(2);
@ -5456,10 +5455,10 @@ void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
{
AActor *mo;
x += ((pr_splat()-128)<<11);
y += ((pr_splat()-128)<<11);
pos.x += ((pr_splat()-128)<<11);
pos.y += ((pr_splat()-128)<<11);
mo = Spawn (bloodcls, x, y, z, NO_REPLACE); // GetBloodType already performed the replacement
mo = Spawn (bloodcls, pos, NO_REPLACE); // GetBloodType already performed the replacement
mo->target = originator;
// colorize the blood!
@ -5472,7 +5471,7 @@ void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
}
if (bloodtype >= 1)
{
P_DrawSplash2 (100, x, y, z, 0u - originator->AngleTo(x, y), 2, bloodcolor);
P_DrawSplash2 (100, pos.x, pos.y, pos.z, 0u - originator->AngleTo(pos), 2, bloodcolor);
}
}
@ -5733,7 +5732,7 @@ bool P_HitFloor (AActor *thing)
{
if (rover->top.plane->ZatPoint(pos.x, pos.y) == thing->Z())
{
return P_HitWater (thing, m->m_sector, pos.x, pos.y, pos.z);
return P_HitWater (thing, m->m_sector, pos);
}
}
}
@ -5743,7 +5742,7 @@ bool P_HitFloor (AActor *thing)
return false;
}
return P_HitWater (thing, m->m_sector, pos.x, pos.y, pos.z);
return P_HitWater (thing, m->m_sector, pos);
}
//---------------------------------------------------------------------------

View file

@ -87,11 +87,18 @@ struct FTraceInfo
return CheckPlane(checkFloor ? sector->floorplane : sector->ceilingplane);
}
bool FTraceInfo::Check3DFloorPlane(const F3DFloor *ffloor, bool checkBottom)
bool Check3DFloorPlane(const F3DFloor *ffloor, bool checkBottom)
{
return CheckPlane(checkBottom? *(ffloor->bottom.plane) : *(ffloor->top.plane));
}
void SetSourcePosition()
{
Results->SrcFromTarget = { StartX, StartY, StartZ };
Results->HitVector = { Vx, Vy, Vz };
Results->SrcAngleToTarget = R_PointToAngle2(0, 0, Results->HitPos.x - StartX, Results->HitPos.y - StartY);
}
};
@ -227,7 +234,7 @@ void FTraceInfo::EnterSectorPortal(int position, fixed_t frac, sector_t *enterse
if (newtrace.TraceTraverse(ActorMask ? PT_ADDLINES | PT_ADDTHINGS | PT_COMPATIBLE : PT_ADDLINES))
{
Results->CopyIfCloser(TempResults);
TempResults->CopyIfCloser(newtrace.Results);
}
}
@ -319,7 +326,7 @@ void FTraceInfo::Setup3DFloors()
if (Check3DFloorPlane(rover, false))
{
Results->Crossed3DWater = rover;
Results->Crossed3DWaterPos = { Results->X, Results->Y, Results->Z };
Results->Crossed3DWaterPos = Results->HitPos;
}
}
@ -468,7 +475,7 @@ bool FTraceInfo::LineCheck(intercept_t *in)
if (CheckSectorPlane(hsec, true))
{
Results->CrossedWater = &sectors[CurSector->sectornum];
Results->CrossedWaterPos = { Results->X, Results->Y, Results->Z };
Results->CrossedWaterPos = Results->HitPos;
}
}
@ -645,9 +652,8 @@ cont:
if (Results->HitType == TRACE_HitWall)
{
Results->X = hitx;
Results->Y = hity;
Results->Z = hitz;
Results->HitPos = { hitx, hity, hitz };
SetSourcePosition();
Results->Distance = dist;
Results->Fraction = in->frac;
Results->Line = in->d.line;
@ -773,9 +779,8 @@ cont1:
Results->HitType = TRACE_HitActor;
Results->X = hitx;
Results->Y = hity;
Results->Z = hitz;
Results->HitPos = { hitx, hity, hitz };
SetSourcePosition();
Results->Distance = dist;
Results->Fraction = in->frac;
Results->Actor = in->d.thing;
@ -823,7 +828,7 @@ bool FTraceInfo::TraceTraverse (int ptflags)
if (Check3DFloorPlane(rover, false))
{
Results->Crossed3DWater = rover;
Results->Crossed3DWaterPos = { Results->X, Results->Y, Results->Z };
Results->Crossed3DWaterPos = Results->HitPos;
}
}
}
@ -852,7 +857,7 @@ bool FTraceInfo::TraceTraverse (int ptflags)
// We still need to do a water check here or this may get missed on occasion
if (Results->CrossedWater == NULL &&
CurSector->heightsec != NULL &&
CurSector->heightsec->floorplane.ZatPoint(Results->X, Results->Y) >= Results->Z)
CurSector->heightsec->floorplane.ZatPoint(Results->HitPos) >= Results->HitPos.z)
{
// Save the result so that the water check doesn't destroy it.
FTraceResults *res = Results;
@ -862,7 +867,7 @@ bool FTraceInfo::TraceTraverse (int ptflags)
if (CheckSectorPlane(CurSector->heightsec, true))
{
Results->CrossedWater = &sectors[CurSector->sectornum];
Results->CrossedWaterPos = { Results->X, Results->Y, Results->Z };
Results->CrossedWaterPos = Results->HitPos;
}
Results = res;
}
@ -889,7 +894,7 @@ bool FTraceInfo::TraceTraverse (int ptflags)
if (Results->CrossedWater == NULL &&
CurSector->heightsec != NULL &&
CurSector->heightsec->floorplane.ZatPoint(Results->X, Results->Y) >= Results->Z)
CurSector->heightsec->floorplane.ZatPoint(Results->HitPos) >= Results->HitPos.z)
{
// Save the result so that the water check doesn't destroy it.
FTraceResults *res = Results;
@ -899,15 +904,17 @@ bool FTraceInfo::TraceTraverse (int ptflags)
if (CheckSectorPlane(CurSector->heightsec, true))
{
Results->CrossedWater = &sectors[CurSector->sectornum];
Results->CrossedWaterPos = { Results->X, Results->Y, Results->Z };
Results->CrossedWaterPos = Results->HitPos;
}
Results = res;
}
if (Results->HitType == TRACE_HitNone && Results->Distance == 0)
{
Results->X = StartX + FixedMul(Vx, MaxDist);
Results->Y = StartY + FixedMul(Vy, MaxDist);
Results->Z = StartZ + FixedMul(Vz, MaxDist);
Results->HitPos = {
StartX + FixedMul(Vx, MaxDist),
StartY + FixedMul(Vy, MaxDist),
StartZ + FixedMul(Vz, MaxDist) };
SetSourcePosition();
Results->Distance = MaxDist;
Results->Fraction = FRACUNIT;
}
@ -934,9 +941,11 @@ bool FTraceInfo::CheckPlane (const secplane_t &plane)
if (hitdist > EnterDist && hitdist < MaxDist)
{
Results->X = StartX + FixedMul (Vx, hitdist);
Results->Y = StartY + FixedMul (Vy, hitdist);
Results->Z = StartZ + FixedMul (Vz, hitdist);
Results->HitPos = {
StartX + FixedMul(Vx, hitdist),
StartY + FixedMul(Vy, hitdist),
StartZ + FixedMul(Vz, hitdist) };
SetSourcePosition();
Results->Distance = hitdist;
Results->Fraction = FixedDiv (hitdist, MaxDist);
return true;

View file

@ -65,7 +65,8 @@ struct FTraceResults
{
sector_t *Sector;
FTextureID HitTexture;
fixed_t X, Y, Z;
fixedvec3 HitPos;
fixedvec3 HitVector;
fixedvec3 SrcFromTarget;
angle_t SrcAngleToTarget;

View file

@ -1078,11 +1078,6 @@ void P_CreateLinkedPortals()
//
//============================================================================
static bool ProcessLayer()
{
}
bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t upperz, fixed_t checkradius, FPortalGroupArray &out)
{
// Keep this temporary work stuff static. This function can never be called recursively

View file

@ -5178,7 +5178,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack)
if ((0 && dpuff->flags3 & MF3_PUFFONACTORS) || !spawnblood)
{
spawnblood = false;
P_SpawnPuff(self, pufftype, bloodpos, angle, 0);
P_SpawnPuff(self, pufftype, bloodpos, angle, angle, 0);
}
}
else if (self->target->flags3 & MF3_GHOST)