Page 1 of 1

Shell-throwing hammer bro help

Posted: Thu Apr 27, 2017 10:58 pm
by Valkyy
When a hammer bro throws a green shell using this code from lunadll.txt:

Code: Select all

NPCMemSet,30,0xE2,113,0,0,w
It kills itself when it throws the shell (and not just green shells but any type of shell). So I made a npc text file saying

Code: Select all

noshell=1
which means that it won't get killed by other npcs. Well, the hammer bro still died. I don't understand why this happens. I don't really know what to do, because I'm not an expert at lunalua.

Re: Shell-throwing hammer bro help

Posted: Thu Apr 27, 2017 11:02 pm
by PersonNamedUser
sadly, the problem is the fact that the code noshell doesn't exist therefore it won't work, maybe there is a way to do it with lunalua though.

Re: Shell-throwing hammer bro help

Posted: Thu Apr 27, 2017 11:56 pm
by FanofSMBX
Valkyy wrote:When a hammer bro throws a green shell using this code from lunadll.txt:

Code: Select all

NPCMemSet,30,0xE2,113,0,0,w
It kills itself when it throws the shell (and not just green shells but any type of shell). So I made a npc text file saying

Code: Select all

noshell=1
which means that it won't get killed by other npcs. Well, the hammer bro still died. I don't understand why this happens. I don't really know what to do, because I'm not an expert at lunalua.
Where you got that code? In my upcoming graphics pack update there is a shell bro. that I didn't test and it must do that :P

Re: Shell-throwing hammer bro help

Posted: Fri Apr 28, 2017 3:05 am
by Hoeloe
Lunadll.txt is at this point insanely outdated. It only exists so that older levels aren't broken. I would very strongly suggest NOT using it, and trying LunaLua instead. You could easily do this there by temporarily setting the shell or hammer bro friendly when it's thrown, or by moving the shell when you spawn it.

Re: Shell-throwing hammer bro help

Posted: Fri Apr 28, 2017 8:04 am
by Valkyy
Hoeloe wrote:Lunadll.txt is at this point insanely outdated. It only exists so that older levels aren't broken. I would very strongly suggest NOT using it, and trying LunaLua instead. You could easily do this there by temporarily setting the shell or hammer bro friendly when it's thrown, or by moving the shell when you spawn it.
How would I do this? I think I have some idea how but not entirely sure. Still learning lunalua.

Re: Shell-throwing hammer bro help

Posted: Sun Apr 30, 2017 8:46 am
by ShaolinTrunks
I know it's a redundant tip. But if you can find a level with a hammer bro throwing a shell in a way you like, then you can like open it. Then you can examine it in all it glory and see the light lol.

Re: Shell-throwing hammer bro help

Posted: Sun Apr 30, 2017 10:55 am
by PixelPest
ShaolinTrunks wrote:I know it's a redundant tip. But if you can find a level with a hammer bro throwing a shell in a way you like, then you can like open it. Then you can examine it in all it glory and see the light lol.
That would only work if someone's done it before...afaik it hasn't been done before.

Well I became interested in trying this and wrote the code. You can use it if you like, it seems to work perfectly. I commented on basically every single line to try to help you understand what's going on. Click "Select all" and then copy it to a lunadll.lua file if you want to make use of it:

Code: Select all

local pnpc = API.load("pnpc"); --init pnpc.lua API

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(29)) do --iterate over all existing Hammer Bros
		local bro = pnpc.wrap(v); --get/create a wrapper for each Hammer Bro
	
		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 == 30 then --if the NPC is a hammer
				bro.data.mHammer = pnpc.wrap(w).uid; --get the unique identifier of the hammer and save it to the Hammer Bro's data table
				w.friendly = true; --make the hammer friendly
				w:transform(172); --transform the hammer into an SMB1 green shell
			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 == 29) and (pnpc.wrap(y).data.mHammer == 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 == 29 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.mHammer == pnpc.wrap(v).uid then --if the killed Hammer Bro's data table reference for "mHammer" is the shell's uid
				v.friendly = false; --make the shell not friendly
			end
		end
	end
end

Re: Shell-throwing hammer bro help

Posted: Sun Apr 30, 2017 12:21 pm
by Valkyy
PixelPest wrote:Well I became interested in trying this and wrote the code. You can use it if you like, it seems to work perfectly. I commented on basically every single line to try to help you understand what's going on. Click "Select all" and then copy it to a lunadll.lua file if you want to make use of it:

Code: Select all

local pnpc = API.load("pnpc"); --init pnpc.lua API

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(29)) do --iterate over all existing Hammer Bros
		local bro = pnpc.wrap(v); --get/create a wrapper for each Hammer Bro
	
		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 == 30 then --if the NPC is a hammer
				bro.data.mHammer = pnpc.wrap(w).uid; --get the unique identifier of the hammer and save it to the Hammer Bro's data table
				w.friendly = true; --make the hammer friendly
				w:transform(172); --transform the hammer into an SMB1 green shell
			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 == 29) and (pnpc.wrap(y).data.mHammer == 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 == 29 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.mHammer == pnpc.wrap(v).uid then --if the killed Hammer Bro's data table reference for "mHammer" is the shell's uid
				v.friendly = false; --make the shell not friendly
			end
		end
	end
end
Thanks so much! I will definitely use this and make sure to credit you.

Re: Shell-throwing hammer bro help

Posted: Sun Apr 30, 2017 5:25 pm
by ShaolinTrunks
I learned something today :)