- SW: added countermeasure to re-enable lower skills on mods not implementing them.

Aside from spawning the enemies from the lowest supported skill it will also reduce the threat level by reducing health of some enemies or by replacing the harder Ninja variants with the base type.
This commit is contained in:
Christoph Oelckers 2021-07-06 10:26:43 +02:00
parent 6062af562d
commit 64fc0b66b2
6 changed files with 57 additions and 24 deletions

View file

@ -562,7 +562,7 @@ int SpawnCoolg(short SpriteNum)
{ {
// Don't do a ghost every time // Don't do a ghost every time
if (RANDOM_RANGE(1000) > 700) if (RANDOM_RANGE(1000) > 700 || Skill < MinEnemySkill - 1)
{ {
return(0); return(0);
} }

View file

@ -2095,6 +2095,7 @@ extern USERSAVE puser[MAX_SW_PLAYERS_REG];
extern double smoothratio; extern double smoothratio;
extern int MoveSkip4, MoveSkip2, MoveSkip8; extern int MoveSkip4, MoveSkip2, MoveSkip8;
extern int MinEnemySkill;
#define MASTER_SWITCHING 1 #define MASTER_SWITCHING 1

View file

@ -728,7 +728,7 @@ SetupGirlNinja(short SpriteNum)
else else
{ {
u = SpawnUser(SpriteNum, GIRLNINJA_RUN_R0, s_GirlNinjaRun[0]); u = SpawnUser(SpriteNum, GIRLNINJA_RUN_R0, s_GirlNinjaRun[0]);
u->Health = 100; u->Health = (Skill < MinEnemySkill - 1) ? 50 : 100;
} }
u->StateEnd = s_GirlNinjaDie; u->StateEnd = s_GirlNinjaDie;

View file

@ -1832,6 +1832,10 @@ SetupNinja(short SpriteNum)
ANIMATOR DoActorDecide; ANIMATOR DoActorDecide;
short pic = sp->picnum; short pic = sp->picnum;
// Fake some skill settings in case the lower skills are empty.
int RedNinjaHealth = MinEnemySkill <= Skill ? HEALTH_RED_NINJA : HEALTH_NINJA;
if (Skill < MinEnemySkill - 1) sp->pal = 0;
if (TEST(sp->cstat, CSTAT_SPRITE_RESTORE)) if (TEST(sp->cstat, CSTAT_SPRITE_RESTORE))
{ {
u = User[SpriteNum].Data(); u = User[SpriteNum].Data();
@ -1853,7 +1857,7 @@ SetupNinja(short SpriteNum)
u->Attrib = &InvisibleNinjaAttrib; u->Attrib = &InvisibleNinjaAttrib;
EnemyDefaults(SpriteNum, &NinjaGreenActionSet, &NinjaPersonality); EnemyDefaults(SpriteNum, &NinjaGreenActionSet, &NinjaPersonality);
if (!TEST(sp->cstat, CSTAT_SPRITE_RESTORE)) if (!TEST(sp->cstat, CSTAT_SPRITE_RESTORE))
u->Health = HEALTH_RED_NINJA; u->Health = RedNinjaHealth;
SET(sp->cstat, CSTAT_SPRITE_TRANSLUCENT); SET(sp->cstat, CSTAT_SPRITE_TRANSLUCENT);
sp->shade = 127; sp->shade = 127;
sp->pal = u->spal = PALETTE_PLAYER5; sp->pal = u->spal = PALETTE_PLAYER5;
@ -1881,7 +1885,7 @@ SetupNinja(short SpriteNum)
u->Attrib = &NinjaAttrib; u->Attrib = &NinjaAttrib;
EnemyDefaults(SpriteNum, &NinjaRedActionSet, &NinjaPersonality); EnemyDefaults(SpriteNum, &NinjaRedActionSet, &NinjaPersonality);
if (!TEST(sp->cstat, CSTAT_SPRITE_RESTORE)) if (!TEST(sp->cstat, CSTAT_SPRITE_RESTORE))
u->Health = HEALTH_RED_NINJA; u->Health = RedNinjaHealth;
sp->pal = u->spal = PALETTE_PLAYER3; sp->pal = u->spal = PALETTE_PLAYER3;
if (pic == NINJA_CRAWL_R0) if (pic == NINJA_CRAWL_R0)
{ {
@ -1906,7 +1910,7 @@ SetupNinja(short SpriteNum)
u->Attrib = &NinjaAttrib; u->Attrib = &NinjaAttrib;
EnemyDefaults(SpriteNum, &NinjaSeekerActionSet, &NinjaPersonality); EnemyDefaults(SpriteNum, &NinjaSeekerActionSet, &NinjaPersonality);
if (!TEST(sp->cstat, CSTAT_SPRITE_RESTORE)) if (!TEST(sp->cstat, CSTAT_SPRITE_RESTORE))
u->Health = HEALTH_RED_NINJA; u->Health = RedNinjaHealth;
sp->pal = u->spal = PAL_XLAT_LT_TAN; sp->pal = u->spal = PAL_XLAT_LT_TAN;
u->Attrib = &NinjaAttrib; u->Attrib = &NinjaAttrib;
} }
@ -1915,7 +1919,7 @@ SetupNinja(short SpriteNum)
u->Attrib = &NinjaAttrib; u->Attrib = &NinjaAttrib;
EnemyDefaults(SpriteNum, &NinjaGrenadeActionSet, &NinjaPersonality); EnemyDefaults(SpriteNum, &NinjaGrenadeActionSet, &NinjaPersonality);
if (!TEST(sp->cstat, CSTAT_SPRITE_RESTORE)) if (!TEST(sp->cstat, CSTAT_SPRITE_RESTORE))
u->Health = HEALTH_RED_NINJA; u->Health = RedNinjaHealth;
sp->pal = u->spal = PAL_XLAT_LT_GREY; sp->pal = u->spal = PAL_XLAT_LT_GREY;
u->Attrib = &NinjaAttrib; u->Attrib = &NinjaAttrib;
} }

View file

@ -1270,6 +1270,7 @@ void GameInterface::SerializeGameState(FSerializer& arc)
.Array("bosswasseen", bosswasseen, 3) .Array("bosswasseen", bosswasseen, 3)
.Array("BossSpriteNum", BossSpriteNum, 3); .Array("BossSpriteNum", BossSpriteNum, 3);
arc.Array("tracks", Track, countof(Track)) arc.Array("tracks", Track, countof(Track))
("minenemyskill", MinEnemySkill)
; ;
postSerializePanelSprites(arc); postSerializePanelSprites(arc);
arc.EndObject(); arc.EndObject();

View file

@ -92,6 +92,7 @@ void InitWeaponUzi(PLAYERp);
bool FAF_Sector(short sectnum); bool FAF_Sector(short sectnum);
int MoveSkip4, MoveSkip2, MoveSkip8; int MoveSkip4, MoveSkip2, MoveSkip8;
int MinEnemySkill;
extern STATE s_CarryFlag[]; extern STATE s_CarryFlag[];
extern STATE s_CarryFlagNoDet[]; extern STATE s_CarryFlagNoDet[];
@ -1049,7 +1050,8 @@ ActorTestSpawn(SPRITEp sp)
} }
// Skill ranges from -1 (No Monsters) to 3 // Skill ranges from -1 (No Monsters) to 3
if (TEST(sp->extra, SPRX_SKILL) > Skill) int spawnskill = TEST(sp->extra, SPRX_SKILL);
if (spawnskill > MinEnemySkill || (MinEnemySkill == 0 && spawnskill > Skill))
{ {
// JBF: hack to fix Wanton Destruction's missing Sumos, Serpents, and Zilla on Skill < 2 // JBF: hack to fix Wanton Destruction's missing Sumos, Serpents, and Zilla on Skill < 2
@ -1091,23 +1093,44 @@ ActorTestSpawn(SPRITEp sp)
} }
void PreCacheRipper(void); int EnemyCheckSkill()
void PreCacheRipper2(void); {
void PreCacheCoolie(void); StatIterator it(STAT_DEFAULT);
void PreCacheSerpent(void); int maxskill = INT_MAX;
void PreCacheGuardian(void); int SpriteNum;
void PreCacheNinja(void); while ((SpriteNum = it.NextIndex()) >= 0)
void PreCacheSumo(void); {
void PreCacheEel(void); auto sp = &sprite[SpriteNum];
void PreCacheToiletGirl(void);
void PreCacheWashGirl(void); switch (sp->picnum)
void PreCacheTrash(void); {
void PreCacheBunny(void); case COOLIE_RUN_R0:
void PreCacheSkel(void); case NINJA_RUN_R0:
void PreCacheHornet(void); case NINJA_CRAWL_R0:
void PreCacheSkull(void); case GORO_RUN_R0:
void PreCacheBetty(void); case 1441:
void PreCachePachinko(void); case COOLG_RUN_R0:
case EEL_RUN_R0:
case SUMO_RUN_R0:
case ZILLA_RUN_R0:
case RIPPER_RUN_R0:
case RIPPER2_RUN_R0:
case SERP_RUN_R0:
case LAVA_RUN_R0:
case SKEL_RUN_R0:
case HORNET_RUN_R0:
case SKULL_R0:
case BETTY_R0:
case GIRLNINJA_RUN_R0:
{
int myskill = sp->extra & SPRX_SKILL;
if (myskill < maxskill) maxskill = myskill;
}
}
}
if (maxskill < 0 || maxskill == INT_MAX) maxskill = 0;
return maxskill;
}
bool bool
ActorSpawn(SPRITEp sp) ActorSpawn(SPRITEp sp)
@ -1789,6 +1812,8 @@ SpriteSetup(void)
short i, num; short i, num;
int cz,fz; int cz,fz;
MinEnemySkill = EnemyCheckSkill();
// special case for player // special case for player
PicAnimOff(PLAYER_NINJA_RUN_R0); PicAnimOff(PLAYER_NINJA_RUN_R0);
@ -1808,6 +1833,8 @@ SpriteSetup(void)
// Call my little sprite setup routine first // Call my little sprite setup routine first
JS_SpriteSetup(); JS_SpriteSetup();
int minEnemySkill = EnemyCheckSkill();
StatIterator it(STAT_DEFAULT); StatIterator it(STAT_DEFAULT);
while ((SpriteNum = it.NextIndex()) >= 0) while ((SpriteNum = it.NextIndex()) >= 0)
{ {