Class StingerAmmo : Ammo { Default { Tag "$T_STINGERAMMO"; Inventory.Icon "I_Stingr"; Inventory.PickupMessage ""; Inventory.Amount 5; Inventory.MaxAmount 200; Ammo.BackpackAmount 20; Ammo.BackpackMaxAmount 400; Ammo.DropAmount 2; } override String PickupMessage() { return String.Format("%s%d%s",StringTable.Localize("$I_STINGERAMMOL"),Amount,StringTable.Localize("$I_STINGERAMMOR")); } States { Spawn: SAMO A -1; Stop; } } Class StingerAmmo2 : StingerAmmo { Default { Tag "$T_STINGERAMMO2"; Inventory.Amount 40; Ammo.DropAmount 15; } States { Spawn: SAMO B -1; Stop; } } Class StingerBurstLight : PaletteLight { Default { Tag "Blue4"; Args 0,0,0,30; ReactionTime 12; } } Class StingerChunk : Actor { int deadtimer; double rollvel, anglevel, pitchvel; Default { Radius 2; Height 2; +NOBLOCKMAP; +MISSILE; +MOVEWITHSECTOR; +THRUACTORS; +NOTELEPORT; +DONTSPLASH; +INTERPOLATEANGLES; BounceType "Doom"; BounceFactor 0.4; Gravity 0.35; } override void PostBeginPlay() { Super.PostBeginPlay(); deadtimer = 0; anglevel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1); pitchvel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1); rollvel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1); frame = Random[Junk](0,8); scale *= Frandom[Junk](0.4,0.8); } override void Tick() { Super.Tick(); if ( isFrozen() ) return; if ( InStateSequence(CurState,ResolveState("Death")) ) { deadtimer++; if ( deadtimer > 60 ) A_FadeOut(0.05); return; } } States { Spawn: CHIP # 1 { angle += anglevel; pitch += pitchvel; roll += rollvel; } Loop; Bounce: CHIP # 0 { anglevel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1); pitchvel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1); rollvel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1); } Goto Spawn; Death: CHIP # -1; Stop; Dummy: CHIP ABCDEFGHI -1; Stop; } } Class ViewStingerChunk : StingerChunk { Vector3 ofs, vvel; Default { +NOCLIP; +NOGRAVITY; -MISSILE; BounceType "None"; } override void Tick() { Actor.Tick(); if ( !target || !target.player ) { Destroy(); return; } Vector3 x, y, z; [x, y, z] = dt_CoordUtil.GetAxes(target.pitch,target.angle,target.roll); Vector3 origin = x*ofs.x+y*ofs.y+z*ofs.z+(0,0,target.player.viewz); SetOrigin(target.Vec2OffsetZ(origin.x,origin.y,origin.z),true); bInvisible = (players[consoleplayer].camera != target); if ( isFrozen() ) return; ofs += vvel; scale *= 0.75; if ( scale.x <= 0.01 ) Destroy(); } } Class StingerProjectile : Actor { Default { Obituary "$O_STINGER"; DamageType 'Stinger'; DamageFunction Random[Stinger](15,25); Speed 40; Radius 2; Height 2; PROJECTILE; +SKYEXPLODE; } override int DoSpecialDamage( Actor target, int damage, Name damagetype ) { if ( !target.bNOBLOOD ) { target.SpawnBlood(pos,AngleTo(target),damage); A_PlaySound("stinger/flesh"); A_AlertMonsters(); } return damage; } action void A_StingerHit() { if ( !Random[Stinger](0,2) ) A_PlaySound("stinger/hit2",CHAN_BODY,0.5,pitch:FRandom[Stinger](0.5,1.5)); else A_PlaySound("stinger/hit",CHAN_BODY,0.6); A_SprayDecal("WallCrack",20); A_AlertMonsters(); Spawn("StingerBurstLight",pos); double ang, pt; int numpt = Random[Stinger](4,8); for ( int i=0; i