mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-15 00:42:08 +00:00
- scriptified the green slimer.
This commit is contained in:
parent
bc34746227
commit
ff6a9b89ac
24 changed files with 524 additions and 477 deletions
|
@ -715,6 +715,7 @@ DEFINE_FIELD_NAMED(DCoreActor, sprext.alpha, alpha)
|
|||
DEFINE_FIELD_NAMED(DCoreActor, time, spawnindex)
|
||||
DEFINE_FIELD(DCoreActor, spritesetindex)
|
||||
DEFINE_FIELD_NAMED(DCoreActor, spr.Angles.Yaw, angle)
|
||||
DEFINE_FIELD_NAMED(DCoreActor, spr.Angles.Pitch, pitch)
|
||||
DEFINE_FIELD(DCoreActor, vel)
|
||||
DEFINE_FIELD(DCoreActor, viewzoffset)
|
||||
DEFINE_FIELD(DCoreActor, opos)
|
||||
|
|
|
@ -909,8 +909,7 @@ void glasspieces(DDukeActor* actor)
|
|||
if(actor->vel.X > 0)
|
||||
{
|
||||
actor->vel.X -= 1/8.;
|
||||
static const ESpriteFlags flips[] = { 0, CSTAT_SPRITE_XFLIP, CSTAT_SPRITE_YFLIP, CSTAT_SPRITE_XFLIP | CSTAT_SPRITE_YFLIP };
|
||||
actor->spr.cstat = flips[int(actor->vel.X * 16) & 3];
|
||||
actor->spr.cstat = randomFlip();
|
||||
}
|
||||
else actor->vel.X = 0;
|
||||
|
||||
|
@ -3580,8 +3579,13 @@ void movefta(void)
|
|||
|
||||
auto check_fta_sounds = [](DDukeActor* act)
|
||||
{
|
||||
if (isRR()) check_fta_sounds_r(act);
|
||||
else check_fta_sounds_d(act);
|
||||
if (act->GetClass() == RUNTIME_CLASS(DDukeActor))
|
||||
{
|
||||
if (isRR()) check_fta_sounds_r(act);
|
||||
else check_fta_sounds_d(act);
|
||||
}
|
||||
else
|
||||
CallPlayFTASound(act);
|
||||
};
|
||||
|
||||
DukeStatIterator it(STAT_ZOMBIEACTOR);
|
||||
|
|
|
@ -108,9 +108,6 @@ void check_fta_sounds_d(DDukeActor* actor)
|
|||
S_PlaySound(BOS4_RECOG);
|
||||
S_PlaySound(BOSS4_FIRSTSEE);
|
||||
break;
|
||||
case GREENSLIME:
|
||||
S_PlayActorSound(SLIM_RECOG, actor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -945,22 +942,7 @@ void movetransports_d(void)
|
|||
break;
|
||||
|
||||
case STAT_ACTOR:
|
||||
switch (act2->spr.picnum)
|
||||
{
|
||||
case SHARK:
|
||||
case COMMANDER:
|
||||
case OCTABRAIN:
|
||||
case GREENSLIME:
|
||||
case GREENSLIME + 1:
|
||||
case GREENSLIME + 2:
|
||||
case GREENSLIME + 3:
|
||||
case GREENSLIME + 4:
|
||||
case GREENSLIME + 5:
|
||||
case GREENSLIME + 6:
|
||||
case GREENSLIME + 7:
|
||||
if (act2->spr.extra > 0)
|
||||
continue;
|
||||
}
|
||||
if (actorflag(act, SFLAG3_DONTDIVEALIVE) && act2->spr.extra > 0) continue;
|
||||
[[fallthrough]];
|
||||
case STAT_PROJECTILE:
|
||||
case STAT_MISC:
|
||||
|
@ -1090,399 +1072,6 @@ void movetransports_d(void)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static void greenslime(DDukeActor *actor)
|
||||
{
|
||||
auto sectp = actor->sector();
|
||||
int j;
|
||||
|
||||
if (monsterCheatCheck(actor)) return;
|
||||
|
||||
actor->temp_data[1] += 128;
|
||||
|
||||
if (sectp->floorstat & CSTAT_SECTOR_SKY)
|
||||
{
|
||||
actor->Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
double xx;
|
||||
int p = findplayer(actor, &xx);
|
||||
|
||||
if (xx > 1280)
|
||||
{
|
||||
actor->timetosleep++;
|
||||
if (actor->timetosleep > SLEEPTIME)
|
||||
{
|
||||
actor->timetosleep = 0;
|
||||
ChangeActorStat(actor, STAT_ZOMBIEACTOR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (actor->temp_data[0] == -5) // FROZEN
|
||||
{
|
||||
actor->temp_data[3]++;
|
||||
if (actor->temp_data[3] > 280)
|
||||
{
|
||||
actor->spr.pal = 0;
|
||||
actor->temp_data[0] = 0;
|
||||
return;
|
||||
}
|
||||
makeitfall(actor);
|
||||
actor->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
|
||||
actor->spr.picnum = GREENSLIME + 2;
|
||||
actor->spr.extra = 1;
|
||||
actor->spr.pal = 1;
|
||||
j = fi.ifhitbyweapon(actor);
|
||||
if (j >= 0)
|
||||
{
|
||||
if (j == FREEZEBLAST)
|
||||
return;
|
||||
for (j = 16; j >= 0; j--)
|
||||
{
|
||||
auto a = randomAngle();
|
||||
auto vel = krandf(2) + 2;
|
||||
auto zvel = 4 - krandf(4);
|
||||
|
||||
auto k = CreateActor(actor->sector(), actor->spr.pos, GLASSPIECES + (j % 3), -32, DVector2(0.5625, 0.5625), a, vel, zvel, actor, 5);
|
||||
k->spr.pal = 1;
|
||||
}
|
||||
ps[p].actors_killed++;
|
||||
S_PlayActorSound(GLASS_BREAKING, actor);
|
||||
actor->Destroy();
|
||||
}
|
||||
else if (xx < 64 && ps[p].quick_kick == 0)
|
||||
{
|
||||
auto ang = absangle(ps[p].GetActor()->spr.Angles.Yaw, (actor->spr.pos.XY() - ps[p].GetActor()->spr.pos.XY()).Angle());
|
||||
if (ang < DAngle22_5)
|
||||
ps[p].quick_kick = 14;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (xx < 99.75)
|
||||
actor->spr.cstat = 0;
|
||||
else actor->spr.cstat = CSTAT_SPRITE_BLOCK_ALL;
|
||||
|
||||
if (actor->temp_data[0] == -4) //On the player
|
||||
{
|
||||
if (ps[p].GetActor()->spr.extra < 1)
|
||||
{
|
||||
actor->temp_data[0] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
SetActor(actor, actor->spr.pos);
|
||||
|
||||
actor->spr.Angles.Yaw = ps[p].GetActor()->spr.Angles.Yaw;
|
||||
|
||||
if ((PlayerInput(p, SB_FIRE) || (ps[p].quick_kick > 0)) && ps[p].GetActor()->spr.extra > 0)
|
||||
if (ps[p].quick_kick > 0 || (ps[p].curr_weapon != HANDREMOTE_WEAPON && ps[p].curr_weapon != HANDBOMB_WEAPON && ps[p].curr_weapon != TRIPBOMB_WEAPON && ps[p].ammo_amount[ps[p].curr_weapon] >= 0))
|
||||
{
|
||||
for (int x = 0; x < 8; x++)
|
||||
{
|
||||
auto a = randomAngle();
|
||||
auto vel = krandf(4) + 4;
|
||||
auto zvel = -krandf(16) - actor->vel.Z * 0.25;
|
||||
|
||||
auto spawned = CreateActor(actor->sector(), actor->spr.pos.plusZ(-8), PClass::FindActor("DukeScrap"), -8, DVector2(0.75, 0.75), a, vel, zvel, actor, STAT_MISC);
|
||||
if (spawned)
|
||||
{
|
||||
if (spawned) spawned->spriteextra = Scrap3 + (krand() & 3);
|
||||
spawned->spr.pal = 6;
|
||||
}
|
||||
}
|
||||
|
||||
S_PlayActorSound(SLIM_DYING, actor);
|
||||
S_PlayActorSound(SQUISHED, actor);
|
||||
if ((krand() & 255) < 32)
|
||||
{
|
||||
auto spawned = spawn(actor, BLOODPOOL);
|
||||
if (spawned) spawned->spr.pal = 0;
|
||||
}
|
||||
ps[p].actors_killed++;
|
||||
actor->temp_data[0] = -3;
|
||||
if (ps[p].somethingonplayer == actor)
|
||||
ps[p].somethingonplayer = nullptr;
|
||||
actor->Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
actor->spr.pos.Z = ps[p].GetActor()->getOffsetZ() + 8 + ps[p].pyoff - (actor->temp_data[2] + (ps[p].GetActor()->spr.Angles.Pitch.Tan() * 2048.)) * zinttoworld;
|
||||
|
||||
if (actor->temp_data[2] > 512)
|
||||
actor->temp_data[2] -= 128;
|
||||
|
||||
if (actor->temp_data[2] < 348)
|
||||
actor->temp_data[2] += 128;
|
||||
|
||||
if (ps[p].newOwner != nullptr)
|
||||
{
|
||||
ps[p].newOwner = nullptr;
|
||||
ps[p].GetActor()->restoreloc();
|
||||
|
||||
updatesector(ps[p].GetActor()->getPosWithOffsetZ(), &ps[p].cursector);
|
||||
|
||||
DukeStatIterator it(STAT_ACTOR);
|
||||
while (auto ac = it.Next())
|
||||
{
|
||||
if (actorflag(ac, SFLAG2_CAMERA)) ac->spr.yint = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (actor->temp_data[3] > 0)
|
||||
{
|
||||
static const uint8_t frames[] = { 5,5,6,6,7,7,6,5 };
|
||||
|
||||
actor->spr.picnum = GREENSLIME + frames[actor->temp_data[3]];
|
||||
|
||||
if (actor->temp_data[3] == 5)
|
||||
{
|
||||
auto psp = ps[p].GetActor();
|
||||
psp->spr.extra += -(5 + (krand() & 3));
|
||||
S_PlayActorSound(SLIM_ATTACK, actor);
|
||||
}
|
||||
|
||||
if (actor->temp_data[3] < 7) actor->temp_data[3]++;
|
||||
else actor->temp_data[3] = 0;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
actor->spr.picnum = GREENSLIME + 5;
|
||||
if (rnd(32))
|
||||
actor->temp_data[3] = 1;
|
||||
}
|
||||
|
||||
double add = (BobVal(actor->temp_data[1]) * 2) * REPEAT_SCALE;
|
||||
actor->spr.scale = DVector2(0.3125 + add, 0.234375 + add);
|
||||
actor->spr.pos.XY() = ps[p].GetActor()->spr.pos.XY() + ps[p].GetActor()->spr.Angles.Yaw.ToVector() * 8;
|
||||
return;
|
||||
}
|
||||
|
||||
else if (actor->vel.X < 4 && xx < 48)
|
||||
{
|
||||
if (ps[p].somethingonplayer == nullptr)
|
||||
{
|
||||
ps[p].somethingonplayer = actor;
|
||||
if (actor->temp_data[0] == 3 || actor->temp_data[0] == 2) //Falling downward
|
||||
actor->temp_data[2] = (12 << 8);
|
||||
else actor->temp_data[2] = -(13 << 8); //Climbing up duke
|
||||
actor->temp_data[0] = -4;
|
||||
}
|
||||
}
|
||||
|
||||
j = fi.ifhitbyweapon(actor);
|
||||
if (j >= 0)
|
||||
{
|
||||
S_PlayActorSound(SLIM_DYING, actor);
|
||||
|
||||
if (ps[p].somethingonplayer == actor)
|
||||
ps[p].somethingonplayer = nullptr;
|
||||
|
||||
if (j == FREEZEBLAST)
|
||||
{
|
||||
S_PlayActorSound(SOMETHINGFROZE, actor);
|
||||
actor->temp_data[0] = -5; actor->temp_data[3] = 0;
|
||||
return;
|
||||
}
|
||||
ps[p].actors_killed++;
|
||||
|
||||
if ((krand() & 255) < 32)
|
||||
{
|
||||
auto spawned = spawn(actor, BLOODPOOL);
|
||||
if (spawned) spawned->spr.pal = 0;
|
||||
}
|
||||
|
||||
for (int x = 0; x < 8; x++)
|
||||
{
|
||||
auto a = randomAngle();
|
||||
auto vel = krandf(4) + 4;
|
||||
auto zvel = -krandf(16) - actor->vel.Z * 0.25;
|
||||
|
||||
auto spawned = CreateActor(actor->sector(), actor->spr.pos.plusZ(-8), PClass::FindActor("DukeScrap"), -8, DVector2(0.75, 0.75), a, vel, zvel, actor, STAT_MISC);
|
||||
if (spawned)
|
||||
{
|
||||
if (spawned) spawned->spriteextra = Scrap3 + (krand() & 3);
|
||||
spawned->spr.pal = 6;
|
||||
}
|
||||
}
|
||||
actor->temp_data[0] = -3;
|
||||
actor->Destroy();
|
||||
return;
|
||||
}
|
||||
// All weap
|
||||
if (actor->temp_data[0] == -1) //Shrinking down
|
||||
{
|
||||
makeitfall(actor);
|
||||
|
||||
actor->spr.cstat &= ~CSTAT_SPRITE_YFLIP;
|
||||
actor->spr.picnum = GREENSLIME + 4;
|
||||
|
||||
if (actor->spr.scale.X > 0.5 ) actor->spr.scale.X += (-(krand() & 7) * REPEAT_SCALE);
|
||||
if (actor->spr.scale.Y > 0.25 ) actor->spr.scale.Y += (-(krand() & 7) * REPEAT_SCALE);
|
||||
else
|
||||
{
|
||||
actor->spr.scale = DVector2(0.625, 0.25);
|
||||
actor->temp_actor = nullptr;
|
||||
actor->temp_data[0] = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else if (actor->temp_data[0] != -2) getglobalz(actor);
|
||||
|
||||
if (actor->temp_data[0] == -2) //On top of somebody (an enemy)
|
||||
{
|
||||
DDukeActor* s5 = actor->temp_actor;
|
||||
makeitfall(actor);
|
||||
if (s5)
|
||||
{
|
||||
s5->vel.X = 0;
|
||||
|
||||
actor->spr.pos = s5->spr.pos + s5->spr.Angles.Yaw.ToVector() * 0.5;
|
||||
actor->spr.picnum = GREENSLIME + 2 + (global_random & 1);
|
||||
|
||||
if (actor->spr.scale.Y < 1) actor->spr.scale.Y += (0.03125);
|
||||
else
|
||||
{
|
||||
if (actor->spr.scale.X < 0.5) actor->spr.scale.X += (0.0625);
|
||||
else
|
||||
{
|
||||
actor->temp_data[0] = -1;
|
||||
double dist = (actor->spr.pos.XY() - s5->spr.pos.XY()).LengthSquared();
|
||||
if (dist < 48*48) {
|
||||
s5->spr.scale.X = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//Check randomly to see of there is an actor near
|
||||
if (rnd(32))
|
||||
{
|
||||
DukeSectIterator it(actor->sector());
|
||||
while (auto a2 = it.Next())
|
||||
{
|
||||
if (actorflag(a2, SFLAG_GREENSLIMEFOOD))
|
||||
{
|
||||
double dist = (actor->spr.pos.XY() - a2->spr.pos.XY()).LengthSquared();
|
||||
if (dist < 48*48 && (abs(actor->spr.pos.Z - a2->spr.pos.Z) < 16)) //Gulp them
|
||||
{
|
||||
actor->temp_actor = a2;
|
||||
actor->temp_data[0] = -2;
|
||||
actor->temp_data[1] = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Moving on the ground or ceiling
|
||||
|
||||
if (actor->temp_data[0] == 0 || actor->temp_data[0] == 2)
|
||||
{
|
||||
actor->spr.picnum = GREENSLIME;
|
||||
|
||||
if ((krand() & 511) == 0)
|
||||
S_PlayActorSound(SLIM_ROAM, actor);
|
||||
|
||||
if (actor->temp_data[0] == 2)
|
||||
{
|
||||
actor->vel.Z = 0;
|
||||
actor->spr.cstat &= ~CSTAT_SPRITE_YFLIP;
|
||||
|
||||
if ((sectp->ceilingstat & CSTAT_SECTOR_SKY) || (actor->ceilingz + 24) < actor->spr.pos.Z)
|
||||
{
|
||||
actor->spr.pos.Z += 8;
|
||||
actor->temp_data[0] = 3;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
actor->spr.cstat |= CSTAT_SPRITE_YFLIP;
|
||||
makeitfall(actor);
|
||||
}
|
||||
|
||||
if (everyothertime & 1) ssp(actor, CLIPMASK0);
|
||||
|
||||
if (actor->vel.X > 6)
|
||||
{
|
||||
actor->vel.X -= 1/8.;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (actor->vel.X < 2) actor->vel.X += 0.25;
|
||||
actor->vel.X = 4 - BobVal(512 + actor->temp_data[1]) * 2;
|
||||
actor->spr.Angles.Yaw += deltaangle(actor->spr.Angles.Yaw, (ps[p].GetActor()->spr.pos.XY() - actor->spr.pos.XY()).Angle()) * 0.125;
|
||||
// TJR
|
||||
}
|
||||
|
||||
actor->spr.scale.X = (0.5625 + BobVal(512 + actor->temp_data[1]) * 0.125);
|
||||
actor->spr.scale.Y = (0.25 + BobVal(actor->temp_data[1]) * 0.03125);
|
||||
|
||||
if (rnd(4) && (sectp->ceilingstat & CSTAT_SECTOR_SKY) == 0 &&
|
||||
abs(actor->floorz - actor->ceilingz) < 192)
|
||||
{
|
||||
actor->vel.Z = 0;
|
||||
actor->temp_data[0]++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (actor->temp_data[0] == 1)
|
||||
{
|
||||
actor->spr.picnum = GREENSLIME;
|
||||
if (actor->spr.scale.Y < 0.625) actor->spr.scale.Y += (0.125);
|
||||
if (actor->spr.scale.X > 0.125 ) actor->spr.scale.X += (-0.0625);
|
||||
if (actor->vel.Z > -12)
|
||||
actor->vel.Z -= 348 / 256.;
|
||||
actor->spr.pos.Z += actor->vel.Z;
|
||||
if (actor->spr.pos.Z < actor->ceilingz + 16)
|
||||
{
|
||||
actor->spr.pos.Z = actor->ceilingz + 16;
|
||||
actor->vel.X = 0;
|
||||
actor->temp_data[0] = 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (actor->temp_data[0] == 3)
|
||||
{
|
||||
actor->spr.picnum = GREENSLIME + 1;
|
||||
|
||||
makeitfall(actor);
|
||||
|
||||
if (actor->spr.pos.Z > actor->floorz - 8)
|
||||
{
|
||||
actor->spr.scale.Y += (-0.0625);
|
||||
actor->spr.scale.X += (0.03125);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (actor->spr.scale.Y < 0.5625) actor->spr.scale.Y += (0.125);
|
||||
if (actor->spr.scale.X > 0.125 ) actor->spr.scale.X += (-0.0625);
|
||||
}
|
||||
|
||||
if (actor->spr.pos.Z > actor->floorz - 8)
|
||||
{
|
||||
actor->spr.pos.Z = actor->floorz - 8;
|
||||
actor->temp_data[0] = 0;
|
||||
actor->vel.X = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static void flamethrowerflame(DDukeActor *actor)
|
||||
{
|
||||
auto sectp = actor->sector();
|
||||
|
@ -1825,17 +1414,6 @@ void moveactors_d(void)
|
|||
if (isWorldTour()) flamethrowerflame(act);
|
||||
continue;
|
||||
|
||||
case GREENSLIME:
|
||||
case GREENSLIME + 1:
|
||||
case GREENSLIME + 2:
|
||||
case GREENSLIME + 3:
|
||||
case GREENSLIME + 4:
|
||||
case GREENSLIME + 5:
|
||||
case GREENSLIME + 6:
|
||||
case GREENSLIME + 7:
|
||||
greenslime(act);
|
||||
continue;
|
||||
|
||||
case BOUNCEMINE:
|
||||
case MORTER:
|
||||
spawn(act, FRAMEEFFECT1)->temp_data[0] = 3;
|
||||
|
@ -2018,8 +1596,8 @@ void moveexplosions_d(void) // STATNUM 5
|
|||
continue;
|
||||
|
||||
case GLASSPIECES:
|
||||
case GLASSPIECES + 1:
|
||||
case GLASSPIECES + 2:
|
||||
case GLASSPIECES1:
|
||||
case GLASSPIECES2:
|
||||
glasspieces(act);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -1810,8 +1810,8 @@ void moveexplosions_r(void) // STATNUM 5
|
|||
continue;
|
||||
|
||||
case GLASSPIECES:
|
||||
case GLASSPIECES + 1:
|
||||
case GLASSPIECES + 2:
|
||||
case GLASSPIECES1:
|
||||
case GLASSPIECES2:
|
||||
case POPCORN:
|
||||
glasspieces(act);
|
||||
continue;
|
||||
|
|
|
@ -58,10 +58,11 @@ void animatesprites_d(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi
|
|||
t = tsprites.get(j);
|
||||
h = static_cast<DDukeActor*>(t->ownerActor);
|
||||
|
||||
if (!actorflag(h, SFLAG2_FORCESECTORSHADE))
|
||||
switch (t->picnum)
|
||||
{
|
||||
case DEVELOPERCOMMENTARY:
|
||||
case DEVELOPERCOMMENTARY + 1:
|
||||
case DEVELOPERCOMMENTARYON:
|
||||
if (isWorldTour() && !wt_commentary)
|
||||
t->scale = DVector2(0, 0);
|
||||
break;
|
||||
|
@ -99,15 +100,6 @@ void animatesprites_d(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi
|
|||
case NEON5:
|
||||
case NEON6:
|
||||
continue;
|
||||
case GREENSLIME:
|
||||
case GREENSLIME + 1:
|
||||
case GREENSLIME + 2:
|
||||
case GREENSLIME + 3:
|
||||
case GREENSLIME + 4:
|
||||
case GREENSLIME + 5:
|
||||
case GREENSLIME + 6:
|
||||
case GREENSLIME + 7:
|
||||
break;
|
||||
default:
|
||||
if (((t->cstat & CSTAT_SPRITE_ALIGNMENT_WALL)) || (badguypic(t->picnum) && t->extra > 0) || t->statnum == STAT_PLAYER)
|
||||
continue;
|
||||
|
|
|
@ -382,12 +382,22 @@ enum sflags2_t
|
|||
SFLAG2_ALTPROJECTILESPRITE = 0x10000000, // yet another shooter flag. :(
|
||||
SFLAG2_UNDERWATERSLOWDOWN = 0x20000000,
|
||||
SFLAG2_TRIGGERRESPAWN = 0x40000000,
|
||||
SFLAG2_FORCESECTORSHADE = 0x80000000,
|
||||
|
||||
};
|
||||
|
||||
using EDukeFlags2 = TFlags<sflags2_t, uint32_t>;
|
||||
DEFINE_TFLAGS_OPERATORS(EDukeFlags2)
|
||||
|
||||
enum sflags3_t
|
||||
{
|
||||
SFLAG3_DONTDIVEALIVE = 0x00000001,
|
||||
|
||||
};
|
||||
|
||||
using EDukeFlags3 = TFlags<sflags3_t, uint32_t>;
|
||||
DEFINE_TFLAGS_OPERATORS(EDukeFlags3)
|
||||
|
||||
// these get stored as user flags inside the texture manager.
|
||||
enum
|
||||
{
|
||||
|
|
|
@ -126,6 +126,7 @@ void CallOnRespawn(DDukeActor* actor, int low);
|
|||
bool CallAnimate(DDukeActor* actor, tspritetype* hitter);
|
||||
bool CallShootThis(DDukeActor* clsdef, DDukeActor* actor, int pn, const DVector3& spos, DAngle sang);
|
||||
void CallStaticSetup(DDukeActor* actor);
|
||||
void CallPlayFTASound(DDukeActor* actor);
|
||||
|
||||
|
||||
END_DUKE_NS
|
||||
|
|
|
@ -78,13 +78,6 @@ void initactorflags_d()
|
|||
BOSS3,
|
||||
BOSS4,
|
||||
GREENSLIME,
|
||||
GREENSLIME+1,
|
||||
GREENSLIME+2,
|
||||
GREENSLIME+3,
|
||||
GREENSLIME+4,
|
||||
GREENSLIME+5,
|
||||
GREENSLIME+6,
|
||||
GREENSLIME+7,
|
||||
RAT,
|
||||
ROTATEGUN });
|
||||
|
||||
|
@ -150,13 +143,6 @@ void initactorflags_d()
|
|||
|
||||
setflag(SFLAG_SHRINKAUTOAIM, {
|
||||
GREENSLIME,
|
||||
GREENSLIME + 1,
|
||||
GREENSLIME + 2,
|
||||
GREENSLIME + 3,
|
||||
GREENSLIME + 4,
|
||||
GREENSLIME + 5,
|
||||
GREENSLIME + 6,
|
||||
GREENSLIME + 7,
|
||||
});
|
||||
|
||||
setflag(SFLAG_HITRADIUSCHECK, {
|
||||
|
@ -214,6 +200,7 @@ void initactorflags_d()
|
|||
TOUGHGAL
|
||||
});
|
||||
|
||||
setflag(SFLAG2_FORCESECTORSHADE, { GREENSLIME });
|
||||
|
||||
// The feature guarded by this flag does not exist in Duke, it always acts as if the flag was set.
|
||||
for (auto& ainf : gs.actorinfo) ainf.flags |= SFLAG_MOVEFTA_CHECKSEE;
|
||||
|
|
|
@ -519,4 +519,14 @@ bool CallShootThis(DDukeActor* clsdef, DDukeActor* actor, int pn, const DVector3
|
|||
return rv;
|
||||
}
|
||||
|
||||
void CallPlayFTASound(DDukeActor* actor)
|
||||
{
|
||||
IFVIRTUALPTR(actor, DDukeActor, PlayFTASound)
|
||||
{
|
||||
VMValue val = actor;
|
||||
VMCall(func, &val, 1, nullptr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
END_DUKE_NS
|
||||
|
|
|
@ -64,6 +64,11 @@ inline int actorflag(DDukeActor* actor, EDukeFlags2 mask)
|
|||
return (((gs.actorinfo[actor->spr.picnum].flags2) & mask) != 0);
|
||||
}
|
||||
|
||||
inline int actorflag(DDukeActor* actor, EDukeFlags3 mask)
|
||||
{
|
||||
return (((gs.actorinfo[actor->spr.picnum].flags3) & mask) != 0);
|
||||
}
|
||||
|
||||
inline int attackerflag(DDukeActor* actor, EDukeFlags1 mask)
|
||||
{
|
||||
return (((gs.actorinfo[actor->attackertype].flags) & mask) != 0);
|
||||
|
|
|
@ -307,6 +307,8 @@ x(MASKWALL15, 1024)
|
|||
x(BOTTLE7, 1025)
|
||||
x(HORSEONSIDE, 1026)
|
||||
x(GLASSPIECES, 1031)
|
||||
x(GLASSPIECES1, 1032)
|
||||
x(GLASSPIECES2, 1033)
|
||||
x(HORSELITE, 1034)
|
||||
x(DONUTS, 1045)
|
||||
x(NEON6, 1046)
|
||||
|
@ -532,6 +534,14 @@ x(SMALLSMOKEMAKER, 2330)
|
|||
x(FLOORFLAME, 2333)
|
||||
x(ROTATEGUN, 2360)
|
||||
x(GREENSLIME, 2370)
|
||||
x(GREENSLIME1, 2371)
|
||||
x(GREENSLIME2, 2372)
|
||||
x(GREENSLIME3, 2373)
|
||||
x(GREENSLIME4, 2374)
|
||||
x(GREENSLIME5, 2375)
|
||||
x(GREENSLIME6, 2376)
|
||||
x(GREENSLIME7, 2377)
|
||||
|
||||
x(WATERDRIPSPLASH, 2380)
|
||||
|
||||
|
||||
|
@ -899,6 +909,7 @@ x(FIREFLYSHRINKEFFECT, 5360)
|
|||
x(FIREFLYGROWEFFECT, 5367)
|
||||
x(FIREFLYFLYINGEFFECT, 5296)
|
||||
x(DEVELOPERCOMMENTARY, 5294)
|
||||
x(DEVELOPERCOMMENTARYON, 5295)
|
||||
x(BOSS5, 5310)
|
||||
x(BOSS5STAYPUT, 5311)
|
||||
x(SERIOUSSAM, 5846)
|
||||
|
|
|
@ -401,6 +401,8 @@ x(SPOTLITE, 1247)
|
|||
x(HANGOOZ, 1249)
|
||||
x(HORSEONSIDE, 1251)
|
||||
x(GLASSPIECES, 1256)
|
||||
x(GLASSPIECES1, 1257)
|
||||
x(GLASSPIECES2, 1258)
|
||||
x(HORSELITE, 1259)
|
||||
x(DONUTS, 1263)
|
||||
x(NEON6, 1264)
|
||||
|
|
|
@ -335,13 +335,6 @@ static void shootweapon(DDukeActor *actor, int p, DVector3 pos, DAngle ang, int
|
|||
switch (aimed->spr.picnum)
|
||||
{
|
||||
case GREENSLIME:
|
||||
case GREENSLIME + 1:
|
||||
case GREENSLIME + 2:
|
||||
case GREENSLIME + 3:
|
||||
case GREENSLIME + 4:
|
||||
case GREENSLIME + 5:
|
||||
case GREENSLIME + 6:
|
||||
case GREENSLIME + 7:
|
||||
case ROTATEGUN:
|
||||
dal -= 8;
|
||||
break;
|
||||
|
@ -907,13 +900,6 @@ static void shootgrowspark(DDukeActor* actor, int p, DVector3 pos, DAngle ang)
|
|||
switch (aimed->spr.picnum)
|
||||
{
|
||||
case GREENSLIME:
|
||||
case GREENSLIME + 1:
|
||||
case GREENSLIME + 2:
|
||||
case GREENSLIME + 3:
|
||||
case GREENSLIME + 4:
|
||||
case GREENSLIME + 5:
|
||||
case GREENSLIME + 6:
|
||||
case GREENSLIME + 7:
|
||||
case ROTATEGUN:
|
||||
dal -= 8;
|
||||
break;
|
||||
|
|
|
@ -286,7 +286,8 @@ void DDukeActor::Serialize(FSerializer& arc)
|
|||
("temp_sect", temp_sect)
|
||||
("uservars", uservars)
|
||||
("flags1", flags1)
|
||||
("flags2", flags2);
|
||||
("flags2", flags2)
|
||||
("flags3", flags3);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -948,7 +948,7 @@ void checkhitdefault_d(DDukeActor* targ, DDukeActor* proj)
|
|||
|
||||
if (proj->spr.picnum == RPG) proj->spr.extra <<= 1;
|
||||
|
||||
if ((targ->spr.picnum != DRONE) && (targ->spr.picnum != ROTATEGUN) && (targ->spr.picnum != COMMANDER) && (targ->spr.picnum < GREENSLIME || targ->spr.picnum > GREENSLIME + 7))
|
||||
if ((targ->spr.picnum != DRONE) && (targ->spr.picnum != ROTATEGUN) && (targ->spr.picnum != COMMANDER) && targ->spr.picnum != GREENSLIME)
|
||||
if (proj->spr.picnum != FREEZEBLAST)
|
||||
//if (actortype[targ->spr.picnum] == 0) //TRANSITIONAL.
|
||||
{
|
||||
|
|
|
@ -525,10 +525,6 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
|
|||
case BOSS3:
|
||||
case BOSS4:
|
||||
case ROTATEGUN:
|
||||
case GREENSLIME:
|
||||
if (act->spr.picnum == GREENSLIME)
|
||||
act->spr.extra = 1;
|
||||
[[fallthrough]];
|
||||
case DRONE:
|
||||
case LIZTROOPONTOILET:
|
||||
case LIZTROOPJUSTSIT:
|
||||
|
|
|
@ -27,6 +27,7 @@ struct ActorInfo
|
|||
uint32_t scriptaddress;
|
||||
EDukeFlags1 flags;
|
||||
EDukeFlags2 flags2;
|
||||
EDukeFlags3 flags3;
|
||||
int aimoffset;
|
||||
int falladjustz;
|
||||
int gutsoffset;
|
||||
|
@ -68,6 +69,7 @@ public:
|
|||
|
||||
EDukeFlags1 flags1;
|
||||
EDukeFlags2 flags2;
|
||||
EDukeFlags3 flags3;
|
||||
|
||||
DDukeActor() = default;
|
||||
size_t PropagateMark() override;
|
||||
|
|
|
@ -207,6 +207,7 @@ DEFINE_FIELD(DDukeActor, temp_actor)
|
|||
DEFINE_FIELD(DDukeActor, seek_actor)
|
||||
DEFINE_FIELD(DDukeActor, flags1)
|
||||
DEFINE_FIELD(DDukeActor, flags2)
|
||||
DEFINE_FIELD(DDukeActor, flags3)
|
||||
DEFINE_FIELD(DDukeActor, spritesetindex)
|
||||
DEFINE_FIELD(DDukeActor, temp_walls)
|
||||
DEFINE_FIELD(DDukeActor, temp_sect)
|
||||
|
@ -681,6 +682,18 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, operateforcefields, DukeActor_operatef
|
|||
return 0;
|
||||
}
|
||||
|
||||
void DukeActor_restoreloc(DDukeActor* self)
|
||||
{
|
||||
self->restoreloc();
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, restoreloc, DukeActor_restoreloc)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DDukeActor);
|
||||
PARAM_INT(tag);
|
||||
DukeActor_restoreloc(self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// temporary helpers to hide the fact that these flags are not part of the actor yet.
|
||||
DEFINE_ACTION_FUNCTION(DDukeActor, actorflag1)
|
||||
|
|
|
@ -110,6 +110,8 @@ spawnclasses
|
|||
1520 = DukePlayerTorso
|
||||
1528 = DukePlayerGun
|
||||
1536 = DukePlayerLeg
|
||||
|
||||
2370 = DukeGreenSlime
|
||||
|
||||
595 = DukeGenericDestructible, "GRATE1", "BGRATE1", "VENT_BUST", solid, unblocking
|
||||
1113 = DukeGenericDestructible, "CIRCLEPANNEL", "CIRCLEPANNELBROKE", "VENT_BUST", unblocking
|
||||
|
|
|
@ -87,6 +87,7 @@ version "4.10"
|
|||
#include "zscript/games/duke/actors/destructibles.zs"
|
||||
#include "zscript/games/duke/actors/ducktarget.zs"
|
||||
#include "zscript/games/duke/actors/helicopt.zs"
|
||||
#include "zscript/games/duke/actors/greenslime.zs"
|
||||
|
||||
#include "zscript/games/duke/actors/redneckmisc.zs"
|
||||
#include "zscript/games/duke/actors/rabbitspawner.zs"
|
||||
|
|
|
@ -54,6 +54,7 @@ class CoreActor native
|
|||
native float alpha;
|
||||
native double clipdist;
|
||||
native double angle;
|
||||
native double pitch;
|
||||
native Vector3 vel;
|
||||
native double viewzoffset;
|
||||
|
||||
|
|
411
wadsrc/static/zscript/games/duke/actors/greenslime.zs
Normal file
411
wadsrc/static/zscript/games/duke/actors/greenslime.zs
Normal file
|
@ -0,0 +1,411 @@
|
|||
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;
|
||||
|
||||
if (self.monsterCheatCheck()) return;
|
||||
|
||||
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', 'DukeGlassPieces', 'DukeGlassPieces'};
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -124,7 +124,7 @@ class DukeActor : CoreActor native
|
|||
native int saved_ammo;
|
||||
native int palvals;
|
||||
native int temp_data[6];
|
||||
native private int flags1, flags2;
|
||||
native private int flags1, flags2, flags3;
|
||||
native walltype temp_walls[2];
|
||||
native sectortype temp_sect, actorstayput;
|
||||
|
||||
|
@ -132,7 +132,7 @@ class DukeActor : CoreActor native
|
|||
native Vector3 temp_pos, temp_pos2;
|
||||
native double temp_angle;
|
||||
|
||||
|
||||
// this is not really usable unless all actors are properly scriptified.
|
||||
flagdef Inventory: flags1, 0;
|
||||
flagdef ShrinkAutoaim: flags1, 1;
|
||||
flagdef Badguy: flags1, 2;
|
||||
|
@ -190,6 +190,7 @@ class DukeActor : CoreActor native
|
|||
virtual void onRespawn(int tag) { }
|
||||
virtual bool animate(tspritetype tspr) { return false; }
|
||||
virtual void RunState() {} // this is the CON function.
|
||||
virtual void PlayFTASound() {}
|
||||
virtual bool shootthis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const // this gets called on the defaults.
|
||||
{
|
||||
return false;
|
||||
|
@ -211,6 +212,7 @@ class DukeActor : CoreActor native
|
|||
native void setClipDistFromTile();
|
||||
native void insertspriteq();
|
||||
native void operateforcefields(int tag);
|
||||
native void restoreloc();
|
||||
|
||||
|
||||
// temporary flag accessors - need to be eliminated once we can have true actor flags
|
||||
|
@ -218,6 +220,34 @@ class DukeActor : CoreActor native
|
|||
native int actorflag2(int mask);
|
||||
native int attackerflag1(int mask);
|
||||
native int attackerflag2(int mask);
|
||||
|
||||
|
||||
void commonEnemySetup(bool countkill = true)
|
||||
{
|
||||
if (self.ownerActor != self) self.lotag = 0;
|
||||
|
||||
if ((self.lotag > ud.player_skill) || ud.monsters_off == 1)
|
||||
{
|
||||
self.scale = (0, 0);
|
||||
self.ChangeStat(STAT_MISC);
|
||||
}
|
||||
else
|
||||
{
|
||||
self.makeitfall();
|
||||
|
||||
self.cstat |= CSTAT_SPRITE_BLOCK_ALL;
|
||||
if (countkill)
|
||||
Duke.GetLocalPlayer().max_actors_killed++;
|
||||
|
||||
if (self.ownerActor != self)
|
||||
{
|
||||
self.timetosleep = 0;
|
||||
self.PlayFTASound();
|
||||
self.ChangeStat(STAT_ACTOR);
|
||||
}
|
||||
else self.ChangeStat(STAT_ZOMBIEACTOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extend struct _
|
||||
|
|
|
@ -137,6 +137,9 @@ struct Duke native
|
|||
SB_INTERFACE_BITS = (SB_WEAPONMASK_BITS | SB_ITEMUSE_BITS | SB_INTERFACE_MASK),
|
||||
SB_ALL = ~0u
|
||||
};
|
||||
|
||||
const SLEEPTIME = 1536;
|
||||
|
||||
|
||||
native static void PlaySpecialMusic(int which);
|
||||
native static int PlaySound(Sound num, int channel = CHAN_AUTO, int flags = 0, float vol =0.8f);
|
||||
|
|
Loading…
Reference in a new issue