// 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 SetupLockdefsCache( SWWMCachedLockInfo cli ) { for ( int i=0; i lines; lines.Clear(); data.Split(lines,"\n"); bool valid = false; for ( int j=0; j spl; spl.Clear(); lines[j].Split(spl," ",TOK_SKIPEMPTY); // check game string (if any) if ( spl.Size() > 2 ) { if ( (spl[2] ~== "DOOM") && !(gameinfo.gametype&GAME_Doom) ) continue; else if ( (spl[2] ~== "HERETIC") && !(gameinfo.gametype&GAME_Heretic) ) continue; else if ( (spl[2] ~== "HEXEN") && !(gameinfo.gametype&GAME_Hexen) ) continue; else if ( (spl[2] ~== "STRIFE") && !(gameinfo.gametype&GAME_Strife) ) continue; else if ( (spl[2] ~== "CHEX") && !(gameinfo.gametype&GAME_Chex) ) continue; } // valid lock, prepare it let li = new("LIEntry"); li.locknumber = spl[1].ToInt(); li.hascolor = false; // see if there's a Mapcolor defined int k = j+1; for ( int k=j+2; k 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; } bool isexit; int exittype; [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; } } }