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

@ -202,28 +202,13 @@ Class HeavyMahSheenGun : SWWMWeapon
}
if ( (st.Results.HitType != TRACE_HitNone) && (st.Results.HitType != TRACE_HasHitSky) && (st.Results.HitType != TRACE_HitActor) )
{
Vector3 hitnormal = -st.Results.HitVector;
if ( st.Results.HitType == TRACE_HitFloor )
{
if ( st.Results.FFloor ) hitnormal = -st.Results.FFloor.top.Normal;
else hitnormal = st.Results.HitSector.floorplane.Normal;
}
else if ( st.Results.HitType == TRACE_HitCeiling )
{
if ( st.Results.FFloor ) hitnormal = -st.Results.FFloor.bottom.Normal;
else hitnormal = st.Results.HitSector.ceilingplane.Normal;
}
else if ( st.Results.HitType == TRACE_HitWall )
{
hitnormal = (-st.Results.HitLine.delta.y,st.Results.HitLine.delta.x,0).unit();
if ( !st.Results.Side ) hitnormal *= -1;
}
Vector3 hitnormal = SWWMUtility.GetLineTracerHitNormal(st.Results);
let p = Spawn("SWWMBulletImpact",st.Results.HitPos+hitnormal*4);
p.angle = atan2(hitnormal.y,hitnormal.x);
p.pitch = asin(-hitnormal.z);
p.target = self;
if ( st.Results.HitType == TRACE_HitFloor ) p.CheckSplash(40);
if ( st.Results.HitLine ) st.Results.HitLine.RemoteActivate(self,st.Results.Side,SPAC_Impact,st.Results.HitPos);
else if ( st.Results.HitType == TRACE_HitWall ) st.Results.HitLine.RemoteActivate(self,st.Results.Side,SPAC_Impact,st.Results.HitPos);
}
for ( int i=0; i<(5-invoker.firespeed); i++ )
{

View file

@ -523,27 +523,12 @@ Class MisterRifle : 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("SpreadImpact",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("MisterBuckshotImpact",d.HitLocation+hitnormal*4.);
b.angle = atan2(hitnormal.y,hitnormal.x);
b.pitch = asin(-hitnormal.z);
@ -590,27 +575,12 @@ Class MisterRifle : 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("MisterBulletImpact",d.HitLocation+hitnormal*4.);
b.angle = atan2(hitnormal.y,hitnormal.x);
b.pitch = asin(-hitnormal.z);
@ -669,27 +639,12 @@ Class MisterRifle : 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("MisterStreamImpact",d.HitLocation+hitnormal*4.);
b.angle = atan2(hitnormal.y,hitnormal.x);
b.pitch = asin(-hitnormal.z);
@ -963,22 +918,7 @@ Class MisterRifle : SWWMWeapon
}
if ( (mrt.Results.HitType != TRACE_HitNone) && (mrt.Results.HitType != TRACE_HasHitSky) && (mrt.Results.HitType != TRACE_HitActor) )
{
Vector3 hitnormal = -mrt.Results.HitVector;
if ( mrt.Results.HitType == TRACE_HitFloor )
{
if ( mrt.Results.FFloor ) hitnormal = -mrt.Results.FFloor.top.Normal;
else hitnormal = mrt.Results.HitSector.floorplane.Normal;
}
else if ( mrt.Results.HitType == TRACE_HitCeiling )
{
if ( mrt.Results.FFloor ) hitnormal = -mrt.Results.FFloor.bottom.Normal;
else hitnormal = mrt.Results.HitSector.ceilingplane.Normal;
}
else if ( mrt.Results.HitType == TRACE_HitWall )
{
hitnormal = (-mrt.Results.HitLine.delta.y,mrt.Results.HitLine.delta.x,0).unit();
if ( !mrt.Results.Side ) hitnormal *= -1;
}
Vector3 hitnormal = SWWMUtility.GetLineTracerHitNormal(mrt.Results);
let b = MisterBulletImpact(Spawn("MisterRailEntryImpact",mrt.Results.HitPos+hitnormal*4.));
b.angle = atan2(hitnormal.y,hitnormal.x);
b.pitch = asin(-hitnormal.z);

View file

@ -233,24 +233,9 @@ Class MisterFuzzy : SWWMNonInteractiveActor
double ang = atan2(dir.y,dir.x);
double pt = asin(-dir.z);
LineTrace(ang,dist,pt,TRF_THRUACTORS|TRF_THRUHITSCAN|TRF_ABSPOSITION,newpos.z,newpos.x,newpos.y,d);
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;
}
if ( d.HitType != TRACE_HitNone )
{
Vector3 hitnormal = SWWMUtility.GetLineTraceHitNormal(d);
dist -= d.Distance;
// should only happen if we bounced
dir = d.HitDir-(FRandom[Puff](1.5,2.)*hitnormal*(d.HitDir dot hitnormal));
@ -1007,45 +992,7 @@ Class MisterGrenade : Actor
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

@ -424,24 +424,9 @@ Class FancyConfetti : SWWMNonInteractiveActor
double ang = atan2(dir.y,dir.x);
double pt = asin(-dir.z);
LineTrace(ang,dist,pt,TRF_THRUACTORS|TRF_THRUHITSCAN|TRF_ABSPOSITION,newpos.z,newpos.x,newpos.y,d);
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;
}
if ( (d.HitType != TRACE_HitNone) && (d.HitType != TRACE_HitFloor) )
{
Vector3 hitnormal = SWWMUtility.GetLineTraceHitNormal(d);
dist -= d.Distance;
// should only happen if we bounced
dir = d.HitDir-(1.2*hitnormal*(d.HitDir dot hitnormal));

View file

@ -386,45 +386,7 @@ Class TheBall : Actor
void A_HandleBounce()
{
lasthit = null;
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);
// send the needed data for a bust
if ( (special1 == 2) || swwm_omnibust )
{
@ -663,23 +625,8 @@ Class SaltBeam : SWWMNonInteractiveActor
if ( t.Results.HitActor && t.Results.HitActor.bIsMonster && !Random[Spreadgun](0,3) )
t.Results.HitActor.Howl();
}
Vector3 norm = -x;
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);
if ( t.Results.HitType != TRACE_HasHitSky )
{
let i = Spawn("SaltImpact",level.Vec3Offset(t.Results.HitPos,norm*4));

View file

@ -215,22 +215,7 @@ Class mkBloodDrop : SWWMNonInteractiveActor
LineTrace(ang,spd,pt,TRF_THRUACTORS|TRF_THRUHITSCAN|TRF_ABSPOSITION,newpos.z,newpos.x,newpos.y,d);
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);
newpos = d.HitLocation+hitnormal;
}
else newpos = level.Vec3Offset(newpos,vel);

View file

@ -124,24 +124,9 @@ Class SWWMSmoke : SWWMNonInteractiveActor
double ang = atan2(dir.y,dir.x);
double pt = asin(-dir.z);
LineTrace(ang,dist,pt,TRF_THRUACTORS|TRF_THRUHITSCAN|TRF_ABSPOSITION,newpos.z,newpos.x,newpos.y,d);
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;
}
if ( d.HitType != TRACE_HitNone )
{
Vector3 hitnormal = SWWMUtility.GetLineTraceHitNormal(d);
dist -= d.Distance;
// should only happen if we bounced
dir = d.HitDir-(FRandom[Puff](1.,1.2)*hitnormal*(d.HitDir dot hitnormal));
@ -318,24 +303,9 @@ Class SWWMBubble : SWWMNonInteractiveActor
double ang = atan2(dir.y,dir.x);
double pt = asin(-dir.z);
LineTrace(ang,dist,pt,TRF_THRUACTORS|TRF_THRUHITSCAN|TRF_ABSPOSITION,newpos.z,newpos.x,newpos.y,d);
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;
}
if ( d.HitType != TRACE_HitNone )
{
Vector3 hitnormal = SWWMUtility.GetLineTraceHitNormal(d);
dist -= d.Distance;
// should only happen if we bounced
dir = d.HitDir-(FRandom[Puff](1.,1.2)*hitnormal*(d.HitDir dot hitnormal));
@ -452,24 +422,9 @@ Class SWWMSpark : SWWMNonInteractiveActor
double ang = atan2(dir.y,dir.x);
double pt = asin(-dir.z);
LineTrace(ang,dist,pt,TRF_THRUACTORS|TRF_THRUHITSCAN|TRF_ABSPOSITION,newpos.z,newpos.x,newpos.y,d);
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;
}
if ( d.HitType != TRACE_HitNone )
{
Vector3 hitnormal = SWWMUtility.GetLineTraceHitNormal(d);
dist -= d.Distance;
// should only happen if we bounced
dir = d.HitDir-(2*hitnormal*(d.HitDir dot hitnormal));
@ -634,24 +589,9 @@ Class SWWMChip : SWWMNonInteractiveActor
double ang = atan2(dir.y,dir.x);
double pt = asin(-dir.z);
LineTrace(ang,dist,pt,TRF_THRUACTORS|TRF_THRUHITSCAN|TRF_ABSPOSITION,newpos.z,newpos.x,newpos.y,d);
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;
}
if ( d.HitType != TRACE_HitNone )
{
Vector3 hitnormal = SWWMUtility.GetLineTraceHitNormal(d);
dist -= d.Distance;
// should only happen if we bounced
dir = d.HitDir-(2*hitnormal*(d.HitDir dot hitnormal));

View file

@ -348,7 +348,7 @@ extend Class SWWMUtility
}
// the stupidest thing ever, it's called BlockingLine but it's not always blocking us
static play bool BlockingLineIsBlocking( Actor a, int blockflags = Line.ML_BLOCKEVERYTHING, Line testline = null )
static clearscope bool BlockingLineIsBlocking( Actor a, int blockflags = Line.ML_BLOCKEVERYTHING, Line testline = null )
{
Line l = testline?testline:a.BlockingLine;
// not blocked
@ -537,6 +537,136 @@ extend Class SWWMUtility
return (al+ah+bl+bh)*.25;
}
// gets the hit normal vector for projectiles and hitscan
// bNoBounce: actor didn't just bounce, meaning the fallback normal shouldn't be the inverse of velocity
static clearscope Vector3 GetActorHitNormal( Actor a, bool bNoBounce = false )
{
Vector3 HitNormal = (0,0,0);
F3DFloor ff;
if ( a.BlockingMobj )
{
let mo = a.BlockingMobj;
Vector3 diff = level.Vec3Diff(mo.pos,a.pos);
if ( diff.x >= mo.radius ) HitNormal += (1,0,0);
else if ( diff.x <= -mo.radius ) HitNormal += (-1,0,0);
if ( diff.y >= mo.radius ) HitNormal += (0,1,0);
else if ( diff.y <= -mo.radius ) HitNormal += (0,-1,0);
if ( diff.z >= mo.height ) HitNormal += (0,0,1);
else if ( diff.z <= 0. ) HitNormal += (0,0,-1);
double len = HitNormal.length();
if ( len < double.epsilon ) HitNormal = Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90));
else HitNormal /= len;
}
else if ( a.BlockingFloor )
{
// find closest 3d floor for its normal
for ( int i=0; i<a.BlockingFloor.Get3DFloorCount(); i++ )
{
if ( !(a.BlockingFloor.Get3DFloor(i).flags&F3DFloor.FF_SOLID) ) continue;
if ( !(a.BlockingFloor.Get3DFloor(i).top.ZAtPoint(a.pos.xy) ~== a.floorz) ) continue;
ff = a.BlockingFloor.Get3DFloor(i);
break;
}
if ( ff ) HitNormal = -ff.top.Normal;
else HitNormal = a.BlockingFloor.floorplane.Normal;
}
else if ( a.BlockingCeiling )
{
// find closest 3d floor for its normal
for ( int i=0; i<a.BlockingCeiling.Get3DFloorCount(); i++ )
{
if ( !(a.BlockingCeiling.Get3DFloor(i).flags&F3DFloor.FF_SOLID) ) continue;
if ( !(a.BlockingCeiling.Get3DFloor(i).bottom.ZAtPoint(a.pos.xy) ~== a.ceilingz) ) continue;
ff = a.BlockingCeiling.Get3DFloor(i);
break;
}
if ( ff ) HitNormal = -ff.bottom.Normal;
else HitNormal = a.BlockingCeiling.ceilingplane.Normal;
}
else if ( a.BlockingLine && BlockingLineIsBlocking(a,Line.ML_BLOCKEVERYTHING|Line.ML_BLOCKPROJECTILE,a.BlockingLine) )
{
HitNormal = (-a.BlockingLine.delta.y,a.BlockingLine.delta.x,0).unit();
if ( !SWWMUtility.PointOnLineSide(a.pos.xy,a.BlockingLine) )
HitNormal *= -1;
}
else
{
double len = a.vel.length();
if ( len > 0. ) HitNormal = bNoBounce?(-a.vel/len):(a.vel/len);
}
return HitNormal;
}
static clearscope Vector3 GetLineTraceHitNormal( FLineTraceData d )
{
Vector3 HitNormal = (0,0,0);
if ( d.HitType == TRACE_HitActor )
{
let mo = d.HitActor;
Vector3 diff = level.Vec3Diff(mo.pos,d.HitLocation);
if ( diff.x >= mo.radius ) HitNormal += (1,0,0);
else if ( diff.x <= -mo.radius ) HitNormal += (-1,0,0);
if ( diff.y >= mo.radius ) HitNormal += (0,1,0);
else if ( diff.y <= -mo.radius ) HitNormal += (0,-1,0);
if ( diff.z >= mo.height ) HitNormal += (0,0,1);
else if ( diff.z <= 0. ) HitNormal += (0,0,-1);
double len = HitNormal.length();
if ( len < double.epsilon ) HitNormal = Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90));
else HitNormal /= len;
}
else 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;
}
else HitNormal = -d.HitDir;
return HitNormal;
}
static clearscope Vector3 GetLineTracerHitNormal( TraceResults r )
{
Vector3 HitNormal = (0,0,0);
if ( r.HitType == TRACE_HitActor )
{
let mo = r.HitActor;
Vector3 diff = level.Vec3Diff(mo.pos,r.HitPos);
if ( diff.x >= mo.radius ) HitNormal += (1,0,0);
else if ( diff.x <= -mo.radius ) HitNormal += (-1,0,0);
if ( diff.y >= mo.radius ) HitNormal += (0,1,0);
else if ( diff.y <= -mo.radius ) HitNormal += (0,-1,0);
if ( diff.z >= mo.height ) HitNormal += (0,0,1);
else if ( diff.z <= 0. ) HitNormal += (0,0,-1);
double len = HitNormal.length();
if ( len < double.epsilon ) HitNormal = Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90));
else HitNormal /= len;
}
else if ( r.HitType == TRACE_HitFloor )
{
if ( r.ffloor ) HitNormal = -r.ffloor.top.Normal;
else HitNormal = r.HitSector.floorplane.Normal;
}
else if ( r.HitType == TRACE_HitCeiling )
{
if ( r.ffloor ) HitNormal = -r.ffloor.bottom.Normal;
else HitNormal = r.HitSector.ceilingplane.Normal;
}
else if ( r.HitType == TRACE_HitWall )
{
HitNormal = (-r.HitLine.delta.y,r.HitLine.delta.x,0).unit();
if ( !r.Side ) HitNormal *= -1;
}
else HitNormal = -r.HitVector;
return HitNormal;
}
static bool, TextureID DefaceTexture( TextureID checkme )
{
String tn = TexMan.GetName(checkme);

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