- fixed enemy setup.

All enemies now run a native init function to reduce script-induced problems.

this required adding a NOGRAVITY flag so that the recon can use the same code as well which was the only enemy relying on custom code.
This commit is contained in:
Christoph Oelckers 2022-12-19 18:45:27 +01:00
parent 0db441accb
commit 38b278b12d
10 changed files with 60 additions and 81 deletions

View file

@ -2966,6 +2966,8 @@ void getglobalz(DDukeActor* actor)
void makeitfall(DDukeActor* actor)
{
if (actorflag(actor, SFLAG3_NOGRAVITY)) return;
double grav;
if( floorspace(actor->sector()) )
@ -2995,7 +2997,7 @@ void makeitfall(DDukeActor* actor)
if( actor->spr.pos.Z < actor->floorz - FOURSLEIGHT_F)
{
if( actor->sector()->lotag == 2 && actor->vel.Z > 3122/256.)
if( actor->sector()->lotag == ST_2_UNDERWATER && actor->vel.Z > 3122/256.)
actor->vel.Z = 3144 / 256.;
if (actor->vel.Z < 24)
actor->vel.Z += grav;

View file

@ -404,6 +404,7 @@ enum sflags3_t
SFLAG3_BROWNBLOOD = 0x00000004,
SFLAG3_LIGHTDAMAGE = 0x00000008,
SFLAG3_FORCERUNCON = 0x00000010, // by default only STAT_ACTOR runs CON - this enables it for other statnums as well, provided they run Tick()
SFLAG3_NOGRAVITY = 0x00000020, // disables makeitfall.
};

View file

@ -40,6 +40,7 @@ BEGIN_DUKE_NS
void initactorflags_d()
{
setflag(SFLAG3_NOGRAVITY, { DTILE_RECON }); // not ported!!!
gs.actorinfo[DTILE_COMMANDER].gutsoffset = -24;

View file

@ -175,6 +175,7 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
void addspritetodelete(int spnum=0);
void checkavailinven(player_struct* p);
bool initspriteforspawn(DDukeActor* spn);
bool commonEnemySetup(DDukeActor* self, DDukeActor* owner);
bool spawninitdefault(DDukeActor* actj, DDukeActor* act);
void spawntransporter(DDukeActor* actj, DDukeActor* acti, bool beam);
int spawnbloodpoolpart1(DDukeActor* acti);

View file

@ -292,6 +292,54 @@ DDukeActor* spawn(DDukeActor* actj, PClassActor * cls)
return nullptr;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
bool commonEnemySetup(DDukeActor* self, DDukeActor* owner)
{
if (!self->mapSpawned) self->spr.lotag = 0;
// Init the size. This is different for internal and user enemies.
if (actorflag(self, SFLAG_INTERNAL_BADGUY))
{
self->spr.scale = DVector2(0.625, 0.625);
}
else if (self->spr.scale.X == 0 || self->spr.scale.Y == 0)
{
self->spr.scale = DVector2(REPEAT_SCALE, REPEAT_SCALE);
}
if ((self->spr.lotag > ud.player_skill) || ud.monsters_off == 1)
{
self->spr.scale.Zero();
ChangeActorStat(self, STAT_MISC);
return false;
}
else
{
makeitfall(self);
self->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL;
if (!isRR() && actorflag(self, SFLAG_KILLCOUNT))
ps[myconnectindex].max_actors_killed++;
self->timetosleep = 0;
if (!self->mapSpawned)
{
CallPlayFTASound(self);
ChangeActorStat(self, STAT_ACTOR);
if (owner && !actorflag(self, SFLAG_INTERNAL_BADGUY)) self->spr.Angles.Yaw = owner->spr.Angles.Yaw;
}
else ChangeActorStat(self, STAT_ZOMBIEACTOR);
return true;
}
}
//---------------------------------------------------------------------------
//
//
@ -316,41 +364,19 @@ bool spawninitdefault(DDukeActor* actj, DDukeActor *act)
if (actorflag(act, SFLAG_BADGUY))
{
if (ud.monsters_off == 1)
{
act->spr.scale = DVector2(0, 0);
ChangeActorStat(act, STAT_MISC);
return false;
}
makeitfall(act);
if (actorflag(act, SFLAG_BADGUYSTAYPUT))
act->actorstayput = act->sector();
if (!isRR() || actorflag(act, SFLAG_KILLCOUNT)) // Duke is just like Doom - Bad guys always count as kill.
ps[myconnectindex].max_actors_killed++;
act->clipdist = 20;
if (actj)
{
if (isrespawncontroller(actj))
act->tempval = act->spr.pal = actj->spr.pal;
ChangeActorStat(act, STAT_ACTOR);
}
else ChangeActorStat(act, STAT_ZOMBIEACTOR);
commonEnemySetup(act, actj);
}
else
{
act->clipdist = 10;
act->SetOwner(act);
ChangeActorStat(act, STAT_ACTOR);
if (actj)
act->spr.Angles.Yaw = actj->spr.Angles.Yaw;
}
act->timetosleep = 0;
if (actj)
act->spr.Angles.Yaw = actj->spr.Angles.Yaw;
}
return true;
}

View file

@ -59,7 +59,7 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
if (act->GetClass() != RUNTIME_CLASS(DDukeActor))
{
if (spawninitdefault(actj, act))
if (!badguy(act) || commonEnemySetup(act, actj))
CallInitialize(act);
return act;
}

View file

@ -51,7 +51,7 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
if (act->GetClass() != RUNTIME_CLASS(DDukeActor))
{
if (spawninitdefault(actj, act))
if (!badguy(act) || commonEnemySetup(act, actj))
CallInitialize(act);
return act;
}

View file

@ -7,7 +7,6 @@ class DukeGreenSlime : DukeActor
override void Initialize()
{
commonEnemySetup();
self.scale = (0.625, 0.625);
self.clipdist = 20;
self.extra = 1;

View file

@ -13,35 +13,11 @@ class DukeRecon : DukeActor
override void initialize()
{
if (self.lotag > ud.player_skill)
{
self.scale = (0, 0);
self.ChangeStat(STAT_MISC);
return;
}
if (!Raze.isRR() || self.actorflag1(SFLAG_KILLCOUNT)) // in Duke bad guys always count as kill. RR uses a flag. Needs to be cleaned up.
Duke.GetLocalPlayer().max_actors_killed++;
self.temp_data[5] = 0;
if (ud.monsters_off == 1)
{
self.scale = (0, 0);
self.ChangeStat(STAT_MISC);
return;
}
self.extra = 130;
self.cstat |= CSTAT_SPRITE_BLOCK_ALL; // Make it hitable
if (ud.multimode < 2 && self.pal != 0)
{
self.scale = (0, 0);
self.ChangeStat(STAT_MISC);
return;
}
self.pal = 0;
self.shade = -17;
self.ChangeStat(STAT_ZOMBIEACTOR);
AttackSnd = "RECO_ATTACK";
PainSnd = "RECO_PAIN";

View file

@ -251,33 +251,6 @@ class DukeActor : CoreActor native
deprecated("4.9") native bool checktype(String name); // this must not stay in the code, so mark it deprecated to keep the annoying warning at startup.
void commonEnemySetup(bool countkill = true)
{
if (!self.mapSpawned) 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.mapSpawned)
{
self.timetosleep = 0;
self.PlayFTASound();
self.ChangeStat(STAT_ACTOR);
}
else self.ChangeStat(STAT_ZOMBIEACTOR);
}
}
int checkLocationForFloorSprite(double radius)
{
bool away = self.isAwayFromWall(radius);