flak_m/zscript/utgore.zsc
Marisa Kirisame 94cba843e4 1.1.1 update (to be made stable after GZDoom updates):
- Sound overhaul, migrated everything to A_StartSound, new sound channels, CHANF_OVERLAP where needed.
 - Fancy titlemap (two variants, one based on the ps2 menu, one based on the v222 menu).
2020-01-04 22:31:56 +01:00

613 lines
13 KiB
Text

// Blood
Class UTBlood : Actor
{
Default
{
RenderStyle "Add";
Scale 1.1;
+NOBLOCKMAP;
+NOGRAVITY;
+NOTELEPORT;
+DONTSPLASH;
+FORCEXYBILLBOARD;
+PUFFGETSOWNER;
}
void A_Bleed( int str = 1 )
{
Scale *= 0.7+0.3*str;
vel *= 0;
let b = Spawn("UTBloodSpurt",pos);
b.angle = angle+FRandom[Blud](-15,15);
b.pitch = pitch+FRandom[Blud](-15,15);
b.translation = translation;
b.args[0] = str;
// transfer blood color for decals
if ( target && target.bloodcolor ) b.SetShade(target.bloodcolor);
else b.SetShade(gameinfo.defaultbloodcolor);
}
States
{
Spawn:
Spray:
TNT1 A 0 NoDelay A_Bleed(3);
Goto Puff;
TNT1 A 0 A_Bleed(2);
Goto Puff;
TNT1 A 0 A_Bleed(1);
Goto Puff;
Puff:
TNT1 A 0
{
int dec = Random[Blod](0,2);
if ( dec == 1 )
return ResolveState("Puff1");
if ( dec == 2 )
return ResolveState("Puff2");
return ResolveState("Puff3");
}
Puff1:
BPF1 ABCDEFGHIJK 1;
Stop;
Puff2:
BPF2 ABCDEFGH 1;
Stop;
Puff3:
BPF3 ABCDEFGHIJ 1;
Stop;
}
}
// single drop of blod
Class UTBloodDrop : Actor
{
Default
{
Scale 0.24;
Gravity 0.8;
Mass 1;
Radius 2;
Height 2;
RenderStyle "Translucent";
+MISSILE;
+NOTELEPORT;
+DONTSPLASH;
+THRUACTORS;
+FORCEXYBILLBOARD;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
SetState(FindState("Spawn")+Random[Blod](0,4));
Scale *= FRandom[Blod](0.6,1.4);
}
void A_BloodDie()
{
// TODO leave decals
}
States
{
Spawn:
BDRP ABCDE -1;
Stop;
Death:
TNT1 A 0 A_BloodDie();
Stop;
}
}
// a burst of blod
Class UTBloodSpurt : Actor
{
double str;
Default
{
+NOBLOCKMAP;
+NOGRAVITY;
+DONTSPLASH;
+NOTELEPORT;
+THRUACTORS;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
str = FRandom[Blood](2.0,3.2)*args[0];
int sz = 7*args[0];
double ang, pt;
if ( !flak_blood ) sz /= 3;
for ( int i=0; i<sz; i++ )
{
Actor d;
if ( flak_blood ) d = Spawn("UTBloodDrop",pos);
else d = Spawn("Blood",pos,ALLOW_REPLACE);
d.translation = translation;
d.SetShade(fillcolor);
ang = angle+FRandom[Blood](-3,3)*str;
pt = pitch+FRandom[Blood](-3,3)*str;
Vector3 dir = (cos(pt)*cos(ang),cos(pt)*sin(ang),-sin(pt));
d.vel = dir*str*FRandom[Blood](0.4,0.8);
d.vel.z += str*0.5;
d.scale *= str*0.15*FRandom[Blood](0.6,1.4);
}
Destroy();
}
}
// for chunks
Class UTBloodTrail : Actor
{
double str;
Default
{
+NOBLOCKMAP;
+NOGRAVITY;
+NOTELEPORT;
+DONTSPLASH;
+THRUACTORS;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
if ( !target ) return;
str = FRandom[Blood](2.0,4.0);
}
private bool IsTargetFlying()
{
if ( !target ) return false;
if ( target.InStateSequence(target.CurState,target.FindState("Spawn")) ) return true;
return false;
}
override void Tick()
{
Super.Tick();
if ( isFrozen() ) return;
if ( !target ) return;
SetOrigin(target.pos,true);
double ang, pt;
int max = flak_blood?3:Random[Blood](-2,1);
for ( int i=0; i<max; i++ )
{
Actor d;
if ( flak_blood ) d = Spawn("UTBloodDrop",pos);
else d = Spawn("Blood",pos,ALLOW_REPLACE);
d.translation = translation;
d.SetShade(fillcolor);
ang = FRandom[Blood](0,360);
pt = FRandom[Blood](-90,90);
Vector3 dir = -target.vel*0.2;
dir += (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*0.8;
d.vel = dir*str*FRandom[Blood](0.8,1.2);
d.scale *= str*0.15*FRandom[Blood](0.6,1.4);
}
bool flying = IsTargetFlying();
if ( !flying ) Destroy();
}
}
// Poof
Class UTBloodPuff : Actor
{
Default
{
RenderStyle "Add";
Scale 1.1;
Alpha 0.4;
+NOBLOCKMAP;
+NOGRAVITY;
+NOTELEPORT;
+DONTSPLASH;
+FORCEXYBILLBOARD;
}
States
{
Spawn:
TNT1 A 0 NoDelay
{
int dec = Random[Blod](0,2);
if ( dec == 1 )
return ResolveState("Puff1");
if ( dec == 2 )
return ResolveState("Puff2");
return ResolveState("Puff3");
}
Puff1:
BPF1 ABCDEFGHIJK 2;
Stop;
Puff2:
BPF2 ABCDEFGH 2;
Stop;
Puff3:
BPF3 ABCDEFGHIJ 2;
Stop;
}
}
// Chunkers
Class UTGibber : Actor
{
Actor Gibbed;
int gibcount, gibsize;
color shadecol;
Vector3 rvel;
virtual void BurstGibs()
{
static const class<Actor> gibcls[] = {"UTGenericGib1","UTGenericGib2","UTGenericGib3","UTGenericGib4"};
Actor a;
double ang, pt;
Vector3 dir;
bool dummy;
for ( int i=0; i<gibsize; i++ )
{
let a = Spawn(gibcls[Random[Blod](0,3)],Vec3Offset(FRandom[Blod](-0.5,0.5)*radius,FRandom[Blod](-0.5,0.5)*radius,FRandom[Blod](0.2,0.8)*height));
a.translation = translation;
a.SetShade(fillcolor);
a.scale *= FRandom[Blod](1.7,2.3)*scale.x;
ang = FRandom[Blod](0,360);
pt = FRandom[Blod](-90,90);
dir = (cos(pt)*cos(ang),cos(pt)*sin(ang),sin(-pt));
a.vel = rvel*0.6+dir*FRandom[Blod](3.0,6.0);
}
for ( int i=0; i<gibsize; i++ )
{
let a = Spawn("UTBloodPuff",Vec3Offset(FRandom[Blod](-12,12),FRandom[Blod](-12,12),FRandom[Blod](0.1,0.9)*height));
a.translation = translation;
a.SetShade(fillcolor);
a.scale *= FRandom[Blod](1.8,2.3)*scale.x;
ang = FRandom[Blod](0,360);
pt = FRandom[Blod](-90,90);
dir = (cos(pt)*cos(ang),cos(pt)*sin(ang),sin(-pt));
a.vel = rvel*0.2+dir*FRandom[Blod](1.5,3.0);
}
A_CountDown();
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
gibsize = int(min(max(radius,height)/24,3));
reactiontime = int(min(max(radius,height)/10,4));
rvel = vel;
vel *= 0;
}
Default
{
+NOCLIP;
+NOGRAVITY;
+NOTELEPORT;
Radius 32;
Height 16;
}
States
{
Spawn:
TNT1 A 0 NoDelay A_StartSound("misc/gibbed");
TNT1 A 1 BurstGibs();
Wait;
}
}
Class UTFemaleLegGibber : UTGibber
{
bool firstgib;
override void BurstGibs()
{
static const class<Actor> parts[] = {"UTFemaleFoot","UTThigh"};
static const double partofsy[] = {9,8};
static const double partofsz[] = {9,20};
Actor a;
double ang, pt;
Vector3 dir;
if ( !firstgib )
{
firstgib = true;
for ( int i=0; i<2; i++ )
{
Actor a = Spawn(parts[i],Vec3Offset(-partofsy[i]*sin(angle),partofsy[i]*cos(angle),partofsz[i]));
ang = FRandom[Blod](0,360);
pt = FRandom[Blod](-90,90);
dir = (cos(pt)*cos(ang),cos(pt)*sin(ang),sin(-pt));
a.vel = rvel*0.6+dir*FRandom[Blod](3.0,6.0);
}
}
for ( int i=0; i<gibsize; i++ )
{
Vector3 box = (FRandom[Blod](-8,8),FRandom[Blod](7,12),FRandom[Blod](5,18));
let a = Spawn("UTBloodPuff",Vec3Offset(box.x*cos(angle)-box.y*sin(angle),box.x*sin(angle)+box.y*cos(angle),box.z));
ang = FRandom[Blod](0,360);
pt = FRandom[Blod](-90,90);
dir = (cos(pt)*cos(ang),cos(pt)*sin(ang),sin(-pt));
a.vel = rvel*0.2+dir*FRandom[Blod](1.5,3.0);
}
A_CountDown();
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
gibsize = 3;
reactiontime = 5;
}
States
{
Spawn:
TNT1 A 0 NoDelay; // no sound, done by player
TNT1 A 1 BurstGibs();
Wait;
}
}
Class UTPlayerGibber : UTGibber
{
bool firstgib;
override void BurstGibs()
{
static const class<Actor> bossparts[] = {"UTBossArm","UTBossArm","UTBossFoot","UTBossFoot","UTMaleTorso","UTHeadBoss"};
static const class<Actor> maleparts[] = {"UTMaleArm","UTMaleArm","UTMaleFoot","UTMaleFoot","UTMaleTorso","UTHeadMale"};
static const class<Actor> femaleparts[] = {"UTFemaleArm","UTFemaleArm","UTFemaleFoot","UTFemaleFoot","UTFemaleTorso","UTHeadFemale"};
static const class<Actor> extraparts[] = {"UTThigh","UTThigh","UTHeart","UTLiver","UTStomach"};
static const double partofsy[] =
{
14,
-14,
9,
-9,
0,
0,
8,
-8,
-2,
5,
-3
};
static const double partofsz[] =
{
36,
36,
9,
9,
32,
48,
20,
20,
40,
32,
35
};
Actor a;
double ang, pt;
Vector3 dir;
if ( !firstgib )
{
firstgib = true;
for ( int i=0; i<11; i++ )
{
if ( (i == 5) && UTPlayer(Gibbed).headless ) continue;
if ( (i == 0) && UTPlayer(Gibbed).armlessR ) continue;
if ( (i == 1) && UTPlayer(Gibbed).armlessL ) continue;
if ( ((i == 2) || (i == 6)) && UTPlayer(Gibbed).leglessR ) continue;
if ( ((i == 3) || (i == 7)) && UTPlayer(Gibbed).leglessL ) continue;
if ( ((i == 4) || (i > 7)) && UTPlayer(Gibbed).torsoless ) continue;
Actor a;
if ( i < 6 )
{
if ( UTPlayer(Gibbed).DollType == UTPlayer.DOLL_Boss )
a = Spawn(bossparts[i],Vec3Offset(-partofsy[i]*sin(angle),partofsy[i]*cos(angle),partofsz[i]));
else if ( UTPlayer(Gibbed).DollType == UTPlayer.DOLL_Female )
a = Spawn(femaleparts[i],Vec3Offset(-partofsy[i]*sin(angle),partofsy[i]*cos(angle),partofsz[i]));
else a = Spawn(maleparts[i],Vec3Offset(-partofsy[i]*sin(angle),partofsy[i]*cos(angle),partofsz[i]));
}
else a = Spawn(extraparts[i-6],Vec3Offset(-partofsy[i]*sin(angle),partofsy[i]*cos(angle),partofsz[i]));
ang = FRandom[Blod](0,360);
pt = FRandom[Blod](-90,90);
if ( a is 'UTHead' )
{
pt = FRandom[Blod](-90,-15);
if ( UTPlayer(Gibbed).player )
{
UTPlayer(Gibbed).player.Camera = a;
UTHead(a).headowner = UTPlayer(Gibbed).player;
}
}
dir = (cos(pt)*cos(ang),cos(pt)*sin(ang),sin(-pt));
a.vel = rvel*0.6+dir*FRandom[Blod](3.0,6.0);
}
}
for ( int i=0; i<gibsize; i++ )
{
let a = Spawn("UTBloodPuff",Vec3Offset(FRandom[Blod](-0.8,0.8)*radius,FRandom[Blod](-0.8,0.8)*radius,FRandom[Blod](0.1,0.9)*height));
ang = FRandom[Blod](0,360);
pt = FRandom[Blod](-90,90);
dir = (cos(pt)*cos(ang),cos(pt)*sin(ang),sin(-pt));
a.vel = rvel*0.2+dir*FRandom[Blod](1.5,3.0);
}
A_CountDown();
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
gibsize = 3;
reactiontime = 5;
}
States
{
Spawn:
TNT1 A 0 NoDelay; // no sound, done by player
TNT1 A 1 BurstGibs();
Wait;
}
}
// Chunks
Class UTGib : Actor
{
double rollvel, anglevel, pitchvel;
Default
{
Radius 4;
Height 4;
BounceType "Hexen";
BounceFactor 0.8;
WallBounceFactor 0.8;
Gravity 0.6;
+ROLLSPRITE;
+ROLLCENTER;
+INTERPOLATEANGLES;
+CANBOUNCEWATER;
+MISSILE;
+THRUACTORS;
+USEBOUNCESTATE;
+NOTELEPORT;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
tracer = Spawn("UTBloodTrail",pos);
tracer.target = self;
if ( bloodcolor ) tracer.SetShade(bloodcolor);
else tracer.SetShade(gameinfo.defaultbloodcolor);
tracer.translation = bloodtranslation;
rollvel = FRandom[Blod](3,6)*RandomPick[Blod](-1,1);
anglevel = FRandom[Blod](3,6)*RandomPick[Blod](-1,1);
pitchvel = FRandom[Blod](3,6)*RandomPick[Blod](-1,1);
}
void A_HandleBounce()
{
double spd = vel.length();
if ( spd > double.epsilon )
vel = (vel.unit()+(FRandom[Blod](-0.2,0.2),FRandom[Blod](-0.2,0.2),FRandom[Blod](-0.2,0.2))).unit()*spd;
if ( BlockingFloor && (vel.xy.length() < 1) )
{
ClearBounce();
ExplodeMissile();
}
if ( spd < 10 )
{
if ( tracer ) tracer.Destroy();
}
else if ( spd > 20 ) vel *= 0.8;
A_StartSound("misc/gibp");
double ang, pt;
int max = flak_blood?6:2;
for ( int i=0; i<max; i++ )
{
Actor d;
if ( flak_blood ) d = Spawn("UTBloodDrop",pos);
else d = Spawn("Blood",pos,ALLOW_REPLACE);
d.translation = bloodtranslation;
if ( bloodcolor ) d.SetShade(bloodcolor);
else d.SetShade(gameinfo.defaultbloodcolor);
ang = FRandom[Blood](0,360);
pt = FRandom[Blood](-90,90);
Vector3 dir = -vel*0.4;
dir += (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*1.3;
d.vel = dir*FRandom[Blood](0.8,1.2);
d.scale *= 0.75*FRandom[Blood](0.6,1.4);
}
rollvel = FRandom[Blod](3,6)*RandomPick[Blod](-1,1);
anglevel = FRandom[Blod](3,6)*RandomPick[Blod](-1,1);
pitchvel = FRandom[Blod](3,6)*RandomPick[Blod](-1,1);
}
States
{
Spawn:
UGIB A 1
{
roll += rollvel;
angle += anglevel;
pitch += pitchvel;
}
Wait;
Bounce:
UGIB A 0 A_HandleBounce();
Goto Spawn;
Death:
UGIB A 1 A_SetTics(Random[Blod](12,18)*15);
UGIB A 1 A_FadeOut(0.05);
Wait;
}
}
Class UTGenericGib1 : UTGib {}
Class UTGenericGib2 : UTGib {}
Class UTGenericGib3 : UTGib {}
Class UTGenericGib4 : UTGib {}
Class UTThigh : UTGib {}
Class UTFemaleArm : UTGib {}
Class UTFemaleFoot : UTGib {}
Class UTFemaleTorso : UTGib {}
Class UTMaleArm : UTGib {}
Class UTMaleFoot : UTGib {}
Class UTMaleTorso : UTGib {}
Class UTBossArm : UTGib {}
Class UTBossFoot : UTGib {}
Class UTBossTorso : UTGib {}
Class UTHeart : UTGib
{
States
{
Spawn:
UGIB ABCDEF 1
{
roll += rollvel;
angle += anglevel;
pitch += pitchvel;
}
Loop;
Death:
UGIB ABCDEFABCDEFABCDEF 2;
UGIB ABCDEFABCDEF 4;
UGIB ABCDEF 8;
UGIB A 1 A_SetTics(Random[Blod](12,18)*15);
UGIB A 1 A_FadeOut(0.05);
Wait;
}
}
Class UTLiver : UTGib {}
Class UTStomach : UTGib {}
Class UTHead : UTGib
{
PlayerInfo headowner;
override void PostBeginPlay()
{
Super.PostBeginPlay();
UTMainHandler.DoFlash(self,Color(128,255,0,0),150);
UTMainHandler.DoFlash(self,Color(96,255,0,0),0);
}
override void Tick()
{
Super.Tick();
if ( headowner && headowner.mo && (headowner.mo.Health > 0) && (headowner.Camera == self) )
{
headowner.Camera = headowner.mo;
headowner = null;
}
}
override void OnDestroy()
{
if ( headowner && (headowner.Camera == self) && headowner.mo )
{
headowner.Camera = headowner.mo;
headowner = null;
}
Super.OnDestroy();
}
States
{
Death:
UGIB A 1 A_SetTics(Random[Blod](12,18)*15);
UGIB A 0 A_JumpIf(headowner,"Death");
UGIB A 1 A_FadeOut(0.05);
Wait;
}
}
Class UTHeadFemale : UTHead {}
Class UTHeadMale : UTHead {}
Class UTHeadBoss : UTHead {}