Mortal Rifle fully implemented (oh my).
This commit is contained in:
parent
dffee0b43d
commit
e571fccc4d
|
@ -22,8 +22,8 @@ More weapons, because we need 'em. In addition, all the "easy to implement" mini
|
|||
- [8] Ray-Khom *(UnSX)*
|
||||
- The Most Silent Takedown *(Kill 40 enemies with the Ray-Khom primary without alerting them)*
|
||||
- John Romero's Curse *(Fry yourself by discharging an electric weapon in water)*
|
||||
- [9] Mortal Rifle *(UnSX 2)*
|
||||
- Railed Hard *(Shoot through 44 enemies with a single Mortal Rifle overpressure shot)*
|
||||
- ✓ [9] Mortal Rifle *(UnSX 2)*
|
||||
- ✓ Railed Hard *(Kill 44 enemies with a single Mortal Rifle overpressure shot)*
|
||||
- [0] Rafan-Kos *(UnSX 4)*
|
||||
- Blasting Ropes *(Melt a grand total of 5000 enemies with the Rafan-Kos)*
|
||||
* ☑ **Additional Voice Acting:**
|
||||
|
|
|
@ -1304,7 +1304,7 @@ SWWM_ACHIEVEMENT_PUZZLE_TXT = "Solve all fractions of \"puzzles\" in the same sa
|
|||
SWWM_ACHIEVEMENT_RAGE_TAG = "No Talk me Angy";
|
||||
SWWM_ACHIEVEMENT_RAGE_TXT = "Use %s Ragekits";
|
||||
SWWM_ACHIEVEMENT_RAIL_TAG = "Railed Hard";
|
||||
SWWM_ACHIEVEMENT_RAIL_TXT = "Shoot through %s enemies with a single Mortal Rifle overpressure shot";
|
||||
SWWM_ACHIEVEMENT_RAIL_TXT = "Kill %s enemies with a single Mortal Rifle overpressure shot";
|
||||
SWWM_ACHIEVEMENT_REFLECT_TAG = "Return to Sender";
|
||||
SWWM_ACHIEVEMENT_REFLECT_TXT = "Kill %s enemies with parried projectiles";
|
||||
SWWM_ACHIEVEMENT_REFRESH_TAG = "Stay Fresh";
|
||||
|
|
|
@ -1151,7 +1151,7 @@ SWWM_ACHIEVEMENT_PUZZLE_TXT = "Resuelve todas las partes de \"puzzles\" en la mi
|
|||
SWWM_ACHIEVEMENT_RAGE_TAG = "No Hablo me Enfado";
|
||||
SWWM_ACHIEVEMENT_RAGE_TXT = "Usa %s Ragekits";
|
||||
SWWM_ACHIEVEMENT_RAIL_TAG = "Metida de Través";
|
||||
SWWM_ACHIEVEMENT_RAIL_TXT = "Atraviesa %s enemigos con un solo disparo a presión del Rifle Mortal";
|
||||
SWWM_ACHIEVEMENT_RAIL_TXT = "Mata %s enemigos con un solo disparo a presión del Rifle Mortal";
|
||||
SWWM_ACHIEVEMENT_REFLECT_TAG = "Devuelto a Remitente";
|
||||
SWWM_ACHIEVEMENT_REFLECT_TXT = "Mata %s enemigos con proyectiles desviados";
|
||||
SWWM_ACHIEVEMENT_REFRESH_TAG = "Siempre Fresco";
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[default]
|
||||
SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r523 \cu(Wed 28 Sep 17:58:30 CEST 2022)\c-";
|
||||
SWWM_SHORTVER="\cw1.3pre r523 \cu(2022-09-28 17:58:30)\c-";
|
||||
SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r524 \cu(Wed 28 Sep 21:00:24 CEST 2022)\c-";
|
||||
SWWM_SHORTVER="\cw1.3pre r524 \cu(2022-09-28 21:00:24)\c-";
|
||||
|
|
|
@ -80,6 +80,37 @@ Model "MisterSubGrenade"
|
|||
FrameIndex XZW1 A 0 0
|
||||
}
|
||||
|
||||
Model "MisterRailBeam"
|
||||
{
|
||||
Path "models/extra"
|
||||
|
||||
Model 0 "YBeam.obj"
|
||||
Skin 0 "MRBolt.png"
|
||||
Scale 1 1 0.6
|
||||
USEACTORPITCH
|
||||
USEACTORROLL
|
||||
DONTCULLBACKFACES
|
||||
|
||||
FrameIndex XZW1 A 0 0
|
||||
Skin 0 "MRBoltS.png"
|
||||
FrameIndex XZW1 B 0 0
|
||||
}
|
||||
Model "MisterRailChildBeam"
|
||||
{
|
||||
Path "models/extra"
|
||||
|
||||
Model 0 "YBeam.obj"
|
||||
Skin 0 "MRBolt.png"
|
||||
Scale 1 1 0.6
|
||||
USEACTORPITCH
|
||||
USEACTORROLL
|
||||
DONTCULLBACKFACES
|
||||
|
||||
FrameIndex XZW1 A 0 0
|
||||
Skin 0 "MRBoltS.png"
|
||||
FrameIndex XZW1 B 0 0
|
||||
}
|
||||
|
||||
Model "MisterRifle"
|
||||
{
|
||||
Path "models"
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 3.9 KiB |
Binary file not shown.
|
@ -163,8 +163,6 @@ extend Class MisterRifle
|
|||
for ( int i=0; i<clipcount; i++ )
|
||||
Screen.DrawTexture(BulletTex[0],false,bx-12,(by-27)+2*i,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
||||
if ( gchambered ) Screen.DrawTexture(BulletTex[1+gfired],false,bx-21,by-10,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,gfired?0x80000000:0x00000000);
|
||||
String str = "THIS WEAPON IS NOT YET FULLY IMPLEMENTED";
|
||||
Screen.DrawText(NewSmallFont,Font.CR_RED,(Screen.GetWidth()-NewSmallFont.StringWidth(str)*CleanXFac_1)/2,Screen.GetHeight()-(NewSmallFont.GetHeight()*CleanYFac_1+clamp(swwm_hudmargin,0,20)*hs),str,DTA_CleanNoMove_1,true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,29 @@
|
|||
// Plutoni Inc. Mortal Rifle (from UnSX 2)
|
||||
// Slot 9, spawns shared with Candygun
|
||||
|
||||
Class MRHitListEntry : HitListEntry
|
||||
{
|
||||
// just needs this
|
||||
bool bExit;
|
||||
}
|
||||
|
||||
// used for splitting model beam between crossed portals (if any)
|
||||
Class MRRailSeg
|
||||
{
|
||||
Vector3 enter, exit;
|
||||
}
|
||||
|
||||
// like the silver bullet tracer except there's no penetration factor
|
||||
// just a maximum possible travel distance (which is mainly used for probing through walls)
|
||||
Class MisterRailTracer : LineTracer
|
||||
{
|
||||
Actor ignoreme;
|
||||
Array<HitListEntry> hitlist;
|
||||
Array<MRHitListEntry> hitlist;
|
||||
Array<Line> shootthroughlist;
|
||||
Array<WaterHit> waterhitlist;
|
||||
Array<MRRailSeg> portalseg;
|
||||
|
||||
double RealMaxDist;
|
||||
double maxdist;
|
||||
|
||||
bool pastwall, fullstop;
|
||||
Array<WallPenetrate> WallPenetrateList;
|
||||
|
@ -34,16 +47,35 @@ Class MisterRailTracer : LineTracer
|
|||
hl.hitpos = Results.Crossed3DWaterPos;
|
||||
WaterHitList.Push(hl);
|
||||
}
|
||||
if ( Results.HitType == TRACE_HitActor )
|
||||
if ( Results.HitType == TRACE_CrossingPortal )
|
||||
{
|
||||
let seg = new("MRRailSeg");
|
||||
seg.enter = Results.HitPos;
|
||||
seg.exit = Results.SrcFromTarget;
|
||||
portalseg.Push(seg);
|
||||
}
|
||||
else if ( Results.HitType == TRACE_HitActor )
|
||||
{
|
||||
if ( Results.HitActor == ignoreme ) return TRACE_Skip;
|
||||
if ( Results.HitActor.bSHOOTABLE )
|
||||
{
|
||||
let ent = new("HitListEntry");
|
||||
let ent = new("MRHitListEntry");
|
||||
ent.hitactor = Results.HitActor;
|
||||
ent.hitlocation = Results.HitPos;
|
||||
ent.x = Results.HitVector;
|
||||
ent.pastwall = pastwall;
|
||||
ent.bExit = false;
|
||||
hitlist.Push(ent);
|
||||
// also include exit point if we can reach it
|
||||
Vector3 exit = SWWMUtility.TraceExit(Results.HitActor,Results.HitPos,Results.HitVector);
|
||||
if ( level.Vec3Diff(Results.HitPos,exit).length() > (maxdist-Results.Distance) )
|
||||
return TRACE_Skip; // exit point is beyond our max distance
|
||||
ent = new("MRHitListEntry");
|
||||
ent.hitactor = Results.HitActor;
|
||||
ent.hitlocation = exit;
|
||||
ent.x = Results.HitVector;
|
||||
ent.pastwall = pastwall;
|
||||
ent.bExit = true;
|
||||
hitlist.Push(ent);
|
||||
return TRACE_Skip;
|
||||
}
|
||||
|
@ -62,7 +94,7 @@ Class MisterRailTracer : LineTracer
|
|||
if ( (Results.Tier == TIER_Middle) && Results.HitLine.sidedef[1] && !(Results.HitLine.Flags&(Line.ML_BlockHitscan|Line.ML_BlockEverything)) )
|
||||
return TRACE_Skip;
|
||||
}
|
||||
int maxstep = int(RealMaxDist-Results.Distance);
|
||||
int maxstep = int(maxdist-Results.Distance);
|
||||
for ( int i=1; i<=maxstep; i++ )
|
||||
{
|
||||
Vector3 ofs = Results.HitPos+Results.HitVector*i;
|
||||
|
@ -144,6 +176,26 @@ Class MisterRailTracer : LineTracer
|
|||
}
|
||||
}
|
||||
|
||||
Class MisterRailCounter : Thinker
|
||||
{
|
||||
PlayerInfo player;
|
||||
Array<Actor> effectors;
|
||||
int nkill;
|
||||
|
||||
override void Tick()
|
||||
{
|
||||
int neff = 0;
|
||||
for ( int i=0; i<effectors.Size(); i++ )
|
||||
{
|
||||
if ( !effectors[i] ) continue;
|
||||
neff++;
|
||||
}
|
||||
if ( neff > 0 ) return;
|
||||
SWWMUtility.AchievementProgress("rail",nkill,player);
|
||||
Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
Class MisterRifle : SWWMWeapon
|
||||
{
|
||||
int clipcount;
|
||||
|
@ -152,7 +204,7 @@ Class MisterRifle : SWWMWeapon
|
|||
bool boltlock;
|
||||
bool waschambered;
|
||||
bool wasgchambered;
|
||||
int prefirecnt;
|
||||
double prefirecnt;
|
||||
transient int holdtic;
|
||||
int firemode;
|
||||
ui int lastfiremode;
|
||||
|
@ -165,8 +217,6 @@ Class MisterRifle : SWWMWeapon
|
|||
|
||||
Property ClipCount : clipcount;
|
||||
|
||||
transient MisterRailTracer mrt; // I pity the fool
|
||||
|
||||
override void InitializeWeapon()
|
||||
{
|
||||
// no round in the chamber
|
||||
|
@ -694,8 +744,15 @@ Class MisterRifle : SWWMWeapon
|
|||
A_StartSound("mister/cancelover",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
return ResolveState("FireOverpressureCancel");
|
||||
}
|
||||
if ( invoker.prefirecnt == 99 ) invoker.holdtic = gametic;
|
||||
invoker.prefirecnt = min(100,int(invoker.prefirecnt+1));
|
||||
if ( invoker.prefirecnt < 100 )
|
||||
{
|
||||
invoker.prefirecnt += 1.5;
|
||||
if ( invoker.prefirecnt >= 100 )
|
||||
{
|
||||
invoker.prefirecnt = 100;
|
||||
invoker.holdtic = gametic;
|
||||
}
|
||||
}
|
||||
A_SoundVolume(CHAN_WEAPONEXTRA,clamp(invoker.prefirecnt*.01,.01,1.));
|
||||
A_SoundPitch(CHAN_WEAPONEXTRA,clamp(.5+invoker.prefirecnt*.005,.5,1.)**.5);
|
||||
if ( (invoker.prefirecnt >= 100) && !((gametic-invoker.holdtic)%32) && CheckLocalView() )
|
||||
|
@ -719,6 +776,299 @@ Class MisterRifle : SWWMWeapon
|
|||
A_QuakeEx(8,8,8,12,0,10,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:2.);
|
||||
A_BumpFOV(.85);
|
||||
A_AlertMonsters(swwm_uncapalert?0:12000);
|
||||
for ( int i=0; i<12; i++ )
|
||||
{
|
||||
let s = Spawn("SWWMSmoke",origin);
|
||||
s.scale *= .4;
|
||||
s.alpha *= .1;
|
||||
s.vel += vel*.5+x*FRandom[Mister](1.,12.);
|
||||
s.SetShade(Color(0,3,4)*Random[ExploS](48,63));
|
||||
}
|
||||
Vector3 dir, startdir;
|
||||
startdir = dir = swwm_CoordUtil.GetAxes(BulletSlope(),angle,roll);
|
||||
let mrt = new("MisterRailTracer"); // I pity the fool
|
||||
mrt.ignoreme = self;
|
||||
mrt.hitlist.Clear();
|
||||
mrt.shootthroughlist.Clear();
|
||||
mrt.waterhitlist.Clear();
|
||||
mrt.wallpenetratelist.Clear();
|
||||
mrt.ffloors.Clear();
|
||||
mrt.portalseg.Clear();
|
||||
for ( int i=0; i<level.Sectors.Size(); i++ )
|
||||
{
|
||||
Sector s = level.Sectors[i];
|
||||
for ( int j=0; j<s.Get3DFloorCount(); j++ )
|
||||
{
|
||||
F3DFloor ff = s.Get3DFloor(j);
|
||||
if ( ff.flags&(F3DFloor.FF_EXISTS|F3DFloor.FF_SOLID) )
|
||||
mrt.ffloors.Push(ff);
|
||||
}
|
||||
}
|
||||
mrt.pastwall = false;
|
||||
Vector3 norigin = origin;
|
||||
mrt.maxdist = 10000.;
|
||||
do
|
||||
{
|
||||
mrt.fullstop = true;
|
||||
mrt.Trace(norigin,level.PointInSector(norigin.xy),dir,mrt.maxdist,TRACE_HitSky|TRACE_ReportPortals);
|
||||
mrt.maxdist -= (mrt.exitpoint-norigin).length();
|
||||
norigin = mrt.exitpoint;
|
||||
dir = mrt.Results.HitVector;
|
||||
}
|
||||
while ( !mrt.fullstop );
|
||||
let mrc = new("MisterRailCounter");
|
||||
mrc.ChangeStatNum(STAT_USER); // so it can tick
|
||||
mrc.player = player;
|
||||
Vector3 sstart = origin;
|
||||
// beam segments
|
||||
if ( mrt.portalseg.Size() <= 0 )
|
||||
{
|
||||
Vector3 sdir = mrt.Results.HitPos-sstart;
|
||||
double sdist = sdir.length();
|
||||
sdir /= sdist;
|
||||
Actor b;
|
||||
if ( sdist > 32 )
|
||||
{
|
||||
b = Spawn("MisterRailBeam",sstart);
|
||||
b.frame = 1;
|
||||
b.scale.y = 32;
|
||||
b.angle = atan2(sdir.y,sdir.x);
|
||||
b.pitch = asin(-sdir.z)+90;
|
||||
MisterRailBeam(b).mrc = mrc;
|
||||
mrc.effectors.Push(b);
|
||||
sstart += sdir*32;
|
||||
sdist -= 32;
|
||||
b = Spawn("MisterRailBeam",sstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
b = Spawn("MisterRailBeam",sstart);
|
||||
b.frame = 1;
|
||||
}
|
||||
b.scale.y = sdist;
|
||||
b.angle = atan2(sdir.y,sdir.x);
|
||||
b.pitch = asin(-sdir.z)+90;
|
||||
MisterRailBeam(b).mrc = mrc;
|
||||
mrc.effectors.Push(b);
|
||||
}
|
||||
else for ( int i=0; i<mrt.portalseg.Size(); i++ )
|
||||
{
|
||||
Vector3 sdir = mrt.portalseg[i].enter-sstart;
|
||||
double sdist = sdir.length();
|
||||
sdir /= sdist;
|
||||
Actor b;
|
||||
if ( i == 0 )
|
||||
{
|
||||
if ( sdist > 32 )
|
||||
{
|
||||
b = Spawn("MisterRailBeam",sstart);
|
||||
b.target = self;
|
||||
b.frame = 1;
|
||||
b.scale.y = 32;
|
||||
b.angle = atan2(sdir.y,sdir.x);
|
||||
b.pitch = asin(-sdir.z)+90;
|
||||
MisterRailBeam(b).mrc = mrc;
|
||||
mrc.effectors.Push(b);
|
||||
sstart += sdir*32;
|
||||
sdist -= 32;
|
||||
b = Spawn("MisterRailBeam",sstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
b = Spawn("MisterRailBeam",sstart);
|
||||
b.frame = 1;
|
||||
}
|
||||
}
|
||||
else b = Spawn("MisterRailBeam",sstart);
|
||||
b.target = self;
|
||||
b.scale.y = sdist;
|
||||
b.angle = atan2(sdir.y,sdir.x);
|
||||
b.pitch = asin(-sdir.z)+90;
|
||||
MisterRailBeam(b).mrc = mrc;
|
||||
mrc.effectors.Push(b);
|
||||
sstart = mrt.portalseg[i].exit;
|
||||
if ( i == (mrt.portalseg.Size()-1) )
|
||||
{
|
||||
sdir = mrt.Results.HitPos-sstart;
|
||||
sdist = sdir.length();
|
||||
sdir /= sdist;
|
||||
b = Spawn("MisterRailBeam",sstart);
|
||||
b.target = self;
|
||||
b.scale.y = sdist;
|
||||
b.angle = atan2(sdir.y,sdir.x);
|
||||
b.pitch = asin(-sdir.z)+90;
|
||||
MisterRailBeam(b).mrc = mrc;
|
||||
mrc.effectors.Push(b);
|
||||
}
|
||||
}
|
||||
for ( int i=0; i<mrt.ShootThroughList.Size(); i++ )
|
||||
{
|
||||
mrt.ShootThroughList[i].Activate(self,0,SPAC_Impact);
|
||||
mrt.ShootThroughList[i].Activate(self,0,SPAC_PCross);
|
||||
}
|
||||
for ( int i=0; i<mrt.WaterHitList.Size(); i++ )
|
||||
{
|
||||
let b = Spawn("InvisibleSplasher",mrt.WaterHitList[i].hitpos);
|
||||
b.target = self;
|
||||
b.A_CheckTerrain();
|
||||
}
|
||||
Array<MisterBulletImpact> bi; // so we can ignite them all at once after main contact damage
|
||||
for ( int i=0; i<mrt.hitlist.Size(); i++ )
|
||||
{
|
||||
if ( mrt.HitList[i].bExit )
|
||||
{
|
||||
let b = MisterBulletImpact(Spawn("MisterRailExitImpact",mrt.hitlist[i].HitLocation-mrt.hitlist[i].x*4.));
|
||||
b.angle = atan2(mrt.HitList[i].x.y,mrt.HitList[i].x.x);
|
||||
b.pitch = asin(-mrt.HitList[i].x.z);
|
||||
b.target = self;
|
||||
b.mrc = mrc;
|
||||
mrc.effectors.Push(b);
|
||||
bi.Push(b);
|
||||
}
|
||||
else
|
||||
{
|
||||
let b = MisterBulletImpact(Spawn("MisterRailEntryImpact",mrt.hitlist[i].HitLocation+mrt.hitlist[i].x*4.));
|
||||
b.angle = atan2(mrt.HitList[i].x.y,mrt.HitList[i].x.x)+180;
|
||||
b.pitch = asin(mrt.HitList[i].x.z);
|
||||
b.target = self;
|
||||
b.mrc = mrc;
|
||||
mrc.effectors.Push(b);
|
||||
bi.Push(b);
|
||||
}
|
||||
if ( !mrt.HitList[i].HitActor || mrt.HitList[i].bExit ) continue;
|
||||
SWWMUtility.DoKnockback(mrt.HitList[i].HitActor,mrt.HitList[i].x+(0,0,0.025),80000);
|
||||
let p = SWWMPuff.Setup(mrt.HitList[i].HitLocation,mrt.HitList[i].x,invoker,self,mrt.HitList[i].HitActor);
|
||||
mrt.HitList[i].HitActor.DamageMobj(p,self,4444,'Mortal',DMG_FOILINVUL|DMG_THRUSTLESS|DMG_INFLICTOR_IS_PUFF);
|
||||
if ( !mrt.HitList[i].HitActor || (mrt.HitList[i].HitActor.Health <= 0) )
|
||||
mrc.nkill++;
|
||||
}
|
||||
LineTracer faketracer = new("LineTracer");
|
||||
for ( int i=0; i<mrt.wallpenetratelist.Size(); i++ )
|
||||
{
|
||||
bool bExit = !!(i%2); // odd-numbered entries are exit points
|
||||
Vector3 hitpos = mrt.WallPenetrateList[i].hitpos;
|
||||
Vector3 hitnormal = mrt.WallPenetrateList[i].hitnormal;
|
||||
let b = MisterBulletImpact(Spawn(bExit?"MisterRailExitImpact":"MisterRailEntryImpact",hitpos+hitnormal*4.));
|
||||
b.angle = atan2(hitnormal.y,hitnormal.x);
|
||||
b.pitch = asin(-hitnormal.z);
|
||||
b.target = self;
|
||||
b.mrc = mrc;
|
||||
mrc.effectors.Push(b);
|
||||
bi.Push(b);
|
||||
if ( mrt.WallPenetrateList[i].hittype == TRACE_HitWall )
|
||||
mrt.WallPenetrateList[i].hitline.Activate(self,mrt.WallPenetrateList[i].hitside,SPAC_Impact);
|
||||
if ( swwm_omnibust )
|
||||
{
|
||||
faketracer.Results.HitType = mrt.WallPenetrateList[i].HitType;
|
||||
faketracer.Results.HitSector = mrt.WallPenetrateList[i].HitSector;
|
||||
faketracer.Results.HitLine = mrt.WallPenetrateList[i].HitLine;
|
||||
faketracer.Results.ffloor = mrt.WallPenetrateList[i].HitFFloor;
|
||||
faketracer.Results.Side = mrt.WallPenetrateList[i].HitSide;
|
||||
faketracer.Results.Tier = mrt.WallPenetrateList[i].HitTier;
|
||||
BusterWall.Bust(faketracer.Results,444,self,mrt.WallPenetrateList[i].BustDir,mrt.WallPenetrateList[i].HitPos.z);
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
let b = MisterBulletImpact(Spawn("MisterRailEntryImpact",mrt.Results.HitPos+hitnormal*4.));
|
||||
b.angle = atan2(hitnormal.y,hitnormal.x);
|
||||
b.pitch = asin(-hitnormal.z);
|
||||
b.target = self;
|
||||
b.mrc = mrc;
|
||||
mrc.effectors.Push(b);
|
||||
bi.Push(b);
|
||||
if ( mrt.Results.HitType == TRACE_HitWall ) mrt.Results.HitLine.RemoteActivate(self,mrt.Results.Side,SPAC_Impact,mrt.Results.HitPos);
|
||||
if ( swwm_omnibust ) BusterWall.Bust(mrt.Results,444,self,mrt.Results.HitVector,mrt.Results.HitPos.z);
|
||||
}
|
||||
for ( int i=0; i<bi.Size(); i++ ) bi[i].A_BulletExplode();
|
||||
double dist = level.Vec3Diff(origin,mrt.Results.HitPos).length();
|
||||
for ( double d=0.; d<=dist; d+=200. )
|
||||
{
|
||||
Vector3 p = level.Vec3Offset(origin,startdir*d);
|
||||
if ( !level.IsPointInlevel(p) ) continue;
|
||||
Spawn("MisterRailLight",p);
|
||||
}
|
||||
int numpt = Random[ExploS](50,100);
|
||||
double dv = max(16.,dist/numpt);
|
||||
for ( double d=32.; d<=dist; d+=dv )
|
||||
{
|
||||
Vector3 np = level.Vec3Offset(origin,startdir*d);
|
||||
np = level.Vec3Offset(np,SWWMUtility.Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90))*FRandom[ExploS](4,12));
|
||||
if ( !level.IsPointInLevel(np) ) continue;
|
||||
let p = Spawn("MisterPop",np);
|
||||
p.target = self;
|
||||
MisterPop(p).mrc = mrc;
|
||||
mrc.effectors.Push(p);
|
||||
}
|
||||
if ( mrt.wallpenetratelist.Size() > 0 )
|
||||
{
|
||||
Vector3 start = origin;
|
||||
Vector3 end = mrt.WallPenetrateList[0].hitpos;
|
||||
Vector3 tdir = level.Vec3Diff(start,end);
|
||||
double dist = tdir.length();
|
||||
tdir /= dist;
|
||||
for ( double d=4.; d<=dist; d+=8. )
|
||||
{
|
||||
if ( !Random[ExploS](0,1) ) continue;
|
||||
Vector3 ofs = level.Vec3Offset(start,tdir*d);
|
||||
if ( !level.IsPointInLevel(ofs) ) continue;
|
||||
let b = Spawn("SWWMHalfSmoke",ofs);
|
||||
b.Scale *= FRandom[ExploS](.7,1.4);
|
||||
b.alpha *= .2;
|
||||
b.special1 = Random[ExploS](1,3);
|
||||
b.SetShade(Color(2,3,4)*Random[ExploS](48,63));
|
||||
}
|
||||
for ( int i=1; i<mrt.WallPenetrateList.Size(); i+=2 )
|
||||
{
|
||||
start = mrt.WallPenetrateList[i].hitpos;
|
||||
if ( i >= mrt.WallPenetrateList.Size()-1 ) end = mrt.Results.HitPos;
|
||||
else end = mrt.WallPenetrateList[i+1].hitpos;
|
||||
tdir = level.Vec3Diff(start,end);
|
||||
dist = tdir.length();
|
||||
tdir /= dist;
|
||||
for ( double d=4.; d<=dist; d+=8. )
|
||||
{
|
||||
if ( !Random[ExploS](0,1) ) continue;
|
||||
Vector3 ofs = level.Vec3Offset(start,tdir*d);
|
||||
if ( !level.IsPointInLevel(ofs) ) continue;
|
||||
let b = Spawn("SWWMHalfSmoke",ofs);
|
||||
b.Scale *= FRandom[ExploS](.7,1.4);
|
||||
b.alpha *= .2;
|
||||
b.special1 = Random[ExploS](1,3);
|
||||
b.SetShade(Color(2,3,4)*Random[ExploS](48,63));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( double d=4.; d<=mrt.Results.Distance; d+=8. )
|
||||
{
|
||||
if ( !Random[ExploS](0,1) ) continue;
|
||||
Vector3 ofs = level.Vec3Offset(origin,startdir*d);
|
||||
if ( !level.IsPointInLevel(ofs) ) continue;
|
||||
let b = Spawn("SWWMHalfSmoke",ofs);
|
||||
b.Scale *= FRandom[ExploS](.7,1.4);
|
||||
b.alpha *= .2;
|
||||
b.special1 = Random[ExploS](1,3);
|
||||
b.SetShade(Color(2,3,4)*Random[ExploS](48,63));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
action void A_MisterFireGrenade()
|
||||
|
|
|
@ -191,6 +191,7 @@ Class MisterBulletImpactPop : Actor
|
|||
|
||||
Class MisterFuzzy : Actor
|
||||
{
|
||||
MisterRailCounter mrc;
|
||||
Default
|
||||
{
|
||||
Obituary "$O_MORTALRIFLE";
|
||||
|
@ -215,7 +216,9 @@ Class MisterFuzzy : Actor
|
|||
override void Tick()
|
||||
{
|
||||
if ( isFrozen() ) return;
|
||||
SWWMUtility.DoExplosion(self,(special2<0)?4:44,3000,80,80,DE_EXTRAZTHRUST);
|
||||
int nhit, nkill;
|
||||
[nhit, nkill] = SWWMUtility.DoExplosion(self,(special2<0)?4:44,3000,80,80,DE_EXTRAZTHRUST|DE_COUNTENEMIES);
|
||||
if ( mrc ) mrc.nkill += nkill;
|
||||
special1--;
|
||||
if ( special1 <= 0 )
|
||||
{
|
||||
|
@ -332,6 +335,7 @@ Class MisterFuzzyTrail : Actor
|
|||
|
||||
Class MisterPop : Actor
|
||||
{
|
||||
MisterRailCounter mrc;
|
||||
Default
|
||||
{
|
||||
Obituary "$O_MORTALRIFLE";
|
||||
|
@ -368,13 +372,18 @@ Class MisterPop : Actor
|
|||
Spawn:
|
||||
TNT1 A 1 NoDelay
|
||||
{
|
||||
A_SetTics(Random[ExploS](1,5));
|
||||
A_SetTics(Random[ExploS](1,15));
|
||||
Scale *= FRandom[ExploS](.5,1.5);
|
||||
Scale.x *= RandomPick[ExploS](-1,1);
|
||||
Scale.y *= RandomPick[ExploS](-1,1);
|
||||
roll = FRandom[ExploS](0,360);
|
||||
}
|
||||
BLPF C 2 Bright { SWWMUtility.DoExplosion(self,4,2000,50,50,DE_EXTRAZTHRUST); }
|
||||
BLPF C 2 Bright
|
||||
{
|
||||
int nhit, nkill;
|
||||
[nhit, nkill] = SWWMUtility.DoExplosion(self,4,2000,50,50,DE_EXTRAZTHRUST|DE_COUNTENEMIES);
|
||||
if ( mrc ) mrc.nkill += nkill;
|
||||
}
|
||||
TNT1 A 1
|
||||
{
|
||||
let p = Spawn("MisterFuzzyTrail",pos);
|
||||
|
@ -387,6 +396,7 @@ Class MisterPop : Actor
|
|||
|
||||
Class MisterBulletImpact : Actor
|
||||
{
|
||||
MisterRailCounter mrc; // simplify code by putting this here
|
||||
Default
|
||||
{
|
||||
Obituary "$O_MORTALRIFLE";
|
||||
|
@ -648,6 +658,280 @@ Class MisterStreamImpact : MisterBulletImpact
|
|||
}
|
||||
}
|
||||
|
||||
Class MisterRailEntryImpact : MisterBulletImpact
|
||||
{
|
||||
Default
|
||||
{
|
||||
Scale 1.2;
|
||||
}
|
||||
override void A_BulletExplode()
|
||||
{
|
||||
A_AlertMonsters(swwm_uncapalert?0:4000);
|
||||
int nhit, nkill;
|
||||
[nhit, nkill] = SWWMUtility.DoExplosion(self,444,200000,100,100,DE_EXTRAZTHRUST|DE_COUNTENEMIES);
|
||||
if ( mrc ) mrc.nkill += nkill;
|
||||
A_QuakeEx(6,6,6,10,0,400,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,falloff:150,rollintensity:.8);
|
||||
A_StartSound("mister/hitover",CHAN_VOICE,attenuation:.35);
|
||||
A_SprayDecal("SmallRocketBlast",-172);
|
||||
Scale *= FRandom[ExploS](0.8,1.1);
|
||||
Scale.x *= RandomPick[ExploS](-1,1);
|
||||
Scale.y *= RandomPick[ExploS](-1,1);
|
||||
int numpt = Random[ExploS](8,12);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pvel = SWWMUtility.Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90))*FRandom[ExploS](1,10);
|
||||
let s = Spawn("SWWMSmoke",pos);
|
||||
s.vel = pvel;
|
||||
s.SetShade(Color(0,3,4)*Random[ExploS](48,63));
|
||||
s.special1 = Random[ExploS](0,2);
|
||||
s.scale *= 3.5;
|
||||
s.alpha *= .4;
|
||||
}
|
||||
numpt = Random[ExploS](4,6);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pvel = SWWMUtility.Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90))*FRandom[ExploS](8,12);
|
||||
let s = Spawn("SWWMSpark",pos);
|
||||
s.vel = pvel;
|
||||
}
|
||||
numpt = Random[ExploS](3,6);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pvel = SWWMUtility.Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90))*FRandom[ExploS](4,16);
|
||||
let s = Spawn("SWWMChip",pos);
|
||||
s.vel = pvel;
|
||||
}
|
||||
numpt = Random[ExploS](4,6);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
let s = Spawn("MisterFuzzy",pos);
|
||||
s.angle = FRandom[ExploS](0,360);
|
||||
s.pitch = FRandom[ExploS](-90,90);
|
||||
s.target = target;
|
||||
s.special1 -= 2;
|
||||
if ( !mrc ) continue;
|
||||
MisterFuzzy(s).mrc = mrc;
|
||||
mrc.effectors.Push(s);
|
||||
}
|
||||
Spawn("MisterExLightTiny",pos);
|
||||
let p = Spawn("MisterBulletImpactPop",pos);
|
||||
p.A_SetScale(4.);
|
||||
}
|
||||
override void A_BulletSubExplode()
|
||||
{
|
||||
if ( special1 && (special1 <= 10) )
|
||||
{
|
||||
int nhit, nkill;
|
||||
[nhit, nkill] = SWWMUtility.DoExplosion(self,44,3000+special1*50,80+special1*4,80+special1*4,DE_EXTRAZTHRUST|DE_COUNTENEMIES);
|
||||
if ( mrc ) mrc.nkill += nkill;
|
||||
int numpt = Random[ExploS](0,special1/2);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 np = level.Vec3Offset(pos,SWWMUtility.Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90))*FRandom[ExploS](2,16)*special1);
|
||||
if ( !level.IsPointInLevel(np) ) continue;
|
||||
let p = Spawn("MisterPop",np);
|
||||
p.target = target;
|
||||
if ( !mrc ) continue;
|
||||
MisterPop(p).mrc = mrc;
|
||||
mrc.effectors.Push(p);
|
||||
}
|
||||
}
|
||||
special1++;
|
||||
}
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
TNT1 A 0;
|
||||
XEX7 ACEGIKMOQSUWY[] 1 Bright A_BulletSubExplode();
|
||||
Stop;
|
||||
}
|
||||
}
|
||||
|
||||
Class MisterRailExitImpact : MisterBulletImpact
|
||||
{
|
||||
Default
|
||||
{
|
||||
Scale 1.8;
|
||||
}
|
||||
override void A_BulletExplode()
|
||||
{
|
||||
A_AlertMonsters(swwm_uncapalert?0:4000);
|
||||
int nhit, nkill;
|
||||
[nhit, nkill] = SWWMUtility.DoExplosion(self,444,80000,200,200,DE_EXTRAZTHRUST|DE_COUNTENEMIES);
|
||||
if ( mrc ) mrc.nkill += nkill;
|
||||
A_QuakeEx(8,8,8,15,0,600,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,falloff:250,rollintensity:1.2);
|
||||
A_StartSound("mister/hitover",CHAN_WEAPON,attenuation:.2);
|
||||
A_SprayDecal("BigRocketBlast",-172);
|
||||
Scale *= FRandom[ExploS](0.8,1.1);
|
||||
Scale.x *= RandomPick[ExploS](-1,1);
|
||||
Scale.y *= RandomPick[ExploS](-1,1);
|
||||
int numpt = Random[ExploS](15,20);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pvel = SWWMUtility.Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90))*FRandom[ExploS](1,12);
|
||||
let s = Spawn("SWWMSmoke",pos);
|
||||
s.vel = pvel;
|
||||
s.SetShade(Color(0,3,4)*Random[ExploS](48,63));
|
||||
s.special1 = Random[ExploS](1,3);
|
||||
s.scale *= 3.5;
|
||||
s.alpha *= .4;
|
||||
}
|
||||
numpt = Random[ExploS](8,12);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pvel = SWWMUtility.Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90))*FRandom[ExploS](8,12);
|
||||
let s = Spawn("SWWMSpark",pos);
|
||||
s.vel = pvel;
|
||||
}
|
||||
numpt = Random[ExploS](6,16);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pvel = SWWMUtility.Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90))*FRandom[ExploS](4,16);
|
||||
let s = Spawn("SWWMChip",pos);
|
||||
s.vel = pvel;
|
||||
}
|
||||
numpt = Random[ExploS](10,15);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
let s = Spawn("MisterFuzzy",pos);
|
||||
s.angle = FRandom[ExploS](0,360);
|
||||
s.pitch = FRandom[ExploS](-90,90);
|
||||
s.target = target;
|
||||
if ( !mrc ) continue;
|
||||
MisterFuzzy(s).mrc = mrc;
|
||||
mrc.effectors.Push(s);
|
||||
}
|
||||
Spawn("MisterExLightBig",pos);
|
||||
let p = Spawn("MisterBulletImpactPop",pos);
|
||||
p.A_SetScale(8.);
|
||||
}
|
||||
override void A_BulletSubExplode()
|
||||
{
|
||||
if ( special1 && (special1 <= 20) )
|
||||
{
|
||||
int nhit, nkill;
|
||||
[nhit, nkill] = SWWMUtility.DoExplosion(self,44,6000+special1*100,150+special1*5,150+special1*5,DE_EXTRAZTHRUST|DE_COUNTENEMIES);
|
||||
if ( mrc ) mrc.nkill += nkill;
|
||||
int numpt = Random[ExploS](0,special1/2);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 np = level.Vec3Offset(pos,SWWMUtility.Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90))*FRandom[ExploS](2,16)*special1);
|
||||
if ( !level.IsPointInLevel(np) ) continue;
|
||||
let p = Spawn("MisterPop",np);
|
||||
p.target = target;
|
||||
if ( !mrc ) continue;
|
||||
MisterPop(p).mrc = mrc;
|
||||
mrc.effectors.Push(p);
|
||||
}
|
||||
}
|
||||
special1++;
|
||||
}
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
TNT1 A 0;
|
||||
XEX7 ABCDEFGHIJKLMNOPQRSTUVWXYZ[\] 1 Bright A_BulletSubExplode();
|
||||
Stop;
|
||||
}
|
||||
}
|
||||
|
||||
Class MisterRailLight : PaletteLight
|
||||
{
|
||||
Default
|
||||
{
|
||||
Tag "Cyanblu,1";
|
||||
ReactionTime 50;
|
||||
Args 0,0,0,250;
|
||||
}
|
||||
}
|
||||
|
||||
Class MisterRailBeam : Actor
|
||||
{
|
||||
MisterRailCounter mrc;
|
||||
transient CandyBeamTracer cbt; // from wikipedia
|
||||
|
||||
Default
|
||||
{
|
||||
Obituary "$O_MORTALRIFLE";
|
||||
RenderStyle "Add";
|
||||
Radius .1;
|
||||
Height 0.;
|
||||
RenderRadius 10000.;
|
||||
+FORCEXYBILLBOARD;
|
||||
+NOGRAVITY;
|
||||
+NOBLOCKMAP;
|
||||
+NOINTERACTION;
|
||||
+DONTSPLASH;
|
||||
+NOTELEPORT;
|
||||
+FOILINVUL;
|
||||
}
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
let b = Spawn("MisterRailChildBeam",pos);
|
||||
b.frame = frame;
|
||||
b.scale.y = scale.y;
|
||||
b.angle = angle;
|
||||
b.pitch = pitch;
|
||||
}
|
||||
override void Tick()
|
||||
{
|
||||
if ( isFrozen() ) return;
|
||||
A_SetScale(scale.x*.85,scale.y);
|
||||
A_FadeOut(.05);
|
||||
if ( frame == 1 ) return;
|
||||
if ( !cbt ) cbt = new("CandyBeamTracer");
|
||||
cbt.hitlist.Clear();
|
||||
Vector3 dir = SWWMUtility.Vec3FromAngles(angle,pitch-90);
|
||||
cbt.ShootThroughList.Clear();
|
||||
cbt.Trace(pos,CurSector,dir,scale.y,0);
|
||||
for ( int i=0; i<cbt.hitlist.Size(); i++ )
|
||||
{
|
||||
if ( !cbt.hitlist[i].hitactor ) continue;
|
||||
SWWMUtility.DoKnockback(cbt.hitlist[i].hitactor,cbt.hitlist[i].x,12000);
|
||||
let p = SWWMPuff.Setup(cbt.hitlist[i].hitlocation,cbt.hitlist[i].x,self,target,cbt.hitlist[i].hitactor);
|
||||
cbt.hitlist[i].hitactor.DamageMobj(p,target,44,'Mortal',DMG_THRUSTLESS|DMG_INFLICTOR_IS_PUFF);
|
||||
if ( mrc && (!cbt.hitlist[i].hitactor || (cbt.hitlist[i].hitactor.Health <= 0)) )
|
||||
mrc.nkill++;
|
||||
}
|
||||
}
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
XZW1 A -1 Bright;
|
||||
Stop;
|
||||
}
|
||||
}
|
||||
Class MisterRailChildBeam : Actor
|
||||
{
|
||||
Default
|
||||
{
|
||||
RenderStyle "Add";
|
||||
Radius .1;
|
||||
Height 0.;
|
||||
Alpha .5;
|
||||
RenderRadius 10000.;
|
||||
+FORCEXYBILLBOARD;
|
||||
+NOGRAVITY;
|
||||
+NOBLOCKMAP;
|
||||
+NOINTERACTION;
|
||||
+DONTSPLASH;
|
||||
+NOTELEPORT;
|
||||
}
|
||||
override void Tick()
|
||||
{
|
||||
if ( isFrozen() ) return;
|
||||
A_SetScale(scale.x*1.05,scale.y);
|
||||
A_FadeOut(.01);
|
||||
}
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
XZW1 A -1 Bright;
|
||||
Stop;
|
||||
}
|
||||
}
|
||||
|
||||
Class MisterGrenadeFlare : Actor
|
||||
{
|
||||
Default
|
||||
|
@ -1147,3 +1431,4 @@ Class MisterSubGrenade : MisterGrenade
|
|||
Stop;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -322,7 +322,7 @@ extend Class SWWMHandler
|
|||
let a = beams[i];
|
||||
if ( !a ) continue;
|
||||
Vector2 rv = a.pos.xy-players[consoleplayer].Camera.pos.xy;
|
||||
double rad = a.speed*cos(a.pitch);
|
||||
double rad = SWWMUtility.IsYBeam(a)?(a.scale.y*cos(a.pitch-90)):(a.speed*cos(a.pitch));
|
||||
if ( max(abs(rv.x)-rad,abs(rv.y)-rad) > viewdist )
|
||||
continue;
|
||||
if ( !level.allmap && !(a.target && a.target.IsFriend(players[consoleplayer].mo)) && !a.CheckSight(players[consoleplayer].Camera,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) )
|
||||
|
@ -380,7 +380,7 @@ extend Class SWWMHandler
|
|||
let a = beams[i];
|
||||
if ( !a ) continue;
|
||||
Vector2 rv = a.pos.xy-relpos;
|
||||
double rad = a.speed*cos(a.pitch);
|
||||
double rad = SWWMUtility.IsYBeam(a)?(a.scale.y*cos(a.pitch-90)):(a.speed*cos(a.pitch));
|
||||
if ( max(abs(rv.x)-rad,abs(rv.y)-rad) > viewdist )
|
||||
continue;
|
||||
if ( !level.allmap && !(a.target && a.target.IsFriend(players[consoleplayer].mo)) && !a.CheckSight(players[consoleplayer].Camera,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) )
|
||||
|
|
|
@ -2198,7 +2198,7 @@ Class SWWMStatusBar : BaseStatusBar
|
|||
{
|
||||
pos = SWWMUtility.LerpVector2(t.target.prev.xy,t.target.pos.xy,FracTic);
|
||||
angle = t.target.angle;
|
||||
radius = t.isbeam?(t.target.speed*cos(t.target.pitch)):t.target.radius;
|
||||
radius = t.isybeam?(t.target.scale.y*cos(t.target.pitch-90)):t.isbeam?(t.target.speed*cos(t.target.pitch)):t.target.radius;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -265,7 +265,7 @@ Class SWWMSimpleTracker play
|
|||
bool vipitem;
|
||||
bool expired;
|
||||
bool ismissile;
|
||||
bool isbeam;
|
||||
bool isbeam, isybeam;
|
||||
int lastupdate;
|
||||
ui double smoothalpha; // smoothened alpha, for ui
|
||||
SWWMSimpleTracker next;
|
||||
|
@ -274,7 +274,8 @@ Class SWWMSimpleTracker play
|
|||
{
|
||||
if ( !target ) return;
|
||||
isbeam = SWWMUtility.IsBeamProj(target);
|
||||
radius = isbeam?(target.speed*cos(target.pitch)):target.radius;
|
||||
isybeam = isbeam&&SWWMUtility.IsYBeam(target);
|
||||
radius = isybeam?(target.scale.y*cos(target.pitch+90)):isbeam?(target.speed*cos(target.pitch)):target.radius;
|
||||
angle = target.angle;
|
||||
pos = target.pos;
|
||||
isplayer = target.player;
|
||||
|
|
|
@ -939,7 +939,7 @@ Class SWWMTeleportLine : Actor
|
|||
|
||||
override void Tick()
|
||||
{
|
||||
if ( !tline )
|
||||
if ( !tline || !tline.special )
|
||||
{
|
||||
Destroy();
|
||||
return;
|
||||
|
|
|
@ -1466,6 +1466,13 @@ Class SWWMUtility
|
|||
if ( a is 'YnykronLightningArc' ) return true;
|
||||
if ( a is 'YnykronAltBeam' ) return true;
|
||||
if ( a is 'MykradvoTendril' ) return true;
|
||||
if ( a is 'MisterRailBeam' ) return true;
|
||||
return false;
|
||||
}
|
||||
// is this a YBeam type? (real pitch is pitch-90, scale.y == length)
|
||||
static play bool IsYBeam( Actor a )
|
||||
{
|
||||
if ( a is 'MisterRailBeam' ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -674,6 +674,7 @@ Class SilverBullet : SWWMWeapon
|
|||
sst.Trace(norigin,level.PointInSector(norigin.xy),x2,maxdist,TRACE_HitSky);
|
||||
maxdist -= (sst.exitpoint-norigin).length();
|
||||
norigin = sst.exitpoint;
|
||||
x2 = sst.Results.HitVector;
|
||||
}
|
||||
while ( !sst.fullstop );
|
||||
invoker.nkills = 0;
|
||||
|
|
Loading…
Reference in New Issue