Going to focus on the HUD now while at the same time doing the remaining weapons.
533 lines
No EOL
12 KiB
Text
533 lines
No EOL
12 KiB
Text
Class Tier3Ammo : RandomSpawner replaces Shell
|
|
{
|
|
Default
|
|
{
|
|
DropItem "BioAmmo", 255, 1;
|
|
DropItem "ShockAmmo", 255, 1;
|
|
}
|
|
}
|
|
Class Tier3Ammo2 : Tier3Ammo replaces ShellBox {}
|
|
Class Tier3Weapon : RandomSpawner replaces Shotgun
|
|
{
|
|
Default
|
|
{
|
|
DropItem "BioRifle", 255, 1;
|
|
DropItem "ShockRifle", 255, 1;
|
|
}
|
|
}
|
|
Class Tier3Weapon2 : Tier3Weapon replaces SuperShotgun {}
|
|
|
|
Class BioAmmo : UTAmmo
|
|
{
|
|
Default
|
|
{
|
|
Tag "Biosludge Ammo";
|
|
Inventory.PickupMessage "You picked up the Biosludge Ammo.";
|
|
Inventory.Amount 25;
|
|
Inventory.MaxAmount 100;
|
|
Ammo.BackpackAmount 50;
|
|
Ammo.BackpackMaxAmount 200;
|
|
Ammo.DropAmount 25;
|
|
UTAmmo.UsedInSlot AMMO_SLOT3;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
BIOA A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class BioHitbox : Actor
|
|
{
|
|
Default
|
|
{
|
|
Radius 2;
|
|
Height 2;
|
|
+SHOOTABLE;
|
|
+NOGRAVITY;
|
|
+NOCLIP;
|
|
+DONTSPLASH;
|
|
+NOBLOOD;
|
|
}
|
|
override int DamageMobj( Actor inflictor, Actor source, int damage, Name mod, int flags, double angle )
|
|
{
|
|
if ( inflictor == target ) return 0;
|
|
if ( target && !target.InStateSequence(target.CurState,target.ResolveState("XDeath")) )
|
|
{
|
|
target.bAMBUSH = true;
|
|
target.ExplodeMissile(null,inflictor);
|
|
}
|
|
return 0;
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( !target )
|
|
{
|
|
Destroy();
|
|
return;
|
|
}
|
|
SetOrigin(target.pos-(0,0,height*0.5),true);
|
|
}
|
|
}
|
|
|
|
Class BioLight : DynamicLight
|
|
{
|
|
Default
|
|
{
|
|
DynamicLight.Type "Point";
|
|
Args 64,255,48,8;
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( !target )
|
|
{
|
|
Destroy();
|
|
return;
|
|
}
|
|
args[LIGHT_INTENSITY] = 8*target.Scale.x;
|
|
}
|
|
}
|
|
|
|
Class BioXLight : DynamicLight
|
|
{
|
|
|
|
double lifetime;
|
|
Default
|
|
{
|
|
DynamicLight.Type "Point";
|
|
Args 64,255,48,30;
|
|
}
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
lifetime = 1.0;
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( globalfreeze || level.frozen ) return;
|
|
args[LIGHT_RED] = 64*lifetime;
|
|
args[LIGHT_GREEN] = 255*lifetime;
|
|
args[LIGHT_BLUE] = 48*lifetime;
|
|
lifetime -= 0.05;
|
|
if ( lifetime <= 0 ) Destroy();
|
|
}
|
|
}
|
|
|
|
Class BioGel : Actor
|
|
{
|
|
Actor l, b;
|
|
enum EHitType
|
|
{
|
|
HIT_NONE,
|
|
HIT_WALL,
|
|
HIT_CEILING,
|
|
HIT_FLOOR
|
|
};
|
|
int hittype;
|
|
int deadtimer;
|
|
Line atline;
|
|
int atside;
|
|
int rollvel, pitchvel, yawvel;
|
|
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
vel.z += 6;
|
|
deadtimer = -1;
|
|
l = Spawn("BioLight",pos);
|
|
l.target = self;
|
|
b = Spawn("BioHitbox",pos);
|
|
b.target = self;
|
|
rollvel = FRandom[GES](10,30)*RandomPick[GES](-1,1);
|
|
pitchvel = FRandom[GES](10,30)*RandomPick[GES](-1,1);
|
|
yawvel = FRandom[GES](10,30)*RandomPick[GES](-1,1);
|
|
}
|
|
override int SpecialMissileHit( Actor victim )
|
|
{
|
|
if ( victim == b ) return 1;
|
|
if ( (victim is 'BioHitbox') && ((victim.target == master) || (victim.target.master == master)) ) return 1;
|
|
return -1;
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( globalfreeze || level.frozen ) return;
|
|
if ( !bNOGRAVITY )
|
|
{
|
|
A_SetRoll(roll+rollvel,SPF_INTERPOLATE);
|
|
A_SetPitch(pitch+pitchvel,SPF_INTERPOLATE);
|
|
A_SetPitch(pitch+yawvel,SPF_INTERPOLATE);
|
|
if ( waterlevel > 0 )
|
|
{
|
|
vel.xy *= 0.98;
|
|
rollvel *= 0.98;
|
|
pitchvel *= 0.98;
|
|
yawvel *= 0.98;
|
|
}
|
|
}
|
|
if ( !InStateSequence(CurState,FindState("XDeath")) && ((!bNOGRAVITY && !Random[GES](0,2)) || !Random[GES](0,10)) )
|
|
{
|
|
int numpt = Min(20,Scale.x*2)+Random[GES](-1,1);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (FRandom[GES](-1,1),FRandom[GES](-1,1),FRandom[GES](-1,1)).unit()*FRandom[GES](1,3);
|
|
A_SpawnParticle("40FF30",SPF_FULLBRIGHT,Random[GES](30,60),FRandom[GES](1.2,2.4),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,-0.2,3.0);
|
|
}
|
|
}
|
|
if ( deadtimer <= -1 ) return;
|
|
let bi = BlockThingsIterator.Create(self,4*Scale.x);
|
|
while ( bi.Next() )
|
|
{
|
|
if ( !bi.Thing || !bi.Thing.bSHOOTABLE || (bi.Thing == b) || ((bi.Thing is 'BioHitbox') && ((bi.Thing.target.master == self) || (bi.Thing.target == master))) ) continue;
|
|
if ( (Distance2D(bi.Thing)-bi.Thing.radius <= 4*Scale.x) && ((bi.Thing.pos.z <= pos.z+4*Scale.x) && (bi.Thing.pos.z+bi.Thing.height >= pos.z-4*Scale.x)) ) deadtimer = 0;
|
|
}
|
|
if ( deadtimer-- <= 0 )
|
|
{
|
|
deadtimer = -1;
|
|
SetStateLabel("XDeath");
|
|
}
|
|
}
|
|
// align self to what surface was hit, currently does not support 3d floors + slopes properly
|
|
virtual void AlignSelf()
|
|
{
|
|
A_NoGravity();
|
|
A_Stop();
|
|
if ( bAMBUSH )
|
|
{
|
|
SetStateLabel("XDeath");
|
|
return;
|
|
}
|
|
Vector3 normal = (0,0,0);
|
|
FLineTraceData d;
|
|
A_SetSize(0.1,0);
|
|
if ( BlockingLine )
|
|
{
|
|
atline = BlockingLine;
|
|
normal = (-BlockingLine.delta.y,BlockingLine.delta.x,0).unit();
|
|
atside = 1;
|
|
if ( !BlockingLine.sidedef[1] || (CurSector == BlockingLine.frontsector) )
|
|
{
|
|
atside = 0;
|
|
normal *= -1;
|
|
}
|
|
angle = atan2(normal.y,normal.x);
|
|
pitch = 0;
|
|
roll = 0;
|
|
LineTrace(angle+180,172,0,TRF_THRUACTORS,data:d);
|
|
SetOrigin(d.HitLocation+normal*0.5,false);
|
|
if ( waterlevel > 0 ) hittype = HIT_FLOOR;
|
|
else hittype = HIT_WALL;
|
|
}
|
|
else if ( pos.z <= floorz+4 )
|
|
{
|
|
normal = cursector.floorplane.Normal;
|
|
pitch = asin(-normal.z);
|
|
angle = atan2(normal.y,normal.x);
|
|
roll = FRandom[GES](0,360);
|
|
SetOrigin((pos.x,pos.y,floorz)+normal*0.5,false);
|
|
hittype = HIT_FLOOR;
|
|
}
|
|
else if ( pos.z >= ceilingz-8 )
|
|
{
|
|
normal = cursector.ceilingplane.Normal;
|
|
pitch = asin(-normal.z);
|
|
angle = atan2(normal.y,normal.x);
|
|
roll = FRandom[GES](0,360);
|
|
SetOrigin((pos.x,pos.y,ceilingz)+normal*0.5,false);
|
|
if ( waterlevel > 0 ) hittype = HIT_FLOOR;
|
|
else if ( normal dot (0,0,-1) > 0.7 )
|
|
hittype = HIT_CEILING;
|
|
else hittype = HIT_FLOOR;
|
|
}
|
|
else
|
|
{
|
|
SetStateLabel("XDeath");
|
|
return;
|
|
}
|
|
A_PlaySound("ges/hit");
|
|
A_SprayDecal("BioSplat",-172);
|
|
int numpt = Min(100,Scale.x*10)+Random[GES](-5,5);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (normal+(FRandom[GES](-.8,.8),FRandom[GES](-.8,.8),FRandom[GES](-.8,.8))).unit()*FRandom[GES](3,6);
|
|
A_SpawnParticle("40FF30",SPF_FULLBRIGHT,Random[GES](30,60),FRandom[GES](1.2,3.6),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,-0.2,3.0);
|
|
}
|
|
}
|
|
action void A_DropDrip()
|
|
{
|
|
let d = Spawn("BioSplash",pos+cursector.ceilingplane.Normal*2*scale.x);
|
|
d.target = target;
|
|
d.angle = angle;
|
|
d.pitch = pitch;
|
|
d.roll = roll;
|
|
d.master = self;
|
|
d.scale = scale*0.5;
|
|
d.vel.z -= 6;
|
|
}
|
|
action void A_GelExplode()
|
|
{
|
|
A_NoGravity();
|
|
A_Stop();
|
|
if ( invoker.l ) invoker.l.Destroy();
|
|
if ( invoker.b ) invoker.b.Destroy();
|
|
let s = Spawn("BioXLight",pos);
|
|
s.args[3] *= Scale.x;
|
|
invoker.deadtimer = -1;
|
|
if ( invoker.atline ) invoker.atline.RemoteActivate(target,invoker.atside,SPAC_Impact,pos);
|
|
A_Explode(Random[GES](15,25)*Scale.x,Min(250,Scale.x*25));
|
|
A_PlaySound("ges/explode",CHAN_VOICE);
|
|
int numpt = Min(300,Scale.x*30)+Random[GES](-10,10);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (FRandom[GES](-1,1),FRandom[GES](-1,1),FRandom[GES](-1,1)).unit()*FRandom[GES](3,12);
|
|
A_SpawnParticle("40FF30",SPF_FULLBRIGHT,Random[GES](30,60),FRandom[GES](2.4,6.4),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,-0.2,3.0);
|
|
}
|
|
Scale *= 0.5;
|
|
}
|
|
Default
|
|
{
|
|
Obituary "%o drank a glass of %k's dripping green load.";
|
|
DamageType 'Slime';
|
|
RenderStyle "Add";
|
|
Radius 4;
|
|
Height 4;
|
|
Scale 2;
|
|
Speed 20;
|
|
PROJECTILE;
|
|
-NOGRAVITY;
|
|
+SKYEXPLODE;
|
|
+FORCERADIUSDMG;
|
|
+FORCEXYBILLBOARD;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
GELF ABCDEFGHIJKLM 1 Bright;
|
|
Loop;
|
|
Death:
|
|
GELH A 1 Bright AlignSelf();
|
|
GELH BCDEFGHIJ 1 Bright;
|
|
GELH J 1 Bright A_SetTics(Random[GES](10,30));
|
|
GELH J -1 Bright
|
|
{
|
|
invoker.deadtimer = Random[GES](250,300);
|
|
if ( invoker.hittype == HIT_WALL ) return ResolveState("Slide");
|
|
else if ( invoker.hittype == HIT_CEILING ) return ResolveState("Drip");
|
|
return ResolveState(null);
|
|
}
|
|
Stop;
|
|
Drip:
|
|
GELD ABCDEFGH 4 Bright;
|
|
GELD I 4 Bright A_DropDrip();
|
|
GELD JKLM 4 Bright;
|
|
GELH J -1 Bright;
|
|
Stop;
|
|
Slide:
|
|
GELS ABCDEF 3 Bright;
|
|
GELS G -1 Bright;
|
|
Stop;
|
|
Crash:
|
|
XDeath:
|
|
#### # 1 Bright A_SetTics(Random[GES](1,3));
|
|
GEX1 A 1 Bright A_GelExplode();
|
|
GEX1 BCDEFGHIJK 3 Bright;
|
|
Stop;
|
|
Shrivel:
|
|
GELX ABCDEFGHIJKL 1 Bright; // UNUSED
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class BioGlob : BioGel
|
|
{
|
|
int numsplash;
|
|
|
|
override void AlignSelf()
|
|
{
|
|
Super.AlignSelf();
|
|
if ( !bAMBUSH ) numsplash = 2*Scale.x-1;
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( globalfreeze || level.frozen ) return;
|
|
Vector3 ofs = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch));
|
|
for ( int i=0; i<2; i++ )
|
|
{
|
|
if ( numsplash-- <= 0 ) return;
|
|
Vector3 dir = (ofs+(FRandom[GES](-.8,.8),FRandom[GES](-.8,.8),FRandom[GES](-.8,.8))).unit();
|
|
let d = Spawn("BioSplash",pos+ofs*4);
|
|
d.target = target;
|
|
d.master = self;
|
|
d.scale *= FRandom[GES](0.5,0.7);
|
|
d.angle = atan2(dir.y,dir.x);
|
|
d.pitch = -asin(dir.z);
|
|
d.vel = (cos(d.angle)*cos(d.pitch),sin(d.angle)*cos(d.pitch),-sin(d.pitch))*d.speed*FRandom[GES](0.25,0.35);
|
|
d.vel.z -= 3;
|
|
}
|
|
}
|
|
}
|
|
|
|
Class BioSplash : BioGel
|
|
{
|
|
override void AlignSelf()
|
|
{
|
|
Super.AlignSelf();
|
|
if ( hittype == HIT_CEILING ) hittype = HIT_FLOOR;
|
|
}
|
|
}
|
|
|
|
Class BioRifle : UTWeapon
|
|
{
|
|
double charge;
|
|
|
|
action void A_BioFire( bool alt = false )
|
|
{
|
|
Weapon weap = Weapon(invoker);
|
|
if ( !weap ) return;
|
|
if ( !alt )
|
|
{
|
|
if ( weap.Ammo1.Amount <= 0 ) return;
|
|
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
|
|
}
|
|
A_PlaySound("ges/fire",CHAN_WEAPON);
|
|
invoker.FireEffect();
|
|
A_AlertMonsters();
|
|
if ( alt ) A_QuakeEx(1+0.5*invoker.charge,1+0.5*invoker.charge,1+0.5*invoker.charge,5+1.2*invoker.charge,0,64,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.05+0.01*invoker.charge);
|
|
else A_QuakeEx(1,1,1,5,0,64,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.05);
|
|
Vector3 x, y, z;
|
|
double a, s;
|
|
[x, y, z] = Matrix4.GetAxes(pitch,angle,roll);
|
|
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+8.0*y-5.0*z;
|
|
Actor p;
|
|
if ( alt )
|
|
{
|
|
p = Spawn("BioGlob",origin);
|
|
p.A_SetScale(1+0.8*invoker.charge);
|
|
}
|
|
else p = Spawn("BioGel",origin);
|
|
p.angle = angle;
|
|
p.pitch = BulletSlope();
|
|
p.vel = (cos(p.angle)*cos(p.pitch),sin(p.angle)*cos(p.pitch),-sin(p.pitch))*p.speed;
|
|
p.target = self;
|
|
}
|
|
action void A_BeginCharge()
|
|
{
|
|
Weapon weap = Weapon(invoker);
|
|
if ( !weap ) return;
|
|
invoker.charge = 0;
|
|
A_PlaySound("ges/charge",CHAN_WEAPON);
|
|
}
|
|
action void A_ChargeUp()
|
|
{
|
|
Weapon weap = Weapon(invoker);
|
|
if ( !weap ) return;
|
|
if ( invoker.charge >= 5.1 ) return;
|
|
if ( weap.Ammo1.Amount <= 0 ) return;
|
|
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
|
|
invoker.charge = min(5.1,invoker.charge+0.5);
|
|
}
|
|
Default
|
|
{
|
|
Tag "GES Bio Rifle";
|
|
Inventory.PickupMessage "You got the GES BioRifle.";
|
|
Weapon.UpSound "ges/select";
|
|
Weapon.SlotNumber 3;
|
|
Weapon.AmmoType "BioAmmo";
|
|
Weapon.AmmoUse 1;
|
|
Weapon.AmmoType2 "BioAmmo";
|
|
Weapon.AmmoUse2 1;
|
|
Weapon.AmmoGive 25;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
BIOP A -1;
|
|
Stop;
|
|
BIOP B -1;
|
|
Stop;
|
|
Ready:
|
|
BIOS ABCDEFGHIJKLMNOPQRSTUV 1;
|
|
Idle:
|
|
BIOI A 1
|
|
{
|
|
A_CheckReload();
|
|
A_WeaponReady();
|
|
}
|
|
Goto Idle;
|
|
Fire:
|
|
BIOF A 1 A_BioFire();
|
|
BIOF BCDEFGHI 1;
|
|
Goto Idle;
|
|
AltFire:
|
|
BIOC A 4 A_BeginCharge();
|
|
BIOC B 5 A_ChargeUp();
|
|
BIOC CD 5;
|
|
BIOC E 0 A_Refire("AltFire2");
|
|
Goto AltRelease;
|
|
AltFire2:
|
|
BIOC E 5 A_ChargeUp();
|
|
BIOC FG 5;
|
|
BIOC H 0 A_Refire("AltFire3");
|
|
Goto AltRelease;
|
|
AltFire3:
|
|
BIOC H 5 A_ChargeUp();
|
|
BIOC IJ 5;
|
|
BIOC K 0 A_Refire("AltFire4");
|
|
Goto AltRelease;
|
|
AltFire4:
|
|
BIOC K 5 A_ChargeUp();
|
|
BIOC LM 5;
|
|
BIOC N 0 A_Refire("AltFire5");
|
|
Goto AltRelease;
|
|
AltFire5:
|
|
BIOC N 5 A_ChargeUp();
|
|
BIOC OP 5;
|
|
BIOC Q 0 A_Refire("AltFire6");
|
|
Goto AltRelease;
|
|
AltFire6:
|
|
BIOC Q 5 A_ChargeUp();
|
|
BIOC RS 5;
|
|
BIOC T 0 A_Refire("AltFire7");
|
|
Goto AltRelease;
|
|
AltFire7:
|
|
BIOC T 5 A_ChargeUp();
|
|
BIOC UV 5;
|
|
BIOC W 0 A_Refire("AltFire8");
|
|
Goto AltRelease;
|
|
AltFire8:
|
|
BIOC W 5 A_ChargeUp();
|
|
BIOC XY 5;
|
|
BIOC Z 0 A_Refire("AltFire9");
|
|
Goto AltRelease;
|
|
AltFire9:
|
|
BIOC Z 5 A_ChargeUp();
|
|
BIC2 AB 5;
|
|
BIC2 C 0 A_Refire("AltFire10");
|
|
Goto AltRelease;
|
|
AltFire10:
|
|
BIC2 C 5 A_ChargeUp();
|
|
BIC2 DE 5;
|
|
BIOM A 0 A_Refire("AltHeld");
|
|
Goto AltRelease;
|
|
AltHeld:
|
|
BIOM A 5 { invoker.charge = min(5.1,invoker.charge+0.1); }
|
|
BIOM A 0 A_Refire("AltHeld");
|
|
AltRelease:
|
|
BIOE A 1;
|
|
BIOF A 2 A_BioFire(true);
|
|
BIOF BCDEFGHI 2;
|
|
Goto Idle;
|
|
Select:
|
|
BIOS A 1 A_Raise(int.max);
|
|
Wait;
|
|
Deselect:
|
|
BIOD ABCDEFGHIJ 1;
|
|
BIOD J 1 A_Lower(int.max);
|
|
Wait;
|
|
}
|
|
} |