More work towards Legacy of Rust support (with caveats).
As of this commit, do not consider the experience when playing that new expansion to be complete. I've only partially written some of the mission texts and rudimentarily enhanced some boss fights. Currently there is one major limitation in that the intermission texts cannot be replaced, as they're hardcoded inside the UMAPINFO. I don't know if I can work around that.
This commit is contained in:
parent
7a3e0ae413
commit
2aa0ea4680
16 changed files with 414 additions and 43 deletions
|
|
@ -139,6 +139,11 @@ Class SWWMLevelCompatibility : LevelPostProcessor
|
|||
level.nextsecretmap = level.nextmap; // so the handler can detect this
|
||||
if ( LevelInfo.MapExists("MAP01") ) level.nextmap = "MAP01";
|
||||
break;
|
||||
// Legacy of Rust E1M7
|
||||
case '7F00D2FAA5F0B10A6028BE2FC5530EC9':
|
||||
level.nextsecretmap = level.nextmap; // so the handler can detect this
|
||||
level.nextmap = "MAP08";
|
||||
break;
|
||||
// Heretic E1M8
|
||||
case '27639D04F8090D57A47D354992435893':
|
||||
level.nextsecretmap = level.nextmap; // so the handler can detect this
|
||||
|
|
@ -539,6 +544,35 @@ Class SWWMLevelCompatibility : LevelPostProcessor
|
|||
}
|
||||
switch ( checksum )
|
||||
{
|
||||
// ALL of Legacy of Rust
|
||||
case '4F9E705F55E45C1047FABF8BDF2B2399':
|
||||
case '5FB5010F988FFAE2679A9BDD57460473':
|
||||
case '7CABD8B043B69996D9777F7070C8BCCE':
|
||||
case '7F00D2FAA5F0B10A6028BE2FC5530EC9':
|
||||
case '8A2C0869EAA69FB7B441CD2B648978D0':
|
||||
case '95B94864754AC50446A456A88DA3E052':
|
||||
case '867B6AD67389A077CE3C9E3CC896F484':
|
||||
case '1283C3288A2F51B7455D817C5B7FCFAD':
|
||||
case '1699E255B8C0DB86EBB00E5B3C44B4AA':
|
||||
case 'A3F7A58FC08C369F1360741A99F1497C':
|
||||
case 'B6447217725A2A709D6D021CDE15FE10':
|
||||
case 'BF34C34C5DFC8BB47228CC304F9A6748':
|
||||
case 'C745F8D0D8824A1910F9DC8B7AB16AA2':
|
||||
case 'E2D2886FD22DC4354939E6E51690C34B':
|
||||
case 'F5AED83945C8BDE642E55E72FE0D92AA':
|
||||
// we need to replace the dehacked things with the
|
||||
// ones defined in zscript internally, for the sake of
|
||||
// script compatibility and whatnot
|
||||
for ( uint i=0; i<GetThingCount(); i++ )
|
||||
{
|
||||
int ednum = GetThingEdNum(i);
|
||||
if ( ((ednum >= 3007) && (ednum <= 3014))
|
||||
|| ((ednum >= 3100) && (ednum <= 3142)) )
|
||||
SetThingEdNum(i,ednum+4204000);
|
||||
}
|
||||
break;
|
||||
case 'F206766043C4D9BA2C36F76106F96279':
|
||||
case 'FCF009C63BBA5F8CEE71ED5EC0B02CDA':
|
||||
// ALL of Equinox
|
||||
case '9705315427A2F951A538B23C39199236':
|
||||
case '54E9953A3C1A88641E00AA353BAF46E9':
|
||||
|
|
|
|||
|
|
@ -77,6 +77,28 @@ Class ROM3R0Death : Inventory
|
|||
return;
|
||||
}
|
||||
}
|
||||
Class TyrantWake : Inventory
|
||||
{
|
||||
override void DoEffect()
|
||||
{
|
||||
if ( Owner.InStateSequence(Owner.CurState,Owner.SeeState) )
|
||||
{
|
||||
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
|
||||
if ( hnd && (hnd.bosstag != "$BT_TYRANT2") )
|
||||
{
|
||||
hnd.bossactors.Clear();
|
||||
hnd.initialized = false;
|
||||
let ti = ThinkerIterator.Create('Deh_Actor_157');
|
||||
Actor a;
|
||||
while ( a = Actor(ti.Next()) )
|
||||
hnd.bossactors.Push(a);
|
||||
hnd.bosstag = "$BT_TYRANT2";
|
||||
}
|
||||
DepleteOrDestroy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extend Class SWWMHandler
|
||||
{
|
||||
|
|
@ -124,7 +146,9 @@ extend Class SWWMHandler
|
|||
MAP_HMAP60,
|
||||
MAP_EVMAP30, // eviternity
|
||||
MAP_EVIIMAP30, // eviternity 2
|
||||
MAP_DE1M8B // "tech gone bad"
|
||||
MAP_DE1M8B, // "tech gone bad"
|
||||
MAP_ID24MAP13, // TODO Soul Silo cybies
|
||||
MAP_ID24MAP14 // TODO Brink tyrants
|
||||
};
|
||||
|
||||
static play void AddBoss( int tid, String tag, bool endgame = false )
|
||||
|
|
@ -237,6 +261,10 @@ extend Class SWWMHandler
|
|||
return MAP_EVMAP30;
|
||||
if ( mapsum ~== "CF2B3E2589CA6FBB6EE3E3A09F19BA18" )
|
||||
return MAP_EVIIMAP30;
|
||||
if ( mapsum ~== "7CABD8B043B69996D9777F7070C8BCCE" )
|
||||
return MAP_ID24MAP13;
|
||||
if ( mapsum ~== "A3F7A58FC08C369F1360741A99F1497C" )
|
||||
return MAP_ID24MAP14;
|
||||
return MAP_NONE;
|
||||
}
|
||||
private void VanillaBossSpawn( WorldEvent e )
|
||||
|
|
@ -320,6 +348,42 @@ extend Class SWWMHandler
|
|||
bosstag = "$BT_CYBIE2";
|
||||
}
|
||||
}
|
||||
else if ( bossmap == MAP_ID24MAP13 )
|
||||
{
|
||||
if ( e.Thing is 'Cyberdemon' )
|
||||
{
|
||||
bossactors.Push(e.Thing);
|
||||
e.Thing.StartHealth = e.Thing.Health *= 4;
|
||||
e.Thing.GiveInventory('BossMarker',1);
|
||||
bosstag = "$BT_CYBIE3";
|
||||
}
|
||||
}
|
||||
else if ( bossmap == MAP_ID24MAP14 )
|
||||
{
|
||||
if ( e.Thing is 'Deh_Actor_156' )
|
||||
{
|
||||
bossactors.Push(e.Thing);
|
||||
e.Thing.StartHealth = e.Thing.Health *= 4;
|
||||
e.Thing.GiveInventory('BossMarker',1);
|
||||
bosstag = "$BT_TYRANT";
|
||||
}
|
||||
else if ( e.Thing is 'Deh_Actor_155' )
|
||||
{
|
||||
e.Thing.StartHealth = e.Thing.Health *= 4;
|
||||
e.Thing.GiveInventory('BossMarker',1);
|
||||
}
|
||||
else if ( e.Thing is 'Deh_Actor_157' )
|
||||
{
|
||||
e.Thing.StartHealth = e.Thing.Health *= 4;
|
||||
e.Thing.GiveInventory('BossMarker',1);
|
||||
e.Thing.GiveInventory('TyrantWake',1);
|
||||
}
|
||||
else if ( e.Thing is 'Cyberdemon' )
|
||||
{
|
||||
e.Thing.StartHealth = e.Thing.Health *= 4;
|
||||
e.Thing.GiveInventory('BossMarker',1);
|
||||
}
|
||||
}
|
||||
else if ( bossmap == MAP_HE1M8_HE4M8 )
|
||||
{
|
||||
if ( e.Thing is 'IronLich' )
|
||||
|
|
|
|||
|
|
@ -80,7 +80,8 @@ extend Class SWWMHandler
|
|||
else if ( SWWMUtility.IsEviternity() )
|
||||
{
|
||||
// we have to do some heavy lifting here because episodes don't match clusters
|
||||
if ( level.levelnum <= 5 ) clust = 1;
|
||||
if ( level.levelnum <= 0 ) {}
|
||||
else if ( level.levelnum <= 5 ) clust = 1;
|
||||
else if ( level.levelnum <= 10 ) clust = 2;
|
||||
else if ( level.levelnum <= 15 ) clust = 3;
|
||||
else if ( level.levelnum <= 20 ) clust = 4;
|
||||
|
|
@ -93,6 +94,15 @@ extend Class SWWMHandler
|
|||
else clust = 8;
|
||||
}
|
||||
}
|
||||
else if ( SWWMUtility.IsLegacyOfRust() )
|
||||
{
|
||||
// clusters must be manually assigned
|
||||
if ( level.levelnum <= 0 ) {}
|
||||
if ( (level.levelnum <= 7) || (level.levelnum == 15) ) clust = 28;
|
||||
else if ( (level.levelnum <= 14) || (level.levelnum == 16) ) clust = 29;
|
||||
if ( (level.levelnum == 15) || (level.levelnum == 16) )
|
||||
secret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (gameinfo.gametype&GAME_DOOM) && ((level.cluster == 9) || (level.cluster == 10)) )
|
||||
|
|
|
|||
|
|
@ -69,6 +69,17 @@ extend Class DemolitionistMenu
|
|||
c_minute = 9;
|
||||
c_tz = "+09";
|
||||
}
|
||||
else if ( SWWMUtility.IsLegacyOfRust() )
|
||||
{
|
||||
// August 8th 2150, 02:31 EDT
|
||||
// (August 8th 2150, 11:31 JST)
|
||||
c_year = 2150;
|
||||
c_month = 7;
|
||||
c_day = 7;
|
||||
c_hour = 2;
|
||||
c_minute = 31;
|
||||
c_tz = "EDT";
|
||||
}
|
||||
else // Doom
|
||||
{
|
||||
// June 6th 2148, 18:37 EDT
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ Class DemolitionistMissionTab : DemolitionistMenuTab
|
|||
}
|
||||
// saves time
|
||||
bool nrftl = false;
|
||||
bool lor = false;
|
||||
bool eviternity = false;
|
||||
bool eviternitwo = false;
|
||||
bool hexdd = false;
|
||||
|
|
@ -32,6 +33,7 @@ Class DemolitionistMissionTab : DemolitionistMenuTab
|
|||
{
|
||||
int clus = level.cluster;
|
||||
if ( clus == 11 ) nrftl = true;
|
||||
lor = SWWMUtility.IsLegacyOfRust();
|
||||
eviternity = SWWMUtility.IsEviternity();
|
||||
eviternitwo = SWWMUtility.IsEviternityTwo();
|
||||
if ( eviternitwo )
|
||||
|
|
@ -59,6 +61,14 @@ Class DemolitionistMissionTab : DemolitionistMenuTab
|
|||
else if ( level.levelnum <= 32 ) clus = 8;
|
||||
missionstr = String.Format("$SWWM_MISSION_EVITERNITY%d",clus);
|
||||
}
|
||||
else if ( lor )
|
||||
{
|
||||
// legacy of rust has its quirks, as with umapinfo there are
|
||||
// technically no clusters
|
||||
if ( (level.levelnum <= 7) || (level.levelnum == 15) ) clus = 28;
|
||||
else if ( (level.levelnum <= 14) || (level.levelnum == 16) ) clus = 29;
|
||||
missionstr = String.Format("$SWWM_MISSION_DOOM%d",clus);
|
||||
}
|
||||
// naive method to guess if this is sigil
|
||||
else if ( (clus == 5) && (level.mapname.Left(2) == "E5") )
|
||||
missionstr = String.Format("$SWWM_MISSION_SIGIL");
|
||||
|
|
|
|||
|
|
@ -223,42 +223,63 @@ Class SWWMStats : SWWMStaticThinker
|
|||
return null;
|
||||
}
|
||||
|
||||
// we doin' that thing again, yup
|
||||
int ClusterRemap( int clus, int levelnum )
|
||||
{
|
||||
if ( SWWMUtility.IsEviternityTwo() )
|
||||
{
|
||||
// clusters in eviternity 2 have to be remapped
|
||||
if ( clus == 5 ) return 1;
|
||||
if ( (clus == 6) || (clus == 13) ) return 2;
|
||||
if ( (clus == 7) || (clus == 14) ) return 3;
|
||||
if ( (clus == 8) || (clus == 15) ) return 4;
|
||||
if ( (clus == 9) || (clus == 16) ) return 5;
|
||||
if ( (clus == 10) || (clus == 17) ) return 6;
|
||||
if ( (clus == 11) || (clus == 12) || (clus == 18) || (clus == 19) ) return 7;
|
||||
}
|
||||
else if ( SWWMUtility.IsEviternity() )
|
||||
{
|
||||
// we have to do some heavy lifting here because episodes don't match clusters
|
||||
if ( levelnum <= 0 ) return clus;
|
||||
if ( levelnum <= 5 ) return 1;
|
||||
if ( levelnum <= 10 ) return 2;
|
||||
if ( levelnum <= 15 ) return 3;
|
||||
if ( levelnum <= 20 ) return 4;
|
||||
if ( levelnum <= 25 ) return 5;
|
||||
if ( levelnum <= 30 ) return 6;
|
||||
if ( levelnum <= 31 ) return 7;
|
||||
if ( levelnum <= 32 ) return 8;
|
||||
}
|
||||
else if ( SWWMUtility.IsLegacyOfRust() )
|
||||
{
|
||||
// legacy of rust has its quirks, as with umapinfo there are
|
||||
// technically no clusters
|
||||
if ( levelnum <= 0 ) return clus;
|
||||
if ( (levelnum <= 7) || (levelnum == 15) ) return 28;
|
||||
else if ( (levelnum <= 14) || (levelnum == 16) ) return 29;
|
||||
}
|
||||
return clus;
|
||||
}
|
||||
|
||||
void PreloadLevelStats()
|
||||
{
|
||||
// pre-adds all unvisited levels from the current cluster
|
||||
int nlevels = LevelInfo.GetLevelInfoCount();
|
||||
int ourcluster = ClusterRemap(level.cluster,level.levelnum);
|
||||
for ( int i=0; i<nlevels; i++ )
|
||||
{
|
||||
let li = LevelInfo.GetLevelInfo(i);
|
||||
if ( !li.isValid() || !LevelInfo.MapExists(li.mapname)
|
||||
|| (li.cluster != level.cluster)
|
||||
|| FindLevelStats(li.mapname) )
|
||||
continue;
|
||||
// wadfusion hack for E1M4B and E1M8B
|
||||
bool wf_hack = false;
|
||||
if ( (li.mapname == "E1M4") && LevelInfo.MapExists("E1M4B") )
|
||||
{
|
||||
let cv = CVar.GetCVar('wf_blackroomswap_e1m4b');
|
||||
if ( cv && cv.GetBool() )
|
||||
{
|
||||
wf_hack = true;
|
||||
li = LevelInfo.FindLevelInfo("E1M4B");
|
||||
}
|
||||
}
|
||||
else if ( (li.mapname == "E1M8") && LevelInfo.MapExists("E1M8B") )
|
||||
{
|
||||
let cv = CVar.GetCVar('wf_blackroomswap_e1m8b');
|
||||
if ( cv && cv.GetBool() )
|
||||
{
|
||||
wf_hack = true;
|
||||
li = LevelInfo.FindLevelInfo("E1M8B");
|
||||
}
|
||||
}
|
||||
int theircluster = ClusterRemap(li.cluster,li.levelnum);
|
||||
if ( theircluster != ourcluster )
|
||||
continue;
|
||||
let ls = new('LevelStat');
|
||||
// we can automatically assume that all levels from the same cluster will have this flag as well
|
||||
ls.hub = !!(level.clusterflags&level.CLUSTER_HUB);
|
||||
ls.visited = false;
|
||||
ls.cluster = wf_hack?1:li.cluster; // force cluster to be 1 for Romero's extra maps
|
||||
ls.cluster = theircluster;
|
||||
ls.levelname = li.LookupLevelName();
|
||||
// level name may contain trailing whitespace due to DEHACKED nonsense, so strip it
|
||||
ls.levelname.StripRight();
|
||||
|
|
@ -614,7 +635,7 @@ Class SWWMLoreLibrary : SWWMStaticThinker
|
|||
else if ( text ~== "SWWM_LORETXT_MARISA" )
|
||||
text = "SWWM_LORETXT_MARISA2"; // post-invasion update
|
||||
}
|
||||
if ( (gameinfo.gametype&GAME_Raven) || SWWMUtility.IsEviternity() || SWWMUtility.IsEviternityTwo() || (mlog && (mlog.year >= 2150) && (mlog.month >= 5)) )
|
||||
if ( (gameinfo.gametype&GAME_Raven) || SWWMUtility.IsEviternity() || SWWMUtility.IsEviternityTwo() || SWWMUtility.IsLegacyOfRust() || (mlog && (mlog.year >= 2150) && (mlog.month >= 5)) )
|
||||
{
|
||||
if ( text ~== "SWWM_LORETXT_AKARILABS" )
|
||||
text = "SWWM_LORETXT_AKARILABS2"; // demo won, akari project announced
|
||||
|
|
|
|||
|
|
@ -52,10 +52,16 @@ extend Class SWWMUtility
|
|||
if ( IsEviternity() ) return true;
|
||||
if ( IsEviternityTwo() ) return true;
|
||||
if ( IsUltDoom2() ) return true;
|
||||
if ( IsLegacyOfRust() ) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsLegacyOfRust()
|
||||
{
|
||||
return CheckMD5List("id1.lst");
|
||||
}
|
||||
|
||||
// detect ultimate doom 2
|
||||
static bool IsUltDoom2()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -84,6 +84,26 @@ extend Class SWWMUtility
|
|||
case 'CyberdemonMAP24':
|
||||
basetag = "CYBER";
|
||||
break;
|
||||
case 'ID24Banshee':
|
||||
basetag = "ID24BANSHEE";
|
||||
break;
|
||||
case 'ID24Ghoul':
|
||||
basetag = "ID24GHOUL";
|
||||
break;
|
||||
case 'ID24Mindweaver':
|
||||
basetag = "ID24MINDWEAVER";
|
||||
break;
|
||||
case 'ID24PlasmaGuy':
|
||||
basetag = "ID24SHOCKTROOPER";
|
||||
break;
|
||||
case 'ID24Vassago':
|
||||
basetag = "ID24VASSAGO";
|
||||
break;
|
||||
case 'ID24Tyrant':
|
||||
case 'ID24TyrantBoss1':
|
||||
case 'ID24TyrantBoss2':
|
||||
basetag = "ID24TYRANT";
|
||||
break;
|
||||
case 'SWWMBossBrain':
|
||||
basetag = "BOSSBRAIN";
|
||||
break;
|
||||
|
|
@ -303,6 +323,8 @@ extend Class SWWMUtility
|
|||
Class<Actor> rescls = res;
|
||||
return rescls;
|
||||
}
|
||||
// special boss tyrants in LoR final map
|
||||
if ( (a == 'ID24TyrantBoss1') || (a == 'ID24TyrantBoss2') ) return 'ID24Tyrant';
|
||||
// stealth monsters, the worst thing ever invented
|
||||
if ( a == 'StealthArachnotron' ) return 'Arachnotron';
|
||||
if ( a == 'StealthArchvile' ) return 'Archvile';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue