Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- SMM2 Physics
- by Cpt. Mono and DeviousQuacks23
- Gives the player some physics improvements.
- Standalone of SMM2 costume code.
- ]]
- local smm2Physics = {}
- smm2Physics.settings = {
- altPhysics = true,
- altSpinjumpPhysics = true,
- altSwimPhysics = true,
- altClimbingPhysics = true,
- minJumpSpeed = 5.3, -- The minimum possible Y speed that the player can jump with.
- maxJumpSpeed = 6.5, -- The maximum possible Y speed that the player can jump with.
- fiveJumpSpeed = 5.9, -- The amount of Y speed needed to jump 5 blocks high.
- springConstant = 0.8, -- Used to make trampolines bounce you faster than regular jumps.
- downSwimSpeed = 1, -- The speed at which the player's Y speed will be capped if they press down while they're underwater.
- }
- local function handleClimbing(p)
- if p.climbing == true then
- if p.keys.right then
- p.direction = DIR_RIGHT
- elseif p.keys.left then
- p.direction = DIR_LEFT
- end
- end
- end
- local lastGroundX = {}
- local lastJumpChain = {}
- local jumpHang = {}
- local function checkBlockHit(p,speed)
- local boxHeight = (speed)
- if Block.iterateIntersecting(p.x, p.y-boxHeight, p.x+p.width, p.y) ~= nil then
- for _,currentBlock in Block.iterateIntersecting(p.x, p.y-boxHeight, p.x+p.width, p.y) do
- if table.icontains(Block.SOLID, currentBlock.id) then
- return true
- end
- end
- end
- for _,currentNPC in NPC.iterateIntersecting(p.x, p.y-boxHeight, p.x+p.width, p.y) do
- if NPC.config[currentNPC.id].playerblock and currentNPC ~= p.holdingNPC then
- return true
- end
- end
- return false
- end
- local function handleJumpPhysics(p)
- lastJumpChain.p = lastJumpChain.p or 0
- lastGroundX.p = lastGroundX.p or 0
- local canJump = true
- local dynamicJumpSpeed = math.min(-smm2Physics.settings.fiveJumpSpeed,-((smm2Physics.settings.maxJumpSpeed - smm2Physics.settings.minJumpSpeed)*(math.abs(lastGroundX.p)+math.max(0,p:mem(0x11C, FIELD_WORD)-20)*smm2Physics.settings.springConstant)/Defines.player_runspeed + smm2Physics.settings.minJumpSpeed))
- if p.forcedState ~= 0 or Defines.player_runspeed == 0 then
- jumpHang.p = false
- elseif p:isOnGround() == true or p:mem(0x34, FIELD_BOOL) or p.climbing then
- if p:mem(0x148, FIELD_WORD) == 2 or p:mem(0x14A, FIELD_WORD) == 2 then
- lastGroundX.p = 0
- else
- lastGroundX.p = math.min(math.abs(p.speedX),Defines.player_runspeed)*math.sign(p.speedX)
- end
- elseif p:mem(0x11C, FIELD_WORD) > 0 or jumpHang.p and not checkBlockHit(p, -dynamicJumpSpeed) then
- if p:mem(0x14A, FIELD_WORD) == 0 and p.speedY < 0 and p.forcedState == 0 then
- jumpHang.p = true
- if not checkBlockHit(p, -dynamicJumpSpeed) then
- if p:mem(0x11C, FIELD_WORD) == 0 and not p:isOnGround() then
- jumpHang.p = false
- if p.speedY >= -smm2Physics.settings.maxJumpSpeed then
- if lastGroundX.p == 0 then
- p.speedY = -smm2Physics.settings.minJumpSpeed
- else
- p.speedY = dynamicJumpSpeed
- end
- end
- lastGroundX.p = smm2Physics.settings.defaultMaxSpeed
- elseif lastGroundX.p == 0 then
- p.y = p.y - p.speedY - (smm2Physics.settings.minJumpSpeed)
- else
- p.y = p.y - p.speedY + dynamicJumpSpeed
- end
- end
- else
- jumpHang.p = false
- end
- end
- lastJumpChain.p = p:mem(0x56, FIELD_WORD)
- end
- local playerManager = require("playerManager")
- local hasSpinJumped = {}
- local storedDirection = {}
- local spinJumpTimer = {}
- local function setHeldNPCPosition(p,x,y)
- p.holdingNPC.x = x
- p.holdingNPC.y = y
- end
- local function handleSpinJumping(p)
- hasSpinJumped[p] = hasSpinJumped[p] or 0
- storedDirection[p] = storedDirection[p] or p.direction
- spinJumpTimer[p] = spinJumpTimer[p] or 0
- if p:mem(0x50, FIELD_BOOL) then
- hasSpinJumped[p] = 2
- end
- if hasSpinJumped[p] > 0 then
- if spinJumpTimer[p] >= 11 then
- spinJumpTimer[p] = 0
- else
- spinJumpTimer[p] = spinJumpTimer[p] + 1
- end
- if p.keys.left and not p.keys.right then
- storedDirection[p] = DIR_LEFT
- elseif p.keys.right and not p.keys.left then
- storedDirection[p] = DIR_RIGHT
- end
- p.direction = storedDirection[p]
- if p.holdingNPC ~= nil and p.holdingNPC.isValid then
- local settings = PlayerSettings.get(playerManager.getBaseID(p.character),p.powerup)
- local heldNPCY = p.y + settings.grabOffsetY - (p.holdingNPC.height - 32)
- local heldNPCX
- if spinJumpTimer[p] >= 9 then
- heldNPCX = p.x + p.width/2 - p.holdingNPC.width/2
- elseif spinJumpTimer[p] >= 6 then
- if p.direction == 1 then
- heldNPCX = p.x + settings.grabOffsetX
- else
- heldNPCX = p.x + p.width - settings.grabOffsetX - p.holdingNPC.width
- end
- elseif spinJumpTimer[p] >= 3 then
- heldNPCX = p.x + p.width/2 - p.holdingNPC.width/2
- else
- if p.direction == -1 then
- heldNPCX = p.x + settings.grabOffsetX
- else
- heldNPCX = p.x + p.width - settings.grabOffsetX - p.holdingNPC.width
- end
- end
- setHeldNPCPosition(p,heldNPCX,heldNPCY)
- end
- else
- spinJumpTimer[p] = 0
- end
- hasSpinJumped[p] = hasSpinJumped[p] - 1
- storedDirection[p] = p.direction
- end
- local function handleSwimPhysics(p)
- if p:mem(0x38, FIELD_WORD) > 1 then
- p:mem(0x38, FIELD_WORD, 1)
- end
- if (p:mem(0x34,FIELD_WORD) > 0 and p:mem(0x06,FIELD_WORD) == 0) and p.keys.down and p.speedY < -smm2Physics.settings.downSwimSpeed then
- p.speedY = -smm2Physics.settings.downSwimSpeed
- end
- end
- function smm2Physics.onTickEnd()
- for _,p in ipairs(Player.get()) do
- if smm2Physics.settings.altPhysics then handleJumpPhysics(p) end
- if smm2Physics.settings.altSwimPhysics then handleSwimPhysics(p) end
- if smm2Physics.settings.altSpinjumpPhysics then handleSpinJumping(p) end
- if smm2Physics.settings.altClimbingPhysics then handleClimbing(p) end
- end
- end
- function smm2Physics.onInitAPI()
- registerEvent(smm2Physics, "onTickEnd")
- end
- return smm2Physics
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement