mirror of
https://github.com/DrBeef/Raze.git
synced 2024-12-15 07:01:21 +00:00
9e3318a2fb
.def is not the right place for this - it needs to run very early in the process, before scripted actors are loaded, so doing this stuff there means that half the initialization has to be postponed and error reporting is sub-par. These are now part of RMAPINFO which gets parsed as one of the very last things - it is also where GZDoom is doing some of these things. The better error reporting also allowed fixing some errors in these definitions.
409 lines
9.1 KiB
Text
409 lines
9.1 KiB
Text
class DukeGreenSlime : DukeActor
|
|
{
|
|
default
|
|
{
|
|
spriteset "GREENSLIME", "GREENSLIME1", "GREENSLIME2", "GREENSLIME3", "GREENSLIME4", "GREENSLIME5", "GREENSLIME6", "GREENSLIME7";
|
|
scaleX 0.625;
|
|
scaleY 0.625;
|
|
clipdist 20;
|
|
extra 1;
|
|
}
|
|
|
|
override void Initialize()
|
|
{
|
|
commonEnemySetup();
|
|
}
|
|
|
|
override void PlayFTASound()
|
|
{
|
|
self.PlayActorSound("SLIM_RECOG");
|
|
}
|
|
|
|
|
|
override void Tick()
|
|
{
|
|
let sectp = self.sector;
|
|
int j;
|
|
|
|
self.temp_data[1] += 128;
|
|
|
|
if (sectp.floorstat & CSTAT_SECTOR_SKY)
|
|
{
|
|
self.Destroy();
|
|
return;
|
|
}
|
|
|
|
double xx;
|
|
DukePlayer p;
|
|
[p, xx] = self.findplayer();
|
|
let pactor = p.actor;
|
|
|
|
if (xx > 1280)
|
|
{
|
|
self.timetosleep++;
|
|
if (self.timetosleep > Duke.SLEEPTIME)
|
|
{
|
|
self.timetosleep = 0;
|
|
self.ChangeStat(STAT_ZOMBIEACTOR);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (self.temp_data[0] == -5) // FROZEN
|
|
{
|
|
self.temp_data[3]++;
|
|
if (self.temp_data[3] > 280)
|
|
{
|
|
self.pal = 0;
|
|
self.temp_data[0] = 0;
|
|
return;
|
|
}
|
|
self.makeitfall();
|
|
self.cstat = CSTAT_SPRITE_BLOCK_ALL;
|
|
self.setSpriteSetImage(2);
|
|
self.extra = 1;
|
|
self.pal = 1;
|
|
j = self.ifhitbyweapon();
|
|
if (j >= 0)
|
|
{
|
|
if (self.attackerflag2(SFLAG2_FREEZEDAMAGE))
|
|
return;
|
|
for (j = 16; j >= 0; j--)
|
|
{
|
|
let a = frandom(0, 360);
|
|
let vel = frandom(0, 2) + 2;
|
|
let zvel = 4 - frandom(0, 4);
|
|
|
|
static const name pieces[] = {'DukeGlassPieces', 'DukeGlassPieces1', 'DukeGlassPieces2'};
|
|
let k = dlevel.SpawnActor(self.sector, self.pos, pieces[j % 3], -32, (0.5625, 0.5625), a, vel, zvel, self, STAT_MISC);
|
|
if (k) k.pal = 1;
|
|
}
|
|
p.actors_killed++;
|
|
self.PlayActorSound("GLASS_BREAKING");
|
|
self.Destroy();
|
|
}
|
|
else if (xx < 64 && p.quick_kick == 0)
|
|
{
|
|
let ang = absangle(pactor.angle, (self.pos.XY - pactor.pos.XY).Angle());
|
|
if (ang < 22.5)
|
|
p.quick_kick = 14;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (xx < 99.75)
|
|
self.cstat = 0;
|
|
else self.cstat = CSTAT_SPRITE_BLOCK_ALL;
|
|
|
|
if (self.temp_data[0] == -4) //On the player
|
|
{
|
|
if (pactor.extra < 1)
|
|
{
|
|
self.temp_data[0] = 0;
|
|
return;
|
|
}
|
|
|
|
self.SetPosition(self.pos);
|
|
|
|
self.angle = pactor.angle;
|
|
|
|
if ((p.PlayerInput(Duke.SB_FIRE) || (p.quick_kick > 0)) && pactor.extra > 0)
|
|
if (p.quick_kick > 0 || (p.curr_weapon != DukeWpn.HANDREMOTE_WEAPON && p.curr_weapon != DukeWpn.HANDBOMB_WEAPON && p.curr_weapon != DukeWpn.TRIPBOMB_WEAPON && p.ammo_amount[p.curr_weapon] >= 0))
|
|
{
|
|
for (int x = 0; x < 8; x++)
|
|
{
|
|
let a = frandom(0, 360);
|
|
let vel = frandom(0, 4) + 4;
|
|
let zvel = -frandom(0, 16) - self.vel.Z * 0.25;
|
|
|
|
let spawned = dlevel.SpawnActor(self.sector, self.pos.plusZ(-8), "DukeScrap", -8, (0.75, 0.75), a, vel, zvel, self, STAT_MISC);
|
|
if (spawned)
|
|
{
|
|
if (spawned) spawned.spriteextra = DukeScrap.Scrap3 + random(0, 3);
|
|
spawned.pal = 6;
|
|
}
|
|
}
|
|
|
|
self.PlayActorSound("SLIM_DYING");
|
|
self.PlayActorSound("SQUISHED");
|
|
if (random(0, 255) < 32)
|
|
{
|
|
let spawned = self.spawn("DukeBloodPool");
|
|
if (spawned) spawned.pal = 0;
|
|
}
|
|
p.actors_killed++;
|
|
self.temp_data[0] = -3;
|
|
if (p.somethingonplayer == self)
|
|
p.somethingonplayer = nullptr;
|
|
self.Destroy();
|
|
return;
|
|
}
|
|
|
|
self.pos.Z = pactor.pos.Z + pactor.viewzoffset + 8 + p.pyoff - (self.temp_data[2] + tan(pactor.pitch) * 2048.) * zmaptoworld;
|
|
|
|
if (self.temp_data[2] > 512)
|
|
self.temp_data[2] -= 128;
|
|
|
|
if (self.temp_data[2] < 348)
|
|
self.temp_data[2] += 128;
|
|
|
|
if (p.newOwner != nullptr)
|
|
{
|
|
p.newOwner = nullptr;
|
|
pactor.restoreloc();
|
|
|
|
p.cursector = Raze.updatesector(pactor.pos.XY, p.cursector);
|
|
|
|
DukeStatIterator it;
|
|
for (let ac = it.First(STAT_ACTOR); ac; ac = it.Next())
|
|
{
|
|
if (ac.actorflag2(SFLAG2_CAMERA)) ac.yint = 0;
|
|
}
|
|
}
|
|
|
|
if (self.temp_data[3] > 0)
|
|
{
|
|
static const int frames[] = { 5,5,6,6,7,7,6,5 };
|
|
|
|
self.setSpriteSetImage(frames[self.temp_data[3]]);
|
|
|
|
if (self.temp_data[3] == 5)
|
|
{
|
|
let psp = pactor;
|
|
psp.extra -= random(5, 8);
|
|
self.PlayActorSound("SLIM_ATTACK");
|
|
}
|
|
|
|
if (self.temp_data[3] < 7) self.temp_data[3]++;
|
|
else self.temp_data[3] = 0;
|
|
|
|
}
|
|
else
|
|
{
|
|
self.setSpriteSetImage(5);
|
|
if (Duke.rnd(32))
|
|
self.temp_data[3] = 1;
|
|
}
|
|
|
|
double add = (Raze.BobVal(self.temp_data[1]) * 2) * REPEAT_SCALE;
|
|
self.scale = (0.3125 + add, 0.234375 + add);
|
|
self.pos.XY = pactor.pos.XY + pactor.angle.ToVector() * 8;
|
|
return;
|
|
}
|
|
|
|
else if (self.vel.X < 4 && xx < 48)
|
|
{
|
|
if (p.somethingonplayer == nullptr)
|
|
{
|
|
p.somethingonplayer = self;
|
|
if (self.temp_data[0] == 3 || self.temp_data[0] == 2) //Falling downward
|
|
self.temp_data[2] = (12 << 8);
|
|
else self.temp_data[2] = -(13 << 8); //Climbing up duke
|
|
self.temp_data[0] = -4;
|
|
}
|
|
}
|
|
|
|
j = self.ifhitbyweapon();
|
|
if (j >= 0)
|
|
{
|
|
self.PlayActorSound("SLIM_DYING");
|
|
|
|
if (p.somethingonplayer == self)
|
|
p.somethingonplayer = nullptr;
|
|
|
|
if (self.attackerflag2(SFLAG2_FREEZEDAMAGE))
|
|
{
|
|
self.PlayActorSound("SOMETHINGFROZE");
|
|
self.temp_data[0] = -5; self.temp_data[3] = 0;
|
|
return;
|
|
}
|
|
p.actors_killed++;
|
|
|
|
if (random(0, 255) < 32)
|
|
{
|
|
let spawned = self.spawn("DukeBloodPool");
|
|
if (spawned) spawned.pal = 0;
|
|
}
|
|
|
|
for (int x = 0; x < 8; x++)
|
|
{
|
|
let a = frandom(0, 360);
|
|
let vel = frandom(0, 4) + 4;
|
|
let zvel = -frandom(0, 16) - self.vel.Z * 0.25;
|
|
|
|
let spawned = dlevel.SpawnActor(self.sector, self.pos.plusZ(-8), "DukeScrap", -8, (0.75, 0.75), a, vel, zvel, self, STAT_MISC);
|
|
if (spawned)
|
|
{
|
|
spawned.spriteextra = DukeScrap.Scrap3 + random(0, 3);
|
|
spawned.pal = 6;
|
|
}
|
|
}
|
|
self.temp_data[0] = -3;
|
|
self.Destroy();
|
|
return;
|
|
}
|
|
// All weap
|
|
if (self.temp_data[0] == -1) //Shrinking down
|
|
{
|
|
self.makeitfall();
|
|
|
|
self.cstat &= ~CSTAT_SPRITE_YFLIP;
|
|
self.setSpriteSetImage(4);
|
|
|
|
if (self.scale.X > 0.5 ) self.scale.X += (-random(0, 7)) * REPEAT_SCALE;
|
|
if (self.scale.Y > 0.25 ) self.scale.Y += (-random(0, 7)) * REPEAT_SCALE;
|
|
else
|
|
{
|
|
self.scale = (0.625, 0.25);
|
|
self.temp_actor = nullptr;
|
|
self.temp_data[0] = 0;
|
|
}
|
|
|
|
return;
|
|
}
|
|
else if (self.temp_data[0] != -2) self.getglobalz();
|
|
|
|
if (self.temp_data[0] == -2) //On top of somebody (an enemy)
|
|
{
|
|
DukeActor s5 = self.temp_actor;
|
|
self.makeitfall();
|
|
if (s5)
|
|
{
|
|
s5.vel.X = 0;
|
|
|
|
self.pos = s5.pos + s5.angle.ToVector() * 0.5;
|
|
self.setspriteSetImage(Duke.global_random() & 1);
|
|
|
|
if (self.scale.Y < 1) self.scale.Y += (0.03125);
|
|
else
|
|
{
|
|
if (self.scale.X < 0.5) self.scale.X += (0.0625);
|
|
else
|
|
{
|
|
self.temp_data[0] = -1;
|
|
double dist = (self.pos.XY - s5.pos.XY).LengthSquared();
|
|
if (dist < 48*48) {
|
|
s5.scale.X = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
//Check randomly to see of there is an actor near
|
|
if (Duke.rnd(32))
|
|
{
|
|
DukeSectIterator it;
|
|
for (let a2 = it.First(self.sector); a2; a2 = it.Next())
|
|
{
|
|
if (a2.actorflag1(SFLAG_GREENSLIMEFOOD))
|
|
{
|
|
double dist = (self.pos.XY - a2.pos.XY).LengthSquared();
|
|
if (dist < 48*48 && (abs(self.pos.Z - a2.pos.Z) < 16)) //Gulp them
|
|
{
|
|
self.temp_actor = a2;
|
|
self.temp_data[0] = -2;
|
|
self.temp_data[1] = 0;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//Moving on the ground or ceiling
|
|
|
|
if (self.temp_data[0] == 0 || self.temp_data[0] == 2)
|
|
{
|
|
self.setspriteSetImage(0);
|
|
|
|
if (random(0, 511) == 0)
|
|
self.PlayActorSound("SLIM_ROAM");
|
|
|
|
if (self.temp_data[0] == 2)
|
|
{
|
|
self.vel.Z = 0;
|
|
self.cstat &= ~CSTAT_SPRITE_YFLIP;
|
|
|
|
if ((sectp.ceilingstat & CSTAT_SECTOR_SKY) || (self.ceilingz + 24) < self.pos.Z)
|
|
{
|
|
self.pos.Z += 8;
|
|
self.temp_data[0] = 3;
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
self.cstat |= CSTAT_SPRITE_YFLIP;
|
|
self.makeitfall();
|
|
}
|
|
|
|
if (PlayClock & 4) self.DoMove(CLIPMASK0);
|
|
|
|
if (self.vel.X > 6)
|
|
{
|
|
self.vel.X -= 1/8.;
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
if (self.vel.X < 2) self.vel.X += 0.25;
|
|
self.vel.X = 4 - Raze.BobVal(512 + self.temp_data[1]) * 2;
|
|
self.angle += deltaangle(self.angle, (pactor.pos.XY - self.pos.XY).Angle()) * 0.125;
|
|
// TJR
|
|
}
|
|
|
|
self.scale.X = (0.5625 + Raze.BobVal(512 + self.temp_data[1]) * 0.125);
|
|
self.scale.Y = (0.25 + Raze.BobVal(self.temp_data[1]) * 0.03125);
|
|
|
|
if (Duke.rnd(4) && (sectp.ceilingstat & CSTAT_SECTOR_SKY) == 0 &&
|
|
abs(self.floorz - self.ceilingz) < 192)
|
|
{
|
|
self.vel.Z = 0;
|
|
self.temp_data[0]++;
|
|
}
|
|
|
|
}
|
|
|
|
if (self.temp_data[0] == 1)
|
|
{
|
|
self.setspriteSetImage(0);
|
|
if (self.scale.Y < 0.625) self.scale.Y += (0.125);
|
|
if (self.scale.X > 0.125 ) self.scale.X += (-0.0625);
|
|
if (self.vel.Z > -12)
|
|
self.vel.Z -= 348 / 256.;
|
|
self.pos.Z += self.vel.Z;
|
|
if (self.pos.Z < self.ceilingz + 16)
|
|
{
|
|
self.pos.Z = self.ceilingz + 16;
|
|
self.vel.X = 0;
|
|
self.temp_data[0] = 2;
|
|
}
|
|
}
|
|
|
|
if (self.temp_data[0] == 3)
|
|
{
|
|
self.setspriteSetImage(1);
|
|
self.makeitfall();
|
|
|
|
if (self.pos.Z > self.floorz - 8)
|
|
{
|
|
self.scale.Y += (-0.0625);
|
|
self.scale.X += (0.03125);
|
|
}
|
|
else
|
|
{
|
|
if (self.scale.Y < 0.5625) self.scale.Y += (0.125);
|
|
if (self.scale.X > 0.125 ) self.scale.X += (-0.0625);
|
|
}
|
|
|
|
if (self.pos.Z > self.floorz - 8)
|
|
{
|
|
self.pos.Z = self.floorz - 8;
|
|
self.temp_data[0] = 0;
|
|
self.vel.X = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|