Added various screen shaders, plus a bunch of other changes.
Spreadgun rebalancing. Underwater sounds. Embiggener use sound. Other small things here and there.
This commit is contained in:
parent
191a9a5bb9
commit
42db2d3603
30 changed files with 754 additions and 194 deletions
|
|
@ -13,12 +13,19 @@ after the first release.
|
|||
- Super Happy Fun Ball (SWWM Z)
|
||||
* Additional Demolitionist Menu features
|
||||
- Per-monster kill tracker in stats tab
|
||||
- Music player with a selection of Saya's favourite tracks
|
||||
- Radio
|
||||
- Pong minigame
|
||||
- Selling items at the store
|
||||
* Fanart on the intermission screen
|
||||
* 4komas on the intermission screen
|
||||
* Actually make a fancy titlemap
|
||||
* Mod trailer
|
||||
* Additional HUD stuff
|
||||
- Minimap with radar like in SWWM Z
|
||||
- Fake livestream chat, with dynamic reactions to all sorts of stuff
|
||||
* Character and item images for the library
|
||||
* Full Mashiro model for Lämp easter egg
|
||||
* Summonable Ibuki companion (w/ optional "stream friendly" clothing)
|
||||
* Saya model, for scenes or something idk
|
||||
* Japanese Localization???
|
||||
* Strife support, with rewritten dialogue
|
||||
|
|
|
|||
BIN
brightmaps/Nobright.png
Normal file
BIN
brightmaps/Nobright.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 67 B |
|
|
@ -36,22 +36,32 @@ HardwareShader Texture "models/Refresher.png"
|
|||
Brightmap Texture "models/GhostArtifact.png"
|
||||
{
|
||||
Map "models/GhostArtifact_bright.png"
|
||||
DisableFullbright
|
||||
}
|
||||
Brightmap Texture "models/Gravity.png"
|
||||
{
|
||||
Map "models/Gravity_bright.png"
|
||||
DisableFullbright
|
||||
}
|
||||
Brightmap Texture "models/Ragekit.png"
|
||||
{
|
||||
Map "models/Ragekit_bright.png"
|
||||
DisableFullbright
|
||||
}
|
||||
Brightmap Texture "models/Omnisight.png"
|
||||
{
|
||||
Map "models/Omnisight_bright.png"
|
||||
DisableFullbright
|
||||
}
|
||||
Brightmap Texture "models/Lamp.png"
|
||||
{
|
||||
Map "models/Lamp_bright.png"
|
||||
DisableFullbright
|
||||
}
|
||||
Brightmap Texture "models/Invinciball.png"
|
||||
{
|
||||
Map "brightmaps/nobright.png"
|
||||
DisableFullbright
|
||||
}
|
||||
Brightmap Texture "models/Moth_Mashiro.png"
|
||||
{
|
||||
|
|
|
|||
21
gldefs.pp
Normal file
21
gldefs.pp
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
HardwareShader PostProcess beforebloom
|
||||
{
|
||||
Name "GhostShader"
|
||||
Shader "shaders/glsl/Ghostscreen.fp" 330
|
||||
}
|
||||
HardwareShader PostProcess scene
|
||||
{
|
||||
Name "InvinciShader"
|
||||
Shader "shaders/glsl/Invinciscreen.fp" 330
|
||||
Uniform float str
|
||||
}
|
||||
|
||||
HardwareShader PostProcess scene
|
||||
{
|
||||
Name "RagekitShader"
|
||||
Shader "shaders/glsl/Ragescreen.fp" 330
|
||||
Texture WarpTex "textures/ragewarp.png"
|
||||
Texture NoiseTex "textures/graynoise.png"
|
||||
Uniform float timer
|
||||
Uniform float xtrastr
|
||||
}
|
||||
|
|
@ -128,7 +128,6 @@ Model "GhostArtifactX"
|
|||
SurfaceSkin 0 0 "darkmap.png"
|
||||
Scale 0.05 0.05 0.05
|
||||
ZOffset 16
|
||||
ROTATING
|
||||
|
||||
FrameIndex XZW1 A 0 0
|
||||
}
|
||||
|
|
@ -138,39 +137,66 @@ Model "GravitySuppressor"
|
|||
Path "models"
|
||||
Model 0 "Gravity_d.3d"
|
||||
SurfaceSkin 0 0 "Gravity.png"
|
||||
SurfaceSkin 0 1 "silvermap.png"
|
||||
Scale 0.06 0.06 0.06
|
||||
ZOffset 16
|
||||
ROTATING
|
||||
|
||||
FrameIndex XZW1 A 0 0
|
||||
}
|
||||
Model "GravityX"
|
||||
{
|
||||
Path "models"
|
||||
Model 0 "Gravity_d.3d"
|
||||
SurfaceSkin 0 1 "silvermap.png"
|
||||
Scale 0.06 0.06 0.06
|
||||
ZOffset 16
|
||||
|
||||
FrameIndex XZW1 A 0 0
|
||||
}
|
||||
|
||||
Model "FuckingInvinciball"
|
||||
{
|
||||
Path "models"
|
||||
Model 0 "Invinciball_d.3d"
|
||||
SurfaceSkin 0 0 "Invinciball.png"
|
||||
SurfaceSkin 0 1 "invincimap.png"
|
||||
Scale 0.04 0.04 0.04
|
||||
ZOffset 16
|
||||
ROTATING
|
||||
|
||||
FrameIndex XZW1 A 0 0
|
||||
}
|
||||
Model "InvinciballX"
|
||||
{
|
||||
Path "models"
|
||||
Model 0 "Invinciball_d.3d"
|
||||
SurfaceSkin 0 1 "invincimap.png"
|
||||
Scale 0.04 0.04 0.04
|
||||
ZOffset 16
|
||||
|
||||
FrameIndex XZW1 A 0 0
|
||||
}
|
||||
|
||||
Model "Ragekit"
|
||||
{
|
||||
Path "models"
|
||||
Model 0 "Ragekit_d.3d"
|
||||
SurfaceSkin 0 0 "Ragekit.png"
|
||||
SurfaceSkin 0 1 "ragemap.png"
|
||||
Scale 0.05 0.05 0.05
|
||||
ZOffset 16
|
||||
ROTATING
|
||||
|
||||
FrameIndex XZW1 A 0 0
|
||||
}
|
||||
Model "RagekitX"
|
||||
{
|
||||
Path "models"
|
||||
Model 0 "Ragekit_d.3d"
|
||||
SurfaceSkin 0 1 "ragemap.png"
|
||||
Scale 0.05 0.05 0.05
|
||||
ZOffset 16
|
||||
|
||||
FrameIndex XZW1 A 0 0
|
||||
}
|
||||
|
||||
Model "Omnisight"
|
||||
{
|
||||
|
|
|
|||
12
shaders/glsl/Ghostscreen.fp
Normal file
12
shaders/glsl/Ghostscreen.fp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
void main()
|
||||
{
|
||||
vec2 uv = TexCoord;
|
||||
vec3 col = texture(InputTexture,uv).rgb;
|
||||
float p = distance(uv,vec2(.5))/sqrt(2.);
|
||||
for ( float i=0.; i<4.; i+=1. )
|
||||
{
|
||||
vec2 suv = fract((.5-uv)*(1.-i*p*p)+.5);
|
||||
col += texture(InputTexture,suv).rgb*pow(p,2.)*vec3(.6,.8,1.3);
|
||||
}
|
||||
FragColor = vec4(col,1.0);
|
||||
}
|
||||
29
shaders/glsl/Glitch.frag
Normal file
29
shaders/glsl/Glitch.frag
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
float rnd2( in vec2 sd )
|
||||
{
|
||||
return fract(cos(dot(sd*floor(Timer*15.0),vec2(145.34,142.55)))*2745.84);
|
||||
}
|
||||
float rnd( in float sd )
|
||||
{
|
||||
return rnd2(vec2(sd,1.0));
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 coord = TexCoord;
|
||||
vec2 uv_c[3] = vec2[3](coord,coord,coord);
|
||||
vec2 blka = floor(coord*vec2(22.0,12.0));
|
||||
vec2 blkb = floor(coord*vec2(6.0,9.0));
|
||||
float noiz = pow(rnd2(blka),thr1)*pow(rnd2(blkb),thr2)-pow(rnd(4.53),thr3)*str2;
|
||||
uv_c[0].x += str1*noiz*(rnd(3.35)-0.5);
|
||||
uv_c[1].x += str1*noiz*(rnd(4.63)-0.5);
|
||||
uv_c[2].x += str1*noiz*(rnd(5.62)-0.5);
|
||||
uv_c[0].y += str1*noiz*(rnd(4.55)-0.5);
|
||||
uv_c[1].y += str1*noiz*(rnd(3.67)-0.5);
|
||||
uv_c[2].y += str1*noiz*(rnd(5.54)-0.5);
|
||||
vec4 res;
|
||||
res.r = texture(InputTexture,uv_c[0]).r;
|
||||
res.g = texture(InputTexture,uv_c[1]).g;
|
||||
res.b = texture(InputTexture,uv_c[2]).b;
|
||||
res.a = 1.0;
|
||||
FragColor = res;
|
||||
}
|
||||
59
shaders/glsl/Grain.frag
Normal file
59
shaders/glsl/Grain.frag
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
Complex grain shader ported over from MariENB
|
||||
(C)2012-2018 Marisa Kirisame
|
||||
*/
|
||||
const float nf = 0.000005;
|
||||
const vec3 nm1 = vec3(2.05,3.11,2.22);
|
||||
const float nk = 0.04;
|
||||
const vec3 nm2 = vec3(4.25,9.42,6.29);
|
||||
const float ns = -0.08;
|
||||
const float np = 3.95;
|
||||
const float bnp = 1.7;
|
||||
|
||||
#define darkmask(a,b) (a>0.5)?(2.0*a*(0.5+b)):(1.0-2.0*(1.0-a)*(1.0-((0.5+b))))
|
||||
|
||||
vec3 grain( in vec3 res, in vec2 coord )
|
||||
{
|
||||
float ts = Timer*nf;
|
||||
vec2 s1 = coord+vec2(0.0,ts);
|
||||
vec2 s2 = coord+vec2(ts,0.0);
|
||||
vec2 s3 = coord+vec2(ts,ts);
|
||||
float n1, n2, n3;
|
||||
vec2 nr = textureSize(NoiseTexture,0);
|
||||
s1 = mod(s1*nm1.x*nr,1.0);
|
||||
s2 = mod(s2*nm1.y*nr,1.0);
|
||||
s3 = mod(s3*nm1.z*nr,1.0);
|
||||
n1 = texture(NoiseTexture,s1).r;
|
||||
n2 = texture(NoiseTexture,s2).g;
|
||||
n3 = texture(NoiseTexture,s3).b;
|
||||
s1 = coord+vec2(ts+n1*nk,n2*nk);
|
||||
s2 = coord+vec2(n2,ts+n3*nk);
|
||||
s3 = coord+vec2(ts+n3*nk,ts+n1*nk);
|
||||
s1 = mod(s1*nm2.x*nr,1.0);
|
||||
s2 = mod(s2*nm2.y*nr,1.0);
|
||||
s3 = mod(s3*nm2.z*nr,1.0);
|
||||
n1 = texture(NoiseTexture,s1).r;
|
||||
n2 = texture(NoiseTexture,s2).g;
|
||||
n3 = texture(NoiseTexture,s3).b;
|
||||
float n4 = (n1+n2+n3)/3.0;
|
||||
vec3 ng = vec3(n4);
|
||||
vec3 nc = vec3(n1,n2,n3);
|
||||
vec3 nt = pow(clamp(mix(ng,nc,ns),0.0,1.0),vec3(np));
|
||||
float bn = 1.0-clamp((res.r+res.g+res.b)/3.0,0.0,1.0);
|
||||
bn = pow(bn,bnp);
|
||||
vec3 nn = clamp(nt*bn,vec3(0.0),vec3(1.0));
|
||||
res.r = darkmask(res.r,(nn.r*ni));
|
||||
res.g = darkmask(res.g,(nn.g*ni));
|
||||
res.b = darkmask(res.b,(nn.b*ni));
|
||||
return res;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 coord = TexCoord;
|
||||
vec4 res = texture(InputTexture,coord);
|
||||
/*vec2 sfact = max(vec2(320.0,200.0),textureSize(InputTexture,0)*0.5);
|
||||
coord = floor(coord*sfact)/sfact;*/
|
||||
res.rgb = grain(res.rgb,coord);
|
||||
FragColor = res;
|
||||
}
|
||||
28
shaders/glsl/Invinciscreen.fp
Normal file
28
shaders/glsl/Invinciscreen.fp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
vec3 sharpened( vec2 uv )
|
||||
{
|
||||
vec3 col = texture(InputTexture,uv).rgb*9.;
|
||||
vec2 bresl = vec2(textureSize(InputTexture,0));
|
||||
vec2 bof = vec2(1./bresl.x,1./bresl.y);
|
||||
col -= texture(InputTexture,uv+vec2(bof.x,0)).rgb;
|
||||
col -= texture(InputTexture,uv+vec2(2.*bof.x,0)).rgb;
|
||||
col -= texture(InputTexture,uv+vec2(-bof.x,0)).rgb;
|
||||
col -= texture(InputTexture,uv+vec2(-2.*bof.x,0)).rgb;
|
||||
col -= texture(InputTexture,uv+vec2(0,bof.y)).rgb;
|
||||
col -= texture(InputTexture,uv+vec2(0,2.*bof.y)).rgb;
|
||||
col -= texture(InputTexture,uv+vec2(0,-bof.y)).rgb;
|
||||
col -= texture(InputTexture,uv+vec2(0,-2.*bof.y)).rgb;
|
||||
return col;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = TexCoord;
|
||||
vec3 col = texture(InputTexture,uv).rgb;
|
||||
float p = distance(uv,vec2(.5));
|
||||
for ( float i=0.; i<4.; i+=1. )
|
||||
{
|
||||
vec2 suv = fract((uv-.5)*(1.-.01*i*(.3+str*4.))+.5);
|
||||
col += sharpened(suv)*pow(p,2.4)*vec3(1.2,.7,.2)*(.4+str);
|
||||
}
|
||||
FragColor = vec4(col,1.0);
|
||||
}
|
||||
20
shaders/glsl/Ragescreen.fp
Normal file
20
shaders/glsl/Ragescreen.fp
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#define TWOPI 6.28318530718
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = TexCoord;
|
||||
vec3 col = texture(InputTexture,uv).rgb;
|
||||
col *= vec3(.5)+texture(WarpTex,vec2(fract(uv.x+.1*sin(uv.y*TWOPI)),fract(uv.y-timer*.1))).rgb*xtrastr;
|
||||
col *= vec3(.5)+texture(WarpTex,2.*vec2(fract(uv.x+.1*cos(uv.y*TWOPI)),fract(uv.y-timer*.1))).rgb*xtrastr;
|
||||
for ( float i=0.; i<4.; i+=1. )
|
||||
{
|
||||
float str = texture(NoiseTex,vec2(fract(timer*.2),fract(timer*.02))).x*.07;
|
||||
str *= pow(xtrastr,1.5);
|
||||
float p = distance(uv,vec2(.5));
|
||||
vec2 suv = (uv-.5)*(1.-(str*i*p))+.5;
|
||||
col += texture(InputTexture,suv).rgb+pow(p,2.)*vec3(1.8,.2,0.)*xtrastr;
|
||||
}
|
||||
col /= 5.;
|
||||
col *= vec3(1.2,.9,.7);
|
||||
FragColor = vec4(col,1.0);
|
||||
}
|
||||
13
sndinfo.txt
13
sndinfo.txt
|
|
@ -551,6 +551,16 @@ misc/chat sounds/menu/chatsnd.ogg
|
|||
misc/chat2 sounds/menu/chatsnd.ogg
|
||||
misc/sundowner sounds/SUNDOWNER.ogg
|
||||
|
||||
misc/underwater sounds/general/uWater1a.ogg
|
||||
misc/underslime sounds/general/uGoop1.ogg
|
||||
misc/underlava sounds/general/uLava1.ogg
|
||||
misc/waterenter sounds/general/DIVE.ogg
|
||||
misc/slimeenter sounds/general/GoopJ1.ogg
|
||||
misc/lavaenter sounds/general/LavaJ1.ogg
|
||||
misc/waterexit sounds/general/surfaceb.ogg
|
||||
misc/slimeexit sounds/general/GoopE1.ogg
|
||||
misc/lavaexit sounds/general/LavaE1.ogg
|
||||
|
||||
armor/blastsuit sounds/items/blastsuit.ogg
|
||||
armor/wararmor sounds/items/wararmor.ogg
|
||||
armor/hit1 sounds/items/hullhit.ogg
|
||||
|
|
@ -575,8 +585,9 @@ powerup/invinciballend sounds/items/invincioff.ogg
|
|||
powerup/ragekit sounds/items/ragekiton.ogg
|
||||
powerup/ragekitact sounds/items/ragekitact.ogg
|
||||
powerup/ragekithit sounds/items/ragekithit.ogg
|
||||
powerup/ragekitend sounds/items/ragekitend.ogg
|
||||
powerup/ragekitend sounds/items/ragekitoff.ogg
|
||||
powerup/omnisight sounds/items/omnisight.ogg
|
||||
powerup/embiggener sounds/items/embiggen.ogg
|
||||
|
||||
lamp/on sounds/items/lampon.ogg
|
||||
lamp/off sounds/items/lampoff.ogg
|
||||
|
|
|
|||
BIN
sounds/general/DIVE.ogg
Normal file
BIN
sounds/general/DIVE.ogg
Normal file
Binary file not shown.
BIN
sounds/general/GoopE1.ogg
Normal file
BIN
sounds/general/GoopE1.ogg
Normal file
Binary file not shown.
BIN
sounds/general/GoopJ1.ogg
Normal file
BIN
sounds/general/GoopJ1.ogg
Normal file
Binary file not shown.
BIN
sounds/general/LavaE1.ogg
Normal file
BIN
sounds/general/LavaE1.ogg
Normal file
Binary file not shown.
BIN
sounds/general/LavaJ1.ogg
Normal file
BIN
sounds/general/LavaJ1.ogg
Normal file
Binary file not shown.
BIN
sounds/general/surfaceb.ogg
Normal file
BIN
sounds/general/surfaceb.ogg
Normal file
Binary file not shown.
BIN
sounds/general/uGoop1.ogg
Normal file
BIN
sounds/general/uGoop1.ogg
Normal file
Binary file not shown.
BIN
sounds/general/uLava1.ogg
Normal file
BIN
sounds/general/uLava1.ogg
Normal file
Binary file not shown.
BIN
sounds/general/uWater1a.ogg
Normal file
BIN
sounds/general/uWater1a.ogg
Normal file
Binary file not shown.
BIN
sounds/items/embiggen.ogg
Normal file
BIN
sounds/items/embiggen.ogg
Normal file
Binary file not shown.
BIN
textures/ragewarp.png
Normal file
BIN
textures/ragewarp.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 86 KiB |
|
|
@ -931,6 +931,7 @@ Class HammerspaceEmbiggener : Inventory
|
|||
{
|
||||
override Inventory CreateCopy( Actor other )
|
||||
{
|
||||
other.A_StartSound("powerup/embiggener",CHAN_ITEMEXTRA);
|
||||
// Find every unique type of ammoitem. Give it to the player if
|
||||
// he doesn't have it already, and increase its maximum capacity.
|
||||
for ( int i=0; i<AllActorClasses.Size(); i++ )
|
||||
|
|
@ -996,6 +997,7 @@ Class HammerspaceEmbiggener : Inventory
|
|||
bool res = Super.HandlePickup(item);
|
||||
if ( item.GetClass() == GetClass() )
|
||||
{
|
||||
Owner.A_StartSound("powerup/embiggener",CHAN_ITEMEXTRA);
|
||||
// readjust ammo values to new capacity
|
||||
for ( Inventory i=Owner.Inv; i; i=i.Inv )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
// common code goes here
|
||||
enum ESWWMGZChannels
|
||||
{
|
||||
CHAN_YOUDONEFUCKEDUP = 63200,
|
||||
CHAN_DEMOVOICE = 63201,
|
||||
CHAN_FOOTSTEP = 63202,
|
||||
CHAN_WEAPONEXTRA = 63203,
|
||||
CHAN_POWERUP = 63204,
|
||||
CHAN_POWERUPEXTRA = 63205,
|
||||
CHAN_JETPACK = 63206,
|
||||
CHAN_ITEMEXTRA = 63207
|
||||
CHAN_YOUDONEFUCKEDUP = 63200, // exception handler
|
||||
CHAN_DEMOVOICE = 63201, // demolitionist voices
|
||||
CHAN_FOOTSTEP = 63202, // footstep sounds and others
|
||||
CHAN_WEAPONEXTRA = 63203, // additional weapon sounds (usually loops)
|
||||
CHAN_POWERUP = 63204, // powerup sounds
|
||||
CHAN_POWERUPEXTRA = 63205, // additional powerup sounds
|
||||
CHAN_JETPACK = 63206, // jetpack sound
|
||||
CHAN_ITEMEXTRA = 63207, // additional item sounds
|
||||
CHAN_AMBEXTRA = 63208 // player ambience when submerged
|
||||
};
|
||||
|
||||
// Misc. Utility code
|
||||
|
|
@ -367,6 +368,8 @@ Class SWWMScoreObj : Thinker
|
|||
int lifespan, initialspan;
|
||||
int starttic, seed, seed2;
|
||||
int ofs;
|
||||
SWWMScoreObj prev, next;
|
||||
bool damnum;
|
||||
|
||||
static SWWMScoreObj Spawn( int score, Vector3 pos, int tcolor = Font.CR_GOLD, String str = "", int ofs = 0 )
|
||||
{
|
||||
|
|
@ -381,9 +384,56 @@ Class SWWMScoreObj : Thinker
|
|||
o.seed = Random[ScoreBits]();
|
||||
o.seed2 = Random[ScoreBits]();
|
||||
o.ofs = ofs;
|
||||
o.damnum = (tcolor == Font.CR_RED) || (tcolor == Font.CR_GREEN);
|
||||
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
|
||||
if ( hnd )
|
||||
{
|
||||
if ( o.damnum )
|
||||
{
|
||||
o.next = hnd.damnums;
|
||||
if ( hnd.damnums ) hnd.damnums.prev = o;
|
||||
hnd.damnums = o;
|
||||
hnd.damnums_cnt++;
|
||||
}
|
||||
else
|
||||
{
|
||||
o.next = hnd.scorenums;
|
||||
if ( hnd.scorenums ) hnd.scorenums.prev = o;
|
||||
hnd.scorenums = o;
|
||||
hnd.scorenums_cnt++;
|
||||
}
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
override void OnDestroy()
|
||||
{
|
||||
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
|
||||
if ( hnd )
|
||||
{
|
||||
if ( damnum )
|
||||
{
|
||||
hnd.damnums_cnt--;
|
||||
if ( !prev ) hnd.damnums = next;
|
||||
}
|
||||
else
|
||||
{
|
||||
hnd.scorenums_cnt--;
|
||||
if ( !prev ) hnd.scorenums = next;
|
||||
}
|
||||
if ( !prev )
|
||||
{
|
||||
if ( next ) next.prev = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev.next = next;
|
||||
if ( next ) next.prev = prev;
|
||||
}
|
||||
}
|
||||
Super.OnDestroy();
|
||||
}
|
||||
|
||||
override void Tick()
|
||||
{
|
||||
lifespan--;
|
||||
|
|
@ -403,6 +453,7 @@ Class SWWMInterest : Thinker
|
|||
Key trackedkey;
|
||||
Line trackedline;
|
||||
Vector3 pos;
|
||||
SWWMInterest prev, next;
|
||||
|
||||
static SWWMInterest Spawn( Vector3 pos = (0,0,0), Key thekey = null, Line theline = null )
|
||||
{
|
||||
|
|
@ -419,9 +470,37 @@ Class SWWMInterest : Thinker
|
|||
return null;
|
||||
}
|
||||
i.pos = thekey?thekey.Vec3Offset(0,0,thekey.height/2):pos;
|
||||
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
|
||||
if ( hnd )
|
||||
{
|
||||
i.next = hnd.intpoints;
|
||||
if ( hnd.intpoints ) hnd.intpoints.prev = i;
|
||||
hnd.intpoints = i;
|
||||
hnd.intpoints_cnt++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
override void OnDestroy()
|
||||
{
|
||||
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
|
||||
if ( hnd )
|
||||
{
|
||||
hnd.intpoints_cnt--;
|
||||
if ( !prev )
|
||||
{
|
||||
hnd.intpoints = next;
|
||||
if ( next ) next.prev = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev.next = next;
|
||||
if ( next ) next.prev = prev;
|
||||
}
|
||||
}
|
||||
Super.OnDestroy();
|
||||
}
|
||||
|
||||
override void Tick()
|
||||
{
|
||||
// update
|
||||
|
|
@ -439,6 +518,7 @@ Class SWWMCombatTracker : Thinker
|
|||
DynamicValueInterpolator intp;
|
||||
Vector3 pos, prevpos;
|
||||
PlayerInfo myplayer;
|
||||
SWWMCombatTracker prev, next;
|
||||
|
||||
static SWWMCombatTracker Spawn( Actor target )
|
||||
{
|
||||
|
|
@ -461,9 +541,37 @@ Class SWWMCombatTracker : Thinker
|
|||
t.prevpos = level.Vec3Offset(target.prev,(0,0,target.default.height));
|
||||
t.intp = DynamicValueInterpolator.Create(t.lasthealth,.5,1,100);
|
||||
t.myplayer = target.player;
|
||||
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
|
||||
if ( hnd )
|
||||
{
|
||||
t.next = hnd.trackers;
|
||||
if ( hnd.trackers ) hnd.trackers.prev = t;
|
||||
hnd.trackers = t;
|
||||
hnd.trackers_cnt++;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
override void OnDestroy()
|
||||
{
|
||||
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
|
||||
if ( hnd )
|
||||
{
|
||||
hnd.trackers_cnt--;
|
||||
if ( !prev )
|
||||
{
|
||||
hnd.trackers = next;
|
||||
if ( next ) next.prev = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev.next = next;
|
||||
if ( next ) next.prev = prev;
|
||||
}
|
||||
}
|
||||
Super.OnDestroy();
|
||||
}
|
||||
|
||||
override void Tick()
|
||||
{
|
||||
// update
|
||||
|
|
@ -1217,6 +1325,10 @@ Class SWWMHandler : EventHandler
|
|||
transient int highesttic;
|
||||
transient Array<QueuedFlash> flashes;
|
||||
transient Array<LastLine> lastlines;
|
||||
SWWMCombatTracker trackers;
|
||||
SWWMScoreObj scorenums, damnums;
|
||||
SWWMInterest intpoints;
|
||||
int trackers_cnt, scorenums_cnt, damnums_cnt, intpoints_cnt;
|
||||
bool tookdamage[MAXPLAYERS];
|
||||
int spreecount[MAXPLAYERS];
|
||||
int lastkill[MAXPLAYERS];
|
||||
|
|
@ -1224,6 +1336,7 @@ Class SWWMHandler : EventHandler
|
|||
int lastitemcount[MAXPLAYERS];
|
||||
|
||||
transient CVar mutevoice;
|
||||
transient ui CVar useshaders;
|
||||
|
||||
static int AddOneliner( String type, int level, int delay = 5 )
|
||||
{
|
||||
|
|
@ -1420,10 +1533,16 @@ Class SWWMHandler : EventHandler
|
|||
else if ( e.IsSaveGame || e.IsReopen )
|
||||
{
|
||||
// clear all floating numbers
|
||||
let ti = ThinkerIterator.Create("SWWMScoreObj",Thinker.STAT_USER);
|
||||
Thinker t;
|
||||
while ( t = ti.Next() )
|
||||
t.Destroy();
|
||||
for ( SWWMScoreObj sc=scorenums; sc; sc=sc.Next )
|
||||
sc.lifespan = 0;
|
||||
for ( SWWMScoreObj sc=damnums; sc; sc=sc.Next )
|
||||
sc.lifespan = 0;
|
||||
// restore underwater sounds for players
|
||||
for ( int i=0; i<MAXPLAYERS; i++ )
|
||||
{
|
||||
if ( !playeringame[i] || (players[i].mo is 'Demolitionist') ) continue;
|
||||
Demolitionist(players[i].mo).CheckUnderwaterAmb(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1876,74 +1995,7 @@ Class SWWMHandler : EventHandler
|
|||
}
|
||||
else if ( e.Replacee is 'CWeaponPiece2' ) e.Replacement = 'CandyGun';
|
||||
else if ( e.Replacee is 'MWeaponPiece1' ) e.Replacement = 'Ynykron';
|
||||
else if ( e.Replacee is 'ArtiPoisonBag' )
|
||||
{
|
||||
switch( Random[Replacement](0,6) )
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
e.Replacement = redpool[!Random[Replacement](0,2)];
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
e.Replacement = greenpool[!Random[Replacement](0,2)];
|
||||
break;
|
||||
default:
|
||||
e.Replacement = 'SWWMNothing';
|
||||
}
|
||||
}
|
||||
else if ( (e.Replacee == 'Clip') || (e.Replacee == 'GoldWandAmmo') || (e.Replacee == 'GoldWandHefty') )
|
||||
{
|
||||
switch( Random[Replacement](0,6) )
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
e.Replacement = redpool[Random[Replacement](0,2)];
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
e.Replacement = greenpool[Random[Replacement](0,2)];
|
||||
break;
|
||||
case 5:
|
||||
e.Replacement = whitepool[Random[Replacement](0,1)];
|
||||
break;
|
||||
case 6:
|
||||
e.Replacement = purplepool[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( (e.Replacee == 'Shell') || (e.Replacee is 'CrossbowAmmo') )
|
||||
{
|
||||
switch( Random[Replacement](0,10) )
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
e.Replacement = redpool[Random[Replacement](2,3)];
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
e.Replacement = greenpool[Random[Replacement](2,3)];
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
e.Replacement = whitepool[Random[Replacement](1,2)];
|
||||
break;
|
||||
case 7:
|
||||
case 8:
|
||||
e.Replacement = purplepool[Random[Replacement](0,2)];
|
||||
break;
|
||||
case 9:
|
||||
e.Replacement = bluepool[Random[Replacement](0,2)];
|
||||
break;
|
||||
case 10:
|
||||
e.Replacement = blackpool[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( (e.Replacee == 'ShellBox') || (e.Replacee is 'CrossbowHefty') )
|
||||
else if ( (e.Replacee == 'Clip') || (e.Replacee == 'GoldWandAmmo') || (e.Replacee == 'GoldWandHefty') || (e.Replacee is 'ArtiPoisonBag') )
|
||||
{
|
||||
switch( Random[Replacement](0,14) )
|
||||
{
|
||||
|
|
@ -1951,27 +2003,87 @@ Class SWWMHandler : EventHandler
|
|||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
e.Replacement = redpool[Random[Replacement](3,5)];
|
||||
e.Replacement = redpool[Random[Replacement](0,1)];
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
e.Replacement = greenpool[Random[Replacement](3,4)];
|
||||
e.Replacement = greenpool[Random[Replacement](0,1)];
|
||||
break;
|
||||
case 7:
|
||||
e.Replacement = purplepool[0];
|
||||
break;
|
||||
case 8:
|
||||
e.Replacement = purplepool[0];
|
||||
break;
|
||||
default:
|
||||
e.Replacement = 'SWWMNothing';
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( (e.Replacee == 'Shell') || (e.Replacee is 'CrossbowAmmo') )
|
||||
{
|
||||
switch( Random[Replacement](0,14) )
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
e.Replacement = redpool[Random[Replacement](1,2)];
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
e.Replacement = greenpool[Random[Replacement](1,2)];
|
||||
break;
|
||||
case 7:
|
||||
case 8:
|
||||
e.Replacement = whitepool[Random[Replacement](0,1)];
|
||||
break;
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
e.Replacement = purplepool[Random[Replacement](0,1)];
|
||||
break;
|
||||
case 12:
|
||||
case 13:
|
||||
e.Replacement = bluepool[Random[Replacement](0,2)];
|
||||
break;
|
||||
case 14:
|
||||
e.Replacement = blackpool[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( (e.Replacee == 'ShellBox') || (e.Replacee is 'CrossbowHefty') )
|
||||
{
|
||||
switch( Random[Replacement](0,15) )
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
e.Replacement = redpool[Random[Replacement](2,5)];
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
e.Replacement = greenpool[Random[Replacement](2,4)];
|
||||
break;
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
e.Replacement = whitepool[Random[Replacement](2,3)];
|
||||
e.Replacement = whitepool[Random[Replacement](1,3)];
|
||||
break;
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
e.Replacement = purplepool[Random[Replacement](1,2)];
|
||||
break;
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
e.Replacement = bluepool[Random[Replacement](2,3)];
|
||||
break;
|
||||
case 14:
|
||||
case 15:
|
||||
e.Replacement = blackpool[Random[Replacement](0,2)];
|
||||
break;
|
||||
}
|
||||
|
|
@ -2224,6 +2336,36 @@ Class SWWMHandler : EventHandler
|
|||
SWWMStatusBar(statusbar).viewrot = (e.viewangle,e.viewpitch,e.viewroll);
|
||||
}
|
||||
|
||||
// various shaders
|
||||
override void RenderOverlay( RenderEvent e )
|
||||
{
|
||||
PlayerInfo p = players[consoleplayer];
|
||||
if ( !useshaders ) useshaders = CVar.GetCVar('swwm_shaders',p);
|
||||
let mo = p.mo;
|
||||
if ( !mo ) return;
|
||||
bool pc = (p.camera == mo);
|
||||
let rage = RagekitPower(mo.FindInventory("RagekitPower"));
|
||||
if ( pc && rage && useshaders.GetBool() )
|
||||
{
|
||||
Shader.SetEnabled(p,"RagekitShader",true);
|
||||
Shader.SetUniform1f(p,"RagekitShader","timer",(gametic+e.FracTic)/Thinker.TICRATE);
|
||||
double xstrastr = 1.+max(0,rage.lastpulse-(gametic+e.Fractic))/35.;
|
||||
Shader.SetUniform1f(p,"RagekitShader","xtrastr",xstrastr**2.);
|
||||
}
|
||||
else Shader.SetEnabled(p,"RagekitShader",false);
|
||||
let ghost = GhostPower(mo.FindInventory("GhostPower"));
|
||||
if ( pc && ghost && useshaders.GetBool() ) Shader.SetEnabled(p,"GhostShader",true);
|
||||
else Shader.SetEnabled(p,"GhostShader",false);
|
||||
let sunny = InvinciballPower(mo.FindInventory("InvinciballPower"));
|
||||
if ( pc && sunny && useshaders.GetBool() )
|
||||
{
|
||||
Shader.SetEnabled(p,"InvinciShader",true);
|
||||
double str = max(0,sunny.lastpulse-(gametic+e.Fractic))/35.;
|
||||
Shader.SetUniform1f(p,"InvinciShader","str",str);
|
||||
}
|
||||
else Shader.SetEnabled(p,"InvinciShader",false);
|
||||
}
|
||||
|
||||
static void DoFlash( Actor camera, Color c, int duration )
|
||||
{
|
||||
// don't flash when paused
|
||||
|
|
|
|||
|
|
@ -16,9 +16,13 @@ Class SWWMStatusBar : BaseStatusBar
|
|||
// this can be accessed from a section of the knowledge base
|
||||
Array<MsgLine> MainQueue, PickupQueue, FullHistory;
|
||||
|
||||
Array<SWWMCombatTracker> targets; // healthbars
|
||||
Array<SWWMScoreObj> scoreobjects; // floating scores
|
||||
Array<SWWMInterest> interesting; // points of interest for omnisight
|
||||
// sorted arrays of various elements
|
||||
Array<SWWMInterest> intpoints;
|
||||
Array<SWWMScoreObj> scoreobjs;
|
||||
Array<SWWMCombatTracker> trackers;
|
||||
|
||||
// the event handler, holding all sorts of stuff
|
||||
SWWMHandler hnd;
|
||||
|
||||
// client cvars
|
||||
transient CVar safezone, maxchat[2], maxpick, chatduration, msgduration, pickduration, chatcol, teamcol, obitcol, critcol, pickcol, targetter, healthnums, scorenums, scorebonus, targettag;
|
||||
|
|
@ -141,11 +145,13 @@ Class SWWMStatusBar : BaseStatusBar
|
|||
|
||||
private bool CmpTarget( SWWMCombatTracker a, SWWMCombatTracker b )
|
||||
{
|
||||
if ( !a || !b ) return true;
|
||||
return (a.myplayer && !b.myplayer);
|
||||
}
|
||||
|
||||
private bool CmpScore( SWWMScoreObj a, SWWMScoreObj b )
|
||||
{
|
||||
if ( !a || !b ) return true;
|
||||
int srt[4] = { Font.CR_GOLD, Font.CR_FIRE, Font.CR_GREEN, Font.CR_RED };
|
||||
int s1 = 0, s2 = 0;
|
||||
for ( int i=0; i<3; i++ )
|
||||
|
|
@ -158,6 +164,7 @@ Class SWWMStatusBar : BaseStatusBar
|
|||
|
||||
private bool CmpInterest( SWWMInterest a, SWWMInterest b )
|
||||
{
|
||||
if ( !a || !b ) return true;
|
||||
return a.type < b.type;
|
||||
}
|
||||
|
||||
|
|
@ -193,99 +200,9 @@ Class SWWMStatusBar : BaseStatusBar
|
|||
MainQueue.Delete(i);
|
||||
i--;
|
||||
}
|
||||
// update omnisight stuff
|
||||
if ( CPlayer.mo.FindInventory("Omnisight") )
|
||||
{
|
||||
interesting.Clear();
|
||||
let ii = ThinkerIterator.Create("SWWMInterest",Thinker.STAT_USER);
|
||||
SWWMInterest poi; // :3
|
||||
while ( poi = SWWMInterest(ii.Next()) ) interesting.Push(poi);
|
||||
// sort by distance
|
||||
for ( int i=0; i<interesting.Size(); i++ )
|
||||
{
|
||||
int j = 1;
|
||||
while ( j < interesting.Size() )
|
||||
{
|
||||
int k = j;
|
||||
while ( (k > 0) && (CmpInterest(interesting[k-1],interesting[k]) || CmpDist(interesting[k-1].pos,interesting[k].pos)) )
|
||||
{
|
||||
SWWMInterest tmp = interesting[k];
|
||||
interesting[k] = interesting[k-1];
|
||||
interesting[k-1] = tmp;
|
||||
k--;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// update target stuff
|
||||
targets.Clear();
|
||||
if ( targetter.GetBool() )
|
||||
{
|
||||
let ti = ThinkerIterator.Create("SWWMCombatTracker",Thinker.STAT_USER);
|
||||
SWWMCombatTracker ct;
|
||||
int extratime = 35;
|
||||
if ( CPlayer.mo.FindInventory("Omnisight") ) extratime += 105;
|
||||
while ( ct = SWWMCombatTracker(ti.Next()) )
|
||||
{
|
||||
// ignore player unless chasecamming
|
||||
if ( (ct.mytarget == players[consoleplayer].mo) && (players[consoleplayer].Camera == players[consoleplayer].mo) && !(players[consoleplayer].cheats&CF_CHASECAM) ) continue;
|
||||
if ( ct.myplayer && deathmatch ) continue; // no players in dm
|
||||
if ( level.maptime > ct.updated+extratime ) continue;
|
||||
targets.Push(ct);
|
||||
}
|
||||
// sort by distance (give priority to players)
|
||||
for ( int i=0; i<targets.Size(); i++ )
|
||||
{
|
||||
int j = 1;
|
||||
while ( j < targets.Size() )
|
||||
{
|
||||
int k = j;
|
||||
while ( (k > 0) && (CmpTarget(targets[k-1],targets[k]) || CmpDist(targets[k-1].pos,targets[k].pos)) )
|
||||
{
|
||||
SWWMCombatTracker tmp = targets[k];
|
||||
targets[k] = targets[k-1];
|
||||
targets[k-1] = tmp;
|
||||
k--;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
// trim size, to unclutter
|
||||
if ( targets.Size() > 40 ) targets.Resize(40);
|
||||
}
|
||||
// update floating scores
|
||||
scoreobjects.Clear();
|
||||
let si = ThinkerIterator.Create("SWWMScoreObj",Thinker.STAT_USER);
|
||||
SWWMScoreObj so;
|
||||
while ( so = SWWMScoreObj(si.Next()) )
|
||||
{
|
||||
if ( ((so.tcolor == Font.CR_RED) || (so.tcolor == Font.CR_GREEN)) && (!healthnums.GetBool() || (level.Vec3Diff(viewpos,so.pos).length() > 2000)) ) continue;
|
||||
else if ( !scorenums.GetBool() || ((so.tcolor != Font.CR_GOLD) && !scorebonus.GetBool()) ) continue;
|
||||
scoreobjects.Push(so);
|
||||
// prevent slowdowns if hurting too many enemies at once
|
||||
if ( scoreobjects.Size() >= 100 ) break;
|
||||
}
|
||||
// sort by distance
|
||||
for ( int i=0; i<scoreobjects.Size(); i++ )
|
||||
{
|
||||
int j = 1;
|
||||
while ( j < scoreobjects.Size() )
|
||||
{
|
||||
int k = j;
|
||||
while ( (k > 0) && (CmpScore(scoreobjects[k-1],scoreobjects[k]) || CmpDist(scoreobjects[k-1].pos,scoreobjects[k].pos)) )
|
||||
{
|
||||
SWWMScoreObj tmp = scoreobjects[k];
|
||||
scoreobjects[k] = scoreobjects[k-1];
|
||||
scoreobjects[k-1] = tmp;
|
||||
k--;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
// update interpolators
|
||||
HealthInter.Update(CPlayer.health);
|
||||
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
|
||||
if ( !hnd ) hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
|
||||
ScoreInter.Update(SWWMCredits.Get(CPlayer));
|
||||
let d = Demolitionist(CPlayer.mo);
|
||||
if ( d )
|
||||
|
|
@ -301,6 +218,98 @@ Class SWWMStatusBar : BaseStatusBar
|
|||
// let weapons update their own interpolators
|
||||
if ( CPlayer.ReadyWeapon is 'SWWMWeapon' )
|
||||
SWWMWeapon(CPlayer.ReadyWeapon).HudTick();
|
||||
bool thesight = CPlayer.mo.FindInventory("Omnisight");
|
||||
if ( thesight )
|
||||
{
|
||||
// update omnisight stuff
|
||||
if ( intpoints.Size() != hnd.intpoints_cnt )
|
||||
intpoints.Resize(hnd.intpoints_cnt);
|
||||
int i = 0;
|
||||
for ( SWWMInterest poi=hnd.intpoints; poi; poi=poi.next )
|
||||
intpoints[i++] = poi;
|
||||
// sort by distance
|
||||
for ( int i=0; i<hnd.intpoints_cnt; i++ )
|
||||
{
|
||||
int j = 1;
|
||||
while ( j < hnd.intpoints_cnt )
|
||||
{
|
||||
int k = j;
|
||||
while ( (k > 0) && (CmpInterest(intpoints[k-1],intpoints[k]) || CmpDist(intpoints[k-1].pos,intpoints[k].pos)) )
|
||||
{
|
||||
SWWMInterest tmp = intpoints[k];
|
||||
intpoints[k] = intpoints[k-1];
|
||||
intpoints[k-1] = tmp;
|
||||
k--;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( targetter.GetBool() )
|
||||
{
|
||||
// update target stuff
|
||||
if ( trackers.Size() != hnd.trackers_cnt )
|
||||
trackers.Resize(hnd.trackers_cnt);
|
||||
int i = 0, actual = 0;
|
||||
for ( SWWMCombatTracker trk=hnd.trackers; trk; trk=trk.next )
|
||||
{
|
||||
actual++;
|
||||
// ignore player unless chasecamming
|
||||
if ( (trk.mytarget == players[consoleplayer].mo) && (players[consoleplayer].Camera == players[consoleplayer].mo) && !(players[consoleplayer].cheats&CF_CHASECAM) ) continue;
|
||||
if ( trk.myplayer && deathmatch ) continue; // no players in dm
|
||||
int mtime = 35;
|
||||
if ( thesight && (trk.lasthealth > 0) ) mtime += 105;
|
||||
if ( level.maptime > trk.updated+mtime ) continue;
|
||||
trackers[i++] = trk;
|
||||
}
|
||||
// squeeze if some were discarded
|
||||
if ( i != hnd.trackers_cnt )
|
||||
trackers.Resize(i);
|
||||
// sort by distance (give priority to players)
|
||||
for ( int i=0; i<trackers.Size(); i++ )
|
||||
{
|
||||
int j = 1;
|
||||
while ( j < trackers.Size() )
|
||||
{
|
||||
int k = j;
|
||||
while ( (k > 0) && (CmpTarget(trackers[k-1],trackers[k]) || CmpDist(trackers[k-1].pos,trackers[k].pos)) )
|
||||
{
|
||||
SWWMCombatTracker tmp = trackers[k];
|
||||
trackers[k] = trackers[k-1];
|
||||
trackers[k-1] = tmp;
|
||||
k--;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// update floating scores, adding the scorenums first, then the damnums
|
||||
int total_sz = hnd.scorenums_cnt;
|
||||
total_sz += min(100,hnd.damnums_cnt);
|
||||
if ( scoreobjs.Size() != total_sz )
|
||||
scoreobjs.Resize(total_sz);
|
||||
int i = 0;
|
||||
for ( SWWMScoreObj scr=hnd.scorenums; scr; scr=scr.next )
|
||||
scoreobjs[i++] = scr;
|
||||
for ( SWWMScoreObj scr=hnd.damnums; scr && (i<total_sz); scr=scr.next )
|
||||
scoreobjs[i++] = scr;
|
||||
// sort by distance
|
||||
for ( int i=0; i<total_sz; i++ )
|
||||
{
|
||||
int j = 1;
|
||||
while ( j < total_sz )
|
||||
{
|
||||
int k = j;
|
||||
while ( (k > 0) && (CmpScore(scoreobjs[k-1],scoreobjs[k]) || CmpDist(scoreobjs[k-1].pos,scoreobjs[k].pos)) )
|
||||
{
|
||||
SWWMScoreObj tmp = scoreobjs[k];
|
||||
scoreobjs[k] = scoreobjs[k-1];
|
||||
scoreobjs[k-1] = tmp;
|
||||
k--;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override void Init()
|
||||
|
|
@ -339,6 +348,7 @@ Class SWWMStatusBar : BaseStatusBar
|
|||
gl_proj = new("swwmLe__GLScreen");
|
||||
sw_proj = new("swwmLe__SWScreen");
|
||||
PrepareProjection();
|
||||
hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
|
||||
}
|
||||
|
||||
static private string FormatDist( double dist )
|
||||
|
|
@ -350,6 +360,8 @@ Class SWWMStatusBar : BaseStatusBar
|
|||
|
||||
private void DrawTarget()
|
||||
{
|
||||
// don't draw when dead or with automap open
|
||||
if ( (CPlayer.health <= 0) || automapactive ) return;
|
||||
if ( !targettag ) targettag = CVar.GetCVar('swwm_targettags',players[consoleplayer]);
|
||||
viewport.FromHud();
|
||||
proj.CacheResolution();
|
||||
|
|
@ -362,17 +374,19 @@ Class SWWMStatusBar : BaseStatusBar
|
|||
String tag;
|
||||
if ( thesight )
|
||||
{
|
||||
for ( int i=0; i<interesting.Size(); i++ )
|
||||
for ( int i=0; i<intpoints.Size(); i++ )
|
||||
{
|
||||
Vector3 tdir = Level.Vec3Diff(ViewPos,interesting[i].pos);
|
||||
let poi = intpoints[i];
|
||||
if ( !poi ) continue;
|
||||
Vector3 tdir = Level.Vec3Diff(ViewPos,poi.pos);
|
||||
proj.ProjectWorldPos(ViewPos+tdir);
|
||||
Vector2 npos = proj.ProjectToNormal();
|
||||
if ( !proj.IsInFront() ) continue;
|
||||
Vector2 vpos = viewport.SceneToWindow(npos);
|
||||
if ( interesting[i].type == INT_Key ) tag = String.Format("\cf%s\c-",StringTable.Localize(interesting[i].trackedkey.GetTag()));
|
||||
else if ( interesting[i].type == INT_Exit )
|
||||
if ( poi.type == INT_Key ) tag = String.Format("\cf%s\c-",StringTable.Localize(poi.trackedkey.GetTag()));
|
||||
else if ( poi.type == INT_Exit )
|
||||
{
|
||||
if ( interesting[i].trackedline.special == Exit_Secret )
|
||||
if ( poi.trackedline.special == Exit_Secret )
|
||||
tag = String.Format("\cx%s\c-",StringTable.Localize("$SWWM_SEXIT"));
|
||||
else tag = String.Format("\cy%s\c-",StringTable.Localize("$SWWM_NEXIT"));
|
||||
}
|
||||
|
|
@ -382,89 +396,96 @@ Class SWWMStatusBar : BaseStatusBar
|
|||
}
|
||||
}
|
||||
// targetting array
|
||||
for ( int i=0; i<targets.Size(); i++ )
|
||||
int displayed = 0;
|
||||
for ( int i=0; i<trackers.Size(); i++ )
|
||||
{
|
||||
Vector3 tdir = Level.Vec3Diff(ViewPos,targets[i].prevpos*(1.-fractic)+targets[i].pos*fractic);
|
||||
let targ = trackers[i];
|
||||
if ( !targ ) continue;
|
||||
// cap to 40, so the screen isn't too cluttered
|
||||
if ( displayed++ > 40 ) break;
|
||||
Vector3 tdir = Level.Vec3Diff(ViewPos,targ.prevpos*(1.-fractic)+targ.pos*fractic);
|
||||
proj.ProjectWorldPos(ViewPos+tdir);
|
||||
Vector2 npos = proj.ProjectToNormal();
|
||||
if ( !proj.IsInFront() ) continue;
|
||||
Vector2 vpos = viewport.SceneToWindow(npos);
|
||||
tag = targets[i].mytag;
|
||||
tag = targ.mytag;
|
||||
int mtime = 35;
|
||||
if ( thesight && (targets[i].lasthealth > 0) ) mtime += 105;
|
||||
double alph = clamp(((targets[i].updated+mtime)-level.maptime)/35.,0.,1.);
|
||||
if ( thesight && (targ.lasthealth > 0) ) mtime += 105;
|
||||
double alph = clamp(((targ.updated+mtime)-level.maptime)/35.,0.,1.);
|
||||
Vector2 barsiz = TexMan.GetScaledSize(EnemyBTex);
|
||||
barsiz.x *= hs.x;
|
||||
barsiz.y *= hs.y;
|
||||
Vector2 barpos = vpos-(barsiz/2.);
|
||||
barpos.y -= 16.;
|
||||
if ( targettag.GetBool() || targets[i].myplayer && (tag != "") )
|
||||
if ( targettag.GetBool() || targ.myplayer && (tag != "") )
|
||||
Screen.DrawText(mMiniwiFont.mFont,Font.CR_WHITE,(barpos.x+barsiz.x/2.-(mMiniwiFont.mFont.StringWidth(tag)*hs.x)/2.)/hs.x,(barpos.y-mMiniwiFont.mFont.GetHeight()*hs.y)/hs.y,tag,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alph);
|
||||
Screen.DrawTexture(EnemyBTex,false,barpos.x/hs.x,barpos.y/hs.y,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alph);
|
||||
int ht = clamp(targets[i].intp.GetValue(),0,targets[i].maxhealth*10);
|
||||
int hw = int((min(ht,targets[i].maxhealth)*50.)/targets[i].maxhealth);
|
||||
if ( targets[i].mytarget && (targets[i].mytarget.bInvulnerable || (targets[i].myplayer && (targets[i].myplayer.cheats&(CF_GODMODE|CF_GODMODE2))) || targets[i].mytarget.FindInventory("InvinciballPower")) )
|
||||
int ht = clamp(targ.intp.GetValue(),0,targ.maxhealth*10);
|
||||
int hw = int((min(ht,targ.maxhealth)*50.)/targ.maxhealth);
|
||||
if ( targ.mytarget && (targ.mytarget.bInvulnerable || (targ.myplayer && (targ.myplayer.cheats&(CF_GODMODE|CF_GODMODE2))) || targ.mytarget.FindInventory("InvinciballPower")) )
|
||||
{
|
||||
Screen.DrawTexture(EnemyHTex[4],false,(barpos.x+2*hs.x)/hs.x,(barpos.y+2*hs.y)/hs.y,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alph,DTA_WindowRight,hw);
|
||||
continue;
|
||||
}
|
||||
Screen.DrawTexture(EnemyHTex[0],false,(barpos.x+2*hs.x)/hs.x,(barpos.y+2*hs.y)/hs.y,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alph,DTA_WindowRight,hw);
|
||||
if ( ht > targets[i].maxhealth )
|
||||
if ( ht > targ.maxhealth )
|
||||
{
|
||||
hw = int((min(ht-targets[i].maxhealth,targets[i].maxhealth)*50.)/targets[i].maxhealth);
|
||||
hw = int((min(ht-targ.maxhealth,targ.maxhealth)*50.)/targ.maxhealth);
|
||||
Screen.DrawTexture(EnemyHTex[1],false,(barpos.x+2*hs.x)/hs.x,(barpos.y+2*hs.y)/hs.y,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alph,DTA_WindowRight,hw);
|
||||
}
|
||||
if ( ht > targets[i].maxhealth*2 )
|
||||
if ( ht > targ.maxhealth*2 )
|
||||
{
|
||||
hw = int((min(ht-targets[i].maxhealth*2,targets[i].maxhealth*3)*50.)/(targets[i].maxhealth*3));
|
||||
hw = int((min(ht-targ.maxhealth*2,targ.maxhealth*3)*50.)/(targ.maxhealth*3));
|
||||
Screen.DrawTexture(EnemyHTex[2],false,(barpos.x+2*hs.x)/hs.x,(barpos.y+2*hs.y)/hs.y,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alph,DTA_WindowRight,hw);
|
||||
}
|
||||
if ( ht > targets[i].maxhealth*5 )
|
||||
if ( ht > targ.maxhealth*5 )
|
||||
{
|
||||
hw = int((min(ht-targets[i].maxhealth*5,targets[i].maxhealth*5)*50.)/(targets[i].maxhealth*5));
|
||||
hw = int((min(ht-targ.maxhealth*5,targ.maxhealth*5)*50.)/(targ.maxhealth*5));
|
||||
Screen.DrawTexture(EnemyHTex[3],false,(barpos.x+2*hs.x)/hs.x,(barpos.y+2*hs.y)/hs.y,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alph,DTA_WindowRight,hw);
|
||||
}
|
||||
}
|
||||
// floating kill scores and others
|
||||
for ( int i=0; i<scoreobjects.Size(); i++ )
|
||||
for ( int i=0; i<scoreobjs.Size(); i++ )
|
||||
{
|
||||
Vector3 tdir = Level.Vec3Diff(ViewPos,scoreobjects[i].pos);
|
||||
let snum = scoreobjs[i];
|
||||
if ( !snum ) continue;
|
||||
Vector3 tdir = Level.Vec3Diff(ViewPos,snum.pos);
|
||||
proj.ProjectWorldPos(ViewPos+tdir);
|
||||
Vector2 npos = proj.ProjectToNormal();
|
||||
if ( !proj.IsInFront() ) continue;
|
||||
Vector2 vpos = viewport.SceneToWindow(npos);
|
||||
if ( scoreobjects[i].str != "" )
|
||||
if ( snum.str != "" )
|
||||
{
|
||||
tag = StringTable.Localize(scoreobjects[i].str);
|
||||
if ( scoreobjects[i].score == int.max ) tag.AppendFormat(" %s",StringTable.Localize("$SWWM_MAX"));
|
||||
else if ( scoreobjects[i].score > 0 ) tag.AppendFormat(" x%d",scoreobjects[i].score);
|
||||
tag = StringTable.Localize(snum.str);
|
||||
if ( snum.score == int.max ) tag.AppendFormat(" %s",StringTable.Localize("$SWWM_MAX"));
|
||||
else if ( snum.score > 0 ) tag.AppendFormat(" x%d",snum.score);
|
||||
}
|
||||
else tag = String.Format("%+d",scoreobjects[i].score);
|
||||
double alph = clamp((scoreobjects[i].lifespan+fractic)/35.,0.,1.);
|
||||
else tag = String.Format("%+d",snum.score);
|
||||
double alph = clamp((snum.lifespan+fractic)/35.,0.,1.);
|
||||
Vector2 fo = (0,0);
|
||||
if ( scoreobjects[i].tcolor == Font.CR_RED )
|
||||
if ( snum.tcolor == Font.CR_RED )
|
||||
{
|
||||
// damage falls down
|
||||
int initspd = (128-scoreobjects[i].seed);
|
||||
int initspd = (128-snum.seed);
|
||||
if ( initspd >= 0 && initspd < 32 ) initspd = 32;
|
||||
if ( initspd < 0 && initspd > -32 ) initspd = -32;
|
||||
int boostup = 64+scoreobjects[i].seed2/2;
|
||||
fo.x = (.05*initspd)*((scoreobjects[i].initialspan-(scoreobjects[i].lifespan-fractic))**.8);
|
||||
fo.y = -((scoreobjects[i].initialspan-(scoreobjects[i].lifespan-fractic))**1.5)+boostup*sin((90./scoreobjects[i].initialspan)*(level.maptime+fractic-scoreobjects[i].starttic));
|
||||
int boostup = 64+snum.seed2/2;
|
||||
fo.x = (.05*initspd)*((snum.initialspan-(snum.lifespan-fractic))**.8);
|
||||
fo.y = -((snum.initialspan-(snum.lifespan-fractic))**1.5)+boostup*sin((90./snum.initialspan)*(level.maptime+fractic-snum.starttic));
|
||||
}
|
||||
else if ( scoreobjects[i].tcolor == Font.CR_GREEN )
|
||||
else if ( snum.tcolor == Font.CR_GREEN )
|
||||
{
|
||||
// health falls up (?)
|
||||
int initspd = (128-scoreobjects[i].seed);
|
||||
int initspd = (128-snum.seed);
|
||||
if ( initspd >= 0 && initspd < 32 ) initspd = 32;
|
||||
if ( initspd < 0 && initspd > -32 ) initspd = -32;
|
||||
int boostup = 16+scoreobjects[i].seed2/4;
|
||||
fo.x = (.15*initspd)*((scoreobjects[i].initialspan-(scoreobjects[i].lifespan-fractic))**.6);
|
||||
fo.y = ((scoreobjects[i].initialspan-(scoreobjects[i].lifespan-fractic))**1.2)-boostup*sin((90./scoreobjects[i].initialspan)*(level.maptime+fractic-scoreobjects[i].starttic));
|
||||
int boostup = 16+snum.seed2/4;
|
||||
fo.x = (.15*initspd)*((snum.initialspan-(snum.lifespan-fractic))**.6);
|
||||
fo.y = ((snum.initialspan-(snum.lifespan-fractic))**1.2)-boostup*sin((90./snum.initialspan)*(level.maptime+fractic-snum.starttic));
|
||||
}
|
||||
else fo.y = scoreobjects[i].initialspan-(scoreobjects[i].lifespan-fractic); // score rises linearly
|
||||
fo.y += scoreobjects[i].ofs*mMiniwiFont.mFont.GetHeight();
|
||||
Screen.DrawText(mMiniwiFont.mFont,scoreobjects[i].tcolor,(vpos.x-hs.x*(fo.x+mMiniwiFont.mFont.StringWidth(tag)/2.))/hs.x,(vpos.y-hs.y*(fo.y+(mMiniwiFont.mFont.GetHeight()/2.)))/hs.y,tag,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alph);
|
||||
else fo.y = snum.initialspan-(snum.lifespan-fractic); // score rises linearly
|
||||
fo.y += snum.ofs*mMiniwiFont.mFont.GetHeight();
|
||||
Screen.DrawText(mMiniwiFont.mFont,snum.tcolor,(vpos.x-hs.x*(fo.x+mMiniwiFont.mFont.StringWidth(tag)/2.))/hs.x,(vpos.y-hs.y*(fo.y+(mMiniwiFont.mFont.GetHeight()/2.)))/hs.y,tag,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alph);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -306,7 +306,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
|
|||
}
|
||||
return true;
|
||||
case MKEY_ENTER:
|
||||
if ( (curtab == TAB_INVENTORY) && (invlist.Size() > 0) )
|
||||
if ( (curtab == TAB_INVENTORY) && (invlist.Size() > 0) && (sel0 < invlist.Size()) )
|
||||
{
|
||||
// can't use this
|
||||
if ( invlist[sel0] is 'Ammo' ) return true;
|
||||
|
|
@ -317,7 +317,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
|
|||
checkuse = gametic+1;
|
||||
EventHandler.SendNetworkEvent(String.Format("swwmuseitem.%s",invlist[sel0].GetClassName()),consoleplayer);
|
||||
}
|
||||
else if ( (curtab == TAB_STORE) && (storelist.Size() > 0) )
|
||||
else if ( (curtab == TAB_STORE) && (storelist.Size() > 0) && (sel0 < storelist.Size()) )
|
||||
{
|
||||
int moni = SWWMCredits.Get(players[consoleplayer]);
|
||||
let itm = GetDefaultByType(storelist[sel0]);
|
||||
|
|
@ -359,7 +359,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
|
|||
MenuSound("menu/democlose");
|
||||
sub = false;
|
||||
}
|
||||
else if ( lorelist.Size() > 0 )
|
||||
else if ( (lorelist.Size() > 0) && (sel0 < lorelist.Size()) )
|
||||
{
|
||||
// mark as read
|
||||
if ( !lorelist[sel0].read )
|
||||
|
|
@ -440,7 +440,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
|
|||
// alphabetically sorted inventory
|
||||
for ( Inventory inv=players[consoleplayer].mo.Inv; inv; inv=inv.Inv )
|
||||
{
|
||||
if ( (inv.Amount <= 0) || !inv.SpawnState.ValidateSpriteFrame() || (inv is 'Key') || (inv is 'BasicArmor') || (inv is 'HexenArmor') || (inv is 'Powerup') || (inv is 'SWWMArmor') ) continue;
|
||||
if ( (inv.Amount <= 0) || !inv.SpawnState.ValidateSpriteFrame() || (inv is 'Key') || (inv is 'BasicArmor') || (inv is 'HexenArmor') || (inv is 'Powerup') || (inv is 'SWWMArmor') || (!(inv is 'Ammo') && !(inv is 'Weapon') && !inv.bINVBAR) ) continue;
|
||||
String tag = inv.GetTag();
|
||||
bool greater = false;
|
||||
for ( int i=0; i<invlist.Size(); i++ )
|
||||
|
|
|
|||
|
|
@ -19,12 +19,21 @@ Class Demolitionist : PlayerPawn
|
|||
|
||||
SWWMStats mystats;
|
||||
int cairtime;
|
||||
Vector3 oldpos;
|
||||
|
||||
int lastmpain;
|
||||
|
||||
double guideangle, guidepitch, guideroll;
|
||||
|
||||
enum EUnderType
|
||||
{
|
||||
UNDER_NONE,
|
||||
UNDER_WATER,
|
||||
UNDER_SLIME,
|
||||
UNDER_LAVA
|
||||
};
|
||||
|
||||
int lastunder;
|
||||
|
||||
Default
|
||||
{
|
||||
Speed 1;
|
||||
|
|
@ -246,7 +255,6 @@ Class Demolitionist : PlayerPawn
|
|||
{
|
||||
Super.PostBeginPlay();
|
||||
mystats = SWWMStats.Find(player);
|
||||
oldpos = pos;
|
||||
lastground = true;
|
||||
}
|
||||
void A_Dash()
|
||||
|
|
@ -290,12 +298,87 @@ Class Demolitionist : PlayerPawn
|
|||
}
|
||||
fuelcooldown = max(20,fuelcooldown);
|
||||
}
|
||||
void CheckUnderwaterAmb( bool restore = false )
|
||||
{
|
||||
Vector3 headpos = Vec3Offset(0,0,player.viewheight);
|
||||
Vector3 centerpos = Vec3Offset(0,0,height/2);
|
||||
Sector headregion = null;
|
||||
if ( CurSector.moreflags&Sector.SECMF_UNDERWATER ) // check underwater sector
|
||||
headregion = CurSector;
|
||||
else if ( CurSector.heightsec ) // check height transfer
|
||||
{
|
||||
let hsec = CurSector.heightsec;
|
||||
double fh = hsec.floorplane.ZAtPoint(pos.xy);
|
||||
if ( pos.z < fh )
|
||||
{
|
||||
if ( headpos.z <= fh )
|
||||
headregion = hsec;
|
||||
}
|
||||
else if ( !(hsec.moreflags&Sector.SECMF_FAKEFLOORONLY) && (headpos.z > hsec.ceilingplane.ZAtPoint(pos.xy)) )
|
||||
headregion = hsec;
|
||||
}
|
||||
else // check 3D floors
|
||||
{
|
||||
for ( int i=0; i<CurSector.Get3DFloorCount(); i++ )
|
||||
{
|
||||
let ff = CurSector.Get3DFloor(i);
|
||||
if ( !(ff.flags&F3DFloor.FF_EXISTS) || (ff.flags&F3DFloor.FF_SOLID) || (!(ff.flags&F3DFloor.FF_SWIMMABLE) && (ff.alpha == 0)) ) continue;
|
||||
double ff_bottom = ff.bottom.ZAtPoint(pos.xy);
|
||||
double ff_top = ff.top.ZAtPoint(pos.xy);
|
||||
if ( (ff_top <= pos.z) || (ff_bottom > centerpos.z) ) continue;
|
||||
if ( headpos.z <= ff_top )
|
||||
{
|
||||
headregion = ff.model;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
int curunder = UNDER_NONE;
|
||||
if ( headregion )
|
||||
{
|
||||
switch ( headregion.damagetype )
|
||||
{
|
||||
case 'Fire':
|
||||
case 'Lava':
|
||||
curunder = UNDER_LAVA;
|
||||
break;
|
||||
case 'Slime':
|
||||
case 'Poison':
|
||||
case 'PoisonCloud':
|
||||
curunder = UNDER_SLIME;
|
||||
break;
|
||||
case 'Ice':
|
||||
case 'Drowning':
|
||||
default:
|
||||
curunder = UNDER_WATER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( (curunder != lastunder) || restore )
|
||||
{
|
||||
static const string undersnd[] = {"","misc/underwater","misc/underslime","misc/underlava"};
|
||||
static const string entersnd[] = {"","misc/waterenter","misc/slimeenter","misc/lavaenter"};
|
||||
static const string exitsnd[] = {"","misc/waterexit","misc/slimeexit","misc/lavaexit"};
|
||||
A_StopSound(CHAN_AMBEXTRA);
|
||||
if ( curunder > UNDER_NONE )
|
||||
{
|
||||
A_StartSound(undersnd[curunder],CHAN_AMBEXTRA,CHANF_LOOPING|CHANF_UI);
|
||||
if ( !restore && (players[consoleplayer].Camera == self) )
|
||||
A_StartSound(entersnd[curunder],CHAN_FOOTSTEP,CHANF_OVERLAP|CHANF_UI);
|
||||
}
|
||||
if ( !restore && (lastunder > UNDER_NONE) && (players[consoleplayer].Camera == self) )
|
||||
A_StartSound(exitsnd[lastunder],CHAN_FOOTSTEP,CHANF_OVERLAP|CHANF_UI);
|
||||
}
|
||||
if ( curunder > UNDER_NONE )
|
||||
A_SoundVolume(CHAN_AMBEXTRA,(players[consoleplayer].Camera==self)?1.:0.);
|
||||
lastunder = curunder;
|
||||
}
|
||||
override void Tick()
|
||||
{
|
||||
Super.Tick();
|
||||
if ( !player ) return;
|
||||
double traveldist = level.Vec3Diff(oldpos,pos).length();
|
||||
if ( waterlevel < 3 )
|
||||
double traveldist = level.Vec3Diff(prev,pos).length();
|
||||
if ( waterlevel < 2 )
|
||||
{
|
||||
if ( !player.onground || bNoGravity )
|
||||
{
|
||||
|
|
@ -309,8 +392,8 @@ Class Demolitionist : PlayerPawn
|
|||
mystats.grounddist += traveldist;
|
||||
}
|
||||
}
|
||||
if ( traveldist > mystats.topspeed ) mystats.topspeed = traveldist;
|
||||
oldpos = pos;
|
||||
CheckUnderwaterAmb();
|
||||
if ( vel.length() > mystats.topspeed ) mystats.topspeed = vel.length();
|
||||
if ( !myvoice ) myvoice = CVar.GetCVar('swwm_voicetype',player);
|
||||
if ( !mute ) mute = CVar.GetCVar('swwm_mutevoice',player);
|
||||
if ( player.onground && !bNoGravity && !lastground && (waterlevel < 2) && (health > 0) )
|
||||
|
|
@ -334,7 +417,8 @@ Class Demolitionist : PlayerPawn
|
|||
if ( lastvelz < -10 ) A_StartSound("demolitionist/runstop",CHAN_FOOTSTEP,CHANF_OVERLAP);
|
||||
if ( (player == players[consoleplayer]) && (lastvelz < -gruntspeed) && (mute.GetInt() < 4) )
|
||||
A_StartSound(String.Format("voice/%s/grunt",myvoice.GetString()),CHAN_DEMOVOICE,CHANF_OVERLAP);
|
||||
A_Footstep(0,true,clamp(-lastvelz*0.05,0.01,1.0));
|
||||
if ( lastvelz < -1 )
|
||||
A_Footstep(0,true,clamp(-lastvelz*0.05,0.0,1.0));
|
||||
}
|
||||
lastground = player.onground;
|
||||
lastvelz = prevvelz;
|
||||
|
|
@ -381,7 +465,7 @@ Class Demolitionist : PlayerPawn
|
|||
double moveang = atan2(dir.y,dir.x);
|
||||
Vector3 sc = level.SphericalCoords(pos,a.pos,(moveang,0));
|
||||
if ( abs(sc.x) > 60 ) continue;
|
||||
// bosses and large monsters will stop the player
|
||||
// large monsters will stop the player
|
||||
A_QuakeEx(1,1,1,3,0,128,"",QF_RELATIVE|QF_SCALEDOWN);
|
||||
a.A_StartSound("demolitionist/bump",CHAN_FOOTSTEP,CHANF_OVERLAP);
|
||||
if ( a.bDONTTHRUST || (a.Mass >= Mass*5) )
|
||||
|
|
@ -715,6 +799,11 @@ Class Demolitionist : PlayerPawn
|
|||
last_jump_held = level.maptime+1;
|
||||
}
|
||||
}
|
||||
override void DeathThink()
|
||||
{
|
||||
// TODO reboot mechanic, death camera that doesn't move body
|
||||
Super.DeathThink();
|
||||
}
|
||||
override void PlayIdle()
|
||||
{
|
||||
if ( !player )
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ Class GhostPower : PowerInvisibility
|
|||
{
|
||||
Super.InitEffect();
|
||||
if ( !Owner ) return;
|
||||
SWWMHandler.DoFlash(Owner,Color(96,224,192,255),20);
|
||||
DoEffect();
|
||||
}
|
||||
override void EndEffect()
|
||||
|
|
@ -144,6 +145,7 @@ Class GhostPower : PowerInvisibility
|
|||
if ( !Owner ) return;
|
||||
Owner.bNOTARGET = false;
|
||||
Owner.A_StartSound("powerup/ghostend",CHAN_ITEMEXTRA);
|
||||
SWWMHandler.DoFlash(Owner,Color(96,224,192,255),20);
|
||||
if ( (EffectTics <= 0) && Owner && Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_GHOSTARTI"));
|
||||
}
|
||||
|
||||
|
|
@ -334,6 +336,14 @@ Class GravityPower : Powerup
|
|||
|
||||
}
|
||||
|
||||
Class GravityX : GhostArtifactX
|
||||
{
|
||||
Default
|
||||
{
|
||||
RenderStyle "Normal";
|
||||
}
|
||||
}
|
||||
|
||||
Class GravitySuppressor : Inventory
|
||||
{
|
||||
Mixin SWWMAutoUseFix;
|
||||
|
|
@ -347,6 +357,15 @@ Class GravitySuppressor : Inventory
|
|||
else Owner.GiveInventory("GravityPower",1);
|
||||
return true;
|
||||
}
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
tracer = Spawn("GravityX",pos);
|
||||
tracer.angle = angle;
|
||||
tracer.target = self;
|
||||
tracer.FloatBobPhase = FloatBobPhase;
|
||||
}
|
||||
|
||||
Default
|
||||
{
|
||||
Tag "$T_GRAVITYS";
|
||||
|
|
@ -439,6 +458,7 @@ Class InvinciballPower : Powerup
|
|||
{
|
||||
Actor l, snd;
|
||||
int lasteffect;
|
||||
transient int lastpulse;
|
||||
|
||||
Default
|
||||
{
|
||||
|
|
@ -455,6 +475,8 @@ Class InvinciballPower : Powerup
|
|||
l = Spawn("InvinciballLight",Owner.pos);
|
||||
l.target = Owner;
|
||||
l.master = self;
|
||||
lastpulse = max(lastpulse,gametic+35);
|
||||
SWWMHandler.DoFlash(Owner,Color(96,255,64,0),20);
|
||||
}
|
||||
|
||||
override void DoEffect()
|
||||
|
|
@ -471,6 +493,7 @@ Class InvinciballPower : Powerup
|
|||
Super.EndEffect();
|
||||
if ( !Owner ) return;
|
||||
Owner.A_StartSound("powerup/invinciballend",CHAN_ITEMEXTRA);
|
||||
SWWMHandler.DoFlash(Owner,Color(96,255,64,0),20);
|
||||
if ( (EffectTics <= 0) && Owner && Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_INVINCIBALL"));
|
||||
}
|
||||
|
||||
|
|
@ -489,11 +512,20 @@ Class InvinciballPower : Powerup
|
|||
SWWMHandler.DoFlash(Owner,Color(64,255,64,0),15);
|
||||
Owner.A_StartSound("powerup/invinciballhit",CHAN_POWERUP);
|
||||
lasteffect = level.maptime;
|
||||
lastpulse = max(lastpulse,gametic+20);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Class InvinciballX : GhostArtifactX
|
||||
{
|
||||
Default
|
||||
{
|
||||
RenderStyle "Normal";
|
||||
}
|
||||
}
|
||||
|
||||
Class FuckingInvinciball : Inventory
|
||||
{
|
||||
Mixin SWWMAutoUseFix;
|
||||
|
|
@ -510,10 +542,24 @@ Class FuckingInvinciball : Inventory
|
|||
Owner.A_StartSound(UseSound,CHAN_ITEMEXTRA);
|
||||
Owner.A_StartSound("misc/sundowner",CHAN_POWERUPEXTRA);
|
||||
let i = InvinciballPower(Owner.FindInventory("InvinciballPower"));
|
||||
if ( i ) i.EffectTics = i.default.EffectTics;
|
||||
if ( i )
|
||||
{
|
||||
i.EffectTics = i.default.EffectTics;
|
||||
i.lastpulse = max(i.lastpulse,gametic+35);
|
||||
SWWMHandler.DoFlash(Owner,Color(96,255,64,0),20);
|
||||
}
|
||||
else Owner.GiveInventory("InvinciballPower",1);
|
||||
return true;
|
||||
}
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
tracer = Spawn("InvinciballX",pos);
|
||||
tracer.angle = angle;
|
||||
tracer.target = self;
|
||||
tracer.FloatBobPhase = FloatBobPhase;
|
||||
}
|
||||
|
||||
Default
|
||||
{
|
||||
Tag "$T_INVINCIBALL";
|
||||
|
|
@ -607,6 +653,7 @@ Class RagekitPower : Powerup
|
|||
{
|
||||
Actor l, snd;
|
||||
int lasteffect, lastrage;
|
||||
transient int lastpulse;
|
||||
|
||||
override double GetSpeedFactor()
|
||||
{
|
||||
|
|
@ -629,6 +676,7 @@ Class RagekitPower : Powerup
|
|||
SWWMHandler.DoFlash(Owner,Color(64,255,0,0),30);
|
||||
Owner.A_QuakeEx(8,8,8,20,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:1.);
|
||||
lasteffect = int.min;
|
||||
lastpulse = max(lastpulse,gametic+35);
|
||||
l = Spawn("RagekitLight",Owner.pos);
|
||||
l.target = Owner;
|
||||
l.master = self;
|
||||
|
|
@ -647,6 +695,7 @@ Class RagekitPower : Powerup
|
|||
if ( (Owner.player == players[consoleplayer]) && (gametic > lastrage) && (CVar.GetCVar('swwm_mutevoice',players[consoleplayer]).GetInt() < 2) )
|
||||
lastrage = SWWMHandler.AddOneliner("ragekit",2,5);
|
||||
Owner.A_QuakeEx(2,2,2,Random[Rage](1,2),0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:.5);
|
||||
lastpulse = max(lastpulse,gametic+10);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -655,6 +704,8 @@ Class RagekitPower : Powerup
|
|||
Super.EndEffect();
|
||||
if ( !Owner ) return;
|
||||
Owner.A_StartSound("powerup/ragekitend",CHAN_ITEMEXTRA);
|
||||
SWWMHandler.DoFlash(Owner,Color(128,255,0,0),30);
|
||||
Owner.A_QuakeEx(4,4,4,20,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:1.);
|
||||
if ( (EffectTics <= 0) && Owner && Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_RAGEKIT"));
|
||||
}
|
||||
|
||||
|
|
@ -671,6 +722,7 @@ Class RagekitPower : Powerup
|
|||
lastrage = SWWMHandler.AddOneliner("ragekit",2,5);
|
||||
Owner.A_StartSound("powerup/ragekithit",CHAN_POWERUP);
|
||||
lasteffect = level.maptime;
|
||||
lastpulse = max(lastpulse,gametic+35);
|
||||
}
|
||||
}
|
||||
else if ( passive )
|
||||
|
|
@ -678,6 +730,14 @@ Class RagekitPower : Powerup
|
|||
}
|
||||
}
|
||||
|
||||
Class RagekitX : GhostArtifactX
|
||||
{
|
||||
Default
|
||||
{
|
||||
RenderStyle "Normal";
|
||||
}
|
||||
}
|
||||
|
||||
Class Ragekit : Inventory
|
||||
{
|
||||
Mixin SWWMAutoUseFix;
|
||||
|
|
@ -687,10 +747,25 @@ Class Ragekit : Inventory
|
|||
if ( pickup && !deathmatch ) return false;
|
||||
Owner.A_StartSound(UseSound,CHAN_ITEMEXTRA);
|
||||
let r = RagekitPower(Owner.FindInventory("RagekitPower"));
|
||||
if ( r ) r.EffectTics = r.default.EffectTics;
|
||||
if ( r )
|
||||
{
|
||||
r.EffectTics = r.default.EffectTics;
|
||||
SWWMHandler.DoFlash(Owner,Color(64,255,0,0),30);
|
||||
Owner.A_QuakeEx(8,8,8,20,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:1.);
|
||||
r.lastpulse = max(r.lastpulse,gametic+35);
|
||||
}
|
||||
else Owner.GiveInventory("RagekitPower",1);
|
||||
return true;
|
||||
}
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
tracer = Spawn("RagekitX",pos);
|
||||
tracer.angle = angle;
|
||||
tracer.target = self;
|
||||
tracer.FloatBobPhase = FloatBobPhase;
|
||||
}
|
||||
|
||||
Default
|
||||
{
|
||||
Tag "$T_RAGEKIT";
|
||||
|
|
|
|||
|
|
@ -525,7 +525,7 @@ Class SaltLight : PaletteLight
|
|||
{
|
||||
Tag "SaltTail";
|
||||
ReactionTime 30;
|
||||
Args 0,0,0,80;
|
||||
Args 0,0,0,120;
|
||||
}
|
||||
}
|
||||
Class SaltLight2 : PaletteLight
|
||||
|
|
@ -534,7 +534,7 @@ Class SaltLight2 : PaletteLight
|
|||
{
|
||||
Tag "SaltExpl";
|
||||
ReactionTime 30;
|
||||
Args 0,0,0,80;
|
||||
Args 0,0,0,70;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -543,7 +543,7 @@ Class SaltImpact : Actor
|
|||
Default
|
||||
{
|
||||
Obituary "$O_SPREADGUN_BLUE";
|
||||
DamageType "Salt";
|
||||
DamageType "Electricity";
|
||||
RenderStyle "Add";
|
||||
Radius 0.1;
|
||||
Height 0;
|
||||
|
|
@ -614,7 +614,7 @@ Class SaltBeam : Actor
|
|||
Default
|
||||
{
|
||||
Obituary "$O_SPREADGUN_BLUE";
|
||||
DamageType "Salt";
|
||||
DamageType "Electricity";
|
||||
RenderStyle "Add";
|
||||
Radius 0.1;
|
||||
Height 0;
|
||||
|
|
@ -645,7 +645,7 @@ Class SaltBeam : Actor
|
|||
let b = Actor.Spawn("InvisibleSplasher",t.WaterHitList[i].hitpos);
|
||||
b.A_CheckTerrain();
|
||||
}
|
||||
for ( int i=8; i<t.Results.Distance; i+=16 )
|
||||
for ( int i=16; i<t.Results.Distance; i+=32 )
|
||||
{
|
||||
if ( !Random[Spreadgun](0,Stamina) ) continue;
|
||||
let b = Actor.Spawn("SWWMSmoke",level.Vec3Offset(pos,x*i));
|
||||
|
|
@ -688,8 +688,16 @@ Class SaltBeam : Actor
|
|||
}
|
||||
return;
|
||||
}
|
||||
else if ( (args[0] > 20) && !Random[Spreadgun](0,800/args[0]) )
|
||||
{
|
||||
let i = Spawn("SaltImpact",level.Vec3Offset(pos,x*32));
|
||||
i.angle = atan2(x.y,x.x);
|
||||
i.pitch = asin(-x.z);
|
||||
i.target = target;
|
||||
return;
|
||||
}
|
||||
// next beam
|
||||
if ( !(special2%2) && !Random[Spreadgun](0,2) )
|
||||
if ( !(special2%2) && !Random[Spreadgun](0,4) )
|
||||
Spawn("SaltLight",level.Vec3Offset(pos,x*16));
|
||||
let next = Spawn("SaltBeam",level.Vec3Offset(pos,x*32));
|
||||
double a = FRandom[Spreadgun](0,360), s = FRandom[Spreadgun](0,.06);
|
||||
|
|
@ -698,6 +706,7 @@ Class SaltBeam : Actor
|
|||
next.pitch = asin(-dir.z);
|
||||
next.target = target;
|
||||
next.special2 = (special2+1)%10;
|
||||
next.args[0] = args[0]+1;
|
||||
next.SetStateLabel("TrailSpawn");
|
||||
}
|
||||
|
||||
|
|
@ -714,10 +723,10 @@ Class SaltBeam : Actor
|
|||
A_FadeOut(.04);
|
||||
if ( Random[Spreadgun](-2,GetAge()/10) == 0 )
|
||||
{
|
||||
SWWMHandler.DoBlast(self,48,5000,target);
|
||||
A_Explode(5,48,0);
|
||||
SWWMHandler.DoBlast(self,64,5000,target);
|
||||
A_Explode(5,64,0);
|
||||
}
|
||||
if ( (special2 || GetAge()) && !special1 ) SpreadOut();
|
||||
if ( ((special2%5) || GetAge()) && !special1 ) SpreadOut();
|
||||
}
|
||||
|
||||
States
|
||||
|
|
@ -1311,8 +1320,7 @@ Class Spreadgun : SWWMWeapon
|
|||
{
|
||||
Super.ModifyDropAmount(dropamount);
|
||||
// toss some ammo while we're at it
|
||||
let am = (Class<Ammo>)(GetReplacement("Shell"));
|
||||
A_DropItem(am,Random[Spreadgun](3,5));
|
||||
A_DropItem(Random[Spreadgun](0,2)?"RedShell":"GreenShell",Random[Spreadgun](1,3));
|
||||
}
|
||||
|
||||
Default
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue