0.9.3b release:

- Add models for debris, akin to DT chunks.
 - Eviscerator chunks have a glow sprite like in DT.
 - Fix potential palette light crash under very special circumstances.
 - Double range of Ynykron altfire explosion.
 - Reduce Ynykron vortex lifetime (grows quicker), and reduce mass gain from kills by 40% (allows it to suck in a couple more enemies in hordes).
 - Adjust v-field compression formula for Ynykron vortex.
 - Reduce max blockmap iterator range of Ynykron vortex, should perform slightly better (maybe) on large maps.
 - Fix Ynykron altfire beam clipping through the world due to incorrect offsets.
 - Adjust Golden shell explosion propagation math.
 - Omnisight doesn't increase the item detection range (clutters screen too much).
 - The people have spoken, build only PK3 for releases from now on.
This commit is contained in:
Mari the Deer 2020-09-20 14:53:46 +02:00
commit a8a74556a8
13 changed files with 239 additions and 36 deletions

View file

@ -1,2 +1,2 @@
[default]
SWWM_MODVER="\chSWWM \czGZ\c- \cw0.9.2b r551 \cu(Sat 19 Sep 17:45:52 CEST 2020)";
SWWM_MODVER="\chSWWM \czGZ\c- \cw0.9.3b r553 \cu(Sun 20 Sep 15:05:43 CEST 2020)";

View file

@ -16,6 +16,36 @@ Model "EvisceratorCasing"
FrameIndex XZW1 C 0 0
}
Model "EvisceratorChunk"
{
Path "models"
Model 0 "Chunky_d.3d"
Skin 0 "Chunky.png"
Scale 0.02 0.02 0.02
USEACTORPITCH
USEACTORROLL
FrameIndex XZW1 A 0 0
FrameIndex XZW1 B 0 1
FrameIndex XZW1 C 0 2
FrameIndex XZW1 D 0 3
FrameIndex XZW1 E 0 4
FrameIndex XZW1 F 0 5
FrameIndex XZW1 G 0 6
FrameIndex XZW1 H 0 7
ZOffset 0.2
FrameIndex XZW2 A 0 0
FrameIndex XZW2 B 0 1
FrameIndex XZW2 C 0 2
FrameIndex XZW2 D 0 3
FrameIndex XZW2 E 0 4
FrameIndex XZW2 F 0 5
FrameIndex XZW2 G 0 6
FrameIndex XZW2 H 0 7
}
Model "EvisceratorProj"
{
Path "models"

View file

@ -50,7 +50,7 @@ Model "HellblazerClusterMini"
Model 0 "HellblazerProj_d.3d"
Skin 0 "HellblazerMissile_Cluster.png"
Scale 0.02 0.02 0.02
Scale 0.05 0.05 0.05
USEACTORPITCH
USEACTORROLL

View file

@ -28,6 +28,35 @@ Model "FancyConfetti"
FrameIndex XZW1 J 0 0
}
Model "SWWMChip"
{
Path "models"
Model 0 "Chunky_d.3d"
Skin 0 "Chunky.png"
Scale 0.02 0.02 0.02
USEACTORPITCH
USEACTORROLL
FrameIndex XZW1 A 0 0
FrameIndex XZW1 B 0 1
FrameIndex XZW1 C 0 2
FrameIndex XZW1 D 0 3
FrameIndex XZW1 E 0 4
FrameIndex XZW1 F 0 5
FrameIndex XZW1 G 0 6
FrameIndex XZW1 H 0 7
ZOffset 0.2
FrameIndex XZW2 A 0 0
FrameIndex XZW2 B 0 1
FrameIndex XZW2 C 0 2
FrameIndex XZW2 D 0 3
FrameIndex XZW2 E 0 4
FrameIndex XZW2 F 0 5
FrameIndex XZW2 G 0 6
FrameIndex XZW2 H 0 7
}
Model "ReflectedBullet"
{
Path "models"

BIN
models/Chunky.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 973 B

BIN
models/Chunky_a.3d Normal file

Binary file not shown.

BIN
models/Chunky_d.3d Normal file

Binary file not shown.

BIN
sprites/ETRLA0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -39,7 +39,7 @@ Class PaletteLight : DynamicLight
}
private void UpdateLight()
{
int index = 255-((255*ReactionTime)/abs(default.ReactionTime));
int index = clamp(255-((255*ReactionTime)/abs(default.ReactionTime)),0,255);
args[LIGHT_RED] = pal[index].r;
args[LIGHT_GREEN] = pal[index].g;
args[LIGHT_BLUE] = pal[index].b;
@ -622,7 +622,7 @@ Class SWWMChip : Actor
{
SWWMChip prevchip, nextchip;
bool killme;
double rollvel;
double anglevel, pitchvel, rollvel;
bool dead;
Sector tracksector;
int trackplane;
@ -645,8 +645,10 @@ Class SWWMChip : Actor
}
override void PostBeginPlay()
{
anglevel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
pitchvel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
rollvel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
frame = Random[Junk](0,5);
frame = Random[Junk](0,7);
scale *= Frandom[Junk](0.8,1.2);
SWWMHandler.QueueChip(self);
}
@ -768,6 +770,8 @@ Class SWWMChip : Actor
trackplane = 0;
}
vel = (0,0,0);
pitch = 0;
roll = 0;
dead = true;
SetStateLabel("Death");
return;
@ -790,22 +794,23 @@ Class SWWMChip : Actor
States
{
Spawn:
JUNK # 1
XZW1 # 1
{
angle += anglevel;
pitch += pitchvel;
roll += rollvel;
}
Loop;
Bounce:
JUNK # 0
XZW1 # 0
{
anglevel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
pitchvel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
rollvel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
}
Goto Spawn;
Death:
JUNK # -1;
Stop;
Dummy:
JUNK ABCDEF -1;
XZW2 # -1;
Stop;
}
}

View file

@ -1,12 +1,11 @@
// Mr. BIG SHOT Industries "Eviscerator" High Load Flak Cannon (from SWWM series)
// Slot 5, replaces Chaingun, Dragon Claw, Hammer of Retribution
Class EvisceratorChunkLight : DynamicLight
Class EvisceratorChunkLight : PointLightAttenuated
{
Default
{
DynamicLight.Type "Point";
Args 255,224,128,8;
Args 255,224,128,16;
}
override void Tick()
{
@ -18,7 +17,7 @@ Class EvisceratorChunkLight : DynamicLight
}
SetOrigin(target.pos,true);
if ( isFrozen() ) return;
double intst = clamp((7-EvisceratorChunk(target).lifetime*10)/7.,0,1);
double intst = clamp((.7-EvisceratorChunk(target).lifetime)/.7,0.,1.);
args[LIGHT_RED] = int(255*intst);
args[LIGHT_GREEN] = int(224*intst);
args[LIGHT_BLUE] = int(128*intst);
@ -70,10 +69,45 @@ Class ChunkImpact : Actor
}
}
Class EvisceratorChunkGlow : Actor
{
Default
{
RenderStyle "Add";
Radius .1;
Height 0.;
Scale .25;
+FORCEXYBILLBOARD;
+NOGRAVITY;
+NOBLOCKMAP;
+NOINTERACTION;
+DONTSPLASH;
+NOTELEPORT;
}
override void Tick()
{
if ( isFrozen() ) return;
if ( !EvisceratorChunk(target) )
{
Destroy();
return;
}
SetOrigin(target.pos,true);
alpha = clamp((.7-EvisceratorChunk(target).lifetime)/.7,0.,1.);
if ( alpha <= 0. ) Destroy();
}
States
{
Spawn:
ETRL A -1 Bright;
Stop;
}
}
Class EvisceratorChunk : Actor
{
Actor lasthit;
double rollvel;
double anglevel, pitchvel, rollvel;
double lifetime, lifespeed;
Vector3 oldvel;
bool justdied;
@ -108,11 +142,15 @@ Class EvisceratorChunk : Actor
Super.PostBeginPlay();
let l = Spawn("EvisceratorChunkLight",pos);
l.target = self;
let t = Spawn("EvisceratorChunkGlow",pos);
t.target = self;
lifetime = 0;
lifespeed = FRandom[Eviscerator](0.01,0.02);
anglevel = FRandom[Eviscerator](50,100)*RandomPick[Eviscerator](-1,1);
pitchvel = FRandom[Eviscerator](50,100)*RandomPick[Eviscerator](-1,1);
rollvel = FRandom[Eviscerator](50,100)*RandomPick[Eviscerator](-1,1);
scale *= Frandom[Eviscerator](0.8,1.2);
frame = Random[Eviscerator](0,5);
frame = Random[Eviscerator](0,7);
}
override void Tick()
@ -131,6 +169,7 @@ Class EvisceratorChunk : Actor
// I guess I can blame graf, randi, or whoever else
if ( isFrozen() || justdied ) return;
lifetime += lifespeed;
if ( waterlevel > 0 ) lifetime = max(.7,lifetime);
A_SetTranslation(tls[clamp(int(lifetime*10),0,7)]);
if ( !Random[Eviscerator](0,3) && (lifetime < .7) )
{
@ -140,7 +179,11 @@ Class EvisceratorChunk : Actor
s.alpha *= scale.x*max(0,.7-lifetime)*1.5;
}
if ( !InStateSequence(CurState,FindState("Death")) )
{
angle += anglevel;
pitch += pitchvel;
roll += rollvel;
}
}
void A_HandleBounce()
@ -200,6 +243,8 @@ Class EvisceratorChunk : Actor
}
A_Gravity();
gravity = .35;
anglevel = FRandom[Eviscerator](50,100)*RandomPick[Eviscerator](-1,1)*(vel.length()/speed);
pitchvel = FRandom[Eviscerator](50,100)*RandomPick[Eviscerator](-1,1)*(vel.length()/speed);
rollvel = FRandom[Eviscerator](50,100)*RandomPick[Eviscerator](-1,1)*(vel.length()/speed);
A_StartSound("eviscerator/hit",CHAN_WEAPON,CHANF_OVERLAP,.4);
if ( swwm_extraalert ) A_AlertMonsters(300);
@ -270,18 +315,20 @@ Class EvisceratorChunk : Actor
States
{
Spawn:
JUNK # -1;
XZW1 # -1;
Stop;
Bounce:
JUNK # 0 A_HandleBounce();
XZW1 # 0 A_HandleBounce();
Goto Spawn;
Death:
JUNK # 0
XZW2 # 0
{
pitch = 0;
roll = 0;
bMOVEWITHSECTOR = true;
A_SetTics(Random[Eviscerator](30,50));
}
JUNK # 1 A_FadeOut();
XZW2 # 1 A_FadeOut();
Wait;
XDeath:
TNT1 A 35 { invoker.justdied = true; }

View file

@ -1214,7 +1214,7 @@ Class GatherDust : Actor
if ( distto < (32.*target.scale.x) )
{
// sucked in
target.specialf2 += FRandom[ExploS](.1,.4);
target.specialf2 += FRandom[ExploS](.2,2.);
Destroy();
return;
}
@ -1959,6 +1959,92 @@ Class YnykronVoidSparkle : Actor
Stop;
}
}
Class YnykronSingularityExplosionArm : Actor
{
Default
{
PROJECTILE;
+THRUACTORS;
+BOUNCEONWALLS;
+BOUNCEONFLOORS;
+BOUNCEONCEILINGS;
+NODAMAGETHRUST;
+FORCERADIUSDMG;
-NOGRAVITY;
Gravity 0.35;
BounceFactor 1.0;
Radius 4;
Height 4;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
reactiontime = Random[ExploS](10,20);
double ang, pt;
ang = FRandom[ExploS](0,360);
pt = FRandom[ExploS](-90,90);
vel = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[ExploS](20.,40.);
}
States
{
Spawn:
TNT1 A 1
{
A_CountDown();
if ( !(reactiontime%2) )
{
Spawn("YnykronSingularityExplosionTrail",pos);
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](1,5);
let s = Spawn("SWWMHalfSmoke",pos);
s.SetShade(Color(1,1,1)*Random[ExploS](128,160)+Color(28,0,31));
s.A_SetRenderStyle(s.alpha*(.1+.4*(ReactionTime/15.)),STYLE_AddShaded);
s.vel = pvel+vel*.2;
s.special1 = Random[ExploS](1,3);
s.scale *= 2.4;
}
}
Wait;
}
}
Class YnykronSingularityExplosionTrail : Actor
{
Default
{
RenderStyle "Add";
+NOBLOCKMAP;
+NOGRAVITY;
+FORCEXYBILLBOARD;
+NOTELEPORT;
+NOINTERACTION;
Scale 3.;
Alpha .2;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
Scale *= FRandom[ExploS](0.8,1.1);
Scale.x *= RandomPick[ExploS](-1,1);
Scale.y *= RandomPick[ExploS](-1,1);
}
override void Tick()
{
if ( isFrozen() ) return;
if ( !CheckNoDelay() || (tics == -1) ) return;
if ( tics > 0 ) tics--;
while ( !tics )
{
if ( !SetState(CurState.NextState) )
return;
}
}
States
{
Spawn:
XEX4 ABCDEFGHIJKLMNOPQRSTUVWXYZ[\ 1 Bright;
Stop;
}
}
Class YnykronSingularityExplosion : Actor
{
@ -2010,6 +2096,12 @@ Class YnykronSingularityExplosion : Actor
s.angle = ang;
s.pitch = pt;
}
numpt = Random[ExploS](-1,3);
for ( int i=0; i<numpt; i++ )
{
let s = Spawn("YnykronSingularityExplosionArm",pos);
s.target = target;
}
}
override void Tick()
{
@ -2183,7 +2275,7 @@ Class YnykronSingularity : Actor
beamers[i].master = self;
}
// suck in reachable targets
let bi = BlockThingsIterator.Create(self,20000*scale.x);
let bi = BlockThingsIterator.Create(self,12800*scale.x);
while ( bi.Next() )
{
let a = bi.Thing;
@ -2233,7 +2325,7 @@ Class YnykronSingularity : Actor
IDontFeelSoGood.DeletThis(a,true); // ensures corpse is deleted too
}
if ( !a || (a.Health <= 0) )
specialf2 += capmass;
specialf2 += capmass*.6; // partial absorption
continue;
}
capmass = max(50.,a.mass);
@ -2254,7 +2346,7 @@ Class YnykronSingularity : Actor
if ( a.mass < LARGE_MASS )
{
// v-force field compression (very rough approximation)
a.vel *= max(0.,1.-.0002*(grav*grav)/(MION_CONST*MION_CONST));
a.vel *= max(.0,1.-.03*(grav*grav)/(MION_CONST*MION_CONST));
a.vel += dirto*grav/(capmass*TICRATE);
}
}
@ -2348,8 +2440,8 @@ Class YnykronSingularity : Actor
}
double factor = (60-special1)/60.;
double invfct = 1.-factor;
SWWMUtility.DoExplosion(self,0,-50000*factor,2000*invfct);
FlashPlayer(int(100*factor),9000);
SWWMUtility.DoExplosion(self,0,-50000*factor,4000*invfct);
FlashPlayer(int(100*factor),10000);
FLineTraceData d;
Vector3 HitNormal;
Vector3 origin;
@ -2357,7 +2449,7 @@ Class YnykronSingularity : Actor
int numpt = clamp(special1/6,2,8);
for ( int i=0; i<numpt; i++ )
{
double totaldist = 30+(special1**2.5)*.05;
double totaldist = 30+(special1**2.5)*.1;
ang = FRandom[ExploS](0,360);
pt = FRandom[ExploS](-90,90);
origin = pos;
@ -2383,7 +2475,7 @@ Class YnykronSingularity : Actor
totaldist -= d.Distance;
if ( totaldist > 0 )
{
Vector3 bounced = d.HitDir-(2*hitnormal*(d.HitDir dot HitNormal));
Vector3 bounced = d.HitDir-(1.2*hitnormal*(d.HitDir dot HitNormal));
ang = atan2(bounced.y,bounced.x);
pt = asin(-bounced.z);
origin = d.HitLocation+hitnormal;
@ -2447,7 +2539,7 @@ Class YnykronAltBeam : Actor
let b = Spawn("InvisibleSplasher",t.WaterHitList[i].hitpos);
b.A_CheckTerrain();
}
for ( int i=0; i<t.Results.Distance; i+=32 )
for ( int i=0; i<t.Results.Distance; i+=16 )
{
if ( Random[Ynykron](0,2) ) continue;
let b = Spawn("SWWMHalfSmoke",level.Vec3Offset(pos,x*i));
@ -2495,7 +2587,7 @@ Class YnykronAltBeam : Actor
int numpt = Random[Ynykron](16,24);
for ( int i=0; i<numpt; i++ )
{
let b = Spawn("SWWMSmoke",level.Vec3Offset(pos,x*128));
let b = Spawn("SWWMSmoke",level.Vec3Offset(pos,x*64));
b.Scale *= FRandom[Ynykron](.6,1.8);
b.special1 = Random[Ynykron](1,2);
b.A_SetRenderStyle(.3,STYLE_Subtract);
@ -2511,7 +2603,7 @@ Class YnykronAltBeam : Actor
Vector3 x, y, z;
[x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll);
// propagate
let next = Spawn("YnykronAltBeam",level.Vec3Offset(pos,x*128));
let next = Spawn("YnykronAltBeam",level.Vec3Offset(pos,x*64));
next.angle = atan2(x.y,x.x);
next.pitch = asin(-x.z);
next.roll = roll;

View file

@ -342,11 +342,11 @@ Class Demolitionist : PlayerPawn
void SenseItems()
{
let thesight = FindInventory("Omnisight");
let bt = BlockThingsIterator.Create(self,1200);
let bt = BlockThingsIterator.Create(self,800);
while ( bt.Next() )
{
let i = Inventory(bt.Thing);
if ( !i || i.bINVISIBLE || !i.bSPECIAL || i.Owner || !SWWMUtility.SphereIntersect(i,pos,thesight?1200:800) ) continue;
if ( !i || i.bINVISIBLE || !i.bSPECIAL || i.Owner || !SWWMUtility.SphereIntersect(i,pos,800) ) continue;
if ( !thesight && !CheckSight(i) ) continue;
SWWMItemSense.Spawn(self,i);
}

View file

@ -1696,7 +1696,7 @@ Class GoldenImpact : Actor
totaldist -= d.Distance;
if ( totaldist > 0 )
{
Vector3 bounced = d.HitDir-(2*hitnormal*(d.HitDir dot HitNormal));
Vector3 bounced = d.HitDir-(1.2*hitnormal*(d.HitDir dot HitNormal));
ang = atan2(bounced.y,bounced.x);
pt = asin(-bounced.z);
origin = d.HitLocation+hitnormal;
@ -1832,7 +1832,7 @@ Class GoldenSubImpact : Actor
totaldist -= d.Distance;
if ( totaldist > 0 )
{
Vector3 bounced = d.HitDir-(2*hitnormal*(d.HitDir dot HitNormal));
Vector3 bounced = d.HitDir-(1.2*hitnormal*(d.HitDir dot HitNormal));
ang = atan2(bounced.y,bounced.x);
pt = asin(-bounced.z);
origin = d.HitLocation+hitnormal;