swwmgz_m/zscript/utility/swwm_utility_compat.zsc
Marisa the Magician cbb1b2a8cb Sigil 2 (v1.0) and Eviternity 2 (RC5) support.
+ Invinciball activation now voiced by Demo (thanks, Vyolette).
+ Retooled exit line merging (should fix those pesky duplicate exit markers).

Note: Oneliners for the Eviternity 2 final boss are not voiced yet.
2024-01-04 19:50:26 +01:00

166 lines
4.2 KiB
Text

// compat / detection code
extend Class SWWMUtility
{
// try to be as thorough as possible in checking if DEHACKED has altered this actor
static bool CheckDehackery( Class<Actor> cls )
{
let def = GetDefaultByType(cls);
for ( State s=def.SpawnState; s; s=s.NextState )
{
if ( s.bDEHACKED ) return true;
// keep checking until we hit a loop, just in case
if ( s.NextState && (s.DistanceTo(s.NextState) <= 0) ) break;
}
for ( State s=def.SeeState; s; s=s.NextState )
{
if ( s.bDEHACKED ) return true;
// keep checking until we hit a loop, just in case
if ( s.NextState && (s.DistanceTo(s.NextState) <= 0) ) break;
}
for ( State s=def.MissileState; s; s=s.NextState )
{
if ( s.bDEHACKED ) return true;
// keep checking until we hit a loop, just in case
if ( s.NextState && (s.DistanceTo(s.NextState) <= 0) ) break;
}
for ( State s=def.MeleeState; s; s=s.NextState )
{
if ( s.bDEHACKED ) return true;
// keep checking until we hit a loop, just in case
if ( s.NextState && (s.DistanceTo(s.NextState) <= 0) ) break;
}
return false;
}
// shorthand for some of these checks (these are generally used by the mission briefing system)
static bool IsKnownMap()
{
if ( (gameinfo.gametype&GAME_DOOM) && (IsKnownCustomWAD() || CheckMD5List("vanilladoom.lst")) )
return true;
if ( (gameinfo.gametype&GAME_HERETIC) && CheckMD5List("vanillaheretic.lst") )
return true;
if ( (gameinfo.gametype&GAME_HEXEN) && CheckMD5List("vanillahexen.lst") )
return true;
return false;
}
// to be filled
static bool IsKnownCustomWAD()
{
if ( gameinfo.gametype&GAME_DOOM )
{
if ( IsEviternity() ) return true;
if ( IsEviternityTwo() ) return true;
if ( IsUltDoom2() ) return true;
}
return false;
}
// detect ultimate doom 2
static bool IsUltDoom2()
{
return CheckMD5List("ultdoom2.lst");
}
// detect eviternity (naive method)
static bool IsEviternity()
{
foreach ( cls:AllActorClasses )
{
if ( cls.GetClassName() != "Archangelus" )
continue;
return true;
}
return false;
}
// detect eviternity 2 (naive method)
static bool IsEviternityTwo()
{
foreach ( cls:AllActorClasses )
{
if ( cls.GetClassName() != "EviternatusAnta" )
continue;
return true;
}
return false;
}
// detect doom vacation
static bool InDoomVacation()
{
// cheap, but hey, it should work
if ( Wads.FindLump("VACABEX") != -1 )
{
// just to make sure
foreach ( cls:AllActorClasses )
{
if ( cls.GetClassName() != "Babe" )
continue;
return true;
}
}
return false;
}
static bool IsDeathkings()
{
if ( (gameinfo.gametype&GAME_HEXEN) && LevelInfo.MapExists("MAP41") )
{
let inf = LevelInfo.FindLevelInfo("MAP41");
if ( inf.cluster == 1 ) return true;
}
return false;
}
// detect vanilla maps (across all IWAD versions)
static bool CheckMD5List( String fname )
{
String csum = level.GetChecksum();
let lmp = Wads.CheckNumForFullName(fname);
if ( lmp == -1 ) return false;
String dat = Wads.ReadLump(lmp);
// Windows pls
dat.Replace("\r","");
Array<String> list;
list.Clear();
dat.Split(list,"\n");
foreach ( l:list )
{
if ( (l.Length() == 0) || (l.Left(1) == "#") || (l.Left(1) == "") )
continue;
if ( csum ~== l )
return true;
}
return false;
}
// WHACK
static play void EndLevelDie( Actor victim )
{
victim.DamageMobj(null,null,victim.Health,'EndLevel',DMG_FORCED|DMG_THRUSTLESS);
}
// for Equinox
static play void SpawnVanillaBossBrain( int tid )
{
let ai = Level.CreateActorIterator(tid);
Actor a;
while ( a = ai.Next() )
{
let bb = a.Spawn("BossBrain",a.pos,NO_REPLACE);
bb.angle = a.angle;
}
}
// checks if we're playing in doom 1
// this is used so we can sometimes replace the shotgun with a SSG slot weapon
static bool IsDoomOne()
{
if ( !(gameinfo.GameType&GAME_DOOM) ) return false;
// is the map in ExMx format? Then it's likely we're playing a doom 1 map
if ( (level.mapname.Length() >= 4) && (level.mapname.Mid(0,1) == "E") && (level.mapname.ByteAt(1) >= 0x30) && (level.mapname.ByteAt(1) < 0x40) && (level.mapname.Mid(2,1) == "M") && (level.mapname.ByteAt(3) >= 0x30) && (level.mapname.ByteAt(3) < 0x40) )
return true;
return false;
}
}