Generalized hitnormal functions (where possible).

This commit is contained in:
Mari the Deer 2022-12-18 20:03:36 +01:00
commit b1683dae8e
24 changed files with 206 additions and 785 deletions

View file

@ -520,23 +520,8 @@ extend Class SWWMWeapon
FLineTraceData d;
LineTrace(angle,DEFMELEERANGE*rangemul,slope,TRF_THRUACTORS,player.viewheight,data:d);
if ( d.HitType == TRACE_HitNone ) return res;
Vector3 HitNormal = -d.HitDir;
if ( d.HitType == TRACE_HitFloor )
{
if ( d.Hit3DFloor ) HitNormal = -d.Hit3DFloor.top.Normal;
else HitNormal = d.HitSector.floorplane.Normal;
}
else if ( d.HitType == TRACE_HitCeiling )
{
if ( d.Hit3DFloor ) HitNormal = -d.Hit3DFloor.bottom.Normal;
else HitNormal = d.HitSector.ceilingplane.Normal;
}
else if ( d.HitType == TRACE_HitWall )
{
HitNormal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit();
if ( !d.LineSide ) HitNormal *= -1;
d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation+HitNormal*4);
}
Vector3 HitNormal = SWWMUtility.GetLineTraceHitNormal(d);
if ( d.HitType == TRACE_HitWall ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
if ( impactclass )
{
let p = Spawn(raging?(Class<Actor>)("BigPunchImpact"):impactclass,d.HitLocation+HitNormal*4);

View file

@ -334,24 +334,8 @@ Class HellblazerMissile : Actor
ang = FRandom[Hellblazer](0,360);
pt = FRandom[Hellblazer](-90,90);
FLineTraceData d;
Vector3 HitNormal;
LineTrace(ang,FRandom[Hellblazer](10,20)+10*special1*xscale,pt,TRF_THRUACTORS,data:d);
hitnormal = -d.HitDir;
if ( d.HitType == TRACE_HitFloor )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.top.Normal;
else hitnormal = d.HitSector.floorplane.Normal;
}
else if ( d.HitType == TRACE_HitCeiling )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.bottom.Normal;
else hitnormal = d.HitSector.ceilingplane.Normal;
}
else if ( d.HitType == TRACE_HitWall )
{
hitnormal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit();
if ( !d.LineSide ) hitnormal *= -1;
}
Vector3 HitNormal = SWWMUtility.GetLineTraceHitNormal(d);
let p = Spawn("HellblazerSubExpl",d.HitLocation+hitnormal*4);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
@ -436,45 +420,7 @@ Class HellblazerMissile2 : HellblazerMissile
}
virtual void A_HandleBounce()
{
Vector3 HitNormal = -vel.unit();
F3DFloor ff;
if ( BlockingFloor )
{
// find closest 3d floor for its normal
for ( int i=0; i<BlockingFloor.Get3DFloorCount(); i++ )
{
if ( !(BlockingFloor.Get3DFloor(i).flags&F3DFloor.FF_SOLID) ) continue;
if ( !(BlockingFloor.Get3DFloor(i).top.ZAtPoint(pos.xy) ~== floorz) ) continue;
ff = BlockingFloor.Get3DFloor(i);
break;
}
if ( ff ) HitNormal = -ff.top.Normal;
else HitNormal = BlockingFloor.floorplane.Normal;
}
else if ( BlockingCeiling )
{
// find closest 3d floor for its normal
for ( int i=0; i<BlockingCeiling.Get3DFloorCount(); i++ )
{
if ( !(BlockingCeiling.Get3DFloor(i).flags&F3DFloor.FF_SOLID) ) continue;
if ( !(BlockingCeiling.Get3DFloor(i).bottom.ZAtPoint(pos.xy) ~== ceilingz) ) continue;
ff = BlockingCeiling.Get3DFloor(i);
break;
}
if ( ff ) HitNormal = -ff.bottom.Normal;
else HitNormal = BlockingCeiling.ceilingplane.Normal;
}
else if ( BlockingLine )
{
HitNormal = (-BlockingLine.delta.y,BlockingLine.delta.x,0).unit();
if ( !SWWMUtility.PointOnLineSide(pos.xy,BlockingLine) )
HitNormal *= -1;
}
else if ( BlockingMobj )
{
Vector3 diff = level.Vec3Diff(BlockingMobj.Vec3Offset(0,0,BlockingMobj.Height/2),pos);
HitNormal = diff.unit();
}
Vector3 HitNormal = SWWMUtility.GetActorHitNormal(self);
// undo the bounce, we need to hook in our own
vel = oldvel;
// re-do the bounce with our formula

View file

@ -115,29 +115,14 @@ Class Wallbuster : SWWMWeapon
}
if ( (t.Results.HitType != TRACE_HitNone) && (t.Results.HitType != TRACE_HasHitSky) && (t.Results.HitType != TRACE_HitActor) )
{
Vector3 hitnormal = -t.Results.HitVector;
if ( t.Results.HitType == TRACE_HitFloor )
{
if ( t.Results.FFloor ) hitnormal = -t.Results.FFloor.top.Normal;
else hitnormal = t.Results.HitSector.floorplane.Normal;
}
else if ( t.Results.HitType == TRACE_HitCeiling )
{
if ( t.Results.FFloor ) hitnormal = -t.Results.FFloor.bottom.Normal;
else hitnormal = t.Results.HitSector.ceilingplane.Normal;
}
else if ( t.Results.HitType == TRACE_HitWall )
{
hitnormal = (-t.Results.HitLine.delta.y,t.Results.HitLine.delta.x,0).unit();
if ( !t.Results.Side ) hitnormal *= -1;
}
if ( t.Results.HitLine ) t.Results.HitLine.RemoteActivate(self,t.Results.Side,SPAC_Impact,t.Results.HitPos);
Vector3 hitnormal = SWWMUtility.GetLineTracerHitNormal(t.Results);
let p = Spawn(impact,t.Results.HitPos+hitnormal*4);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
p.target = self;
p.special1 = max(0,(bc-5)/4);
if ( t.Results.HitType == TRACE_HitFloor ) p.CheckSplash(40);
if ( t.Results.HitType == TRACE_HitWall ) t.Results.HitLine.RemoteActivate(self,t.Results.Side,SPAC_Impact,t.Results.HitPos);
}
}
override Vector3 GetTraceOffset( int index )

View file

@ -181,7 +181,7 @@ Class BusterWall : Thinker
{
LineTracer faketracer = new("LineTracer");
F3DFloor ff;
Vector3 HitNormal;
Vector3 HitNormal = (0,0,0);
if ( a.BlockingFloor )
{
// find closest 3d floor for its normal
@ -220,7 +220,7 @@ Class BusterWall : Thinker
faketracer.Results.HitType = TRACE_HitCeiling;
faketracer.Results.HitSector = a.BlockingCeiling;
}
else if ( a.BlockingLine )
else if ( a.BlockingLine && SWWMUtility.BlockingLineIsBlocking(a,Line.ML_BLOCKEVERYTHING|Line.ML_BLOCKPROJECTILE,a.BlockingLine) )
{
HitNormal = (-a.BlockingLine.delta.y,a.BlockingLine.delta.x,0).unit();
int wside = SWWMUtility.PointOnLineSide(a.pos.xy,a.BlockingLine);
@ -238,12 +238,7 @@ Class BusterWall : Thinker
else if ( (a.pos.z+a.Height) <= flor ) faketracer.Results.Tier = TIER_Lower;
}
}
else if ( a.BlockingMobj )
{
Vector3 diff = level.Vec3Diff(a.BlockingMobj.Vec3Offset(0,0,a.BlockingMobj.Height/2),a.pos);
HitNormal = diff.unit();
faketracer.Results.HitType = TRACE_HitActor;
}
else return false; // nothing busted
return Bust(faketracer.Results,accdamage,a.target,x,a.pos.z+a.Height/2.);
}

View file

@ -222,46 +222,7 @@ Class EvisceratorChunk : Actor
void A_HandleBounce()
{
Vector3 HitNormal = (0,0,0);
F3DFloor ff;
if ( BlockingFloor )
{
// find closest 3d floor for its normal
for ( int i=0; i<BlockingFloor.Get3DFloorCount(); i++ )
{
if ( !(BlockingFloor.Get3DFloor(i).flags&F3DFloor.FF_SOLID) ) continue;
if ( !(BlockingFloor.Get3DFloor(i).top.ZAtPoint(pos.xy) ~== floorz) ) continue;
ff = BlockingFloor.Get3DFloor(i);
break;
}
if ( ff ) HitNormal = -ff.top.Normal;
else HitNormal = BlockingFloor.floorplane.Normal;
}
else if ( BlockingCeiling )
{
// find closest 3d floor for its normal
for ( int i=0; i<BlockingCeiling.Get3DFloorCount(); i++ )
{
if ( !(BlockingCeiling.Get3DFloor(i).flags&F3DFloor.FF_SOLID) ) continue;
if ( !(BlockingCeiling.Get3DFloor(i).bottom.ZAtPoint(pos.xy) ~== ceilingz) ) continue;
ff = BlockingCeiling.Get3DFloor(i);
break;
}
if ( ff ) HitNormal = -ff.bottom.Normal;
else HitNormal = BlockingCeiling.ceilingplane.Normal;
}
else if ( BlockingLine )
{
HitNormal = (-BlockingLine.delta.y,BlockingLine.delta.x,0).unit();
if ( !SWWMUtility.PointOnLineSide(pos.xy,BlockingLine) )
HitNormal *= -1;
}
else if ( BlockingMobj )
{
Vector3 diff = level.Vec3Diff(BlockingMobj.Vec3Offset(0,0,BlockingMobj.Height/2),pos);
HitNormal = diff.unit();
}
else if ( vel.length() > 0. ) HitNormal = vel.unit();
Vector3 HitNormal = SWWMUtility.GetActorHitNormal(self);
if ( swwm_omnibust ) BusterWall.ProjectileBust(self,GetMissileDamage(0,0),oldvel.unit());
// undo the bounce, we need to hook in our own
vel = oldvel;
@ -558,22 +519,7 @@ Class EvisceratorProj : Actor
FLineTraceData d;
Vector3 HitNormal;
LineTrace(ang,FRandom[Eviscerator](10,30)+10*special1,pt,TRF_THRUACTORS,data:d);
hitnormal = -d.HitDir;
if ( d.HitType == TRACE_HitFloor )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.top.Normal;
else hitnormal = d.HitSector.floorplane.Normal;
}
else if ( d.HitType == TRACE_HitCeiling )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.bottom.Normal;
else hitnormal = d.HitSector.ceilingplane.Normal;
}
else if ( d.HitType == TRACE_HitWall )
{
hitnormal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit();
if ( !d.LineSide ) hitnormal *= -1;
}
hitnormal = SWWMUtility.GetLineTraceHitNormal(d);
let p = Spawn("EvisceratorSubExpl",d.HitLocation+hitnormal*4);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);

View file

@ -395,27 +395,12 @@ Class YnykronLightningArc : SWWMNonInteractiveActor
let p = SWWMPuff.Setup(hit.hitlocation,hit.x,self,target,hit.hitactor);
hit.hitactor.DamageMobj(p,target,GetMissileDamage(0,0),'Electric',DMG_THRUSTLESS|DMG_INFLICTOR_IS_PUFF);
}
Vector3 normal = -t.Results.HitVector, dir = t.Results.HitVector;
Vector3 normal = SWWMUtility.GetLineTracerHitNormal(t.Results), dir = t.Results.HitVector;
if ( t.Results.HitType != TRACE_HitNone )
{
if ( t.Results.HitType != TRACE_HasHitSky )
{
if ( t.Results.HitType == TRACE_HitWall )
{
normal = (-t.Results.HitLine.delta.y,t.Results.HitLine.delta.x,0).unit();
if ( !t.Results.Side ) normal *= -1;
t.Results.HitLine.RemoteActivate(target,t.Results.Side,SPAC_Impact,t.Results.HitPos);
}
else if ( t.Results.HitType == TRACE_HitFloor )
{
if ( t.Results.ffloor ) normal = -t.Results.ffloor.top.Normal;
else normal = t.Results.HitSector.floorplane.Normal;
}
else if ( t.Results.HitType == TRACE_HitCeiling )
{
if ( t.Results.ffloor ) normal = -t.Results.ffloor.bottom.Normal;
else normal = t.Results.HitSector.ceilingplane.Normal;
}
if ( t.Results.HitType == TRACE_HitWall ) t.Results.HitLine.RemoteActivate(target,t.Results.Side,SPAC_Impact,t.Results.HitPos);
let s = Spawn("YnykronLightningImpact",level.Vec3Offset(t.Results.HitPos,normal*8));
s.target = target;
s.angle = atan2(normal.y,normal.x);
@ -1040,23 +1025,7 @@ Class YnykronSingularity : SWWMNonInteractiveActor
FLineTraceData d;
double dst = FRandom[ExploS](1500,2000)*scale.x;
LineTrace(ang,dst,pt,TRF_THRUACTORS|TRF_THRUHITSCAN,data:d);
Vector3 norm;
if ( d.HitType == TRACE_HitWall )
{
norm = (d.HitLine.delta.y,-d.HitLine.delta.x,0).unit();
if ( d.LineSide ) norm *= -1;
}
else if ( d.HitType == TRACE_HitFloor )
{
if ( d.Hit3DFloor ) norm = -d.Hit3DFloor.top.Normal;
else norm = d.HitSector.floorplane.Normal;
}
else if ( d.HitType == TRACE_HitCeiling )
{
if ( d.Hit3DFloor ) norm = -d.Hit3DFloor.bottom.Normal;
else norm = d.HitSector.ceilingplane.Normal;
}
else norm = (0,0,0);
Vector3 norm = SWWMUtility.GetLineTraceHitNormal(d);
let gd = Spawn("GatherDust",level.Vec3Offset(d.HitLocation,norm*8));
gd.target = self;
}
@ -1325,22 +1294,7 @@ Class YnykronSingularity : SWWMNonInteractiveActor
while ( totaldist > 0 )
{
LineTrace(ang,totaldist,pt,TRF_THRUACTORS|TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
hitnormal = -d.HitDir;
if ( d.HitType == TRACE_HitFloor )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.top.Normal;
else hitnormal = d.HitSector.floorplane.Normal;
}
else if ( d.HitType == TRACE_HitCeiling )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.bottom.Normal;
else hitnormal = d.HitSector.ceilingplane.Normal;
}
else if ( d.HitType == TRACE_HitWall )
{
hitnormal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit();
if ( !d.LineSide ) hitnormal *= -1;
}
HitNormal = SWWMUtility.GetLineTraceHitNormal(d);
totaldist -= d.Distance;
if ( totaldist > 0 )
{
@ -1419,23 +1373,8 @@ Class YnykronAltBeam : SWWMNonInteractiveActor
if ( t.Results.HitType != TRACE_HitNone )
{
// hit something
Vector3 norm = -t.Results.HitVector;
if ( t.Results.HitType == TRACE_HitWall )
{
norm = (t.Results.HitLine.delta.y,-t.Results.HitLine.delta.x,0).unit();
if ( t.Results.Side ) norm *= -1;
t.Results.HitLine.RemoteActivate(tracer,t.Results.Side,SPAC_Impact,t.Results.HitPos);
}
else if ( t.Results.HitType == TRACE_HitFloor )
{
if ( t.Results.ffloor ) norm = -t.Results.ffloor.top.Normal;
else norm = t.Results.HitSector.floorplane.Normal;
}
else if ( t.Results.HitType == TRACE_HitCeiling )
{
if ( t.Results.ffloor ) norm = -t.Results.ffloor.bottom.Normal;
else norm = t.Results.HitSector.ceilingplane.Normal;
}
Vector3 norm = SWWMUtility.GetLineTracerHitNormal(t.Results);
if ( t.Results.HitType == TRACE_HitWall ) t.Results.HitLine.RemoteActivate(tracer,t.Results.Side,SPAC_Impact,t.Results.HitPos);
let b = Spawn("YnykronSingularity",level.Vec3Offset(t.Results.HitPos,norm*16));
b.target = target;
b.angle = atan2(norm.y,norm.x);

View file

@ -690,23 +690,8 @@ Class YnykronBeam : SWWMNonInteractiveActor
if ( t.Results.HitType != TRACE_HitNone )
{
// hit something
Vector3 norm = -t.Results.HitVector;
if ( t.Results.HitType == TRACE_HitWall )
{
norm = (t.Results.HitLine.delta.y,-t.Results.HitLine.delta.x,0).unit();
if ( t.Results.Side ) norm *= -1;
t.Results.HitLine.RemoteActivate(tracer,t.Results.Side,SPAC_Impact,t.Results.HitPos);
}
else if ( t.Results.HitType == TRACE_HitFloor )
{
if ( t.Results.ffloor ) norm = -t.Results.ffloor.top.Normal;
else norm = t.Results.HitSector.floorplane.Normal;
}
else if ( t.Results.HitType == TRACE_HitCeiling )
{
if ( t.Results.ffloor ) norm = -t.Results.ffloor.bottom.Normal;
else norm = t.Results.HitSector.ceilingplane.Normal;
}
Vector3 norm = SWWMUtility.GetLineTracerHitNormal(t.Results);
if ( t.Results.HitType == TRACE_HitWall ) t.Results.HitLine.RemoteActivate(tracer,t.Results.Side,SPAC_Impact,t.Results.HitPos);
let b = Spawn("YnykronImpact",level.Vec3Offset(t.Results.HitPos,norm*16));
b.target = target;
b.master = master;

View file

@ -198,28 +198,13 @@ Class Spreadgun : SWWMWeapon
}
if ( (t.Results.HitType != TRACE_HitNone) && (t.Results.HitType != TRACE_HasHitSky) && (t.Results.HitType != TRACE_HitActor) )
{
Vector3 hitnormal = -t.Results.HitVector;
if ( t.Results.HitType == TRACE_HitFloor )
{
if ( t.Results.FFloor ) hitnormal = -t.Results.FFloor.top.Normal;
else hitnormal = t.Results.HitSector.floorplane.Normal;
}
else if ( t.Results.HitType == TRACE_HitCeiling )
{
if ( t.Results.FFloor ) hitnormal = -t.Results.FFloor.bottom.Normal;
else hitnormal = t.Results.HitSector.ceilingplane.Normal;
}
else if ( t.Results.HitType == TRACE_HitWall )
{
hitnormal = (-t.Results.HitLine.delta.y,t.Results.HitLine.delta.x,0).unit();
if ( !t.Results.Side ) hitnormal *= -1;
}
Vector3 hitnormal = SWWMUtility.GetLineTracerHitNormal(t.Results);
let p = Spawn(impact,t.Results.HitPos+hitnormal*4);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
p.target = self;
if ( t.Results.HitType == TRACE_HitFloor ) p.CheckSplash(40);
if ( t.Results.HitLine ) t.Results.HitLine.RemoteActivate(self,t.Results.Side,SPAC_Impact,t.Results.HitPos);
if ( t.Results.HitType == TRACE_HitWall ) t.Results.HitLine.RemoteActivate(self,t.Results.Side,SPAC_Impact,t.Results.HitPos);
}
}
@ -266,27 +251,12 @@ Class Spreadgun : SWWMWeapon
SWWMBulletTrail.DoTrail(self,origin,dir,10000,2,true);
if ( d.HitType != TRACE_HitNone )
{
Vector3 hitnormal = -d.HitDir;
if ( d.HitType == TRACE_HitFloor )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.top.Normal;
else hitnormal = d.HitSector.floorplane.Normal;
}
else if ( d.HitType == TRACE_HitCeiling )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.bottom.Normal;
else hitnormal = d.HitSector.ceilingplane.Normal;
}
else if ( d.HitType == TRACE_HitWall )
{
hitnormal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit();
if ( !d.LineSide ) hitnormal *= -1;
}
Vector3 hitnormal = SWWMUtility.GetLineTraceHitNormal(d);
let p = Spawn("SWWMBulletImpact",d.HitLocation+hitnormal);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
p.target = self;
if ( d.HitLine ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
if ( d.HitType == TRACE_HitWall ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
let b = Spawn("GoldenImpact",d.HitLocation+hitnormal*4.);
b.angle = atan2(hitnormal.y,hitnormal.x);
b.pitch = asin(-hitnormal.z);

View file

@ -159,22 +159,7 @@ Class GoldenImpact : SWWMNonInteractiveActor
while ( totaldist > 0 )
{
LineTrace(ang,totaldist,pt,TRF_THRUACTORS|TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
hitnormal = -d.HitDir;
if ( d.HitType == TRACE_HitFloor )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.top.Normal;
else hitnormal = d.HitSector.floorplane.Normal;
}
else if ( d.HitType == TRACE_HitCeiling )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.bottom.Normal;
else hitnormal = d.HitSector.ceilingplane.Normal;
}
else if ( d.HitType == TRACE_HitWall )
{
hitnormal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit();
if ( !d.LineSide ) hitnormal *= -1;
}
HitNormal = SWWMUtility.GetLineTraceHitNormal(d);
totaldist -= d.Distance;
if ( totaldist > 0 )
{
@ -272,22 +257,7 @@ Class GoldenSubImpact : SWWMNonInteractiveActor
while ( totaldist > 0 )
{
LineTrace(ang,totaldist,pt,TRF_THRUACTORS|TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
hitnormal = -d.HitDir;
if ( d.HitType == TRACE_HitFloor )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.top.Normal;
else hitnormal = d.HitSector.floorplane.Normal;
}
else if ( d.HitType == TRACE_HitCeiling )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.bottom.Normal;
else hitnormal = d.HitSector.ceilingplane.Normal;
}
else if ( d.HitType == TRACE_HitWall )
{
hitnormal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit();
if ( !d.LineSide ) hitnormal *= -1;
}
HitNormal = SWWMUtility.GetLineTraceHitNormal(d);
totaldist -= d.Distance;
if ( totaldist > 0 )
{

View file

@ -970,22 +970,7 @@ Class BiosparkComboImpact : SWWMNonInteractiveActor
FLineTraceData d;
Vector3 HitNormal;
LineTrace(ang,FRandom[Sparkster](10,20)+mul*special2,pt,TRF_THRUACTORS,data:d);
hitnormal = -d.HitDir;
if ( d.HitType == TRACE_HitFloor )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.top.Normal;
else hitnormal = d.HitSector.floorplane.Normal;
}
else if ( d.HitType == TRACE_HitCeiling )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.bottom.Normal;
else hitnormal = d.HitSector.ceilingplane.Normal;
}
else if ( d.HitType == TRACE_HitWall )
{
hitnormal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit();
if ( !d.LineSide ) hitnormal *= -1;
}
hitnormal = SWWMUtility.GetLineTraceHitNormal(d);
let p = Spawn("BiosparkComboImpactSub",d.HitLocation+hitnormal*4);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
@ -1056,25 +1041,8 @@ Class BiosparkBeam : SWWMNonInteractiveActor
hit.hitactor.Howl();
}
}
Vector3 normal = -t.Results.HitVector, dir = t.Results.HitVector;
if ( t.Results.HitType == TRACE_HitWall )
{
normal = (-t.Results.HitLine.delta.y,t.Results.HitLine.delta.x,0).unit();
if ( !t.Results.Side ) normal *= -1;
t.Results.HitLine.RemoteActivate(target,t.Results.Side,SPAC_Impact,t.Results.HitPos);
}
else if ( t.Results.HitType == TRACE_HitFloor )
{
if ( t.Results.ffloor ) normal = -t.Results.ffloor.top.Normal;
else normal = t.Results.HitSector.floorplane.Normal;
}
else if ( t.Results.HitType == TRACE_HitCeiling )
{
if ( t.Results.ffloor ) normal = -t.Results.ffloor.bottom.Normal;
else normal = t.Results.HitSector.ceilingplane.Normal;
}
else normal *= 0;
nextpos = level.Vec3Offset(t.Results.HitPos,normal*8.);
Vector3 normal = SWWMUtility.GetLineTracerHitNormal(t.Results), dir = t.Results.HitVector;
if ( t.Results.HitType == TRACE_HitWall ) t.Results.HitLine.RemoteActivate(target,t.Results.Side,SPAC_Impact,t.Results.HitPos);
if ( t.Results.HitType == TRACE_HasHitSky )
{
bAMBUSH = true;
@ -1083,7 +1051,7 @@ Class BiosparkBeam : SWWMNonInteractiveActor
}
if ( t.Results.HitType != TRACE_HitNone )
{
let s = Spawn("BiosparkBeamImpact",nextpos);
let s = Spawn("BiosparkBeamImpact",t.Results.HitPos+normal*8.);
s.target = target;
s.angle = atan2(normal.y,normal.x);
s.pitch = asin(-normal.z);
@ -1092,6 +1060,7 @@ Class BiosparkBeam : SWWMNonInteractiveActor
speed = t.Results.Distance; // shortens in minimap
return;
}
nextpos = t.Results.HitPos;
double closest = double.infinity;
let bt = BlockThingsIterator.Create(self,500);
while ( bt.Next() )
@ -1378,35 +1347,20 @@ Class BiosparkArc : SWWMNonInteractiveActor
if ( hit.hitactor && hit.hitactor.bISMONSTER && !Random[Sparkster](0,3) )
hit.hitactor.Howl();
}
Vector3 normal = -t.Results.HitVector, dir = t.Results.HitVector;
if ( t.Results.HitType == TRACE_HitWall )
{
normal = (-t.Results.HitLine.delta.y,t.Results.HitLine.delta.x,0).unit();
if ( !t.Results.Side ) normal *= -1;
t.Results.HitLine.RemoteActivate(target,t.Results.Side,SPAC_Impact,t.Results.HitPos);
dir -= 2*normal*(dir dot normal);
}
else if ( t.Results.HitType == TRACE_HitFloor )
{
if ( t.Results.ffloor ) normal = -t.Results.ffloor.top.Normal;
else normal = t.Results.HitSector.floorplane.Normal;
dir -= 2*normal*(dir dot normal);
}
else if ( t.Results.HitType == TRACE_HitCeiling )
{
if ( t.Results.ffloor ) normal = -t.Results.ffloor.bottom.Normal;
else normal = t.Results.HitSector.ceilingplane.Normal;
dir -= 2*normal*(dir dot normal);
}
else normal *= 0;
nextpos = level.Vec3Offset(t.Results.HitPos,normal);
if ( t.Results.HitType != TRACE_HitNone ) speed = t.Results.Distance; // shortens in minimap
Vector3 normal = SWWMUtility.GetLineTracerHitNormal(t.Results), dir = t.Results.HitVector;
if ( t.Results.HitType == TRACE_HitWall ) t.Results.HitLine.RemoteActivate(target,t.Results.Side,SPAC_Impact,t.Results.HitPos);
if ( t.Results.HitType == TRACE_HasHitSky )
{
bAMBUSH = true;
speed = t.Results.Distance; // shortens in minimap
return;
}
if ( t.Results.HitType != TRACE_HitNone )
{
speed = t.Results.Distance; // shortens in minimap
nextpos = level.Vec3Offset(t.Results.HitPos,normal); // offset by normal so next segment doesn't spawn inside walls
}
else nextpos = t.Results.HitPos;
double a = FRandom[Sparkster](0,360), s = FRandom[Sparkster](0.,.8);
dir = SWWMUtility.ConeSpread(dir,y,z,a,s);
if ( master )
@ -1608,45 +1562,7 @@ Class BiosparkCore : Actor
void A_HandleBounce()
{
bHITOWNER = true;
Vector3 HitNormal = -vel.unit();
F3DFloor ff;
if ( BlockingFloor )
{
// find closest 3d floor for its normal
for ( int i=0; i<BlockingFloor.Get3DFloorCount(); i++ )
{
if ( !(BlockingFloor.Get3DFloor(i).flags&F3DFloor.FF_SOLID) ) continue;
if ( !(BlockingFloor.Get3DFloor(i).top.ZAtPoint(pos.xy) ~== floorz) ) continue;
ff = BlockingFloor.Get3DFloor(i);
break;
}
if ( ff ) HitNormal = -ff.top.Normal;
else HitNormal = BlockingFloor.floorplane.Normal;
}
else if ( BlockingCeiling )
{
// find closest 3d floor for its normal
for ( int i=0; i<BlockingCeiling.Get3DFloorCount(); i++ )
{
if ( !(BlockingCeiling.Get3DFloor(i).flags&F3DFloor.FF_SOLID) ) continue;
if ( !(BlockingCeiling.Get3DFloor(i).bottom.ZAtPoint(pos.xy) ~== ceilingz) ) continue;
ff = BlockingCeiling.Get3DFloor(i);
break;
}
if ( ff ) HitNormal = -ff.bottom.Normal;
else HitNormal = BlockingCeiling.ceilingplane.Normal;
}
else if ( BlockingLine )
{
HitNormal = (-BlockingLine.delta.y,BlockingLine.delta.x,0).unit();
int wside = SWWMUtility.PointOnLineSide(pos.xy,BlockingLine);
if ( !wside ) HitNormal *= -1;
}
else if ( BlockingMobj )
{
Vector3 diff = level.Vec3Diff(BlockingMobj.Vec3Offset(0,0,BlockingMobj.Height/2),pos);
HitNormal = diff.unit();
}
Vector3 HitNormal = SWWMUtility.GetActorHitNormal(self);
// undo the bounce, we need to hook in our own
vel = oldvel;
// re-do the bounce with our formula

View file

@ -127,27 +127,12 @@ Class ExplodiumGun : SWWMWeapon
else if ( d.HitType != TRACE_HitNone )
{
invoker.deadeyecnt = 0;
Vector3 hitnormal = -d.HitDir;
if ( d.HitType == TRACE_HitFloor )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.top.Normal;
else hitnormal = d.HitSector.floorplane.Normal;
}
else if ( d.HitType == TRACE_HitCeiling )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.bottom.Normal;
else hitnormal = d.HitSector.ceilingplane.Normal;
}
else if ( d.HitType == TRACE_HitWall )
{
hitnormal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit();
if ( !d.LineSide ) hitnormal *= -1;
}
Vector3 hitnormal = SWWMUtility.GetLineTraceHitNormal(d);
let p = Spawn("SWWMBulletImpact",d.HitLocation+hitnormal*0.01);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
p.target = self;
if ( d.HitLine ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
if ( d.HitType == TRACE_HitWall ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
let b = Spawn("ExplodiumBulletImpact",d.HitLocation+hitnormal*4.);
b.angle = atan2(hitnormal.y,hitnormal.x);
b.pitch = asin(-hitnormal.z);
@ -663,27 +648,12 @@ Class DualExplodiumGun : SWWMWeapon
else if ( d.HitType != TRACE_HitNone )
{
ExplodiumGun(invoker.SisterWeapon).deadeyecnt = 0;
Vector3 hitnormal = -d.HitDir;
if ( d.HitType == TRACE_HitFloor )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.top.Normal;
else hitnormal = d.HitSector.floorplane.Normal;
}
else if ( d.HitType == TRACE_HitCeiling )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.bottom.Normal;
else hitnormal = d.HitSector.ceilingplane.Normal;
}
else if ( d.HitType == TRACE_HitWall )
{
hitnormal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit();
if ( !d.LineSide ) hitnormal *= -1;
}
Vector3 hitnormal = SWWMUtility.GetLineTraceHitNormal(d);
let p = Spawn("SWWMBulletImpact",d.HitLocation+hitnormal*0.01);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
p.target = self;
if ( d.HitLine ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
if ( d.HitType == TRACE_HitWall ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
let b = Spawn("ExplodiumBulletImpact",d.HitLocation+hitnormal*4.);
b.angle = atan2(hitnormal.y,hitnormal.x);
b.pitch = asin(-hitnormal.z);

View file

@ -389,7 +389,7 @@ Class ExplodiumMagAttach : ExplodiumMagProj
SetOrigin((pos.x,pos.y,ceilingz)+normal*.75,true);
atz = pos.z-atsector.GetPlaneTexZ(atplane);
}
else if ( BlockingLine )
else if ( BlockingLine && SWWMUtility.BlockingLineIsBlocking(self,Line.ML_BLOCKEVERYTHING|Line.ML_BLOCKPROJECTILE,BlockingLine) )
{
atline = BlockingLine;
normal = (-BlockingLine.delta.y,BlockingLine.delta.x,0).unit();

View file

@ -168,27 +168,12 @@ Class CandyGun : SWWMWeapon
}
else if ( d.HitType != TRACE_HitNone )
{
Vector3 hitnormal = -d.HitDir;
if ( d.HitType == TRACE_HitFloor )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.top.Normal;
else hitnormal = d.HitSector.floorplane.Normal;
}
else if ( d.HitType == TRACE_HitCeiling )
{
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.bottom.Normal;
else hitnormal = d.HitSector.ceilingplane.Normal;
}
else if ( d.HitType == TRACE_HitWall )
{
hitnormal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit();
if ( !d.LineSide ) hitnormal *= -1;
}
Vector3 hitnormal = SWWMUtility.GetLineTraceHitNormal(d);
let p = Spawn("SWWMBulletImpact",d.HitLocation+hitnormal*0.01);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
p.target = self;
if ( d.HitLine ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
if ( d.HitType == TRACE_HitWall ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
let b = Spawn("CandyBulletImpact",d.HitLocation+hitnormal*4.);
b.angle = atan2(hitnormal.y,hitnormal.x);
b.pitch = asin(-hitnormal.z);

View file

@ -113,30 +113,15 @@ Class CandyBeam : SWWMNonInteractiveActor
let p = SWWMPuff.Setup(hit.hitlocation,hit.x,self,target,hit.hitactor);
hit.hitactor.DamageMobj(p,target,GetMissileDamage(0,0),'Candy',DMG_THRUSTLESS|DMG_INFLICTOR_IS_PUFF);
}
Vector3 normal = -t.Results.HitVector, dir = t.Results.HitVector;
if ( t.Results.HitType == TRACE_HitWall )
Vector3 normal = SWWMUtility.GetLineTracerHitNormal(t.Results), dir = t.Results.HitVector;
if ( t.Results.HitType == TRACE_HitWall ) t.Results.HitLine.RemoteActivate(target,t.Results.Side,SPAC_Impact,t.Results.HitPos);
if ( t.Results.HitType != TRACE_HitNone )
{
normal = (-t.Results.HitLine.delta.y,t.Results.HitLine.delta.x,0).unit();
if ( !t.Results.Side ) normal *= -1;
t.Results.HitLine.RemoteActivate(target,t.Results.Side,SPAC_Impact,t.Results.HitPos);
dir -= 2*normal*(dir dot normal);
speed = t.Results.Distance; // shortens in minimap
nextpos = level.Vec3Offset(t.Results.HitPos,normal); // offset by normal so next segment doesn't spawn inside walls
}
else if ( t.Results.HitType == TRACE_HitFloor )
{
if ( t.Results.ffloor ) normal = -t.Results.ffloor.top.Normal;
else normal = t.Results.HitSector.floorplane.Normal;
dir -= 2*normal*(dir dot normal);
}
else if ( t.Results.HitType == TRACE_HitCeiling )
{
if ( t.Results.ffloor ) normal = -t.Results.ffloor.bottom.Normal;
else normal = t.Results.HitSector.ceilingplane.Normal;
dir -= 2*normal*(dir dot normal);
}
else normal *= 0;
if ( t.Results.HitType != TRACE_HitNone ) speed = t.Results.Distance; // shortens in minimap
else nextpos = t.Results.HitPos;
double a = FRandom[Candy](0,360), s = FRandom[Candy](0.,.8);
nextpos = level.Vec3Offset(t.Results.HitPos,normal);
nextdir = SWWMUtility.ConeSpread(dir,y,z,a,s);
}
void A_Spread( Class<Actor> pop = "CandyPop", Class<Actor> smk = "SWWMHalfSmoke" )

View file

@ -357,22 +357,7 @@ Class SilverBullet : SWWMWeapon
}
if ( (t.Results.HitType != TRACE_HitNone) && (t.Results.HitType != TRACE_HasHitSky) && (t.Results.HitType != TRACE_HitActor) )
{
Vector3 hitnormal = -t.Results.HitVector;
if ( t.Results.HitType == TRACE_HitFloor )
{
if ( t.Results.FFloor ) hitnormal = -t.Results.FFloor.top.Normal;
else hitnormal = t.Results.HitSector.floorplane.Normal;
}
else if ( t.Results.HitType == TRACE_HitCeiling )
{
if ( t.Results.FFloor ) hitnormal = -t.Results.FFloor.bottom.Normal;
else hitnormal = t.Results.HitSector.ceilingplane.Normal;
}
else if ( t.Results.HitType == TRACE_HitWall )
{
hitnormal = (-t.Results.HitLine.delta.y,t.Results.HitLine.delta.x,0).unit();
if ( !t.Results.Side ) hitnormal *= -1;
}
Vector3 hitnormal = SWWMUtility.GetLineTracerHitNormal(t.Results);
let p = Spawn("SilverImpact",t.Results.HitPos+hitnormal*4);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);