520 lines
10 KiB
Text
520 lines
10 KiB
Text
// 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<numpt; i++ )
|
|
{
|
|
Vector3 pvel = SWWMUtility.Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90))*FRandom[ExploS](1,6);
|
|
let s = Spawn("SWWMSmoke",pos);
|
|
s.vel = pvel;
|
|
s.SetShade(Color(1,1,1)*Random[ExploS](64,224));
|
|
s.special1 = Random[ExploS](1,4);
|
|
s.scale *= 2.8;
|
|
s.alpha *= .4;
|
|
}
|
|
numpt = Random[ExploS](5,10);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = SWWMUtility.Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90))*FRandom[ExploS](2,12);
|
|
let s = Spawn("SWWMSpark",pos);
|
|
s.vel = pvel;
|
|
}
|
|
numpt = Random[ExploS](10,15);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = SWWMUtility.Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90))*FRandom[ExploS](2,24);
|
|
let s = Spawn("SWWMChip",pos);
|
|
s.vel = pvel;
|
|
}
|
|
numpt = int(Random[ExploS](-1,2)+special1);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
let s = Spawn("SWWMBossBrainExplArm",pos);
|
|
s.target = target;
|
|
}
|
|
}
|
|
Default
|
|
{
|
|
RenderStyle "Add";
|
|
Scale 2.5;
|
|
Radius .1;
|
|
Height 0.;
|
|
+NOGRAVITY;
|
|
+NOBLOCKMAP;
|
|
+NOINTERACTION;
|
|
+DONTSPLASH;
|
|
+NOTELEPORT;
|
|
+FORCEXYBILLBOARD;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
TNT1 A 10;
|
|
TNT1 A 0 A_Ignite();
|
|
XEX1 ABCDEFGHIJKLMNOPQRSTUVWXYZ[\] 1 Bright;
|
|
Stop;
|
|
}
|
|
}
|
|
Class SWWMBossBrainExplArm : Actor
|
|
{
|
|
Default
|
|
{
|
|
PROJECTILE;
|
|
+THRUACTORS;
|
|
+BOUNCEONWALLS;
|
|
+BOUNCEONFLOORS;
|
|
+BOUNCEONCEILINGS;
|
|
-NOGRAVITY;
|
|
Gravity 0.35;
|
|
BounceFactor 1.0;
|
|
Radius 4;
|
|
Height 4;
|
|
}
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
reactiontime = Random[ExploS](10,15);
|
|
double ang, pt;
|
|
ang = FRandom[ExploS](0,360);
|
|
pt = FRandom[ExploS](-90,90);
|
|
vel = SWWMUtility.Vec3FromAngles(ang,pt)*FRandom[ExploS](8.,20.);
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
TNT1 A 1
|
|
{
|
|
A_CountDown();
|
|
Spawn("ExplodiumMagTrail",pos);
|
|
Vector3 pvel = SWWMUtility.Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90))*FRandom[ExploS](1,5);
|
|
let s = Spawn("SWWMHalfSmoke",pos);
|
|
s.vel = pvel+vel*.2;
|
|
s.SetShade(Color(1,1,1)*Random[ExploS](64,224));
|
|
s.special1 = Random[ExploS](1,3);
|
|
s.scale *= 2.4;
|
|
s.alpha *= 0.1+.4*(ReactionTime/15.);
|
|
}
|
|
Wait;
|
|
}
|
|
}
|
|
Class SWWMBossBrainPain : Actor
|
|
{
|
|
Default
|
|
{
|
|
RenderStyle "Add";
|
|
Radius .1;
|
|
Height 0.;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
MBRN B 1 Bright A_FadeOut(.05);
|
|
Wait;
|
|
}
|
|
}
|
|
Class SWWMBossBrain : BossBrain
|
|
{
|
|
bool eyeless;
|
|
bool tntdir;
|
|
int smallcooldown;
|
|
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
let ti = ThinkerIterator.Create("BossEye");
|
|
Actor eye;
|
|
if ( eye = Actor(ti.Next()) ) eyeless = false;
|
|
else eyeless = true;
|
|
if ( !eyeless )
|
|
{
|
|
// proper boss
|
|
bCOUNTKILL = true;
|
|
level.total_monsters++;
|
|
// check if the eye is to the north of us (TNT MAP30)
|
|
if ( eye.pos.y > 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;
|
|
}
|
|
}
|