--Tweaks a few minor things in the game that annoy me, inspired by L_ManyMinorTweaks-v5.3.1 by EeveeEuphoria-- --Created by Kamen Laudo (aka gabruel_0). Feel free to reuse it and/or modify it-- --Function to check if player is valid-- local function isPlayerValid(player) return player and player.valid and player.mo and player.mo.valid and player.playerstate == PST_LIVE end --Function to check if player is in NiGHTS mode-- local function isPlayerNights(player) return (player.powers[pw_carry] == CR_NIGHTSMODE or player.powers[pw_carry] == CR_NIGHTSFALL) or (maptol & TOL_NIGHTS) or (maptol & TOL_XMAS) end --Function to check if object is valid-- local function isMobjValid(mobj) return mobj and mobj.valid end --Function to update states without reseting them every frame-- local function setNewState(actor, newstate) if actor.state ~= newstate then actor.state = newstate end end --Function to count how many players alive there are in the Special Stage-- local function getSStagePlayersRemaining() local players_alive = 0 for player in players.iterate do if player.nightstime > 0 then players_alive = $ + 1 end end return players_alive end --Coyote Time setup-- addHook("PlayerSpawn", function(player) if isPlayerValid(player) then player.coyotetime = 0 end end) --General gameplay tweaks-- addHook("PlayerThink", function(player) --Check if player is, well, playing!-- if isPlayerValid(player) and not isPlayerNights(player) then --Update Coyote Time flag (prevent player from jumping after launching from springs or slopes)-- if P_IsObjectOnGround(player.mo) then player.coyotetime = TICRATE / 3 elseif player.powers[pw_justsprung] or player.powers[pw_justlaunched] then player.coyotetime = 0 elseif player.coyotetime > 0 then player.coyotetime = $ - 1 end ----Ability tweaks---- --Make flying characters work better-- if (player.charability == CA_FLY) and (player.powers[pw_tailsfly] > 0) and (player.cmd.buttons & BT_JUMP) then player.fly1 = 1 --Characters with Homing Attack cannot use it more the once in the same jump-- elseif (player.charability == CA_HOMINGTHOK) then player.charflags = $ & ~SF_MULTIABILITY --Ensure the Homing Attack doesn't conflict with the Attraction Shield-- if (player.powers[pw_shield] == SH_ATTRACT) then player.charflags = $|SF_NOSHIELDABILITY elseif not (skins[player.mo.skin].flags & SF_NOSHIELDABILITY) then player.charflags = $ & ~SF_NOSHIELDABILITY end --Allow gliding characters to glide multiple times consecutively-- elseif (player.charability == CA_GLIDEANDCLIMB) then player.charflags = $|SF_MULTIABILITY end --Add super forms to everyone (except Neo Sonic, cuz he's buggy T_T)-- if player.mo.skin ~= "msonic" then player.charflags = $|SF_SUPER end --Allow everyone to steer while spinning (except SA Sonic, cuz he doesn't need it ;D)-- if player.mo.skin ~= "adventuresonic" then if P_IsObjectOnGround(player.mo) and (player.mo.state == S_PLAY_ROLL or player.mo.state == S_PLAY_SPINDASH) then player.thrustfactor = 60 else player.thrustfactor = skins[player.mo.skin].thrustfactor end end --Characters in Dash Mode emit ghosts-- if player.charflags & SF_DASHMODE and player.dashmode >= 3 * TICRATE then --Prevent Metal from spawning too many ghost objects-- if player.mo.skin ~= "metalsonic" or player.normalspeed < skins[player.skin].normalspeed * 2 then local ghost = P_SpawnGhostMobj(player.mo) ghost.fuse = 4 if ghost.tracer then ghost.tracer.fuse = ghost.fuse end end end --Prevent machine type characters from drowning or suffocating (dude, seriously, why???)-- if player.charflags & SF_MACHINE then player.powers[pw_underwater] = 100 * TICRATE --Just some arbitrary number player.powers[pw_spacetime] = 100 * TICRATE --Same here end ----Character tweaks---- --Enables Dash Mode for the vanilla trio-- if player.mo.skin == "sonic" or player.mo.skin == "tails" or player.mo.skin == "knuckles" then player.charflags = $|SF_DASHMODE end --Give Sonic and Metal Sonic the Homing Attack-- if player.mo.skin == "sonic" or player.mo.skin == "metalsonic" then player.charability = CA_HOMINGTHOK --Fix Knuckles's jump height (for the love of Kami, WHY???)-- elseif player.mo.skin == "knuckles" then player.jumpfactor = 1 * FRACUNIT end --Slope launch animation (doesn't apply to SA Sonic, X Sonic and Modern Sonic, they don't need it)-- if player.mo.skin ~= "adventuresonic" and player.mo.skin ~= "xsonic" and player.mo.skin ~= "modernsonic" and not P_IsObjectOnGround(player.mo) and not (player.pflags & (PF_JUMPED|PF_THOKKED)) and player.powers[pw_justlaunched] and not P_PlayerInPain(player) then setNewState(player.mo, S_PLAY_SPRING) end end end) --Allow players to respawn in coop special stages ;)-- addHook("ThinkFrame", do for player in players.iterate do if multiplayer and gametype == GT_COOP and G_IsSpecialStage(gamemap) and player.spectator and getSStagePlayersRemaining() > 0 then G_DoReborn(#player) --I got tired of trying to figure out what flags or variables I had to reset for this to work, so I simply reset all of them!-- player.spectator = false player.exiting = 0 player.nightstime = sstimer - leveltime player.powers[pw_nocontrol] = 0 player.pflags = $ & ~PF_FULLSTASIS & ~PF_FINISHED end end end) --Allow players to exit minecarts (except for X Sonic and Modern Sonic, they don't need it)-- addHook("PreThinkFrame", function() for player in players.iterate do if isPlayerValid(player) and not isPlayerNights(player) then if player.powers[pw_carry] == CR_MINECART and isMobjValid(player.mo.tracer) and player.mo.tracer.type == MT_MINECART and player.mo.skin ~= "xsonic" and player.mo.skin ~= "modernsonic" then local minecart = player.mo.tracer if (player.cmd.buttons & BT_SPIN) and not (player.pflags & PF_SPINDOWN) then player.powers[pw_carry] = CR_NONE player.mo.momx = minecart.momx player.mo.momy = minecart.momy P_SetObjectMomZ(player.mo, 8 * FRACUNIT, true) player.mo.state = S_PLAY_FALL minecart.target = nil end end end end end) --Coyote Time and Air Recurl, no more stupid deaths! (Doesn't apply to SA Sonic, tho, didn't figure out how to make it work properly)-- addHook("JumpSpecial", function(player) if isPlayerValid(player) and not isPlayerNights(player) and player.mo.skin ~= "adventuresonic" then if not P_IsObjectOnGround(player.mo) and not (player.pflags & (PF_JUMPED|PF_THOKKED|PF_JUMPDOWN)) and player.powers[pw_carry] == CR_NONE then if player.coyotetime then P_DoJump(player) player.pflags = $|PF_JUMPDOWN & ~PF_THOKKED elseif not (player.charflags & SF_NOJUMPSPIN) player.pflags = $|PF_JUMPDOWN|PF_JUMPED & ~PF_NOJUMPDAMAGE player.mo.state = S_PLAY_JUMP else player.pflags = $|PF_JUMPDOWN|PF_JUMPED end player.secondjump = 0 return true else return false end else return false end end) --Allow players to Uncurl from rolling (except for X Sonic and SA Sonic, they don't need it)-- addHook("SpinSpecial", function(player) if isPlayerValid(player) and not isPlayerNights(player) and not (player.pflags & PF_SPINDOWN) then if P_IsObjectOnGround(player.mo) and (player.pflags & PF_SPINNING) and player.mo.skin ~= "adventuresonic" and player.mo.skin ~= "xsonic" player.mo.state = S_PLAY_SKID player.pflags = $ & ~PF_SPINNING return true else return false end else return false end end) --Token to Rings!-- addHook("TouchSpecial", function(emeraldtoken, toucher) if toucher.type == MT_PLAYER then local player = toucher.player if player and All7Emeralds(emeralds) then P_GivePlayerRings(player, 50) P_AddPlayerScore(player, 1000) end end end, MT_TOKEN)