Page 1 of 1

Destroying levels on the world map?

Posted: Thu Sep 16, 2021 5:29 pm
by JordanTRS
This is pretty simple. In the NSMB games you can only use a toad house once before it's "destroyed". I was wondering if it was possible to bring that functionality over to SMBX2, as I don't want the player to be able to get infinite powerups and 1ups from my toad houses.

Re: Destroying levels on the world map?

Posted: Thu Sep 16, 2021 6:20 pm
by deice
there's multiple ways to go about this. the simplest would be to implement the functionality within the level itself, writing a value to SaveData when the level is first visited, and simply hiding the powerups if the level's been visited before.

if you want to implement the functionality on the world map, you'd once again have to write to SaveData when the level gets visited, but then on the world map you'd do something like change the level's filename to a blank string on startup if it's been visited before (making it inaccessible). currently (according to the documentation, at least) there's no way to change a level's icon on the world map, so you'd have to get creative with that. one way would be to make it so the level's default icon is what's displayed when it's already been visited, meaning you'd just draw a toad house image over it before that's happened.

for reference, here's the documentation for overworld levels.

Re: Destroying levels on the world map?

Posted: Thu Sep 16, 2021 6:31 pm
by JordanTRS
deice wrote:
Thu Sep 16, 2021 6:20 pm
there's multiple ways to go about this. the simplest would be to implement the functionality within the level itself, writing a value to SaveData when the level is first visited, and simply hiding the powerups if the level's been visited before.

if you want to implement the functionality on the world map, you'd once again have to write to SaveData when the level gets visited, but then on the world map you'd do something like change the level's filename to a blank string on startup if it's been visited before (making it inaccessible). currently (according to the documentation, at least) there's no way to change a level's icon on the world map, so you'd have to get creative with that. one way would be to make it so the level's default icon is what's displayed when it's already been visited, meaning you'd just draw a toad house image over it before that's happened.

for reference, here's the documentation for overworld levels.
hmm, that first idea sounds like something I could do. Only problem is I don't really know how to do that. Like, I have an idea of how it'd be possible, I just don't really know how to put it into code.

Re: Destroying levels on the world map?

Posted: Fri Sep 17, 2021 8:34 am
by deice
it's pretty simple, just control the powerup disappearance through an event (either through more lua or just a layer hide) and put something like this in the level's onStart() event:

Code: Select all

SaveData["toad_house.lvlx"] = SaveData["toad_house.lvlx"] or {}
if(SaveData["toad_house.lvlx"].visited == nil) then
	SaveData["toad_house.lvlx"].visited = true
else
	triggerEvent("hidePowerups")
end
obviously, you'd change the names here according to your level
if you wanted to get fancy, you could even package this into a library and use require() in each toad house to save some copying and pasting, but it doesn't really matter

Re: Destroying levels on the world map?

Posted: Fri Sep 17, 2021 11:04 am
by JordanTRS
deice wrote:
Fri Sep 17, 2021 8:34 am
it's pretty simple, just control the powerup disappearance through an event (either through more lua or just a layer hide) and put something like this in the level's onStart() event:

Code: Select all

SaveData["toad_house.lvlx"] = SaveData["toad_house.lvlx"] or {}
if(SaveData["toad_house.lvlx"].visited == nil) then
	SaveData["toad_house.lvlx"].visited = true
else
	triggerEvent("hidePowerups")
end
obviously, you'd change the names here according to your level
if you wanted to get fancy, you could even package this into a library and use require() in each toad house to save some copying and pasting, but it doesn't really matter
Hmmm, alright. I’ll try that. There is one last problem though, and that’s the fact that I want it to act like NSMBW, where after you beat the game all the road houses reappear and never go away. Is there any way to check and see if the player has beaten the episode, because if there’s a variable for that or something, then that would make this a lot easier.

edit: wait, how would I put it in the onStart event?

Re: Destroying levels on the world map?

Posted: Fri Sep 17, 2021 11:26 am
by deice
JordanTRS wrote:
Fri Sep 17, 2021 11:04 am
Hmmm, alright. I’ll try that. There is one last problem though, and that’s the fact that I want it to act like NSMBW, where after you beat the game all the road houses reappear and never go away. Is there any way to check and see if the player has beaten the episode, because if there’s a variable for that or something, then that would make this a lot easier.
to my knowlegde, there's no variable that stores that automatically. but you could, for instance, just trigger an event when you beat the final boss that sets a unique value in SaveData and replace

Code: Select all

if(SaveData["toad_house.lvlx"].visited == nil) then
	SaveData["toad_house.lvlx"].visited = true
else
	triggerEvent("hidePowerups")
end
with

Code: Select all

if(SaveData["toad_house.lvlx"].visited == nil) then
	SaveData["toad_house.lvlx"].visited = true
else
	if(SaveData.gameCleared == nil) then
		triggerEvent("hidePowerups")
	end
end
JordanTRS wrote:
Fri Sep 17, 2021 11:04 am
edit: wait, how would I put it in the onStart event?
wrap the code like this:

Code: Select all

function onStart()
	<code goes here>
end

Re: Destroying levels on the world map?

Posted: Fri Sep 17, 2021 12:22 pm
by JordanTRS
deice wrote:
Fri Sep 17, 2021 11:26 am
JordanTRS wrote:
Fri Sep 17, 2021 11:04 am
Hmmm, alright. I’ll try that. There is one last problem though, and that’s the fact that I want it to act like NSMBW, where after you beat the game all the road houses reappear and never go away. Is there any way to check and see if the player has beaten the episode, because if there’s a variable for that or something, then that would make this a lot easier.
to my knowlegde, there's no variable that stores that automatically. but you could, for instance, just trigger an event when you beat the final boss that sets a unique value in SaveData and replace

Code: Select all

if(SaveData["toad_house.lvlx"].visited == nil) then
	SaveData["toad_house.lvlx"].visited = true
else
	triggerEvent("hidePowerups")
end
with

Code: Select all

if(SaveData["toad_house.lvlx"].visited == nil) then
	SaveData["toad_house.lvlx"].visited = true
else
	if(SaveData.gameCleared == nil) then
		triggerEvent("hidePowerups")
	end
end
JordanTRS wrote:
Fri Sep 17, 2021 11:04 am
edit: wait, how would I put it in the onStart event?
wrap the code like this:

Code: Select all

function onStart()
	<code goes here>
end
so let me make sure I've got all this: I need to make a .lua file with the exact same name as the toad house level. Then I need to put this in:

Code: Select all

function onStart()
	SaveData["1-toadr.lvlx"] = SaveData["1-toadr.lvlx"] or {}
	if(SaveData["1-toadr.lvlx"].visited == nil) then
		SaveData["1-toadr.lvlx"].visited = true
		triggerEvent("toadTalk")
	else
		if(SaveData.gameCleared == nil) then
			triggerEvent("alreadyUsed")
		end
	end
end
Then in the editor I need to have to make events with the names "toadTalk" and "alreadyUsed", where "alreadyUsed" is for when the toad house has already been used. If that's all correct, then we have a problem, because nothing happened when I entered the Toad House for the second time. It just kept letting me get more powerups.

Re: Destroying levels on the world map?

Posted: Fri Sep 17, 2021 1:05 pm
by deice
JordanTRS wrote:
Fri Sep 17, 2021 12:22 pm
so let me make sure I've got all this: I need to make a .lua file with the exact same name as the toad house level. Then I need to put this in:

Code: Select all

function onStart()
	SaveData["1-toadr.lvlx"] = SaveData["1-toadr.lvlx"] or {}
	if(SaveData["1-toadr.lvlx"].visited == nil) then
		SaveData["1-toadr.lvlx"].visited = true
		triggerEvent("toadTalk")
	else
		if(SaveData.gameCleared == nil) then
			triggerEvent("alreadyUsed")
		end
	end
end
Then in the editor I need to have to make events with the names "toadTalk" and "alreadyUsed", where "alreadyUsed" is for when the toad house has already been used. If that's all correct, then we have a problem, because nothing happened when I entered the Toad House for the second time. It just kept letting me get more powerups.
almost but not quite. the file should be within the level folder and should be called luna.lua, and you have to remember not to test this from the editor but from the launcher (SaveData isn't maintained during playtesting)

Re: Destroying levels on the world map?

Posted: Fri Sep 17, 2021 1:22 pm
by JordanTRS
deice wrote:
Fri Sep 17, 2021 1:05 pm
JordanTRS wrote:
Fri Sep 17, 2021 12:22 pm
so let me make sure I've got all this: I need to make a .lua file with the exact same name as the toad house level. Then I need to put this in:

Code: Select all

function onStart()
	SaveData["1-toadr.lvlx"] = SaveData["1-toadr.lvlx"] or {}
	if(SaveData["1-toadr.lvlx"].visited == nil) then
		SaveData["1-toadr.lvlx"].visited = true
		triggerEvent("toadTalk")
	else
		if(SaveData.gameCleared == nil) then
			triggerEvent("alreadyUsed")
		end
	end
end
Then in the editor I need to have to make events with the names "toadTalk" and "alreadyUsed", where "alreadyUsed" is for when the toad house has already been used. If that's all correct, then we have a problem, because nothing happened when I entered the Toad House for the second time. It just kept letting me get more powerups.
almost but not quite. the file should be within the level folder and should be called luna.lua, and you have to remember not to test this from the editor but from the launcher (SaveData isn't maintained during playtesting)
oh, alright. I made that change and it now actually works perfectly! Thank you!

Re: Destroying levels on the world map?

Posted: Tue Mar 08, 2022 11:36 am
by Mal8rk
And how can I make it so that the code activates when the level is cleared instead of the code appearing when the level is visited?