// enemies 'n stuff // Less mean-spirited Keen Class SWWMHangingKeen : Actor { action void A_DropKeen() { Spawn("SWWMDroppedKeen",Vec3Offset(0,0,8)); if ( target ) SWWMUtility.MarkAchievement("keen",target.player); } override bool Used( Actor user ) { // test vertical range Vector3 diff = level.Vec3Diff(user.Vec3Offset(0,0,user.Height/2),Vec3Offset(0,0,Height/2)); double rang = user.player?PlayerPawn(user.player.mo).UseRange:(user.Height/2); if ( abs(diff.z) > rang ) return false; if ( Health > 0 ) { DamageMobj(user,user,Health,'Untie',DMG_FORCED|DMG_THRUSTLESS); return true; } return false; } Default { Tag "$FN_KEEN"; Health 100; Radius 10; Height 54; Mass int.max; PainChance 256; +SOLID; +SPAWNCEILING; +NOGRAVITY; +SHOOTABLE; +NOICEDEATH; +DONTFALL; +NOBLOOD; +DONTTHRUST; } States { Spawn: KEE2 A -1; Stop; Death: KEE2 A 6 A_StartSound("newkeen/hit"); KEE2 B 6 A_DropKeen(); KEE2 C 6; KEE2 DE 6; KEE2 F 30; KEE2 F -1 A_KeenDie(); Stop; Pain: KEE2 G 4 A_StartSound("newkeen/hit"); KEE2 G 8; Goto Spawn; } } Class SWWMDroppedKeen : Actor { Default { Radius 10; Height 32; Gravity .5; +NOBLOCKMAP; } States { Spawn: KEE3 A 0 NoDelay { A_StartSound("newkeen/fall",volume:.5); A_StartSound("newkeen/die",CHAN_VOICE); } KEE3 A 1 A_JumpIf(pos.z<=floorz,1); Wait; KEE3 B 1 { A_StartSound("newkeen/bounce"); vel.z = 4; } KEE3 B 1 A_JumpIf(pos.z<=floorz,1); Wait; KEE3 B 1 { A_StartSound("newkeen/bounce",volume:.8); vel.z = 2; } KEE3 B 1 A_JumpIf(pos.z<=floorz,1); Wait; KEE3 B 12 A_StartSound("newkeen/bounce",volume:.6); TNT1 A 1 { Spawn("TeleportFog",pos,ALLOW_REPLACE); } Stop; } } Class SWWMBossBrainExpl : Actor { void A_Ignite() { A_QuakeEx(3,3,3,20,0,400,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,falloff:300,rollintensity:2.); A_StartSound("explodium/hit",CHAN_VOICE,CHANF_DEFAULT,.4,.5); Scale *= FRandom[ExploS](0.8,1.1); Scale.x *= RandomPick[ExploS](-1,1); Scale.y *= RandomPick[ExploS](-1,1); int numpt = Random[ExploS](8,16); for ( int i=0; i pos.y ) tntdir = true; } } void SpawnBrainExpl( bool death = false ) { if ( death ) { // big explosions throughout for ( int x=-350; x<=350; x+=10 ) { let s = Spawn("SWWMBossBrainExpl",Vec2OffsetZ(x,tntdir?280:-280,Random[BrainExplode](120,500))); s.tics = Random[BrainExplode](5,120); s.special1 = Random[BrainExplode](0,3); } return; } if ( level.maptime < smallcooldown ) return; smallcooldown = level.maptime+10; // small explosion on brain hole for ( int x=-40; x<=40; x+=20 ) { let s = Spawn("SWWMBossBrainExpl",Vec2OffsetZ(x,tntdir?280:-280,Random[BrainExplode](380,420))); s.tics = Random[BrainExplode](1,10); s.scale *= .5; } } // kill every single monster in the map, burn away spawn cubes, remove eyes // just let players have their 100% kills in peace void EverythingDies() { let ti = ThinkerIterator.Create("Actor"); Actor a; while ( a = Actor(ti.Next()) ) { if ( a is 'BossEye' ) a.SetStateLabel("Null"); else if ( a is 'SpawnShot' ) { a.Spawn("SpawnFire",a.pos,ALLOW_REPLACE); a.SetStateLabel("Null"); } else if ( (a.Health > 0) && (a.bBossSpawned || a.bCOUNTKILL) ) a.DamageMobj(self,self,a.Health,'EndMii',DMG_FORCED|DMG_THRUSTLESS); } } Default { Tag "$FN_BOSSBRAIN"; Radius 16; Height 32; +NOBLOOD; +CASTSPRITESHADOW; } States { Spawn: MBRN A -1; Stop; Pain: MBRN A 10 { A_StartSound("brain/pain",CHAN_VOICE,attenuation:ATTN_NONE); A_QuakeEx(3,3,3,15,0,65535,"",QF_RELATIVE|QF_SCALEDOWN,falloff:65535,rollIntensity:.3); if ( !eyeless ) SpawnBrainExpl(false); Spawn("SWWMBossBrainPain",pos); } Goto Spawn; Death: MBRN A 20 { A_SetTranslation('DeadOats'); A_StartSound("brain/death",CHAN_VOICE,attenuation:ATTN_NONE); A_QuakeEx(9,9,9,120,0,65535,"",QF_RELATIVE|QF_SCALEDOWN,falloff:65535,rollIntensity:1.); if ( !eyeless ) { SpawnBrainExpl(true); EverythingDies(); } Spawn("SWWMBossBrainPain",pos); } MBRN A 1 { A_FadeOut(.025,FTF_CLAMP); return A_JumpIf(alpha<=0,1); } Wait; MBRN A 80; MBRN A 1 A_BrainDie(); Stop; } } // MAP31/MAP32 wolfenstein enemies (rough DOS replication) Class SWWMGuard : Actor { Default { Scale 2; Health 20; Radius 25; Height 90; Speed 12; PainChance 170; Monster; +FLOORCLIP; SeeSound "wolf3d/guardsight"; DeathSound "wolf3d/guarddie"; AttackSound "wolf3d/guardfire"; Obituary "$OB_WOLFGUARD"; Tag "$FN_WOLFGUARD"; Species "WolfensteinSS"; DropItem "Clip"; } States { Spawn: XGRD A 5 A_Look; Wait; See: XGRD BBCCDDEE 2 A_Chase; Loop; Missile: XGRD FG 8 A_FaceTarget; XGRD H 0 A_StartSound(AttackSound,CHAN_WEAPON); XGRD H 8 Bright A_CustomBulletAttack(22.5,0,1,Random[PosAttack](1,5)*3,flags:CBAF_NORANDOM,spawnheight:64); Goto See; Pain: XGRD I 0 A_JumpIf(Health&1,2); XGRD I 2 A_Pain(); Goto See; XGRD J 2 A_Pain(); Goto See; Death: XGRD K 5; XGRD L 5 A_Scream(); XGRD M 5 A_NoBlocking(); XGRD N -1; Stop; } } Class SWWMSS : Actor { Default { Scale 2; Health 50; Radius 40; Height 112; Speed 12; PainChance 170; Monster; +FLOORCLIP; SeeSound "wolf3d/sssight"; DeathSound "wolf3d/ssdie"; AttackSound "wolf3d/ssfire"; Obituary "$OB_WOLFSS_ORIG"; Tag "$FN_WOLFSS_ORIG"; Species "WolfensteinSS"; DropItem "Clip"; } States { Spawn: XSSW W 5 A_Look; Wait; See: XSSW AABBCCDD 2 A_Chase; Loop; Missile: XSSW EF 5 A_FaceTarget(); XSSW G 0 A_StartSound(AttackSound,CHAN_WEAPON); XSSW G 2 Bright A_CustomBulletAttack(22.5,0,1,Random[CPosAttack](1,5)*3,flags:CBAF_NORANDOM,spawnheight:64); XSSW F 3 A_FaceTarget(); XSSW G 2 Bright A_CustomBulletAttack(22.5,0,1,Random[CPosAttack](1,5)*3,flags:CBAF_NORANDOM,spawnheight:64); XSSW F 3 A_FaceTarget(); XSSW G 2 Bright A_CustomBulletAttack(22.5,0,1,Random[CPosAttack](1,5)*3,flags:CBAF_NORANDOM,spawnheight:64); XSSW F 3 A_FaceTarget(); XSSW G 2 Bright A_CustomBulletAttack(22.5,0,1,Random[CPosAttack](1,5)*3,flags:CBAF_NORANDOM,spawnheight:64); Goto See; Pain: XSSW H 0 A_JumpIf(Health&1,2); XSSW H 2 A_Pain(); Goto See; XSSW I 2 A_Pain(); Goto See; Death: XSSW J 5; XSSW K 5 A_Scream(); XSSW L 5 A_NoBlocking(); XSSW M -1; Stop; } } Class SWWMHans : Actor { Default { Scale 2; Health 1200; Radius 40; Height 112; Mass 1000; Speed 12; Monster; MinMissileChance 160; +BOSS; +MISSILEMORE; +FLOORCLIP; +NORADIUSDMG; +DONTMORPH; +LOOKALLAROUND; AttackSound "wolf3d/hansfire"; DeathSound "wolf3d/hansdie"; SeeSound "wolf3d/hanssight"; Obituary "$OB_WOLFHANS"; Tag "$FN_WOLFHANS"; Species "WolfensteinSS"; } States { Spawn: XHNS A 5 A_Look(); Wait; See: XHNS AABBCCDD 2 A_Chase(); Loop; Missile: XHNS E 8 A_FaceTarget(); XHNS F 4 A_FaceTarget(); XHNS G 0 A_StartSound(AttackSound,CHAN_WEAPON); XHNS GFGFGE 3 Bright A_CustomBulletAttack(22.5,0,3,Random[CPosAttack](1,5)*3,flags:CBAF_NORANDOM,spawnheight:64); Goto See; Death: XHNS H 10; XHNS I 10 A_Scream(); XHNS J 10 A_NoBlocking(); XHNS K -1; Stop; } } Class SWWMDog : Actor { Default { Scale 2; Health 1; Speed 12; Radius 24; Height 56; Mass 100; Monster; AttackSound "wolf3d/dogbite"; DeathSound "wolf3d/dogdie"; SeeSound "wolf3d/dogsight"; Obituary "$OB_DOG"; Tag "$FN_DOG"; } States { Spawn: XDOG A 5 A_Look(); Wait; See: XDOG AABBCCDD 2 A_Chase(); Loop; Melee: XDOG EF 5 A_FaceTarget(); XDOG G 5 A_SargAttack(); XDOG EA 5; Goto See; Death: XDOG H 5; XDOG I 5 A_Scream(); XDOG J 5 A_NoBlocking(); XDOG K -1; Stop; } }