User:Radicalicious/SRB2 Lua Beginner Tutorial Part 2

From SRB2 Wiki
Jump to navigation Jump to search
This article or section is incomplete. However, Radicalicious has requested that this article be untouched until it's completed. Please discuss this article on its talk page.

Alright, where were we? Oh yeah, modifying entity behavior.

Open up a new .lua file in your SRB2 directory called "TokensGiveRings.lua". Let's start with something pretty simple in concept, Touch Events. Using the hook "TouchSpecial", we can have objects that are labelled with the flag "MF_SPECIAL" in the game code execute a script when you touch it. Enter this code into the file:

local function TokensGiveRings(token, player)

end

addHook("TouchSpecial", TokensGiveRings, MT_TOKEN)

If you read Part 1, then you would know that this makes a new function (called TokensGiveRings) and then adds that function to a game hook. This time though, the "addHook()" function takes 3 arguments instead of 2, and the function we're using takes 2 arguments instead of none. When the hook "TouchSpecial" is run, it needs an object type to execute on! If the "MT_TOKEN" (token object ID) parameter was left out, it would execute on all special items, like Rings. As for the function, the TouchSpecial hook takes 2 function arguments:

  • token - The token object being touched.
  • player - The player's object. Not the player itself, but we'll get to that.

Alright, let's code! Add this line of code into the file:

local function TokensGiveRings(token, player)
    player.player.rings = $ + 50
end

addHook("TouchSpecial", TokensGiveRings, MT_TOKEN)

Uh, what is player.player? Time to explain.. The function takes the player argument as an Object, not a player. Players are player_ts, and Objects are mobj_ts. Mobjs have a value in them called "player", which, if the mobj is a player, will be a player_t. Essentially: player_ts are what we want for this. So, what does this code do? It simply adds 50 rings to the player's ring count when you pick up a Special Stage token. No matter how cool it is, it's not entirely foolproof. Let's foolproof it. Add this code to the file:

local function TokensGiveRings(token, player)
    player.player.rings = $ + 50
    S_StartSound(player, sfx_token, player.player)
    P_KillMobj(token)
    return true
end

addHook("TouchSpecial", TokensGiveRings, MT_TOKEN)

What's going on here? This looks a bit complex. What we are doing here is completely overriding the token behavior. When the function returns true, the existing behavior is overridden, and ours is executed instead.