Disabling the score system

Post here for help and support regarding LunaLua and SMBX2's libraries and features.
BrokenAce
Swooper
Swooper
Posts: 51
Joined: Sat Feb 06, 2016 11:48 am

Disabling the score system

Postby BrokenAce » Thu Aug 04, 2022 7:00 pm

If possible, I'd like to to disable SMBX's score system for my episode. I'm aware it's possible to set all NPCs to give 0 points, but this doesn't account for things such as coin collection or enemies destroyed via a goal.

Are there any easy lunalua tricks to prevent things from giving out points? I know just erasing the score graphics in effect-79 is always an option, but it's certainly not ideal.

Emral
Cute Yoshi Egg
Cute Yoshi Egg
Posts: 9722
Joined: Mon Jan 20, 2014 12:58 pm
Flair: Phoenix

Re: Disabling the score system

Postby Emral » Thu Aug 04, 2022 8:02 pm

The ideal trick is 3 steps.
1. Make the score counter graphic completely transparent
2. Disable the counter's visuals with a piece of lua code like this:

Code: Select all

local hudoverride = require("hudoverride")
hudoverride.visible.score = false
3. Prevent the player's score combo from increasing.

Code: Select all

function onTick()
	for _, p in ipairs(Player.get()) do
		p:mem(0x56, FIELD_WORD, 0)
	end
end
No need to worry about the actual score values if you can't hear or see them.

BrokenAce
Swooper
Swooper
Posts: 51
Joined: Sat Feb 06, 2016 11:48 am

Re: Disabling the score system

Postby BrokenAce » Fri Aug 05, 2022 6:04 am

Enjl wrote:
Thu Aug 04, 2022 8:02 pm
The ideal trick is 3 steps.
1. Make the score counter graphic completely transparent
2. Disable the counter's visuals with a piece of lua code like this:

Code: Select all

local hudoverride = require("hudoverride")
hudoverride.visible.score = false
3. Prevent the player's score combo from increasing.

Code: Select all

function onTick()
	for _, p in ipairs(Player.get()) do
		p:mem(0x56, FIELD_WORD, 0)
	end
end
No need to worry about the actual score values if you can't hear or see them.

This only prevents jump combos; the score combo for shell kicks and goals still occur even with this code in place.
I was considering working around it by keeping combos and replacing the graphics for the scores with a combo count (e.g. x2, x3, etc), but I'm not sure if there's anything that can be done about the fixed several thousand points from powerups in that regard, or the fact that the combos annoyingly switch between 1-ups and 2-ups by default (which would bring the combo display back to x9 after the first 1up in my setup).

Emral
Cute Yoshi Egg
Cute Yoshi Egg
Posts: 9722
Joined: Mon Jan 20, 2014 12:58 pm
Flair: Phoenix

Re: Disabling the score system

Postby Emral » Fri Aug 05, 2022 6:47 am

Ah, right. Forgot about those. Those are stored in the elusive "NPC 0" which redigit uses for like, general NPC-related global stuff.

Merge the onTick part with your existing onTick:

Code: Select all

--this sets the score counter to 0 to prevent 1ups
--redigit stores this in NPC 0
local function dummyNpcMem(offset, value, set)
    return mem(readmem(0xB259E8, FIELD_DWORD) + 0xac00 + offset, value, set)
end

function onTick()
	dummyNpcMem(0x24, FIELD_WORD, 0)
end
I'm not sure if that covers score combo at the end, but it shoooould?

For goal NPCs there are some defines for this you can set in onStart, like:
Defines.smb3RouletteScoreValueStar = 0
Defines.smb3RouletteScoreValueFlower = 0
Defines.smb3RouletteScoreValueMushroom = 0

but for other goals like SMW Tape, I'm not so sure. Perhaps making a npc-ID.txt for them and setting score=0 in them works for those edge cases.

deice
Volcano Lotus
Volcano Lotus
Posts: 549
Joined: Fri Jul 23, 2021 7:35 am

Re: Disabling the score system

Postby deice » Fri Aug 05, 2022 8:12 am

Enjl wrote:
Fri Aug 05, 2022 6:47 am
but for other goals like SMW Tape, I'm not so sure. Perhaps making a npc-ID.txt for them and setting score=0 in them works for those edge cases.
unfortunately, the score given by the smw goal tape is calculated at the time it's collected. solving that equation for "Special2" gives:

Code: Select all

function onTick()
	for _, v in ipairs(NPC.get(197)) do
		v.ai2 = (v.y - v.spawnY) / 1.1 + v.spawnY
	end
end
which makes it always give 0 points no matter how high up it's collected. however, i'm not sure if doing this has the potential to cause other issues (such as division by 0). i've tested it and it seems to be fine but who knows.

(by the way, the documentation should be updated regarding this, as it says changing this ai value has no effect)

Emral
Cute Yoshi Egg
Cute Yoshi Egg
Posts: 9722
Joined: Mon Jan 20, 2014 12:58 pm
Flair: Phoenix

Re: Disabling the score system

Postby Emral » Fri Aug 05, 2022 8:34 am

deice wrote:
Fri Aug 05, 2022 8:12 am
Enjl wrote:
Fri Aug 05, 2022 6:47 am
but for other goals like SMW Tape, I'm not so sure. Perhaps making a npc-ID.txt for them and setting score=0 in them works for those edge cases.
unfortunately, the score given by the smw goal tape is calculated at the time it's collected. solving that equation for "Special2" gives:

Code: Select all

function onTick()
	for _, v in ipairs(NPC.get(197)) do
		v.ai2 = (v.y - v.spawnY) / 1.1 + v.spawnY
	end
end
which makes it always give 0 points no matter how high up it's collected. however, i'm not sure if doing this has the potential to cause other issues (such as division by 0). i've tested it and it seems to be fine but who knows.

(by the way, the documentation should be updated regarding this, as it says changing this ai value has no effect)
Thanks for this. I'll update the documentation shortly. If you find other mistakes, you can also create pull requests https://docs.codehaus.moe/#/guides/cont ... o-the-docs

BrokenAce
Swooper
Swooper
Posts: 51
Joined: Sat Feb 06, 2016 11:48 am

Re: Disabling the score system

Postby BrokenAce » Fri Aug 05, 2022 10:18 am

Enjl wrote:
Fri Aug 05, 2022 6:47 am
Ah, right. Forgot about those. Those are stored in the elusive "NPC 0" which redigit uses for like, general NPC-related global stuff.

Merge the onTick part with your existing onTick:

Code: Select all

--this sets the score counter to 0 to prevent 1ups
--redigit stores this in NPC 0
local function dummyNpcMem(offset, value, set)
    return mem(readmem(0xB259E8, FIELD_DWORD) + 0xac00 + offset, value, set)
end

function onTick()
	dummyNpcMem(0x24, FIELD_WORD, 0)
end

Unfortunately I haven't had any success with merging the onTick. attempting to paste the dummyNpcMem(0x24, FIELD_WORD, 0) before the end spits out this error message:
Image

As I am not experienced with lua I'm sure I'm doing something wrong, though I have tried many different ways of merging it (e.g. including the extra onTick and extra end) and all give similar errors.

Emral
Cute Yoshi Egg
Cute Yoshi Egg
Posts: 9722
Joined: Mon Jan 20, 2014 12:58 pm
Flair: Phoenix

Re: Disabling the score system

Postby Emral » Fri Aug 05, 2022 10:40 am

Did you paste the dummyNPCMem function into your code ABOVE the onTick? If not, please do so.

BrokenAce
Swooper
Swooper
Posts: 51
Joined: Sat Feb 06, 2016 11:48 am

Re: Disabling the score system

Postby BrokenAce » Fri Aug 05, 2022 11:04 am

Enjl wrote:
Fri Aug 05, 2022 10:40 am
Did you paste the dummyNPCMem function into your code ABOVE the onTick? If not, please do so.

I didn't, but I've just tried it now, and It spits out the same nil value error as before.
I have also tried including the local function part of the code. Doing so does prevent the error message, but the code doesn't seem to work with this in place, as shells and goals still create combos.

Emral
Cute Yoshi Egg
Cute Yoshi Egg
Posts: 9722
Joined: Mon Jan 20, 2014 12:58 pm
Flair: Phoenix

Re: Disabling the score system

Postby Emral » Fri Aug 05, 2022 11:20 am

that's odd. it worked in subzero heroes, where i copied it from for this message.
the "local function part" IS the dummyNPCMem function I mentioned, by the way. There is a chance you made a mistake copying things over. I can't help in detail right now, but if you post the entire code into a code block I can take a look tomorrow.

BrokenAce
Swooper
Swooper
Posts: 51
Joined: Sat Feb 06, 2016 11:48 am

Re: Disabling the score system

Postby BrokenAce » Fri Aug 05, 2022 12:12 pm

Enjl wrote:
Fri Aug 05, 2022 11:20 am
that's odd. it worked in subzero heroes, where i copied it from for this message.
the "local function part" IS the dummyNPCMem function I mentioned, by the way. There is a chance you made a mistake copying things over. I can't help in detail right now, but if you post the entire code into a code block I can take a look tomorrow.

Ah, I see. Well, even having included the dummyNPCMem function, the code still isn't doing what it's supposed to. Here's how I have it set up as of now:

Code: Select all

local function dummyNpcMem(offset, value, set)
    return mem(readmem(0xB259E8, FIELD_DWORD) + 0xac00 + offset, value, set)
end

function onTick()
	for _, p in ipairs(Player.get()) do
		p:mem(0x56, FIELD_WORD, 0)
	dummyNpcMem(0x24, FIELD_WORD, 0)
	end
end
Hopefully this can be resolved, and thanks for the help.

Edit: Upon further testing, I have discovered this script does prevent combo scoring for shells/projectiles, but only if the npc being hit is set to score=0. Score combos from goals, on the other hand, are still very much intact.

Emral
Cute Yoshi Egg
Cute Yoshi Egg
Posts: 9722
Joined: Mon Jan 20, 2014 12:58 pm
Flair: Phoenix

Re: Disabling the score system

Postby Emral » Fri Aug 05, 2022 9:22 pm

Hm. This might not be fully comprehensive, but I've combined all things we talked about so far and some other experiments into one script you can use to replace the current one.
The to coins combo thing is annoying, as it is not currently something that can be prevented. Just circumvented. This code disables all NPC's abilities to turn into coins, and spawns a different effect instead.
If you want it to use the default effect for this, you cannot use effect 11. Instead, you must copy the effect's image from data/graphics/effect and effect config from data/config/effects into your episode folder and rename them to an ID between 751 and 1000. Then, you can change the ID in Effect.spawn(71, v) to Effect.spawn(751, v), for instance.

Code: Select all

-- Stop drawing the score bit in the UI
local hudoverride = require("hudoverride")
hudoverride.visible.score = false

--this sets the score counter to 0 to prevent 1ups
--redigit stores this in NPC 0
local function dummyNpcMem(offset, value, set)
    return mem(readmem(0xB259E8, FIELD_DWORD) + 0xac00 + offset, value, set)
end

local cointransformable = {}

function onStart()
	-- Erase the roulette score
	Defines.smb3RouletteScoreValueStar = 1
	Defines.smb3RouletteScoreValueFlower = 1
	Defines.smb3RouletteScoreValueMushroom = 1
	
	-- Zero the score config for all NPC IDs and make them notcointransformable by internal code
	for i=1, NPC_MAX_ID do
		NPC.config[i].score = 0
        cointransformable[i] = not NPC.config[i].notcointransformable
		NPC.config[i].notcointransformable = true
	end
end

local lastWinState = 0

-- Zero the combo counter in onPostNPCKill instead
function onPostNPCKill()
	dummyNpcMem(0x24, FIELD_WORD, 0)

    -- New coin collection effect
    if lastWinState == 0 and Level.winState() > 0 then
        lastWinState = Level.winState()
        for k,v in NPC.iterateByFilterMap(cointransformable) do
            if not v.isHidden then
                if v.isGenerator then
                    v.isHidden = true
                elseif v.despawnTimer > 0 then
                    v:harm(9)
                    Effect.spawn(71,v) -- Replace 71 with any effect ID you like
                end
            end
        end
    end
end

function onTick()
	-- Zero the player's combo counter
	for _, p in ipairs(Player.get()) do
		p:mem(0x56, FIELD_WORD, 0)
	end
	
	-- Get rid of goal tape combo score (courtesy of deice)
	for _, v in NPC.iterate(197) do
		v.ai2 = (v.y - v.spawnY) / 1.1 + v.spawnY
	end
end

BrokenAce
Swooper
Swooper
Posts: 51
Joined: Sat Feb 06, 2016 11:48 am

Re: Disabling the score system

Postby BrokenAce » Sat Aug 06, 2022 5:54 am

Enjl wrote:
Fri Aug 05, 2022 9:22 pm
Hm. This might not be fully comprehensive, but I've combined all things we talked about so far and some other experiments into one script you can use to replace the current one.
The to coins combo thing is annoying, as it is not currently something that can be prevented. Just circumvented. This code disables all NPC's abilities to turn into coins, and spawns a different effect instead.
If you want it to use the default effect for this, you cannot use effect 11. Instead, you must copy the effect's image from data/graphics/effect and effect config from data/config/effects into your episode folder and rename them to an ID between 751 and 1000. Then, you can change the ID in Effect.spawn(71, v) to Effect.spawn(751, v), for instance.

Code: Select all

-- Stop drawing the score bit in the UI
local hudoverride = require("hudoverride")
hudoverride.visible.score = false

--this sets the score counter to 0 to prevent 1ups
--redigit stores this in NPC 0
local function dummyNpcMem(offset, value, set)
    return mem(readmem(0xB259E8, FIELD_DWORD) + 0xac00 + offset, value, set)
end

local cointransformable = {}

function onStart()
	-- Erase the roulette score
	Defines.smb3RouletteScoreValueStar = 1
	Defines.smb3RouletteScoreValueFlower = 1
	Defines.smb3RouletteScoreValueMushroom = 1
	
	-- Zero the score config for all NPC IDs and make them notcointransformable by internal code
	for i=1, NPC_MAX_ID do
		NPC.config[i].score = 0
        cointransformable[i] = not NPC.config[i].notcointransformable
		NPC.config[i].notcointransformable = true
	end
end

local lastWinState = 0

-- Zero the combo counter in onPostNPCKill instead
function onPostNPCKill()
	dummyNpcMem(0x24, FIELD_WORD, 0)

    -- New coin collection effect
    if lastWinState == 0 and Level.winState() > 0 then
        lastWinState = Level.winState()
        for k,v in NPC.iterateByFilterMap(cointransformable) do
            if not v.isHidden then
                if v.isGenerator then
                    v.isHidden = true
                elseif v.despawnTimer > 0 then
                    v:harm(9)
                    Effect.spawn(71,v) -- Replace 71 with any effect ID you like
                end
            end
        end
    end
end

function onTick()
	-- Zero the player's combo counter
	for _, p in ipairs(Player.get()) do
		p:mem(0x56, FIELD_WORD, 0)
	end
	
	-- Get rid of goal tape combo score (courtesy of deice)
	for _, v in NPC.iterate(197) do
		v.ai2 = (v.y - v.spawnY) / 1.1 + v.spawnY
	end
end

This is really, really good. Can confirm it all checks out, and being able to replace the goal npc despawn with any effect is a very nice touch.
There's only one small caveat - the effect also plays for certain NPCs that do not get destroyed, such as keys and frozen NPCs. It'd be nice if this could be fixed, but all in all it's more of a nitpick than anything.

Emral
Cute Yoshi Egg
Cute Yoshi Egg
Posts: 9722
Joined: Mon Jan 20, 2014 12:58 pm
Flair: Phoenix

Re: Disabling the score system

Postby Emral » Sat Aug 06, 2022 6:12 am

ah, should be v:kill(9) instead of v:harm(9). a little oversight.


Return to “LunaLua Help”

Who is online

Users browsing this forum: No registered users and 1 guest

SMWCentralTalkhausMario Fan Games GalaxyKafukaMarioWikiSMBXEquipoEstelari