diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index 3e8275250..019be65ca 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -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; diff --git a/source/games/duke/src/constants.h b/source/games/duke/src/constants.h index 3b94d2bb1..3cf06df77 100644 --- a/source/games/duke/src/constants.h +++ b/source/games/duke/src/constants.h @@ -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. }; diff --git a/source/games/duke/src/flags_d.cpp b/source/games/duke/src/flags_d.cpp index 9e950d42f..611866d49 100644 --- a/source/games/duke/src/flags_d.cpp +++ b/source/games/duke/src/flags_d.cpp @@ -40,6 +40,7 @@ BEGIN_DUKE_NS void initactorflags_d() { + setflag(SFLAG3_NOGRAVITY, { DTILE_RECON }); // not ported!!! gs.actorinfo[DTILE_COMMANDER].gutsoffset = -24; diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index 5dbf8bb5d..1a16c9da1 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -175,6 +175,7 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray* 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); diff --git a/source/games/duke/src/spawn.cpp b/source/games/duke/src/spawn.cpp index 2903f4343..7768cb15b 100644 --- a/source/games/duke/src/spawn.cpp +++ b/source/games/duke/src/spawn.cpp @@ -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; } diff --git a/source/games/duke/src/spawn_d.cpp b/source/games/duke/src/spawn_d.cpp index c78a7a715..f8b803ae0 100644 --- a/source/games/duke/src/spawn_d.cpp +++ b/source/games/duke/src/spawn_d.cpp @@ -59,7 +59,7 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray* if (act->GetClass() != RUNTIME_CLASS(DDukeActor)) { - if (spawninitdefault(actj, act)) + if (!badguy(act) || commonEnemySetup(act, actj)) CallInitialize(act); return act; } diff --git a/source/games/duke/src/spawn_r.cpp b/source/games/duke/src/spawn_r.cpp index 78a693f52..c8d51b60d 100644 --- a/source/games/duke/src/spawn_r.cpp +++ b/source/games/duke/src/spawn_r.cpp @@ -51,7 +51,7 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray* if (act->GetClass() != RUNTIME_CLASS(DDukeActor)) { - if (spawninitdefault(actj, act)) + if (!badguy(act) || commonEnemySetup(act, actj)) CallInitialize(act); return act; } diff --git a/wadsrc/static/zscript/games/duke/actors/greenslime.zs b/wadsrc/static/zscript/games/duke/actors/greenslime.zs index e95d0fdf4..fcc83a441 100644 --- a/wadsrc/static/zscript/games/duke/actors/greenslime.zs +++ b/wadsrc/static/zscript/games/duke/actors/greenslime.zs @@ -7,7 +7,6 @@ class DukeGreenSlime : DukeActor override void Initialize() { - commonEnemySetup(); self.scale = (0.625, 0.625); self.clipdist = 20; self.extra = 1; diff --git a/wadsrc/static/zscript/games/duke/actors/recon.zs b/wadsrc/static/zscript/games/duke/actors/recon.zs index 645c1a164..eb5052c07 100644 --- a/wadsrc/static/zscript/games/duke/actors/recon.zs +++ b/wadsrc/static/zscript/games/duke/actors/recon.zs @@ -13,36 +13,12 @@ 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"; RoamSnd = "RECO_ROAM"; diff --git a/wadsrc/static/zscript/games/duke/dukeactor.zs b/wadsrc/static/zscript/games/duke/dukeactor.zs index a5a4ab80a..d8a653a73 100644 --- a/wadsrc/static/zscript/games/duke/dukeactor.zs +++ b/wadsrc/static/zscript/games/duke/dukeactor.zs @@ -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);