-- j2b2's Starpost Warp local CV_SWMode = { ["Off"] = 0, ["All"] = 1, ["Checkpoint"] = 2, ["Finished"] = 3 } local cvSWMode = CV_RegisterVar({name="swarp_mode",defaultvalue="Finished",flags=CV_NETVAR | CV_SHOWMODIF,PossibleValue=CV_SWMode}) local function IsValid(a) if a ~= nil then return a.valid end return false end local function CanWarp(player) return cvSWMode.value ~= 0 and (player.pflags & PF_FINISHED or cvSWMode.value < 3) and player.playerstate & PST_DEAD == 0 and player.spectator == false and player.exiting == 0 end local function CheckpointValid(player,checkpoint) return checkpoint ~= nil and checkpoint.valid and (player.starpostnum >= checkpoint.health or cvSWMode.value ~= 2) end local function GetStarposts() local starposts = {} for mobj in mobjs.iterate() do if mobj.type == MT_STARPOST then table.insert(starposts,mobj) end end table.sort(starposts,function(a,b) return a.health < b.health end) return starposts end local function GetNextStarpost(player,starposts) if CheckpointValid(player,player.starpostlast) == false then if CheckpointValid(player,starposts[1]) then return 1, starposts[1] else return nil end end for i,v in ipairs(starposts) do if v == player.starpostlast then local nextStarpost = starposts[i+1] if CheckpointValid(player,nextStarpost) then return i+1, nextStarpost elseif CheckpointValid(player,starposts[1]) then return 1, starposts[1] else return end end end end local function GetPrevStarpost(player,starposts) local heighestStarpostNum = 0 local heighestStarpost for i,v in ipairs(starposts) do if v == player.starpostlast and i > 1 and CheckpointValid(player,starposts[i-1]) then return i-1, starposts[i-1] elseif CheckpointValid(player,v) then heighestStarpostNum = i heighestStarpost = v end end return heighestStarpostNum, heighestStarpost end local function WarpToStarpost(player,starpost,starpostNumber) player.powers[pw_flashing] = 2*TICRATE player.powers[pw_carry] = CR_NONE player.pflags = player.pflags & ~(PF_JUMPED | PF_SPINNING | PF_STARTDASH | PF_THOKKED | PF_SHIELDABILITY | PF_GLIDING | PF_BOUNCING | PF_SLIDING) player.mo.momx = 0 player.mo.momy = 0 player.mo.momz = 0 player.mo.angle = starpost.angle player.drawangle = starpost.angle player.mo.state = S_PLAY_STND player.mo.flags2 = player.mo.flags2 & ~MF2_TWOD if starpost.flags2 & MF2_OBJECTFLIP then player.mo.flags2 = player.mo.flags2 | MF2_OBJECTFLIP P_TeleportMove(player.mo,starpost.x,starpost.y,starpost.z+starpost.height) else player.mo.flags2 = player.mo.flags2 & ~MF2_OBJECTFLIP P_TeleportMove(player.mo,starpost.x,starpost.y,starpost.z) end S_StartSound(player.mo,sfx_mixup) if player == displayplayer then print("Warping to checkpoint #"..starpostNumber) end end addHook("TouchSpecial",function(mobj,toucher) if IsValid(toucher) then local shouldOverride = false if toucher.type == MT_PLAYER and CanWarp(toucher.player) and toucher.player.starpostlast ~= mobj and mobj.health <= toucher.player.starpostnum then toucher.player.starpostx = toucher.player.mo.x/FRACUNIT toucher.player.starposty = toucher.player.mo.y/FRACUNIT if mobj.flags2 & MF2_OBJECTFLIP then toucher.player.starpostz = mobj.z/FRACUNIT+mobj.height/FRACUNIT toucher.player.starpostscale = -toucher.player.mo.scale else toucher.player.starpostz = mobj.z/FRACUNIT toucher.player.starpostscale = toucher.player.mo.scale end toucher.player.starposttime = leveltime toucher.player.starpostangle = mobj.angle mobj.state = mobj.info.painstate S_StartSound(mobj,mobj.info.painsound) shouldOverride = true end toucher.player.starpostlast = mobj return shouldOverride end end,MT_STARPOST) addHook("PlayerThink",function(player) if CanWarp(player) then if player.cmd.buttons & BT_WEAPONNEXT and player.warping == false then local starposts = GetStarposts() local starpostNumber, starpost = GetNextStarpost(player,starposts) if starpost ~= nil then WarpToStarpost(player,starpost,starpostNumber) end elseif player.cmd.buttons & BT_WEAPONPREV and player.warping == false then local starposts = GetStarposts() local starpostNumber, starpost = GetPrevStarpost(player,starposts) if starpost ~= nil then WarpToStarpost(player,starpost,starpostNumber) end end end player.warping = player.cmd.buttons & (BT_WEAPONNEXT | BT_WEAPONPREV) > 0 end) local HUD_X = 16 local HUD_Y = 76 local hudDelay = 0 hud.add(function(v) if CanWarp(displayplayer) and displayplayer.pflags & PF_FINISHED then if hudDelay > 0 then v.drawString(HUD_X,HUD_Y,"prev/next weapon:", V_SNAPTOTOP | V_SNAPTOLEFT | V_YELLOWMAP | V_HUDTRANS, "thin") v.drawString(HUD_X,HUD_Y+8,"warp to checkpoints", V_SNAPTOTOP | V_SNAPTOLEFT | V_HUDTRANS, "thin") else hudDelay = hudDelay + 1 end else hudDelay = 0 end end,"game") -- j2b2's Starpost Warp