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(2.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_StartSound("uflak/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 = dt_Utility.ConeSpread(x,y,z,a,s); p.angle = atan2(dir.y,dir.x); p.pitch = -asin(dir.z); p.vel = dt_Utility.Vec3FromAngle(p.angle,p.pitch)*(p.speed+FRandom[Flak](-3,3)); p.target = target; } int numpt = Random[Flak](8,12); for ( int i=0; i 0 ) A_Loading(); } FLKL BCEFGIJKMNO 1; Goto Idle; AltLoading: FLKL A 2 { A_CheckReload(); if ( invoker.Ammo1.Amount > 0 ) A_Loading(); } FLKL BCEFGIJKMNO 2; 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_StartSound("uflak/click",CHAN_WEAPONMISC,CHANF_OVERLAP,Dampener.Active(self)?.05:.5); FLKE BCDEFGHIJKLMN 1; FLKE S 4 { Vector3 x, y, z, origin; [x,y,z] = dt_CoordUtil.GetAxes(pitch,angle,roll); origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),x*4.-y*3.-z*8.); let c = Spawn("UFlakMag",origin); c.angle = angle; c.pitch = pitch; c.vel = vel*.5+x*FRandom[Junk](-.8,.1)+y*FRandom[Junk](-.2,.2)-z*FRandom[Junk](1,2); } Goto Loading; AltFire: FLKA A 1 A_FireSlug(); FLKA BCDEFGHIJK 1; FLKA K 10; Goto AltLoading; 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;*/ } }