Skip to content

Instantly share code, notes, and snippets.

@ShadowXeldron
Last active March 14, 2022 08:26
Show Gist options
  • Save ShadowXeldron/53abdf8b765851d8d76933bf1dd020c2 to your computer and use it in GitHub Desktop.
Save ShadowXeldron/53abdf8b765851d8d76933bf1dd020c2 to your computer and use it in GitHub Desktop.
Stats.lua - A basic RPG mechanics script for SMBX2

DOCUMENTATION

DISCLAIMER: I will not provide support for any versions of SMBX2 prior to Beta 4.

QUICK START

The library can be loaded by adding stats = require("Stats") to the top of your episode-wide luna.lua file. Alternatively, Here's a starter script with a simple Textplus-based HUD to get you going:

stats = require("Stats")
local textplus = require("textplus")

local fontB = textplus.loadFont("textplus/font/6.ini")

function onHUDDraw()
    textplus.print{
        x = 30,
        y = 550,
        xscale = 2,
        yscale = 2,
        font = fontB,
        text = "LEVEL: " .. stat.level
    }
    textplus.print{
        x = 200,
        y = 550,
        xscale = 2,
        yscale = 2,
        font = fontB,
        text = "EXPERIENCE: " .. stat.xp
    }
    --textplus.print{
      --  x = 0,
        --y = 20,
    --    xscale = 2,
      --  yscale = 2,
        --font = fontB,
       -- text = "FP: " .. stat.fp
    --}
    if stat.hp >= stats.criticalHP then
        textplus.print{
            x = 0,
            y = 0,
            xscale = 2,
            yscale = 2,
            font = fontB,
            text = "HP: " .. stat.hp .. "/" .. stat.maxhp
        }
    else
        textplus.print{
            x = 0,
            y = 0,
            xscale =2,
            yscale = 2,
            font = fontB,
            text = "HP: " .. stat.hp .."!/" .. stat.maxhp
        }
    end
end

stats.registerNPC(127, 3, 0, 4) -- Bit
stats.xpDrop(127, 4)

FUNCTIONS

stats.registerNPC(NPCID, pow, def, xpdrop) - Registers an NPC and defines its stats. For reference:

  • NPCID - The ID of the NPC you are registering.
  • pow - The base amount of damage that an NPC will do to the player. Note that if an NPC does not have a defined POW stat then it will throw an error if the player comes into contact with them.
  • def - Currently not used, so you may as well leave it as 0. Meant to interace with LightHitPoint somehow.
  • xpdrop- The amount of XP the player is given by defeating that enemy. You do not have to.

Example usage:

stats.registerNPC(1,>stats.registerNPC(1, 1, 0, 1) -- Registers the SMB3 Goomba, gives it 1 HP and POW, 0 DEF and awards one EXP for defeating it

[========]

stats.LevelUp(x) - Increases the player's level by the specified ammount as well as their max HP by (5 * X) and POW by (1 * X). This script includes a new LunaLua event in the form of OnLevelUp(), which is run whenever stats.LevelUp() is called.

Example usage:

function onJump()
	stats.LevelUp(1) -- Grants a single level every time the player does a big jump.
end

function onLevelUp()
	Misc.dialog("Celebrate good times, come on!") -- Opens a dialog box whenever the player levels up.
end

[========]

stats.GainXP() - Grants the player experience points. If their EXP total reaches, stat.level * 5 + stat.level it will call stats.LevelUp(1). stat.xp will then be subtracted by stat.level * 5 + stat.level. This is applied multiple times until the player does not have enough experience to level up again.

Example usage:

function onDraw()
    stats.GainXP(1) - Grants 1 experience point every frame
end

[========]

stats.heal(x) - Restores the player's HP by X. Will not restore more HP than the player has. If X is zero, fully restores their HP.

Example usage:

function onJump()
	stats.heal(1) -- Restores 1 HP whenever you do a big jump
end

function onNPCKill()
    stats.heal(0) -- Fully restores HP every time an NPC is killed
end

VARIABLES

STATS

All stat variables are stored as save data. Note that stats is used for functions while stat is used for variables.

stat.pow - The player's POW stat. POW does not do anything by itself. Instead meant to be used in tandem with other scripts. stat.def - The player's DEF stat. Enemy damage is subtracted by this. However, it does not naturally increment upon leveling up. stat.maxhp - The player's max HP. Automatically increments upon leveling up. stat.alwaysBig- A configuration option that defaults to true. Prevents you from entering a small state after taking damage. Is a functional component of the damage system, and is recommended to be left as true.

The following variables are public but should not be altered directly. Instead, they are meant to be displayed via textplus.

stat.level - The player's level. Please do not attempt to manipulate this directly, as LevelUp() increases the player's POW and max HP along with triggering onLevelUp(). stat.xp - The player's experience. Please use GainXP() instead of manipulating it directly, as doing so will not trigger level ups. stat.hp - The player's current HP. Manipulating it directly does not respect stats.maxhp, so you should use stats.heal() instead.

CONFIGURATION

There are a few more variables meant as configuration options:

stats.criticalHP - Point from where your HP is considered critically low. Meant to be used with other scripts. stats.HPgrowth - The HP increase for each levelup. Defaults to 5. stats.POWgrowth - The POW increase for each levelup. Defaults to 1. stats.DEFgrowth - The DEF increase for each levelup. Defaults to 0. stats.baseHP - Base HP. Added onto by HP growth. Defaults to 5. stats.alwaysBig - Prevents the player from entering a small state after taking damage. Defaults to true. It is a functional component of the damage system, and is recommended to be left as true.

--Stats.lua - Gainus Levelus! This lets you gain experience and level up. Also includes HP and FP.
--COPPYRIT KMAKEVURSE LAL RITES RIZURVURVD DOO NUT DSITRIBUT
--Should I upload this?
--These are commented because 1. I don't mind people raiding my episode files and 2. I like talking to myself.
--Comments, Lua pretends these don't exist.
local colliders = require("colliders") -- We neeed this later
--NOTE TO SELF: "stat" is Levels and Experience, "stats" refers to the library itself.
local stats = {} -- API Table. I don't have a clue what this does.
--CONFIGURATION SETTINGS
--HP-related
stats.criticalHP = 5 -- Point from where your HP is considered critically low. If this is the case, stats.LowHP will equal true.
stats.HPgrowth = 5 -- The HP increase for each levelup. Defaults to 5.
stats.POWgrowth = 1 -- The POW increase for each levelup. Defaults to 5.
stats.DEFgrowth = 0 -- The DEF increase for each levelup.
stats.baseHP = 5 -- Base HP. Added onto by HP growth
stats.alwaysBig = true -- Prevents you from entering a small state after taking damage. Is a functional component of the damage system, and is recommended to be left as true.
local xpDrops = {
-- Everything from GainXP is installed here
}
local enemyPOW = {}
local enemyDEF = {}
-- Load required libraries
--local textplus = require("textplus")
function stats.registerNPC(NPCID, pow, def, xpdrop)
enemyPOW[NPCID] = pow
enemyDEF[NPCID] = def
xpDrops[NPCID] = xpdrop
end
-- This function is included for backwards compatability with an internal version.
function stats.xpDrop(NPCID, reward) -- xpDrop - Adds an enemy and its experience drop to the xpDrops. Not to be confused with it! Replace NPCID with the ID of the NPC in question and reward with the XP drop.
xpDrops[NPCID] = reward
end --Remember, xpDrop goes below xpDrops.
--local fontB = textplus.loadFont("textplus/font/6.ini") -- Used for text rendering
--Set up the levelup function
SaveData["episode"] = SaveData["episode"] or {}
stat = SaveData["episode"] -- Stat cannot be accessed from outside the game
function stats.onInitAPI() --Initialize variables whenever Stats.lua is loaded
if stat.level == nil then
stat.level = 1
end
if stat.xp == nil then
stat.xp = 0
end
if stat.maxhp == nil then
stat.maxhp = stats.baseHP + (stat.level * stats.HPgrowth)
end
if stat.hp == nil then
stat.hp = stat.maxhp
end
if stat.pow == nil then
stat.pow = 1 * stat.level
end
if stat.def == nil then
stat.def = 1 * (stat.level - 1)
end
--Phase 2: Events
registerEvent(stats,"onNPCKill","onNPCKill",false); -- Shamelessly plagirazied from followa.lua, by Hoeloe.
registerEvent(stats,"onDraw","onDraw",false)
registerEvent(stats,"onStart","onStart",false)
registerEvent(stats,"onPlayerHarm","onPlayerHarm",false)
--registerEvent(stats,"onPostPlayerHarm","onPlayerHarm",false)
registerCustomEvent(stats,"onLevelUp","onLevelUp",false)
end
function stats.onPlayerHarm() --Handles playerHP
local subjectpow = 0 -- In case it complains
-- Check who the enemy is and how much POW they've got
for k,v in pairs(NPC.get()) do
if (colliders.collide(player, v)) then
subjectpow = enemyPOW[v.id] -- Records the target's POW
end
end
local damagecalc = subjectpow - stat.def -- Calculates damage
if damagecalc < 1 then
damagecalc = 1 -- No healing when an enemy hits you, because that's just dumb
end
stat.hp = stat.hp - damagecalc -- OUCH!
if stat.hp < 1 then
player:kill() -- oof
end
--player.powerup = 2
end
--stats.levelFormula = stat.level * 5 + stat.level -- The formula used for gainXP's level up functionality. Remember to use BIDMAS!
function stats.LevelUp(x) -- LevelUp - This grants a level. Input a minus number to make the player level down. Included for ease of use.
stat.level = stat.level + x
stat.maxhp = stat.maxhp + stats.HPgrowth
stat.pow = stat.pow + stats.POWgrowth
stat.def = stat.def + stats.DEFgrowth
onLevelUp()
end
function onLevelUp()
--This is called whenever you level up. What do you want to do with it? Entirely up to you!
end
function stats.GainXP(x) -- GainXP - This function grants you experience points.
stat.xp = stat.xp + x
if stat.xp > stat.level * 5 + stat.level then
repeat
stat.xp = stat.xp - (stat.level * 5 + stat.level)
stats.LevelUp(1) --Keep going until you haven't got enough experience points
until stat.xp < stat.level * 5 + stat.level
end
end
function stats.onStart()
if stat.hp < 1 then
stat.hp = stat.maxhp
end
end
function stats.onDraw() -- Prints your stats. It has to be global for some reason.
if stats.alwaysBig == true then
if player.powerup == 1 and player.forcedState ~= FORCEDSTATE_POWERDOWN_SMALL then -- Shamelessly stolen from SmgLifeSystem by Marioman2007. Thanks for solving my problem for me!
player.powerup = 2
end
end
end
function stats.heal(x) -- Heals player HP by the specified amount, set to 0 if you want to fully restore HP. Cannot go over the cap.
if x == 0 then
stat.hp = stat.maxhp
else
stat.hp = stat.hp + x
if stat.hp > stat.maxhp then
stat.hp = stat.maxhp
end
end
end
function stats.onNPCKill(EventObj, killedNPC, killReason) -- This raids xpDrops and dispenses XP for the NPC you just murdered, as long as you have declared it.
if xpDrops[killedNPC.id] ~= nil then
stats.GainXP(xpDrops[killedNPC.id])
end
end
return stats
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment