This is the place for discussion and support for LunaLua and related modifications and libraries.
Moderator: Userbase Moderators
Forum rules
Before you make a topic/post, consider the following:
-Is there a topic for this already?
-Is your post on topic/appropriate?
-Are you posting in the right forum/following the forum rules?
|
|
|
|
-
PixelPest
- Link

- Posts: 7111
- Joined: Sun Jul 12, 2015 5:38 pm
- Flair: Tamer of Boom Booms
-
Contact:
Postby PixelPest » Tue Jun 27, 2017 6:30 am
You can call NPC:transform() with the new ID in the brackets
|
|
|
|
|
|
|
|
|
-
Hoeloe
- Phanto

- Posts: 1465
- Joined: Sat Oct 03, 2015 6:18 pm
- Flair: The Codehaus Girl
- Pronouns: she/her
Postby Hoeloe » Tue Jun 27, 2017 6:31 am
IttaBaby wrote:Okay, so long ago autocode let you change all instances of an npc with another, which was good to make things like spiny eggs turning into blocks and other things like that.
Is there an equivalent to that?
Literally everything Autocode could do, Lua can do.
In this case, you want to use 3 things:
1) NPC.get() - This will get you a list of all the NPCs in the level. Feeding it an ID will get you all NPCs of a specific ID.
2) for k,v in ipairs(list) do - This will run some code once for each object in a list. When you do this, the value of v will be the object at that point in the list, while k will be the position of that object in the list. You don't really need to care about k in this instance.
3) npc:transform(newid) - There is an API called ClassExpander, which I believe is loaded by default (I'm not 100% sure if this is true in Beta 3 though). This API allows access to a transform function for NPCs, that will change the NPC in a clean and safe way.
|
|
|
|
|
|
|
|
|
-
IttaBaby
- Bot

- Posts: 55
- Joined: Sat Apr 08, 2017 8:19 pm
Postby IttaBaby » Tue Jun 27, 2017 7:30 am
Hoeloe wrote:
Literally everything Autocode could do, Lua can do.
In this case, you want to use 3 things: Helpful stuff
Can I have an example, maybe? I'm still not getting it...
|
|
|
|
|
|
|
|
|
-
Emral
- Cute Yoshi Egg

- Posts: 9887
- Joined: Mon Jan 20, 2014 12:58 pm
- Flair: Phoenix
Postby Emral » Tue Jun 27, 2017 8:08 am
Mr Briney wrote:The0x539 wrote:Mr Briney wrote:For the third time,
Answer would be greatly appreciated.
Take a look at Hypnosis Redo's lunaworld, maybe. Looks like it's draining the coin reserves and storing them itself.
Is Hypnosis Redo in the 2k1x series? Thanks btw.
Yes and yes.
The default counter flows back to 0 after reaching 100 so I check when coins are in that pool and move them over to a custom one.
As for the red coin counter, I think adding to a counter when a red coin npc is collected should work? You can use onNPCKill and check for killreason 9 (despawn) which also is for collection of items. To make sure it doesn't count up when a coin naturally despawns, check if it is close to the player.
IttaBaby wrote:Hoeloe wrote:
Literally everything Autocode could do, Lua can do.
In this case, you want to use 3 things: Helpful stuff
Can I have an example, maybe? I'm still not getting it...
Use combine the things he said:
Code: Select all function onTick() --every frame
for k,v in pairs(NPC.get(myID, sectionNumber)) do --loop over every npc of id "myID" (integer) in section sectionnumber (section 1 is 0, 2 is 1, etc)
v:transform(newID) --transform each element into an npc with the id newID (within a k,v for loop, element v is the "k"th element in the table it loops over.
end
end
|
|
|
|
|
|
|
|
|
-
IttaBaby
- Bot

- Posts: 55
- Joined: Sat Apr 08, 2017 8:19 pm
Postby IttaBaby » Tue Jun 27, 2017 11:20 am
Enjl wrote:
IttaBaby wrote:Hoeloe wrote:
Literally everything Autocode could do, Lua can do.
In this case, you want to use 3 things: Helpful stuff
Can I have an example, maybe? I'm still not getting it...
Use combine the things he said:
Code: Select all function onTick() --every frame
for k,v in pairs(NPC.get(myID, sectionNumber)) do --loop over every npc of id "myID" (integer) in section sectionnumber (section 1 is 0, 2 is 1, etc)
v:transform(newID) --transform each element into an npc with the id newID (within a k,v for loop, element v is the "k"th element in the table it loops over.
end
end
Thank you all so much "orz
|
|
|
|
|
|
|
|
|
-
IttaBaby
- Bot

- Posts: 55
- Joined: Sat Apr 08, 2017 8:19 pm
Postby IttaBaby » Wed Jun 28, 2017 2:48 pm
I get the feeling I'm going to frequent this topic >w>;
So I'm trying to load up Textblox but I don't know how to use it. I've got it to replace messages, but I'm looking to customize the windows, and the instructions say to customize a table, but I'm not sure how...
While I'm here, is there a way to make a character zip forwards a bit when a button is pressed, like a dash/air dash?
|
|
|
|
|
|
|
|
|
-
Gamma_Metroid
- Goomba

- Posts: 3
- Joined: Mon Jul 03, 2017 6:42 pm
Postby Gamma_Metroid » Mon Jul 03, 2017 6:48 pm
I'm trying to have an event occur when five dragon coins are collected, but whenever I try to access the memory offset where that's stored, SMBX crashes. I commented out all other code besides this:
Code: Select all function onStart()
tokens = mem(0x05844B7C, FIELD_WORD)
end
and it still happens. This is the stacktrace it shows me when it crashes:
Code: Select all **** THE STACKTRACE ****
0: c:\_repos\lunalua\lunadll\misc\miscfuncs.cpp (391): GetMem
1: c:\_repos\lunalua\lunadll\luamain\luaproxycomponent\luaproxyglobalfunctions.cpp (237): LuaProxy::mem
2: c:\_repos\lunalua\lunadll\libs\luabind-include\luabind\detail\call.hpp (283): luabind::detail::invoke_normal<luabind::adl::object (__cdecl*)(int,enum LuaProxy::L_FIELDTYPE,lua_State *),boost::mpl::vector4<luabind::adl::object,int,enum LuaProxy::L_FIELDTYPE,lua_State *>,luabind::detail::null_type>
3: c:\_repos\lunalua\lunadll\libs\luabind-include\luabind\make_function.hpp (63): luabind::detail::function_object_impl<luabind::adl::object (__cdecl*)(int,enum LuaProxy::L_FIELDTYPE,lua_State *),boost::mpl::vector4<luabind::adl::object,int,enum LuaProxy::L_FIELDTYPE,lua_State *>,luabind::detail::null_type>::entry_point
4: 0F8127FA (LunaDll): (filename not available): lj_BC_FUNCC
5: 0F985EC6 (LunaDll): (filename not available): lua_pcall
6: 0F83EF20 (LunaDll): (filename not available): luabind::detail::pcall
7: c:\_repos\lunalua\lunadll\libs\luabind-include\luabind\detail\call_function.hpp (264): luabind::detail::proxy_function_void_caller<boost::tuples::tuple<std::shared_ptr<Event> const *,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type> >::~proxy_function_void_caller<boost::tuples::tuple<std::shared_ptr<Event> const *,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type> >
8: c:\_repos\lunalua\lunadll\luamain\lunaluamain.h (69): CLunaLua::callLuaFunction<lua_State *,char const *,std::shared_ptr<Event> >
9: c:\_repos\lunalua\lunadll\luamain\lunaluamain.cpp (1439): CLunaLua::doEvents
10: c:\_repos\lunalua\lunadll\main.cpp (206): TestFunc
11: 008CA240 (smbx): (filename not available): (function-name not available)
12: 008C224A (smbx): (filename not available): (function-name not available)
13: 6600A048 (MSVBVM60): (filename not available): EbLoadRunTime
14: 66007B3E (MSVBVM60): (filename not available): BASIC_CLASS_QueryInterface
15: 66003981 (MSVBVM60): (filename not available): ThunRTMain
16: 660036FA (MSVBVM60): (filename not available): ThunRTMain
17: 66003600 (MSVBVM60): (filename not available): ThunRTMain
18: 0040BDE2 (smbx): (filename not available): (function-name not available)
19: 77AD0FD9 (ntdll): (filename not available): RtlSubscribeWnfStateChangeNotification
20: 77AD0FA4 (ntdll): (filename not available): RtlSubscribeWnfStateChangeNotification
|
|
|
|
|
|
|
|
|
-
The0x539
- Eerie

- Posts: 751
- Joined: Fri Jan 22, 2016 8:02 pm
Postby The0x539 » Mon Jul 03, 2017 7:20 pm
Gamma_Metroid wrote:I'm trying to have an event occur when five dragon coins are collected, but whenever I try to access the memory offset where that's stored, SMBX crashes. I commented out all other code besides this:
Code: Select all function onStart()
tokens = mem(0x05844B7C, FIELD_WORD)
end
and it still happens.
I cannot reproduce this crash using an exact copy-paste of your code.
|
|
|
|
|
|
|
|
|
-
Gamma_Metroid
- Goomba

- Posts: 3
- Joined: Mon Jul 03, 2017 6:42 pm
Postby Gamma_Metroid » Mon Jul 03, 2017 7:49 pm
Huh. I'm using multipoints in this level as well, so I deleted the LuaData_Save0_Multipoints.txt file and it doesn't crash any more. Not sure what happened there.
Anyway, now I've run into another problem: The dragon coin value seems to be stuck at -1, or at least that's what's being displayed when I try to print it to the screen every tick.
|
|
|
|
|
|
|
|
|
-
PixelPest
- Link

- Posts: 7111
- Joined: Sun Jul 12, 2015 5:38 pm
- Flair: Tamer of Boom Booms
-
Contact:
Postby PixelPest » Mon Jul 03, 2017 8:24 pm
Gamma_Metroid wrote:Anyway, now I've run into another problem: The dragon coin value seems to be stuck at -1, or at least that's what's being displayed when I try to print it to the screen every tick.
That's because onStart() only runs once. Grab the value of the mem field in onTick() so that you get the updated values each frame
|
|
|
|
|
|
|
|
|
-
Gamma_Metroid
- Goomba

- Posts: 3
- Joined: Mon Jul 03, 2017 6:42 pm
Postby Gamma_Metroid » Mon Jul 03, 2017 8:32 pm
I am. This is all my relevant code:
Code: Select all function onStart()
tokens = mem(0x05844B7C, FIELD_WORD)
tokenGoal = tokens + 5
end
function onTick()
if (player:mem(0xF0,FIELD_WORD) == 1) then
Text.print("TOKENS = " .. tokens,3,180,50)
end
if (player:mem(0xF0,FIELD_WORD) == 18) then
Text.print("TOKENS = " .. tokens,3,5,80)
end
if not(tokens == mem(0x05844B7C, FIELD_WORD)) then
if (tokens == tokenGoal) then
triggerEvent("open tourian gate")
end
end
tokens = mem(0x05844B7C, FIELD_WORD)
end
I did it this way so it only checks whether the goal is reached once, not repeatedly. I did it in another level with regular coins and it worked fine, so I'm not sure what's wrong here.
EDIT: The crashing has come back, and deleting that file doesn't seem to fix it this time. Also, I've confirmed that the game is keeping track of the dragon coins, because the event does occur when five have been collected, but it still shows -1 on the screen all the time.
EDIT2: It shows -1 when testing from PGE, and 0 when playing the whole episode normally
Just to be perfectly clear, I'm sure it's the dragon coin memory address that's doing this. If I switch all instances of that memory address with the one for the regular coin count, it works exactly as it should.
It occurred to me that maybe the address (which I got here) is incorrect... but I would think someone would have noticed that before now. Does anyone know if that's correct?
EDIT: I tried changing the calls to "global:mem(0x05844B7C, FIELD_WORD)" just to see what would happen, and it threw a lua error and just didn't load the lua file, so I played around a little bit before changing it back. Now it's displaying 7196 all the time.... It's like something is interfering with what that memory address is reading from. Sometimes it reads from one place, sometimes another place. But regardless of what is displayed, the code that triggers an event when all five are collected still works....
This is what I have currently:
Code: Select all function onStart()
tokens = mem(0x05844B7C, FIELD_WORD)
end
function onTick()
if (player:mem(0xF0,FIELD_WORD) == 1) then
Text.print("TOKENS = " .. tokens,3,180,50)
end
if (player:mem(0xF0,FIELD_WORD) == 18) then
Text.print("TOKENS = " .. tokens,3,5,80)
end
if not(tokens == mem(0x05844B7C, FIELD_WORD)) then
if (tokens == 5) then
triggerEvent("open tourian gate")
end
end
tokens = mem(0x05844B7C, FIELD_WORD)
end
EDIT2: Turns out the event is still being triggered by the layer of dragon coins being empty, which I had done before trying to get it with lua. So that's fine, but it doesn't solve the problem of the crashes or the displayed number.
Last edited by JupiHornet on Thu Jul 06, 2017 11:35 pm, edited 1 time in total.
Reason: merged double post
|
|
|
|
|
|
|
|
|
-
PixelPest
- Link

- Posts: 7111
- Joined: Sun Jul 12, 2015 5:38 pm
- Flair: Tamer of Boom Booms
-
Contact:
Postby PixelPest » Tue Jul 04, 2017 5:46 pm
That memory field is buggy iirc so it'd probably work to just increase a counter (that starts at 0) each time a Dragon Coin is collected (probably through the onNPCKill() event)
|
|
|
|
|
|
|
|
|
-
PersonNamedUser
- Reznor

- Posts: 2882
- Joined: Fri Feb 27, 2015 8:07 pm
Postby PersonNamedUser » Tue Jul 04, 2017 6:27 pm
Code: Select all local lineguide = API.load("lineguide")
local hasGenerated = false;
local hasTransformed = false; --if we've transformed an egg or not
local ran;
local frameCount = 0;
local pnpc = API.load("pnpc"); --init pnpc.lua API
timerApi = loadAPI("leveltimer");
lineguide.lineNpcs = {155, 172, 26}
function OnStart()
lineguide.registerNpcs({155, 172, 26})
end
function onLoad()
timerApi.setSecondsLeft(600);
timerApi.setTimerState(true);
end
function onTick()
for _, n in pairs(NPC.get(40, -1)) do
n.id = 172
end
end
function onTick() --run the code every tick (a unit of time); most logic for NPCs, etc. is performed in this event
for _, v in pairs(NPC.get(39)) do
local birdo = pnpc.wrap(v);
for _, w in pairs(NPC.getIntersecting(v.x, v.y, v.x + v.width, v.y + v.height)) do --iterate over all NPCs that are intersecting with its hitbox
if w.id == 40 then --if the NPC is an egg
birdo.data.megg = pnpc.wrap(w).uid; --get the unique identifier of the hammer and save it to the Hammer Bro's data table
w.friendly = true;
w:transform(172);
end
end
end
for _, x in pairs(NPC.get(172)) do --iterate over all SMB1 green shells
local shellID = pnpc.wrap(x).uid; --get the unique identifier of the shell
local intersects = false; --a variable that will be set to true if the shell is still intersecting with the Hammer Bro that threw it
for _, y in pairs(NPC.getIntersecting(x.x, x.y, x.x + x.width, x.y + x.height)) do --iterate over all NPCs that are intersecting with the shell
if (y.id == 39) and (pnpc.wrap(y).data.megg == shellID) then --if the NPC is a Hammer Bro and its data table reference for "mHammer" is the shell's uid
intersects = true; --the shell intersects still with the Hammer Bro that threw it, so this variable is set to true
end
end
if not intersects then --if the variable intersects is false
x.friendly = false; --make the shell not be friendly
else --if the variable intersects is true
x.friendly = true; --make the shell be friendly
end
end
end
function onNPCKill(eventObj, killedNPC, killReason) --an event run every time an NPC is killed; makes sure that if a Hammer Bro is killed before the shell it threw is set to not friendly (the shell was intersecting with the bro when it was killed still) that the shell is set to not friendly
if killedNPC.id == 40 then --if the killed NPC is a Hammer Bro
for _, v in pairs(NPC.get(172)) do --iterate over all shells
if pnpc.wrap(killedNPC).data.megg == pnpc.wrap(v).uid then
v.friendly = false;
end
end
end
end
nigga what
basically, lineguide just stopped working one day for no reason
|
|
|
|
|
|
|
|
|
-
The0x539
- Eerie

- Posts: 751
- Joined: Fri Jan 22, 2016 8:02 pm
Postby The0x539 » Tue Jul 04, 2017 6:47 pm
MosaicMario wrote:Code: Select all local lineguide = API.load("lineguide")
local hasGenerated = false;
local hasTransformed = false; --if we've transformed an egg or not
local ran;
local frameCount = 0;
local pnpc = API.load("pnpc"); --init pnpc.lua API
timerApi = loadAPI("leveltimer");
lineguide.lineNpcs = {155, 172, 26}
function OnStart()
lineguide.registerNpcs({155, 172, 26})
end
function onLoad()
timerApi.setSecondsLeft(600);
timerApi.setTimerState(true);
end
function onTick()
for _, n in pairs(NPC.get(40, -1)) do
n.id = 172
end
end
function onTick() --run the code every tick (a unit of time); most logic for NPCs, etc. is performed in this event
for _, v in pairs(NPC.get(39)) do
local birdo = pnpc.wrap(v);
for _, w in pairs(NPC.getIntersecting(v.x, v.y, v.x + v.width, v.y + v.height)) do --iterate over all NPCs that are intersecting with its hitbox
if w.id == 40 then --if the NPC is an egg
birdo.data.megg = pnpc.wrap(w).uid; --get the unique identifier of the hammer and save it to the Hammer Bro's data table
w.friendly = true;
w:transform(172);
end
end
end
for _, x in pairs(NPC.get(172)) do --iterate over all SMB1 green shells
local shellID = pnpc.wrap(x).uid; --get the unique identifier of the shell
local intersects = false; --a variable that will be set to true if the shell is still intersecting with the Hammer Bro that threw it
for _, y in pairs(NPC.getIntersecting(x.x, x.y, x.x + x.width, x.y + x.height)) do --iterate over all NPCs that are intersecting with the shell
if (y.id == 39) and (pnpc.wrap(y).data.megg == shellID) then --if the NPC is a Hammer Bro and its data table reference for "mHammer" is the shell's uid
intersects = true; --the shell intersects still with the Hammer Bro that threw it, so this variable is set to true
end
end
if not intersects then --if the variable intersects is false
x.friendly = false; --make the shell not be friendly
else --if the variable intersects is true
x.friendly = true; --make the shell be friendly
end
end
end
function onNPCKill(eventObj, killedNPC, killReason) --an event run every time an NPC is killed; makes sure that if a Hammer Bro is killed before the shell it threw is set to not friendly (the shell was intersecting with the bro when it was killed still) that the shell is set to not friendly
if killedNPC.id == 40 then --if the killed NPC is a Hammer Bro
for _, v in pairs(NPC.get(172)) do --iterate over all shells
if pnpc.wrap(killedNPC).data.megg == pnpc.wrap(v).uid then
v.friendly = false;
end
end
end
end
nigga what
basically, lineguide just stopped working one day for no reason
Two onTick functions and a capital O in what's supposed to be onStart???
|
|
|
|
|
|
|
|
|
-
PersonNamedUser
- Reznor

- Posts: 2882
- Joined: Fri Feb 27, 2015 8:07 pm
Postby PersonNamedUser » Sat Jul 08, 2017 2:18 am
Are you able to make an item add seconds to the leveltimer, like the api i mean, upon collecting it?
|
|
|
|
|
|
|
|
|
-
PixelPest
- Link

- Posts: 7111
- Joined: Sun Jul 12, 2015 5:38 pm
- Flair: Tamer of Boom Booms
-
Contact:
Postby PixelPest » Sat Jul 08, 2017 7:34 am
Something along the lines of: leveltimer.setSecondsLeft(leveltimer.getSecondsLeft() + #);
(Those are the functions iirc)
|
|
|
|
|
|
|
|
|
-
PersonNamedUser
- Reznor

- Posts: 2882
- Joined: Fri Feb 27, 2015 8:07 pm
Postby PersonNamedUser » Sun Jul 09, 2017 12:58 pm
This is a pretty basic question, but how do you make projectiles that bounce off walls?
|
|
|
|
|
|
|
|
|
-
PixelPest
- Link

- Posts: 7111
- Joined: Sun Jul 12, 2015 5:38 pm
- Flair: Tamer of Boom Booms
-
Contact:
Postby PixelPest » Sun Jul 09, 2017 2:10 pm
Check out the bouncing Podoboos in Beta 3
|
|
|
|
|
|
|
|
|
-
IttaBaby
- Bot

- Posts: 55
- Joined: Sat Apr 08, 2017 8:19 pm
Postby IttaBaby » Sat Jul 22, 2017 2:18 pm
In SMBX2, is there a way to force a costume?
|
|
|
|
|
|
|
|
|
-
PixelPest
- Link

- Posts: 7111
- Joined: Sun Jul 12, 2015 5:38 pm
- Flair: Tamer of Boom Booms
-
Contact:
Postby PixelPest » Sat Jul 22, 2017 6:04 pm
IttaBaby wrote:In SMBX2, is there a way to force a costume?
Just copy the files into the level/episode folder
|
|
|
|
|
Return to “LunaLua”
Users browsing this forum: No registered users and 1 guest
|