Assigned all pickup models. Implemented all ammo types. Finished Flak Cannon. Additional cleanup. Slot reassignments and other adjustments to match known Unreal prototype info.
364 lines
9.7 KiB
Text
364 lines
9.7 KiB
Text
Class UFlakBox : Ammo
|
|
{
|
|
Default
|
|
{
|
|
Tag "$T_FLAKAMMO";
|
|
Inventory.Icon "I_FlakAm";
|
|
Inventory.PickupMessage "";
|
|
Inventory.Amount 10;
|
|
Inventory.MaxAmount 50;
|
|
Ammo.BackpackAmount 5;
|
|
Ammo.BackpackMaxAmount 100;
|
|
Ammo.DropAmount 5;
|
|
}
|
|
override String PickupMessage()
|
|
{
|
|
if ( PickupMsg.Length() > 0 ) return Super.PickupMessage();
|
|
return String.Format("%s%d%s",StringTable.Localize("$I_FLAKAMMOL"),Amount,StringTable.Localize("$I_FLAKAMMOR"));
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
FAMO A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class UFlakAmmo : UFlakBox
|
|
{
|
|
Default
|
|
{
|
|
Tag "$T_FLAKAMMO2";
|
|
Inventory.Icon "I_FlakAm";
|
|
Inventory.PickupMessage "$I_FLAKAMMO2";
|
|
Inventory.Amount 1;
|
|
Ammo.DropAmount 1;
|
|
+INVENTORY.IGNORESKILL;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
FAMO B -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
// subclass to save time, much of the behavior is the same anyway
|
|
Class UFlakChunk : FlakChunk
|
|
{
|
|
override void PostBeginPlay()
|
|
{
|
|
Actor.PostBeginPlay();
|
|
// no trail, spin much slower
|
|
lifetime = 0;
|
|
rollvel = FRandom[Flak](5,10)*RandomPick[Flak](-1,1);
|
|
pitchvel = FRandom[Flak](5,10)*RandomPick[Flak](-1,1);
|
|
yawvel = FRandom[Flak](5,10)*RandomPick[Flak](-1,1);
|
|
scale *= Frandom[Flak](0.8,1.2);
|
|
SetState(ResolveState("Spawn")+Random[Flak](0,3));
|
|
}
|
|
override void Tick()
|
|
{
|
|
oldvel = vel;
|
|
Actor.Tick();
|
|
if ( isFrozen() ) return;
|
|
// no slowing down in water, only set to falling
|
|
if ( waterlevel > 0 )
|
|
{
|
|
bNOGRAVITY = false;
|
|
bAMBUSH = true;
|
|
}
|
|
lifetime += lifespeed;
|
|
// no frame changes, smoke based on speed + age
|
|
if ( (waterlevel <= 0) && !bAMBUSH && !(GetAge()%2) )
|
|
{
|
|
let s = Spawn("UTSmoke",pos);
|
|
s.vel = (FRandom[Flak](-0.1,0.1),FRandom[Flak](-0.1,0.1),FRandom[Flak](-0.1,0.1));
|
|
s.alpha = (scale.x*clamp((120-GetAge())/120.+(vel.length()/20.),0.5,2.0))/0.5;
|
|
s.SetShade("AAAAAA");
|
|
}
|
|
else if ( waterlevel > 0 )
|
|
{
|
|
let s = Spawn("UTBubble",pos);
|
|
s.vel = (FRandom[Flak](-0.1,0.1),FRandom[Flak](-0.1,0.1),FRandom[Flak](-0.1,0.1));
|
|
s.scale *= scale.x*0.5;
|
|
}
|
|
if ( InStateSequence(CurState,FindState("Death")) ) return;
|
|
roll += rollvel;
|
|
pitch += pitchvel;
|
|
angle += pitchvel;
|
|
}
|
|
Default
|
|
{
|
|
DamageFunction 17; // exactly 1 point higher than UT
|
|
Scale 0.5;
|
|
}
|
|
States
|
|
{
|
|
Bounce:
|
|
#### # 0
|
|
{
|
|
A_HandleBounce();
|
|
// override spin velocity changes from parent class
|
|
rollvel = FRandom[Flak](5,10)*RandomPick[Flak](-1,1);
|
|
pitchvel = FRandom[Flak](5,10)*RandomPick[Flak](-1,1);
|
|
yawvel = FRandom[Flak](5,10)*RandomPick[Flak](-1,1);
|
|
}
|
|
Goto Idle;
|
|
}
|
|
}
|
|
|
|
// Also subclassed to save time, only the explosion needs to change
|
|
Class UFlakSlug : FlakSlug
|
|
{
|
|
action void A_UFlakExplode()
|
|
{
|
|
bForceXYBillboard = true;
|
|
A_SetRenderStyle(1.0,STYLE_Add);
|
|
A_SprayDecal("RocketBlast",50);
|
|
A_NoGravity();
|
|
A_SetScale(1.2);
|
|
UTMainHandler.DoBlast(self,120,75000);
|
|
A_Explode(70,120);
|
|
A_QuakeEx(4,4,4,8,0,170,"",QF_RELATIVE|QF_SCALEDOWN,falloff:120,rollIntensity:0.2);
|
|
A_PlaySound("flak/explode",CHAN_VOICE);
|
|
A_AlertMonsters();
|
|
if ( !Tracer ) Spawn("SlugSmoke",pos);
|
|
Spawn("SlugLight",pos);
|
|
Vector3 x, y, z;
|
|
double a, s;
|
|
[x, y, z] = dt_CoordUtil.GetAxes(pitch,angle,roll);
|
|
Actor p;
|
|
Vector3 spawnofs;
|
|
if ( BlockingMobj ) spawnofs = level.Vec3Diff(pos,BlockingMobj.Vec3Offset(0,0,BlockingMobj.height/2)).unit()*8;
|
|
else if ( BlockingFloor ) spawnofs = BlockingFloor.floorplane.Normal*8;
|
|
else if ( BlockingCeiling ) spawnofs = BlockingCeiling.ceilingplane.Normal*8;
|
|
else if ( BlockingLine )
|
|
{
|
|
spawnofs = (-BlockingLine.delta.y,BlockingLine.delta.x,0).unit()*8;
|
|
if ( !BlockingLine.sidedef[1] || (CurSector == BlockingLine.frontsector) )
|
|
spawnofs *= -1;
|
|
}
|
|
for ( int i=0; i<5; i++ )
|
|
{
|
|
p = Spawn("UFlakChunk",Vec3Offset(spawnofs.x,spawnofs.y,spawnofs.z));
|
|
p.bHITOWNER = true;
|
|
a = FRandom[Flak](0,360);
|
|
s = FRandom[Flak](0,0.1);
|
|
Vector3 dir = (x+y*cos(a)*s+z*sin(a)*s).unit();
|
|
p.angle = atan2(dir.y,dir.x);
|
|
p.pitch = -asin(dir.z);
|
|
p.vel = (cos(p.angle)*cos(p.pitch),sin(p.angle)*cos(p.pitch),-sin(p.pitch))*(p.speed+FRandom[Flak](-3,3));
|
|
p.target = target;
|
|
}
|
|
int numpt = Random[Flak](8,12);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (FRandom[Flak](-1,1),FRandom[Flak](-1,1),FRandom[Flak](-1,1)).unit()*FRandom[Flak](2,8);
|
|
let s = Spawn("UTSpark",pos);
|
|
s.vel = pvel;
|
|
}
|
|
numpt = Random[Flak](15,30);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (FRandom[Flak](-1,1),FRandom[Flak](-1,1),FRandom[Flak](-1,1)).unit()*FRandom[Flak](6,16);
|
|
let s = Spawn("UTChip",pos);
|
|
s.vel = pvel;
|
|
s.scale *= FRandom[Flak](0.9,1.8);
|
|
}
|
|
}
|
|
States
|
|
{
|
|
Death:
|
|
FEXP A 0 A_UFlakExplode();
|
|
FEXP ABCDEFGHIJ 2 BRIGHT;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class UFlakCannon : UnrealWeapon
|
|
{
|
|
action void A_Loading( bool first = false )
|
|
{
|
|
if ( first ) A_PlaySound("flak/load",CHAN_WEAPON,Dampener.Active(self)?.1:1.);
|
|
else A_PlaySound("flak/reload",CHAN_6,Dampener.Active(self)?.06:.6);
|
|
}
|
|
action void A_FireChunks()
|
|
{
|
|
Weapon weap = Weapon(invoker);
|
|
if ( !weap ) return;
|
|
if ( weap.Ammo1.Amount <= 0 ) return;
|
|
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
|
|
A_PlaySound("flak/fire",CHAN_WEAPON,Dampener.Active(self)?.2:1.);
|
|
A_Overlay(PSP_FLASH,"Flash");
|
|
A_OverlayFlags(PSP_FLASH,PSPF_RenderStyle,true);
|
|
A_OverlayRenderstyle(PSP_FLASH,STYLE_Add);
|
|
invoker.FireEffect();
|
|
UTMainHandler.DoFlash(self,Color(48,255,96,0),1);
|
|
UTMainHandler.DoSwing(self,(FRandom[Flak](-0.3,-0.8),FRandom[Flak](-0.5,0.5)),4,-1.5,2,SWING_Spring,2,2);
|
|
if ( !Dampener.Active(self) ) A_AlertMonsters();
|
|
A_QuakeEx(1,1,1,3,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.05);
|
|
Vector3 x, y, z;
|
|
double a, s;
|
|
[x, y, z] = dt_CoordUtil.GetAxes(pitch,angle,roll);
|
|
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+5.0*y-4.0*z;
|
|
[x, y, z] = dt_CoordUtil.GetAxes(BulletSlope(),angle,roll);
|
|
Vector3 offsets[8]; // vanilla adds these to each chunk
|
|
offsets[0] = (0,0,0);
|
|
offsets[1] = -z;
|
|
offsets[2] = 2*y+z;
|
|
offsets[3] = -y;
|
|
offsets[4] = 2*y-z;
|
|
offsets[5] = (0,0,0);
|
|
offsets[6] = y-z;
|
|
offsets[7] = 2*y+z;
|
|
Actor p;
|
|
for ( int i=0; i<8; i++ )
|
|
{
|
|
p = Spawn("UFlakChunk",level.Vec3Offset(origin,offsets[i]));
|
|
a = FRandom[Flak](0,360);
|
|
s = FRandom[Flak](0,0.1);
|
|
Vector3 dir = (x+y*cos(a)*s+z*sin(a)*s).unit();
|
|
p.angle = atan2(dir.y,dir.x);
|
|
p.pitch = -asin(dir.z);
|
|
p.vel = (cos(p.angle)*cos(p.pitch),sin(p.angle)*cos(p.pitch),-sin(p.pitch))*(p.speed+FRandom[Flak](-3,3));
|
|
p.target = self;
|
|
}
|
|
int numpt = Random[Flak](20,30);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
let s = Spawn("UTViewSpark",origin);
|
|
UTViewSpark(s).ofs = (10,5,-4);
|
|
UTViewSpark(s).vvel = (FRandom[Flak](3,12),FRandom[Flak](-4,4),FRandom[Flak](-4,4));
|
|
s.target = self;
|
|
}
|
|
for ( int i=0; i<10; i++ )
|
|
{
|
|
let s = Spawn("UTViewSmoke",origin);
|
|
UTViewSmoke(s).ofs = (10,5,-4);
|
|
UTViewSmoke(s).vvel = (FRandom[Flak](0,1.2),FRandom[Flak](-.4,.4),FRandom[Flak](-.4,.4));
|
|
s.target = self;
|
|
s.scale *= 1.6;
|
|
s.alpha *= 0.5;
|
|
}
|
|
}
|
|
action void A_FireSlug()
|
|
{
|
|
Weapon weap = Weapon(invoker);
|
|
if ( !weap ) return;
|
|
if ( weap.Ammo1.Amount <= 0 ) return;
|
|
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
|
|
A_PlaySound("flak/altfire",CHAN_WEAPON,Dampener.Active(self)?.2:1.);
|
|
A_Overlay(PSP_FLASH,"Flash");
|
|
A_OverlayFlags(PSP_FLASH,PSPF_RenderStyle,true);
|
|
A_OverlayRenderstyle(PSP_FLASH,STYLE_Add);
|
|
invoker.FireEffect();
|
|
UTMainHandler.DoFlash(self,Color(32,255,96,0),1);
|
|
UTMainHandler.DoSwing(self,(FRandom[Flak](-0.4,-0.8),FRandom[Flak](0.4,0.8)),4,-1,3,SWING_Spring,3,5);
|
|
if ( !Dampener.Active(self) ) A_AlertMonsters();
|
|
A_QuakeEx(2,2,2,6,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1);
|
|
Vector3 x, y, z;
|
|
double a, s;
|
|
[x, y, z] = dt_CoordUtil.GetAxes(pitch,angle,roll);
|
|
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+5.0*y-4.0*z;
|
|
Actor p = Spawn("UFlakSlug",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;
|
|
int numpt = Random[Flak](10,15);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
let s = Spawn("UTViewSpark",origin);
|
|
UTViewSpark(s).ofs = (10,5,-4);
|
|
UTViewSpark(s).vvel = (FRandom[Flak](3,12),FRandom[Flak](-4,4),FRandom[Flak](-4,4));
|
|
s.target = self;
|
|
}
|
|
for ( int i=0; i<8; i++ )
|
|
{
|
|
let s = Spawn("UTViewSmoke",origin);
|
|
UTViewSmoke(s).ofs = (10,5,-4);
|
|
UTViewSmoke(s).vvel = (FRandom[Flak](0,1.2),FRandom[Flak](-.8,.8),FRandom[Flak](-.8,.8));
|
|
s.target = self;
|
|
s.scale *= 1.6;
|
|
s.alpha *= 0.5;
|
|
}
|
|
}
|
|
Default
|
|
{
|
|
Tag "$T_FLAKCANNON";
|
|
Inventory.PickupMessage "$I_FLAKCANNON";
|
|
Weapon.UpSound "flak/select";
|
|
Weapon.SlotNumber 6;
|
|
Weapon.SelectionOrder 4;
|
|
Weapon.AmmoType "UFlakBox";
|
|
Weapon.AmmoUse 1;
|
|
Weapon.AmmoType2 "UFlakBox";
|
|
Weapon.AmmoUse2 1;
|
|
Weapon.AmmoGive 10;
|
|
UTWeapon.DropAmmo 5;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
FPCK A -1;
|
|
Stop;
|
|
FPCK B -1;
|
|
Stop;
|
|
Select:
|
|
FLKS A 1 A_Raise(int.max);
|
|
Wait;
|
|
Ready:
|
|
FLKS ABCDFGHIKLMNPQRSUVWXZ 1 A_WeaponReady(WRF_NOFIRE);
|
|
FLS2 ABC 1 A_WeaponReady(WRF_NOFIRE);
|
|
FLKL A 1 A_Loading(true);
|
|
FLKL BCEFGIJKMNO 1;
|
|
Goto Idle;
|
|
Loading:
|
|
FLKL A 1
|
|
{
|
|
A_CheckReload();
|
|
if ( invoker.Ammo1.Amount > 0 ) A_Loading();
|
|
}
|
|
FLKL BCEFGIJKMNO 1;
|
|
Goto Idle;
|
|
Idle:
|
|
FLKI A 1 A_WeaponReady();
|
|
Wait;
|
|
Fire:
|
|
FLKF A 1 A_FireChunks();
|
|
FLKF BCDEFGHI 1;
|
|
FLKF J 5;
|
|
FLKE A 1 A_PlaySound("flak/click",CHAN_6,Dampener.Active(self)?.05:.5);
|
|
FLKE BCDEFGHIJKLMN 1;
|
|
FLKE S 4;
|
|
Goto Loading;
|
|
AltFire:
|
|
FLKA A 1 A_FireSlug();
|
|
FLKA BCDEFGHIJK 1;
|
|
FLKA K 10;
|
|
Goto Loading;
|
|
Deselect:
|
|
FLKD A 0 A_JumpIfNoAmmo("Deselect2");
|
|
FLKD ABCDEF 1;
|
|
FLKD F 1 A_Lower(int.max);
|
|
Wait;
|
|
Deselect2:
|
|
FLD2 ABCDEF 1;
|
|
FLD2 F 1 A_Lower(int.max);
|
|
Wait;
|
|
Flash:
|
|
FMUZ A 3 Bright
|
|
{
|
|
let l = Spawn("FlakLight",pos);
|
|
l.target = self;
|
|
}
|
|
Stop;
|
|
/*Flash:
|
|
FLFF ABCDEFGHIJ 1 Bright;
|
|
Stop;
|
|
AltFlash:
|
|
FLFA ABCDEF 1 Bright;
|
|
Stop;*/
|
|
}
|
|
}
|