Advertisement
Guest User

smm2Physics.lua

a guest
Jun 8th, 2025
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.76 KB | None | 0 0
  1. --[[
  2.  
  3.     SMM2 Physics
  4.     by Cpt. Mono and DeviousQuacks23
  5.  
  6.     Gives the player some physics improvements.
  7.     Standalone of SMM2 costume code.
  8.  
  9. ]]
  10.  
  11. local smm2Physics = {}
  12.  
  13. smm2Physics.settings = {
  14.     altPhysics = true,
  15.     altSpinjumpPhysics = true,
  16.     altSwimPhysics = true,
  17.     altClimbingPhysics = true,
  18.    
  19.     minJumpSpeed = 5.3, -- The minimum possible Y speed that the player can jump with.
  20.     maxJumpSpeed = 6.5, -- The maximum possible Y speed that the player can jump with.
  21.     fiveJumpSpeed = 5.9, -- The amount of Y speed needed to jump 5 blocks high.
  22.     springConstant = 0.8, -- Used to make trampolines bounce you faster than regular jumps.
  23.     downSwimSpeed = 1, -- The speed at which the player's Y speed will be capped if they press down while they're underwater.
  24. }
  25.  
  26. local function handleClimbing(p)
  27.     if p.climbing == true then
  28.         if p.keys.right then
  29.             p.direction = DIR_RIGHT
  30.         elseif p.keys.left then
  31.             p.direction = DIR_LEFT
  32.         end
  33.     end
  34. end
  35.  
  36. local lastGroundX = {}
  37. local lastJumpChain = {}
  38. local jumpHang = {}
  39.  
  40. local function checkBlockHit(p,speed)
  41.     local boxHeight = (speed)
  42.     if Block.iterateIntersecting(p.x, p.y-boxHeight, p.x+p.width, p.y) ~= nil then
  43.         for _,currentBlock in Block.iterateIntersecting(p.x, p.y-boxHeight, p.x+p.width, p.y) do
  44.             if table.icontains(Block.SOLID, currentBlock.id) then
  45.                 return true
  46.             end
  47.         end
  48.     end
  49.     for _,currentNPC in NPC.iterateIntersecting(p.x, p.y-boxHeight, p.x+p.width, p.y) do
  50.         if NPC.config[currentNPC.id].playerblock and currentNPC ~= p.holdingNPC then
  51.             return true
  52.         end
  53.     end
  54.     return false
  55. end
  56.  
  57. local function handleJumpPhysics(p)
  58.     lastJumpChain.p = lastJumpChain.p or 0
  59.     lastGroundX.p = lastGroundX.p or 0
  60.     local canJump = true
  61.     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))
  62.  
  63.     if p.forcedState ~= 0 or Defines.player_runspeed == 0 then
  64.         jumpHang.p = false
  65.     elseif p:isOnGround() == true or p:mem(0x34, FIELD_BOOL) or p.climbing then
  66.         if p:mem(0x148, FIELD_WORD) == 2 or p:mem(0x14A, FIELD_WORD) == 2 then
  67.             lastGroundX.p = 0
  68.         else
  69.             lastGroundX.p = math.min(math.abs(p.speedX),Defines.player_runspeed)*math.sign(p.speedX)
  70.         end
  71.     elseif p:mem(0x11C, FIELD_WORD) > 0 or jumpHang.p and not checkBlockHit(p, -dynamicJumpSpeed) then
  72.         if p:mem(0x14A, FIELD_WORD) == 0 and p.speedY < 0 and p.forcedState == 0 then
  73.             jumpHang.p = true
  74.             if not checkBlockHit(p, -dynamicJumpSpeed) then
  75.                 if p:mem(0x11C, FIELD_WORD) == 0 and not p:isOnGround() then
  76.                     jumpHang.p = false
  77.                     if p.speedY >= -smm2Physics.settings.maxJumpSpeed then
  78.                         if lastGroundX.p == 0 then
  79.                             p.speedY = -smm2Physics.settings.minJumpSpeed
  80.                         else
  81.                             p.speedY = dynamicJumpSpeed
  82.                         end
  83.                     end
  84.                     lastGroundX.p = smm2Physics.settings.defaultMaxSpeed
  85.                 elseif lastGroundX.p == 0 then
  86.                     p.y = p.y - p.speedY - (smm2Physics.settings.minJumpSpeed)
  87.                 else
  88.                     p.y = p.y - p.speedY + dynamicJumpSpeed
  89.                 end
  90.             end
  91.         else
  92.             jumpHang.p = false
  93.         end
  94.     end
  95.     lastJumpChain.p = p:mem(0x56, FIELD_WORD)
  96. end
  97.  
  98. local playerManager = require("playerManager")
  99.  
  100. local hasSpinJumped = {}
  101. local storedDirection = {}
  102. local spinJumpTimer = {}
  103.  
  104. local function setHeldNPCPosition(p,x,y)
  105.     p.holdingNPC.x = x
  106.     p.holdingNPC.y = y
  107. end
  108.  
  109. local function handleSpinJumping(p)
  110.     hasSpinJumped[p] = hasSpinJumped[p] or 0
  111.     storedDirection[p] = storedDirection[p] or p.direction
  112.     spinJumpTimer[p] = spinJumpTimer[p] or 0
  113.     if p:mem(0x50, FIELD_BOOL) then
  114.         hasSpinJumped[p] = 2
  115.     end
  116.     if hasSpinJumped[p] > 0 then
  117.         if spinJumpTimer[p] >= 11 then
  118.             spinJumpTimer[p] = 0
  119.         else
  120.             spinJumpTimer[p] = spinJumpTimer[p] + 1
  121.         end
  122.         if p.keys.left and not p.keys.right then
  123.             storedDirection[p] = DIR_LEFT
  124.         elseif p.keys.right and not p.keys.left then
  125.             storedDirection[p] = DIR_RIGHT
  126.         end
  127.         p.direction = storedDirection[p]
  128.         if p.holdingNPC ~= nil and p.holdingNPC.isValid then
  129.             local settings = PlayerSettings.get(playerManager.getBaseID(p.character),p.powerup)
  130.             local heldNPCY = p.y + settings.grabOffsetY - (p.holdingNPC.height - 32)
  131.             local heldNPCX
  132.             if spinJumpTimer[p] >= 9 then
  133.                 heldNPCX = p.x + p.width/2 - p.holdingNPC.width/2
  134.             elseif spinJumpTimer[p] >= 6 then
  135.                 if p.direction == 1 then
  136.                     heldNPCX = p.x + settings.grabOffsetX
  137.                 else
  138.                     heldNPCX = p.x + p.width - settings.grabOffsetX - p.holdingNPC.width
  139.                 end
  140.             elseif spinJumpTimer[p] >= 3 then
  141.                 heldNPCX = p.x + p.width/2 - p.holdingNPC.width/2
  142.             else
  143.                 if p.direction == -1 then
  144.                     heldNPCX = p.x + settings.grabOffsetX
  145.                 else
  146.                     heldNPCX = p.x + p.width - settings.grabOffsetX - p.holdingNPC.width
  147.                 end
  148.             end
  149.             setHeldNPCPosition(p,heldNPCX,heldNPCY)
  150.         end
  151.     else
  152.         spinJumpTimer[p] = 0
  153.     end
  154.     hasSpinJumped[p] = hasSpinJumped[p] - 1
  155.     storedDirection[p] = p.direction
  156. end
  157.  
  158. local function handleSwimPhysics(p)
  159.     if p:mem(0x38, FIELD_WORD) > 1 then
  160.         p:mem(0x38, FIELD_WORD, 1)
  161.     end
  162.     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
  163.         p.speedY = -smm2Physics.settings.downSwimSpeed
  164.     end
  165. end
  166.  
  167. function smm2Physics.onTickEnd()
  168.     for _,p in ipairs(Player.get()) do
  169.         if smm2Physics.settings.altPhysics then handleJumpPhysics(p) end
  170.         if smm2Physics.settings.altSwimPhysics then handleSwimPhysics(p) end
  171.         if smm2Physics.settings.altSpinjumpPhysics then handleSpinJumping(p) end
  172.         if smm2Physics.settings.altClimbingPhysics then handleClimbing(p) end
  173.     end
  174. end
  175.  
  176. function smm2Physics.onInitAPI()
  177.     registerEvent(smm2Physics, "onTickEnd")
  178. end
  179.  
  180. return smm2Physics
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement