//Hello! Cosmic Emerald here, you guys can re-use the code and what not, just give credits. know that I guess local SKIN = "sonic" //the skin we're applying the ability to local stasisdelay = 8 local crouchstyle = 1 //the way crouching works; 0 is based on the classic games (crouch at low speeds, roll at high speeds), 1 is being able to crouch at any speed local stopspinspam = false //whether it stop us from spindashing from pressing spin a second time or not local allowjspindash = true //change tis to false if you don't want your character to be able to Spindash while crouching using jump freeslot("S_PLAY_CROUCH", "S_PLAY_UNCROUCH") states[S_PLAY_CROUCH] = { sprite = SPR_PLAY, frame = A|SPR2_LAND, var1 = 0, var2 = 0, tics = 2, //keep this at 2 for the transition to work nextstate = S_PLAY_UNCROUCH } states[S_PLAY_UNCROUCH] = { sprite = SPR_PLAY, frame = FF_SPR2ENDSTATE|SPR2_LAND, var1 = S_PLAY_STND, var2 = 0, tics = 2, //the duration should end up to be at least 10 tics, you want to make it a division of it though so the amount of uncrouching frames can make it to that point without being too long nextstate = S_PLAY_UNCROUCH } addHook("PlayerThink", function(player) if (player.mo and player.mo.valid) //do we exist? and player.mo.skin == SKIN //and are we using that specified skin? //convenience stuff local mo = player.mo local cmd = player.cmd if player.thecrouch == nil player.thecrouch = {} //new table cause it's cool! end local ya_crouch = player.thecrouch //shorten the code writing if ya_crouch.state == nil //we should make this valid ya_crouch.state = 0 //it exists now :D ya_crouch.stasisdelay = 0 elseif ya_crouch.state == 1 //Crouching if mo.state ~= S_PLAY_CROUCH //stop it,,, ya_crouch.state = 3 //mo.height = P_GetPlayerHeight(player) player.height = P_GetPlayerHeight(player) return else if not (player.cmd.buttons&BT_SPIN) //spin let go? ya_crouch.state = 2 //we are Uncrouching now mo.state = S_PLAY_UNCROUCH ya_crouch.stasisdelay = stasisdelay //mo.height = P_GetPlayerHeight(player) player.height = P_GetPlayerHeight(player) else //mo.height = P_GetPlayerSpinHeight(player) player.height = P_GetPlayerSpinHeight(player) mo.state = S_PLAY_CROUCH //constantly set it to the state mo.frame = $|0 & ~FF_FRAMEMASK //make sure it's the first frame player.pflags = $|PF_STASIS //no movement end end elseif ya_crouch.state == 2 //Uncrouching player.pflags = $ & ~PF_STASIS //we wanna detect our inputs mo.height = P_GetPlayerHeight(player) player.height = skins[mo.skin].height if (cmd.forwardmove ~= 0 or cmd.sidemove ~= 0) and ya_crouch.stasisdelay < stasisdelay - 4 or mo.state ~= S_PLAY_UNCROUCH ya_crouch.state = 0 if mo.state == S_PLAY_UNCROUCH P_Thrust(mo, cmd.angleturn<<16 + R_PointToAngle2(0,0,cmd.forwardmove*FRACUNIT,cmd.sidemove*FRACUNIT), FixedMul(player.accelstart, player.thrustfactor)) //do a start thrust based off the acceleration equation & control angle :p mo.state = S_PLAY_WALK player.pflags = $ & ~PF_STASIS end elseif mo.state == S_PLAY_UNCROUCH and ya_crouch.stasisdelay //player.pflags = $|PF_STASIS end elseif ya_crouch.state == 3 //Reset mo.height = P_GetPlayerHeight(player) player.height = skins[mo.skin].height ya_crouch.state = 0 end ya_crouch.stasisdelay = max($-1, 0) else return //stop the code from running end end) //Initiating Crouch addHook("SpinSpecial", function(player) if (player.mo and player.mo.valid) //do we exist? and player.mo.skin == SKIN //and are we using that specified skin? //convenience stuff local mo = player.mo local cmd = player.cmd if player.thecrouch ~= nil and player.thecrouch.state //and not player.thecrouch.stasisdelay /*if player.speed >= 5*FRACUNIT and not stopspinspam //spamdash stuff P_Thrust(mo, R_PointToAngle2(mo.x,mo.y,mo.momx,mo.momy), 5*FRACUNIT - player.speed) end*/ return stopspinspam end if P_IsObjectOnGround(mo) and not (player.pflags&PF_SPINNING) and not (player.powers[pw_carry]) //main checks and (player.speed <= 5*FRACUNIT and crouchstyle == 0 or crouchstyle == 1) and player.charability2 == skins[SKIN].ability2 //speed stuff and player.thecrouch ~= nil and (player.thecrouch.state == 0 //we aren't crouching or player.thecrouch.state == 2 and not player.thecrouch.stasisdelay) //or we are Uncrouching and 0 stasis delay mo.state = S_PLAY_CROUCH //change the state player.thecrouch.state = 1 //set this to on player.pflags = $|PF_STASIS //stasis return true end else return //stop the code from running end end) //Spindashing addHook("JumpSpecial", function(player) if (player.mo and player.mo.valid) //do we exist? and player.mo.skin == SKIN //and are we using that specified skin? //convenience stuff local mo = player.mo local cmd = player.cmd if (player.pflags&PF_JUMPDOWN) if (player.pflags&PF_SPINNING|PF_STARTDASH) return true else return end end if P_IsObjectOnGround(mo) and player.thecrouch ~= nil and player.thecrouch.state == 1 if allowjspindash //make us spindash player.thecrouch.state = 0 player.pflags = $|PF_SPINNING|PF_STARTDASH|PF_JUMPDOWN & ~PF_STASIS mo.state = S_PLAY_SPINDASH S_StartSound(mo, sfx_spndsh) mo.height = P_GetPlayerHeight(player) player.height = skins[mo.skin].height if player.speed >= 5*FRACUNIT //speed stuff P_Thrust(mo, R_PointToAngle2(0, 0, mo.momx, mo.momy), 5*FRACUNIT - player.speed - 1) end return true end return end else return //stop the code from running end end) //Making the height be set correctly for spin gaps local MakeTheHeightWork = function(player) if player.mo and player.mo.valid and player.mo.skin == SKIN if player.thecrouch ~= nil and player.thecrouch.state >= 2 or player.mo.state == S_PLAY_UNCROUCH return P_GetPlayerHeight(player) elseif player.thecrouch ~= nil and player.thecrouch.state == 1 or player.mo.state == S_PLAY_CROUCH return P_GetPlayerSpinHeight(player) end else return end end addHook("PlayerHeight", MakeTheHeightWork)