Implement Hexen MAP40 instakill workaround.

Omnisight increases how long targetted monsters stay on-screen, by 4 seconds.
This commit is contained in:
Mari the Deer 2020-02-27 14:00:35 +01:00
commit 83585826d2
3 changed files with 74 additions and 8 deletions

View file

@ -1175,6 +1175,36 @@ Class LastLine
int lineno;
}
// Korax instakill handler
Class UglyBoyGetsFuckedUp : Thinker
{
bool wedone;
override void Tick()
{
if ( wedone ) return;
if ( level.killed_monsters < level.total_monsters )
{
// stop portal door
int sidx = level.CreateSectorTagIterator(145).Next();
if ( sidx == -1 ) return;
Sector door = level.Sectors[sidx];
let ti = ThinkerIterator.Create("SectorEffect");
SectorEffect se;
while ( se = SectorEffect(ti.Next()) )
{
if ( se.GetSector() != door ) continue;
se.Destroy();
door.StopSoundSequence(CHAN_VOICE);
}
return;
}
wedone = true;
level.ExecuteSpecial(Door_Open,null,null,false,145,8);
Destroy();
}
}
// Handler responsible for item replacements and whatever else
Class SWWMHandler : EventHandler
{
@ -1566,6 +1596,14 @@ Class SWWMHandler : EventHandler
lastcombat = AddOneliner("fightstart",1,10);
}
private bool HexenMap40()
{
if ( level.GetChecksum() ~== "2A6C4235B942467D25FD50D5B313E67A" ) return true; // 1.1
if ( level.GetChecksum() ~== "1C5DE5A921DEE405E98E7E09D9829387" ) return true; // 1.0
if ( level.GetChecksum() ~== "EFAFE59092DE5E613562ACF52B86C37F" ) return true; // beta
return false;
}
override void WorldThingDied( WorldEvent e )
{
if ( (e.Thing.default.bBOSS && !Random[GoldDrop](0,2)) || (e.Thing.default.bBOSSDEATH && !Random[GoldDrop](0,6)) )
@ -1575,6 +1613,27 @@ Class SWWMHandler : EventHandler
g.vel.xy = (cos(ang),sin(ang))*FRandom[SpareShells](.4,.8);
g.vel.z = FRandom[SpareShells](2.,4.);
}
// Korax instakill
if ( (e.Thing is 'Korax') && !e.Thing.special2 && HexenMap40() )
{
e.Thing.special2 = 1;
// terminate the monster closet scripts, open all the
// doors ourselves
level.ExecuteSpecial(ACS_Terminate,e.Thing,null,false,220);
level.ExecuteSpecial(ACS_Terminate,e.Thing,null,false,220);
level.ExecuteSpecial(ACS_Terminate,e.Thing,null,false,221);
level.ExecuteSpecial(ACS_Terminate,e.Thing,null,false,255);
level.ExecuteSpecial(Door_Open,e.Thing,null,false,10,16);
level.ExecuteSpecial(Door_Open,e.Thing,null,false,11,16);
level.ExecuteSpecial(Door_Open,e.Thing,null,false,12,16);
level.ExecuteSpecial(Door_Open,e.Thing,null,false,13,16);
level.ExecuteSpecial(Door_Open,e.Thing,null,false,14,16);
level.ExecuteSpecial(Door_Open,e.Thing,null,false,10,16);
// keep the portal closed, you can't leave unless you
// kill everyone else
let t = new("UglyBoyGetsFuckedUp");
t.ChangeStatNum(Thinker.STAT_USER);
}
}
override void WorldThingDamaged( WorldEvent e )

View file

@ -44,7 +44,8 @@ Class SWWMStatusBar : BaseStatusBar
override void FlushNotify()
{
if ( level.maptime <= 1 ) {
if ( level.maptime <= 1 )
{
// flush ALL messages
MainQueue.Clear();
PickupQueue.Clear();
@ -157,7 +158,8 @@ Class SWWMStatusBar : BaseStatusBar
private bool CmpInterest( SWWMInterest a, SWWMInterest b )
{
return a.type < b.type; }
return a.type < b.type;
}
private bool CmpDist( Vector3 a, Vector3 b )
{
@ -222,13 +224,15 @@ Class SWWMStatusBar : BaseStatusBar
targets.Clear();
let ti = ThinkerIterator.Create("SWWMCombatTracker",Thinker.STAT_USER);
SWWMCombatTracker ct;
int extratime = 35;
if ( CPlayer.mo.FindInventory("Omnisight") ) extratime += 105;
while ( ct = SWWMCombatTracker(ti.Next()) )
{
if ( !targetter.GetBool() ) break;
// ignore player unless chasecamming
if ( (ct.mytarget == players[consoleplayer].mo) && (players[consoleplayer].Camera == players[consoleplayer].mo) && !(players[consoleplayer].cheats&CF_CHASECAM) ) continue;
if ( ct.myplayer && deathmatch ) continue; // no players in dm
if ( level.maptime > ct.updated+35 ) continue;
if ( level.maptime > ct.updated+extratime ) continue;
targets.Push(ct);
}
// sort by distance (give priority to players)
@ -353,9 +357,10 @@ Class SWWMStatusBar : BaseStatusBar
proj.Reorient(ViewPos,ViewRot);
proj.BeginProjection();
Vector3 vdir = (cos(ViewRot.x)*cos(ViewRot.y),sin(ViewRot.x)*cos(ViewRot.y),-sin(ViewRot.y));
bool thesight = !!CPlayer.mo.FindInventory("Omnisight");
// points of interest
String tag;
if ( CPlayer.mo.FindInventory("Omnisight") )
if ( thesight )
{
for ( int i=0; i<interesting.Size(); i++ )
{
@ -385,7 +390,9 @@ Class SWWMStatusBar : BaseStatusBar
if ( !proj.IsInFront() ) continue;
Vector2 vpos = viewport.SceneToWindow(npos);
tag = targets[i].mytag;
double alph = ((targets[i].updated+35)-level.maptime)/35.;
int mtime = 35;
if ( thesight && (targets[i].lasthealth > 0) ) mtime += 105;
double alph = clamp(((targets[i].updated+mtime)-level.maptime)/35.,0.,1.);
Vector2 barsiz = TexMan.GetScaledSize(EnemyBTex);
barsiz.x *= hs.x;
barsiz.y *= hs.y;

View file

@ -340,7 +340,7 @@ Class Demolitionist : PlayerPawn
lastground = player.onground;
lastvelz = prevvelz;
prevvelz = vel.z;
bNOFRICTION = (((waterlevel<2)&&(bFly||bFlyCheat||(player.cheats&CF_NOCLIP2)))||InStateSequence(CurState,FindState("Dash")));
bNOFRICTION = (((waterlevel<2)&&(bFly||bFlyCheat&&!(player.cheats&CF_NOCLIP2)))||InStateSequence(CurState,FindState("Dash")));
fuelcooldown = max(0,fuelcooldown-1);
dashcooldown = max(0,dashcooldown-1);
boostcooldown = max(0,boostcooldown-1);
@ -437,7 +437,7 @@ Class Demolitionist : PlayerPawn
}
override void CheckPitch()
{
if ( (waterlevel < 2) && (bFly || bFlyCheat || (player.cheats&CF_NOCLIP2)) )
if ( (waterlevel < 2) && (bFly || bFlyCheat) && !(player.cheats&CF_NOCLIP2) )
return; // handled in moveplayer
Super.CheckPitch();
}
@ -473,7 +473,7 @@ Class Demolitionist : PlayerPawn
{
if ( InStateSequence(CurState,FindState("Dash")) )
player.cmd.forwardmove = player.cmd.sidemove = 0;
if ( (waterlevel < 2) && (bFly || bFlyCheat) )
if ( (waterlevel < 2) && (bFly || bFlyCheat) && !(player.cheats&CF_NOCLIP2) )
{
player.onground = false;
if ( player.turnticks )