Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- Super Mario 3D World Move
- Allows player to Crawl + Long Jump
- sm3dwMovePal is library name.
- ]]
- -- Yes, I know that if you hold Alt Jump you will be fast for a little bit.
- -- Toad is slightly slower because his top speed is a headache.
- local inputs = API.load("inputs2");
- local textblox = API.load("textblox");
- local sm3dwMovePal = {}
- local trueCharacterID = {};
- local footContact = {};
- local players = {player, player2};
- local isBannedCharacter = {};
- local isInSomething = {};
- local isDoingBannedStuff = {};
- local allowCrawl = {};
- local isHoldingSomething = {};
- local isRunning = {};
- local currentPowerUp = {};
- local inGroundNow = {};
- local inSlopeNow = {};
- local inStandNPC = {};
- local isInVine = {};
- local pressedAltJump = {};
- local isInMount = {};
- local isInWater = {};
- local spriteHeld = {};
- local characterId = {};
- local isStatue = {};
- local isInRainbowShell = {};
- local isLeft = {};
- local playerZoomFactor = {};
- local truePowerup = {};
- local currentPowerUp = {};
- local crouchWalkEntered = {};
- local addSpeed = {};
- local times = {};
- local isLongJumping = {};
- local BannedCrouchList = {0, 0, 1, 0, 1, 2, 2, 1, 1, 1, 0, 1, 0, 0, 1, 2}; -- 0 is allowed with own character, 1 is allowed if changing to other characters is allowed, 2 is never allowed
- local BannedLongJumpList = {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}; -- I don't know why this is still here, but used for long jump
- local maxSpeed = {6, 6, 6, 6.42, 6, 6.4, 8, 4, 6, 6, 6, 6, 6, 5.5, 5, 6}; -- Maximum speed of a character. Certian characters have a different max speed depending what they are doing, which is what specialMaxSpeed and preventspecialMaxEnforce are for.
- local allowedInSmallState = {false, false, true, false, true, false, false, true, true, true, false, true, false, false, true, false}; -- Used, as some characters small state can't fit into a 1 block gap.
- local specialMaxSpeed = {6, 6, 6, 6.42, 6, 3.4, 4, 4, 3, 6, 6, 6, 6, 5.5, 5, 6}; -- Some characters run speed define changes, and this is used to deal with that.
- local preferedMorph = {1, 2, 1, 4, 2, 6, 7, 1, 4, 4, 11, 2, 13, 14, 4, 16}; -- Character morphed into during crawl. If they are a 2 on the BannedCrouchList they are just listed as their own character instead of nil.
- local walkMax = {3, 3, 3, 3, 3, 2.8, 3, 2, 3, 3, 3, 3, 3, 5.5, 3, 3}; -- Not used, the Default Defines.player_walkspeed
- local preventspecialMaxEnforce = {nil, nil, nil, nil, nil, nil, altjump, nil, run, nil, nil, nil, nil, nil, nil, nil}; -- Button, that if pressed, ignores specialMaxSpeed and changes to maxSpeed
- local isCrawling = {}; -- Detects if character is currently crawling
- local timer = 0; -- Used to prevent character from going over their max define speed.
- local ymodifier = {}; -- Used to force characters to crouch
- local player_isCrouching = {}; -- Used to force characters to crouch
- local player_lowCeiling = {}; -- Used to force characters to crouch
- sm3dwMovePal.speed = 1.5 -- speed added during long jump
- sm3dwMovePal.allowCharacterTransform = true; -- Used to see if characters who are a 1 in BannedCrouchList can crawl anyway
- zoomFactor = math.abs(tonumber(sm3dwMovePal.speed))
- Defines.player_runspeed = 10 + sm3dwMovePal.speed;
- currentPowerUp[1] = players[1].powerup
- trueCharacterID[1] = players[1].character
- if Player.count() == 2 then
- currentPowerUp[2] = players[2].powerup
- trueCharacterID[2] = players[2].character
- end
- function sm3dwMovePal.onInitAPI()
- registerEvent(sm3dwMovePal, "onTick", "onTick");
- registerEvent(sm3dwMovePal, "onStart", "onStart");
- registerEvent(sm3dwMovePal, "onInputUpdate");
- registerEvent(sm3dwMovePal, "onTickEnd", "onTickEnd");
- end
- local function memRecognitionFunction()
- for d, y in ipairs(Player.get()) do
- currentPowerUp[d] = y:mem(0x112, FIELD_WORD)
- inGroundNow[d] = y:mem(0x146, FIELD_BOOL)
- inSlopeNow[d] = y:mem(0x48, FIELD_BOOL)
- inStandNPC[d] = y:mem(0x176, FIELD_BOOL)
- isInVine[d] = y:mem(0x40, FIELD_BOOL)
- pressedAltJump[d] = y.altJumpKeyPressing
- isInMount[d] = y:mem(0x108, FIELD_BOOL)
- isInWater[d] = y:mem(0x44, FIELD_BOOL)
- spriteHeld[d] = y:mem(0x154, FIELD_WORD)
- characterId[d] = y:mem(0xF0, FIELD_WORD)
- isStatue[d] = y:mem(0x4A, FIELD_BOOL)
- isInRainbowShell[d] = y:mem(0x44, FIELD_BOOL)
- isLeft[d] = y:mem(0x106, FIELD_WORD) < 0
- playerZoomFactor[d] = y:mem(0xE0, FIELD_DFLOAT)
- end
- end
- local function memFusions()
- for e,z in ipairs(Player.get()) do
- if math.abs(z.speedX) > walkMax[trueCharacterID[e]] then
- isRunning[e] = true;
- else
- isRunning[e] = false;
- end
- if not inSlopeNow[e] and
- not inGroundNow[e] and
- not inStandNPC[e] then
- footContact[e] = false;
- else
- footContact[e] = true;
- end
- if spriteHeld[e] >= 1 then
- isHoldingSomething[e] = true;
- else
- isHoldingSomething[e] = false;
- end
- if isInVine[e] or
- isInMount[e] or
- isInWater[e] or
- isInRainbowShell[e] or
- isStatue[e] then
- isInSomething[e] = true;
- else
- isInSomething[e] = false
- end
- end
- end
- function checkSpeed()
- for i,v in ipairs(Player.get()) do
- if footContact[i] and
- (inputs.state[i].altjump ~= 1 and (inputs.state[i].altjump ~= 2 or times[i] > 5)) and not isBannedCharacter[i] then
- isLongJumping[i] = false
- end
- if inputs.state[i].altjump == 2 and not isBannedCharacter[i] then
- times[i] = times [i] + 1
- else
- times[i] = 0
- end
- end
- end
- local function doingBannedStuff()
- for i,v in ipairs(Player.get()) do
- if not footContact[i] or
- isInSomething[i] or
- isHoldingSomething[i] then
- isDoingBannedStuff[i] = true;
- else
- isDoingBannedStuff[i] = false;
- end
- end
- end
- local function preventZoom() -- Stop player from going over their normal Run Speed define
- for i, v in ipairs(Player.get()) do
- if not isLongJumping[i] and (math.abs(v.speedX) > specialMaxSpeed[v.character]) then --Make sure the character is not long jumping. It uses specialMaxSpeed because most characters specialMaxSpeed is the same as their maxSpeed
- if v.character == 6 then -- Megaman
- if v.height < 20 and -- Checking if megaman is sliding by checking hitbox, not if button pressed to avoid exploits.
- (math.abs(v.speedX) > maxSpeed[v.character]) then
- if v.speedX < 0 then
- v.speedX = 0 - maxSpeed[v.character];
- else
- v.speedX = maxSpeed[v.character];
- end
- else
- if v.speedX < 0 then
- v.speedX = 0 - specialMaxSpeed[v.character];
- else
- v.speedX = specialMaxSpeed[v.character];
- end
- end
- elseif v.character == 9 then -- Klonoa
- if (inputs.state[i].altrun == inputs.HOLD) and
- math.abs(v.speedX) > maxSpeed[v.character] then
- if v.speedX < 0 then
- v.speedX = 0 - maxSpeed[v.character];
- else
- v.speedX = maxSpeed[v.character];
- end
- else
- if v.speedX < 0 then
- v.speedX = 0 - specialMaxSpeed[v.character];
- else
- v.speedX = specialMaxSpeed[v.character];
- end
- end
- elseif v.character == 7 then
- if (inputs.state[i].altrun == inputs.HOLD) and
- math.abs(v.speedX) > maxSpeed[v.character] then
- if v.speedX < 0 then
- v.speedX = 0 - maxSpeed[v.character];
- else
- v.speedX = maxSpeed[v.character];
- end
- else
- if v.speedX < 0 then
- v.speedX = 0 - specialMaxSpeed[v.character];
- else
- v.speedX = specialMaxSpeed[v.character];
- end
- end
- else
- if math.abs(v.speedX) > maxSpeed[v.character] then
- if v.speedX < 0 then
- v.speedX = 0 - maxSpeed[v.character];
- else
- v.speedX = maxSpeed[v.character];
- end
- end
- end
- end
- end
- end
- for c, x in ipairs(Player.get()) do
- if not isBannedCharacter[c] then
- inputs.locked[c].down = true;
- else
- inputs.locked[c].down = false;
- end
- end
- local function longJump(i) -- Adds more speed than define allows
- if not isDoingBannedStuff[i] and isRunning[i] and
- inputs.state[i].altjump == 1 then
- isLongJumping[i] = true
- players[i].runKeyPressing = false;
- addSpeed[i] = v.speedX
- if isLeft[i] then
- players[i].leftKeyPressing = false;
- else
- players[i].rightKeyPressing = false;
- end
- players[i].speedX = 0
- Audio.playSFX(1);
- if isLeft[i] then
- players[i].speedX = addSpeed[i] - zoomFactor
- else
- players[i].speedX = addSpeed[i] + zoomFactor
- end
- players[i].jumpKeyPressing = true
- end
- end
- local function crouchwalk(i)
- if not isDoingBannedStuff[i] and
- ((currentPowerUp[i] ~= PLAYER_SMALL and not allowedInSmallState[trueCharacterID[i]]) or
- (allowedInSmallState[trueCharacterID[i]] and trueCharacterID[i] == players[i].character))
- Audio.playSFX(26);
- truePowerup[i] = players[i].powerup;
- trueCharacterID[i] = players[i].character;
- players[i]:mem(0x112, FIELD_WORD, 1);
- players[i]:mem(0xF0, FIELD_WORD, preferedMorph[trueCharacterID[i]]);
- isCrawling[i] = true;
- end
- if ((truePowerup[i] ~= currentPowerUp[i] and not allowedInSmallState[trueCharacterID[i]]) or
- (trueCharacterID[i] ~= players[i].character and allowedInSmallState[trueCharacterID[i]])) and
- inputs.state[i].down == inputs.RELEASE and
- ((truePowerup[i] ~= 1 and not allowedInSmallState[trueCharacterID[i]]) or allowedInSmallState[i]) and
- isCrawling[i] then
- Audio.playSFX(71);
- players[i]:mem(0x112, FIELD_WORD, truePowerup[i]);
- players[i]:mem(0xF0, FIELD_WORD, trueCharacterID[i]);
- isCrawling[i] = false;
- end
- end
- for i,v in ipairs(Player.get()) do
- trueCharacterID[i] = v:mem(0xF0, FIELD_WORD);
- truePowerup[i] = v.powerup;
- currentPowerUp[i] = v.powerup;
- if trueCharacterID[i] == 1 or trueCharacterID[i] == 2 or trueCharacterID[i] == 4 then
- isBannedCharacter[i] = false
- else
- isBannedCharacter[i] = true
- end
- end
- local function runOnInput(c)
- if not isBannedCharacter[c] then
- if inputs.state[c].down == inputs.PRESS and
- ((inSlopeNow[c] and (characterId[c] == 1 or characterId[c] == 2)) or isInVine[c] or isInMount[c] or not footContact[c]) then
- inputs.locked[c].down = false;
- end
- if inputs.locked[c].down == false and
- not((inSlopeNow[c] and (characterId[c] == 1 or characterId[c] == 2)) or isInVine[c] or isInMount[c] or not footContact[c]) then
- inputs.locked[c].down = true;
- end
- if(players[c].altJumpKeyPressing) and (players[c]:mem(0x108,FIELD_WORD) < 1) and not players[c].jumpKeyPressing and isRunning[c] then
- players[c].altJumpKeyPressing = false;
- longJump(c);
- end
- end
- function sm3dwMovePal.onInputUpdate()
- runOnInput(1);
- bugInput(1);
- if Player.count() == 2 then
- inputs.locked[c].down = false
- end
- end
- function sm3dwMovePal.onTick()
- preventZoom();
- timer = timer + 1;
- if timer % 2 == 0 then
- checkSpeed();
- end
- textblox.printExt ("True Character ID:" + tostring(trueCharacterID[1]), {x=400,y=150, halign=textblox.HALIGN_MID, valign=textblox.VALIGN_MID})
- for c, x in ipairs(Player.get()) do
- if (BannedCrouchList[trueCharacterID[c]] == 0) or
- (BannedCrouchList[trueCharacterID[c]] == 1 and sm3dwMovePal.allowCharacterTransform) then
- memRecognitionFunction();
- memFusions();
- doingBannedStuff();
- if inputs.state[c].down == inputs.PRESS or
- inputs.state[c].down == inputs.RELEASE then
- crouchwalk(c);
- end
- end
- end
- end
- end
- -- SMBX Crouching Bugfix --
- -- by Nat The Porcupine --
- --Further work by BulbyVR --
- function has_value (tab, val)
- for index, value in ipairs(tab) do
- if value == val then
- return true
- end
- end
- return false
- end
- function bugInput(i)
- if true then
- -- Stores the player's crouching state in a variable --
- if players[i]:mem(0x12E,FIELD_WORD) == -1 then
- player_isCrouching[i] = true;
- ymodifier[i] = 32;
- else
- player_isCrouching[i] = false;
- ymodifier[i] = 0;
- end
- -- Checks if the player is small or touching ground--
- if players[i]:mem(0x112, FIELD_WORD) ~= 1 and footContact[i] then
- -- Checks for blocks above the player while they're crouching --
- for k,v in pairs(Block.getIntersecting(players[i].x, players[i].y - ymodifier[i], players[i].x + players[i].width, players[i].y)) do
- -- Checks for visible blocks only --
- if v:mem(0x1C,FIELD_WORD) == 0 then
- -- Block exception list: list of blocks that will not force the player to duck --
- local exception = {8, 25, 26, 27, 28, 30, 38, 69, 79, 108, 121, 122, 123,130, 161, 168, 172, 175, 178,
- 181, 240, 241, 242, 243, 244, 245, 259, 260, 261, 287, 288, 289, 290, 370, 371, 372, 373, 374, 375, 379, 380, 381, 382, 389, 391, 392, 404, 405, 406, 420, 437, 438, 439, 440 ,441, 442, 443, 444, 445, 446, 447, 448, 459, 460
- ,461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 506, 507, 508, 568, 572, 575, 579};
- if has_value(exception, v.id) then player_lowCeiling[i] = false else player_lowCeiling[i] = true end
- end
- end
- end
- -- Forces the player to crouch --
- if f.downKeyPressing == false then
- if player_lowCeiling[i] == true then
- players[i].downKeyPressing = true;
- elseif players[i]:mem(0x146,FIELD_WORD) == 0 and player_isCrouching[i] == true then
- players[i].downKeyPressing = true;
- else
- players[i].downKeyPressing = false;
- end
- end
- end
- end
- function sm3dwMovePal.onTickEnd()
- -- Resets the player's low ceiling variable for technical reasons --
- for i, v in ipairs(Player.get()) do
- if not isBannedCharacter[i] then
- player_lowCeiling[i] = false;
- end
- end
- end
- return sm3dwMovePal;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement