// WorldLoaded/WorldUnloaded events Class RampancyLogonDummy : Actor { States { Spawn: TNT1 A 7; TNT1 AAAAAAAAAAAAAAAA 1 { for ( int i=0; i<16; i++ ) A_Log("Remote login failed."); } TNT1 A 7; TNT1 A 1 A_Log("\cgWARNING:\cj 256 failed remote login attempts have been reported in the last second.\c-"); Stop; } } extend Class SWWMHandler { bool maphaskeys; // level end stats override void WorldUnloaded( WorldEvent e ) { let ti = ThinkerIterator.Create("SWWMStats",Thinker.STAT_STATIC); SWWMStats s; while ( s = SWWMStats(ti.Next()) ) { int clust = 0; bool secret = false; if ( SWWMUtility.IsEviternity() ) { // we have to do some heavy lifting here because episodes don't match clusters 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; else if ( level.levelnum <= 25 ) clust = 5; else if ( level.levelnum <= 30 ) clust = 6; else if ( level.levelnum <= 32 ) { secret = true; if ( level.levelnum <= 31 ) clust = 7; else clust = 8; } } else { if ( (gameinfo.gametype&GAME_DOOM) && ((level.cluster == 9) || (level.cluster == 10)) ) secret = true; clust = level.cluster; } int csiz = s.clustervisit.Size(); if ( csiz == 0 ) { s.clustervisit.Push(clust); s.secretdone.Push(secret); } else if ( s.clustervisit[csiz-1] != clust ) { s.clustervisit.Push(clust); s.secretdone.Push(secret|s.secretdone[csiz-1]); } s.AddLevelStats(); s.lastcluster = level.cluster; // nazi cleanup let ti = ThinkerIterator.Create("Actor"); Actor a; bool hasnazis = false; bool livenazis = false; while ( a = Actor(ti.Next()) ) { // yes, the dogs don't count (they're just dogs) if ( !(a is 'SWWMGuard') && !(a is 'SWWMSS') && !(a is 'SWWMHans') ) continue; hasnazis = true; if ( a.Health > 0 ) livenazis = true; } if ( hasnazis && !livenazis ) { if ( level.levelnum == 31 ) s.nazicleanup |= 1; else if ( level.levelnum == 32 ) s.nazicleanup |= 2; } if ( s.nazicleanup == 3 ) SWWMUtility.MarkAchievement("trash",s.myplayer); } // reset score on dead players (death exitâ„¢) for ( int i=0; i 0) || (level.total_items > 0) || (level.total_secrets > 0)) && (level.killed_monsters == 0) && (level.found_items == 0) && (level.found_secrets == 0) ) SWWMUtility.MarkAchievement("hurry",players[consoleplayer]); } private void MapStartDialogues() { int whichboss = WhichVanillaBossMap(); switch ( whichboss ) { case MAP_DE1M8: SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_PHOBOS); break; case MAP_DE2M8: SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_DEIMOS); break; case MAP_DE3M8: SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_DIS); break; case MAP_DE4M8: SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_THY); break; case MAP_DMAP07: SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_DIMPLE); break; case MAP_DMAP30: bool rampancy = false; foreach ( cls:AllActorClasses ) { if ( cls.GetClassName() != "Robot_BossBrain" ) continue; rampancy = true; break; } if ( rampancy ) SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_RAMPANCY); else SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_IOS); break; case MAP_DLVL08: SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_NERVE); break; case MAP_EVMAP30: SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_EVIA); break; case MAP_HE1M8_HE4M8: if ( level.mapname ~== "E1M8" ) SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_MAW); else SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_HEADS); break; case MAP_HE2M8_HE5M8: if ( level.mapname ~== "E2M8" ) SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_PORTALS); else SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_BULLS); break; case MAP_HE3M8: SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_DSPARIL); break; case MAP_HMAP38: SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_CLERIC); break; case MAP_HMAP36: SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_FIGHTER); break; case MAP_HMAP37: SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_MAGE); break; case MAP_HMAP12: SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_HYPO); break; case MAP_HMAP40: SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_KORAX); break; case MAP_HMAP23_HMAP27_HMAP48_HMAP55: if ( level.mapname ~== "MAP48" ) SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_CONSTABLE); break; case MAP_HMAP60: SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_DEATHKINGS); break; case MAP_NONE: String csum = level.GetChecksum(); // SIGIL E5M8 if ( (csum ~== "3D72FD17F36D2D43FD9A21E6E57EE357") || (csum ~== "09B30C9DA9D73D3D5A709502FBB947AA") || (csum ~== "6EAD80DA1F30B4B3546FA294EEF9F87C") ) SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_SIGIL); // Doom 2 MAP11 else if ( (csum ~== "73D9E03CEE7BF1A97EFD2EAD86688EF8") || (csum ~== "F4F2A769609988837458772AAE99008C") || (csum ~== "DF6A001A6C42DB5CCA599EE5883B294A") ) SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_CIRCLE); // Doom 2 MAP20 else if ( (csum ~== "8898F5EC9CBDCD98019A1BC1BF892A8A") || (csum ~== "CC53CFFCB30E873669AA2F09DA0D3566") ) SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_GOTCHA); // Eviternity // MAP05 else if ( csum ~== "33B8501B10CE5E2555C03725F765A914" ) SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_DMN); // MAP10 else if ( csum ~== "9E83602D325677B8D7C3BC44BEF9B03F" ) SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_CRE); // MAP15 else if ( csum ~== "CA40E6DDAB6B5C924CDC36B1F851421E" ) SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_CRY); // MAP20 else if ( csum ~== "F34B3FD4D13AC763469A8E0D7379B9D0" ) SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_CON); // MAP25 else if ( csum ~== "196BC735473C593F924A59B238574C35" ) SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_SLA); // Deathkings // Blight else if ( csum ~== "E3EFB0156A20ADF2DF00915A0EA85DF5" ) SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_BLIGHT); // Nave else if ( csum ~== "E2B5D1400279335811C1C1C0B437D9C8" ) SendInterfaceEvent(consoleplayer,"swwmsetdialogue",SWWMDLG_NAVE); break; } } override void WorldLoaded( WorldEvent e ) { // session globals must be loaded here // (if we do it in OnRegister the existing thinker might not have been deserialized yet) gdat = SWWMGlobals.Get(); if ( e.IsReopen ) return; MapStartDialogues(); if ( gamestate != GS_TITLELEVEL ) { if ( (level.GetChecksum() ~== "D0E5ECD94BD38DF33F25515C00148693") || (level.GetChecksum() ~== "D20297AE8447232F6DBE4851E3104668") || (level.GetChecksum() ~== "EBBB8663AD4AB22294A8A1D211A026CD") ) { if ( !AddOneliner("nutstart",3) ) AddOneliner("mapstart",3); } else AddOneliner("mapstart",3); } if ( level.levelname ~== "Modder Test Map" ) { level.ReplaceTextures("-noflat-","kinstile",0); S_ChangeMusic("music/CARDISH1.XM"); AddBoss(6666,"$BT_DOOMTEST"); // for testing boss healthbars } // doom vacation map01 hackaround for OPEN script not letting us // change certain line specials in levelpostprocessor because // ACS is just mindbogglingly weird like that, seriously if ( (level.GetChecksum() ~== "F286BABF0D152259CD6B996E8920CA70") || (level.GetChecksum() ~== "A52BD2038CF814101AAB7D9C78F9ACE2") ) level.ExecuteSpecial(ACS_Execute,null,null,false,-Int('DVACATION_UNSCREW')); // rampancy boss brain fix (repeatedly triggering "map clear") let ti = ThinkerIterator.Create("Actor"); Actor a, brain; bool haseye = false; while ( a = Actor(ti.Next()) ) { if ( a.GetClassName() == "Robot_BossEye" ) haseye = true; if ( a.GetClassName() == "Robot_BossBrain" ) brain = a; } if ( haseye && brain ) { brain.bCOUNTKILL = true; level.total_monsters++; // while we're at it Actor.Spawn("RampancyLogonDummy"); } // KDiKDiZD abort fix due to voodoo doll post-spawn replacement // (we have our own mikoportal compatibility, anyway) // // note that the mods are mutually incompatible nonetheless // since KDiKDiZD requires software rendering, while this is a // hardware-only mod... but hey, they can sort-of-work together // (with broken visual effects, but still... somewhat working) foreach ( cls:AllClasses ) { if ( cls.GetClassName() != 'KdikdizdCompatEventHandler' ) continue; ti = ThinkerIterator.Create("Thinker"); Thinker t; while ( t = ti.Next() ) { if ( t.GetClassName() != 'VoodooPusher' ) continue; t.Destroy(); } break; } // for skipping over merged exit lines (sharing vertices) Array skipme; skipme.Clear(); // find exit lines, and use lines that aren't exits foreach ( l:level.Lines ) { // all lines are immediately visible in DM if ( deathmatch && !(l.flags&Line.ML_DONTDRAW) ) l.flags |= Line.ML_MAPPED; // while we're at it, add teleporter sparks if ( SWWMUtility.IsTeleportLine(l) ) { let a = SWWMTeleportLine(Actor.Spawn("SWWMTeleportLine")); a.tline = l; } let [isexit, exittype] = SWWMUtility.IsExitLine(l); if ( !isexit ) continue; if ( skipme.Find(l) < skipme.Size() ) continue; skipme.Push(l); // look for connected lines Array con; con.Clear(); con.Push(l); int found; if ( l.frontsector ) { do { found = 0; foreach ( l2:l.frontsector.Lines ) { if ( (l2.special != l.special) || (con.Find(l2) < con.Size()) ) continue; // needs to have a point in common with this one or any of the added lines bool nomatches = true; foreach ( c:con ) { if ( (l2.v1 != c.v1) && (l2.v2 != c.v2) && (l2.v1 != c.v2) && (l2.v2 != c.v1) ) continue; nomatches = false; break; } if ( nomatches ) continue; skipme.Push(l2); con.Push(l2); found++; } } while ( found > 0 ); } if ( l.backsector ) { do { found = 0; foreach ( l2:l.backsector.Lines ) { if ( (l2.special != l.special) || (con.Find(l2) < con.Size()) ) continue; // needs to have a point in common with this one or any of the added lines bool nomatches = true; foreach ( s:skipme ) { if ( (l2.v1 != s.v1) && (l2.v2 != s.v2) && (l2.v1 != s.v2) && (l2.v2 != s.v1) ) continue; nomatches = false; break; } if ( nomatches ) continue; skipme.Push(l2); con.Push(l2); found++; } } while ( found > 0 ); } Vector3 lpos = (0,0,0); foreach ( c:con ) lpos += SWWMUtility.UseLinePos(c); lpos /= con.Size(); SWWMInterest.Spawn(self,lpos,theline:l,theexit:exittype); } // spawn loot if ( !deathmatch ) Chancebox.SpawnChanceboxes(); // list map keys maphaskeys = false; ti = ThinkerIterator.Create("Key"); Key k; while ( k = Key(ti.Next()) ) { if ( k.Owner ) continue; maphaskeys = true; break; } } }