How To: Overwrite or lock player input

From PGE Wiki
Jump to: navigation, search

Whether it be for cutscenes, to screw with the player and inverse their controls, overwriting the player input is actually simpler than it seems. One would think it would be a complicated mess of mem functions, however, it's as simple as overriding fields, similar to how we override SMBX functions such as onLoop() or onLoad().

Introduction to Overriding

In our code file we will override the onInputUpdate() function. This function is specifically created to override either Player 1 or Player 2's input, whereas onKeyDown() is more fine tuned for accepting input for a specific key.

From here, we must check the various Player.__KeyPressing fields. These are simple booleans, and because they are fields, they can be easily read/assigned to.

Example: Disabling Spin Jump

Recall that we need an instance of our player class. From here, we override the onInputUpdate() function, and check the Player.altJumpKeyPressing field. Internally, this field is updated whenever the player's run key pressing, no matter what they assign the key to. So whether the player is using a keyboard or controller, you can ensure this value is constant and you will not need to check multiple key codes. Finally, because it is a field, we can force override it to false, and because onInputUpdate() is looped, it is continuously set to false. Thus, the player will not spin jump!

function onInputUpdate()
   if(player.altJumpKeyPressing) then
       player.altJumpKeyPressing = false;
   end
end

However, if we want this to work for the second player, we have to add some code to this:

function onInputUpdate()
   if(player.altJumpKeyPressing) then
       player.altJumpKeyPressing = false;
   end
   if(player2)then
       if(player2.altJumpKeyPressing) then
           player2.altJumpKeyPressing = false;
       end
   end
end

Improvements/Quality Control

The one downside to this method is that the player will

1. Not be able to jump using the alt jump button

2. Dismount mounts

This may be fine for you, but it may not be for other players. Luckily, with a little bit of memory check and extra field setting, we can fix this.

The player offsets page for details on all the memory offsets for use with Player:mem(). Offset 0x108 contains mount information. 0 is the magic value for no mount. So, anything greater than 0 indicates the player is on a mount. In addition, we can set Player.jumpKeyPressing to true and this will instead make the player jump normally. Our updated code then looks like this:

function onInputUpdate()
    if(player.altJumpKeyPressing) and (player:mem(0x108,FIELD_WORD) < 1) then
        player.altJumpKeyPressing = false;
        player.jumpKeyPressing = true;
    end 
    if(player2)then
        if(player2.altJumpKeyPressing) and (player2:mem(0x108, FIELD_WORD) < 1) then
            player2.altJumpKeyPressing = false;
            player2.jumpKeyPressing = true;
        end 
    end
end

Test it out yourself!

NOTE: The code will be similar for other player reference.