Trying to make a pseudo-block NPC(SMM style Muncher) killable

Post here for help and support regarding LunaLua and SMBX2's libraries and features.

Moderator: Userbase Moderators

Lithobraker
Fighter Fly
Fighter Fly
Posts: 31
Joined: Sat Mar 09, 2019 1:41 am

Trying to make a pseudo-block NPC(SMM style Muncher) killable

Postby Lithobraker » Sun Jul 05, 2020 3:49 am

...But I seem to have unlocked the secret to immortality. No matter what harmtypes I set or options I tweak, this NPC is 100% impossible to kill.
Hammers just fly through it, POW blocks have no effect, and they find lavabathing altogether far too relaxing. I'm comparing their code to my Koopatrol NPC, and I've flipped booleans around to try to get them to die- but replacing their registerHarmType with the Koopatrol's, using all its bools, none of that seems to allow them to die. I did try replacing their .lua with the Koopatrol NPC's in its entirety, and that did make them killable, but just trying to copy parts of it around doesn't seem to get the result I need.

I've looked up the documentation as usual, and can find no information about why this might be happening(or, for that matter, what makes an NPC vulnerable to POW block damage anyway).

NPC.ini:
Spoiler: show

Code: Select all

[npc]
name = "Muncher (Vertical)"
group = "Super Mario Maker"
category = "Enemy"
image = "npc-889.png"
description = "A near-invincible enemy. Can only be defeated by using a POW Block, hammers, or lava."
gfx-offset-x = 0
gfx-offset-y = 2
gfx-width = 32
gfx-height = 32
physical-width = 32
physical-height = 32
grid = 32
grid-offset-x = 0
grid-offset-y = 0
frame-style = 1
frames = 2
frame-delay = 128
foreground = 0
animation-direction = 0
animation-bidirectional = 1
direction-alt-left-field = "Up"
direction-alt-right-field = "Down"
custom-animation = 0
container = 0
contents-id = 0
have-special = 0
NPC.lua:
Spoiler: show

Code: Select all

--NPCManager is required for setting basic NPC properties
local npcManager = require("npcManager")

--Create the library table
local smwfuzzy = {}
--NPC_ID is dynamic based on the name of the library file
local npcID = NPC_ID
local deathEffectID = (npcID)

--Defines NPC config for our NPC. You can remove superfluous definitions.
local config = {
	id = npcID,
	--Sprite size
	gfxheight = 32,
	gfxwidth = 32,
	--Hitbox size. Bottom-center-bound to sprite size.
	width = 32,
	height = 32,
	--Sprite offset from hitbox for adjusting hitbox anchor on sprite.
	gfxoffsetx = 0,
	gfxoffsety = 0,
	--Frameloop-related
	frames = 2,
	framestyle = 1,
	framespeed = 8, --# frames between frame change
	--Movement speed. Only affects speedX by default.
	speed = 0,
	--Collision-related
	npcblock = true,
	npcblocktop = true, --Misnomer, affects whether thrown NPCs bounce off the NPC.
	playerblock = true,
	playerblocktop = true, --Also handles other NPCs walking atop this NPC.

	nohurt=false,
	nogravity = true,
	noblockcollision = true,
	nofireball = true,
	noiceball = true,
	noyoshi= true,
	nowaterphysics = true,
	--Various interactions
	jumphurt = true, --If true, spiny-like
	spinjumpsafe = false, --If true, prevents player hurt when spinjumping
	harmlessgrab = false, --Held NPC hurts other NPCs if false
	harmlessthrown = false, --Thrown NPC hurts other NPCs if false

	grabside=false,
	grabtop=false,

	--Identity-related flags. Apply various vanilla AI based on the flag:
	--iswalker = false,
	--cliffturn = false,
	--isbot = false,
	--isvegetable = false,
	--isshoe = false,
	--isyoshi = false,
	--isinteractable = false,
	--iscoin = false,
	--isvine = false,
	--iscollectablegoal = false,
	--isflying = false,
	--iswaternpc = false,
	--isshell = false,

	--Emits light if the Darkness feature is active:
	--lightradius = 100,
	--lightbrightness = 1,
	--lightoffsetx = 0,
	--lightoffsety = 0,
	--lightcolor = Color.white,

	--Define custom properties below
 	deathEffectID = deathEffectID, -- The ID of the effect spawned when the enemy is killed outright(as by hammer), or can be nil for none.
}

--Applies NPC settings
npcManager.setNpcSettings(config)

--Register the vulnerable harm types for this NPC. The first table defines the harm types the NPC should be affected by, while the second maps an effect to each, if desired.
npcManager.registerHarmTypes(npcID,
	{
		--HARM_TYPE_JUMP,
		--HARM_TYPE_FROMBELOW,
		--HARM_TYPE_NPC,
		--HARM_TYPE_PROJECTILE_USED,
		HARM_TYPE_LAVA,
		--HARM_TYPE_HELD,
		--HARM_TYPE_TAIL,
		--HARM_TYPE_SPINJUMP,
		--HARM_TYPE_OFFSCREEN,
		--HARM_TYPE_SWORD,
		HARM_TYPE_EXT_HAMMER
	}, 
	{
		--[HARM_TYPE_JUMP]=10,
		--[HARM_TYPE_FROMBELOW]= 10,
		--[HARM_TYPE_NPC]= 10,
		--[HARM_TYPE_PROJECTILE_USED]= 10,
		[HARM_TYPE_LAVA]={id=13, xoffset=0.5, xoffsetBack = 0, yoffset=1, yoffsetBack = 1.5},
		--[HARM_TYPE_HELD]= 10,
		--[HARM_TYPE_TAIL]=10,
		--[HARM_TYPE_SPINJUMP]=10,
		--[HARM_TYPE_OFFSCREEN]=10,
		--[HARM_TYPE_SWORD]= 10,
		[HARM_TYPE_EXT_HAMMER] = deathEffectID,
	}
);

function smwfuzzy.onTickEndNPC(v)
    if Defines.levelFreeze then return end

    if v:mem(0x12A, FIELD_WORD) <= 0 then
        return
    end

    for k,p in ipairs(Player.get()) do
        if Colliders.speedCollide(p, v) then
            p:harm()
        end
    end
end

return smwfuzzy

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

Re: Trying to make a pseudo-block NPC(SMM style Muncher) killable

Postby Emral » Sun Jul 05, 2020 4:04 am

If you enable noblockcollision, there can be no interaction with lava. I'm also not sure how HARM_TYPE_EXT_HAMMER even works, if it does at all? Those flags and that harm type seem unrelated to the identity of SMM2 muncher... Is the lua file you posted just outdated, or is that the issue?

Back when I made SMM2 munchers (before npc-n.lua) I was able to simulate their POW cause of death at least by checking for when POWs die and then looping over the (mushroom block) Muncher and killing them with a reason not registered for the NPC. https://i.imgur.com/TvhP3Ui.png
Not sure you have any other specialized causes of death planned for your interpretation, but this might at least be a start.

Lithobraker
Fighter Fly
Fighter Fly
Posts: 31
Joined: Sat Mar 09, 2019 1:41 am

Re: Trying to make a pseudo-block NPC(SMM style Muncher) killable

Postby Lithobraker » Sun Jul 05, 2020 4:12 am

Enjl wrote:
Sun Jul 05, 2020 4:04 am
If you enable noblockcollision, there can be no interaction with lava. I'm also not sure how HARM_TYPE_EXT_HAMMER even works, if it does at all? Those flags and that harm type seem unrelated to the identity of SMM2 muncher... Is the lua file you posted just outdated, or is that the issue?

Back when I made SMM2 munchers (before npc-n.lua) I was able to simulate their POW cause of death at least by checking for when POWs die and then looping over the (mushroom block) Muncher and killing them with a reason not registered for the NPC. https://i.imgur.com/TvhP3Ui.png
Not sure you have any other specialized causes of death planned for your interpretation, but this might at least be a start.
Ah, I kind of forgot lava was a block for a bit. HARM_TYPE_EXT_HAMMER is real though, and I use it for the Koopatrol.
It's not normally in the first part of the registerHarmTypes, but it got put there at one point during testing.
Now, I... didn't know you already made SMM2 Munchers! Maybe I should just use those, then? I didn't find them on my original hunt for custom NPCs(or maybe I ignored them). Could you direct me there?

I still would like to know what's causing these guys to be immune to POW block damage, though. It's clearly something in their .lua files, but I can't seem to pinpoint what.

Edit: You can see an example of some harm types on this page: https://wohlsoft.ru/wiki/index.php?titl ... ew_desktop
HARM_TYPE_EXT_HAMMER is there.

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

Re: Trying to make a pseudo-block NPC(SMM style Muncher) killable

Postby Emral » Sun Jul 05, 2020 4:19 am

POW block damage I believe is either HARM_TYPE_NPC, _FROMBELOW or _PROJECTILE_USED... I don't quite remember. The problem with enabling all or any of those harmtypes is that a lot of other things trigger it, too! Which is why I initially made that workaround.
My interpretation of the muncher is one I've never released because it was designed specifically in the context of mechanics present in this level. And this being a level made in 2 weeks for a contest before npc-n.lua was a thing, the entire code is in... one file. Granted, it's not TOO big, but given the circumstances I wonder how useful of a guide it would be.
Here's a slightly annotated version. Be on the lookout for IDs 155 and 156 (small and big muncher respectively), if you wanna take a skim through. Muncher-related code starts in lines 278 for onTickEnd and 757 for onNPCKill:
https://hastebin.com/lafopukoce.lua

Lithobraker
Fighter Fly
Fighter Fly
Posts: 31
Joined: Sat Mar 09, 2019 1:41 am

Re: Trying to make a pseudo-block NPC(SMM style Muncher) killable

Postby Lithobraker » Sun Jul 05, 2020 4:37 am

Enjl wrote:
Sun Jul 05, 2020 4:19 am
POW block damage I believe is either HARM_TYPE_NPC, _FROMBELOW or _PROJECTILE_USED... I don't quite remember. The problem with enabling all or any of those harmtypes is that a lot of other things trigger it, too! Which is why I initially made that workaround.
My interpretation of the muncher is one I've never released because it was designed specifically in the context of mechanics present in this level. And this being a level made in 2 weeks for a contest before npc-n.lua was a thing, the entire code is in... one file. Granted, it's not TOO big, but given the circumstances I wonder how useful of a guide it would be.
Here's a slightly annotated version. Be on the lookout for IDs 155 and 156 (small and big muncher respectively), if you wanna take a skim through. Muncher-related code starts in lines 278 for onTickEnd and 757 for onNPCKill:
https://hastebin.com/lafopukoce.lua
Actually, I may have a better solution- the only problem is, I don't know what "reason" values mean what in onNPCKill, and there seems to be no resource telling me. Which number corresponds to which kill reason?

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

Re: Trying to make a pseudo-block NPC(SMM style Muncher) killable

Postby Emral » Sun Jul 05, 2020 4:58 am

They can be found in the description of onNPCKill here: https://wohlsoft.ru/pgewiki/LunaLua_events
There's also this page for the EXT ones but idk what numerical values they have, or if they even have unique ones in onNPCKill https://wohlsoft.ru/pgewiki/LunaLua_constants

Lithobraker
Fighter Fly
Fighter Fly
Posts: 31
Joined: Sat Mar 09, 2019 1:41 am

Re: Trying to make a pseudo-block NPC(SMM style Muncher) killable

Postby Lithobraker » Sun Jul 05, 2020 5:12 am

Enjl wrote:
Sun Jul 05, 2020 4:58 am
They can be found in the description of onNPCKill here: https://wohlsoft.ru/pgewiki/LunaLua_events
There's also this page for the EXT ones but idk what numerical values they have, or if they even have unique ones in onNPCKill https://wohlsoft.ru/pgewiki/LunaLua_constants
Hmm. It doesn't seem like there's any easy way to distinguish hammers from anything else- so I can't make them vulnerable to hammers without also making them vulnerable to shells and other thrown items.
It'd be easy if I could detect whether or not they intersect with a thrown hammer NPC, but my lack of experience prevents me from doing that. I dislike how so many different kill reasons are baked into the same number.
I might just stick with Munchers as blocks, to be honest.

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

Re: Trying to make a pseudo-block NPC(SMM style Muncher) killable

Postby Emral » Sun Jul 05, 2020 5:17 am

Lithobraker wrote:
Sun Jul 05, 2020 5:12 am
Enjl wrote:
Sun Jul 05, 2020 4:58 am
They can be found in the description of onNPCKill here: https://wohlsoft.ru/pgewiki/LunaLua_events
There's also this page for the EXT ones but idk what numerical values they have, or if they even have unique ones in onNPCKill https://wohlsoft.ru/pgewiki/LunaLua_constants
Hmm. It doesn't seem like there's any easy way to distinguish hammers from anything else- so I can't make them vulnerable to hammers without also making them vulnerable to shells and other thrown items.
It'd be easy if I could detect whether or not they intersect with a thrown hammer NPC, but my lack of experience prevents me from doing that. I dislike how so many different kill reasons are baked into the same number.
I might just stick with Munchers as blocks, to be honest.
Oh, the hammer thing is intentional, then?
If the hammer ID is specific you can use the new onNPCHarm function (added in beta 4). That one runs a tad sooner than onNPCKill and passes a 4th argument, which either contains the culprit object or nil. If the culprit isn't nil, it is either an NPC or a player... So you could do the following:

Code: Select all

function smwfuzzy.onNPCHarm(killEvent, killedNPC, killReason, culprit)
	if killedNPC.id == npcID then
		if type(culprit) == "NPC" and culprit.id == 176 then
			-- do things
		else
			killEvent.cancelled = true
		end
	end
end

Lithobraker
Fighter Fly
Fighter Fly
Posts: 31
Joined: Sat Mar 09, 2019 1:41 am

Re: Trying to make a pseudo-block NPC(SMM style Muncher) killable

Postby Lithobraker » Sun Jul 05, 2020 5:40 am

Enjl wrote:
Sun Jul 05, 2020 5:17 am
-snip-
Okay, well, I'm trying to make sure this NPC can only die from POW blocks and hammers, but it seems canceling the kill event doesn't work here.

If the culprit NPC's id does not equal 176, it should prevent the NPC from dying, but this isn't the case. It still dies normally from shells, thrown items, etc.
NPC.lua:
Spoiler: show

Code: Select all

--NPCManager is required for setting basic NPC properties
local npcManager = require("npcManager")

--Create the library table
local smwfuzzy = {}
--NPC_ID is dynamic based on the name of the library file
local npcID = NPC_ID
local deathEffectID = (npcID)

--Defines NPC config for our NPC. You can remove superfluous definitions.
local config = {
	id = npcID,
	--Sprite size
	gfxheight = 32,
	gfxwidth = 32,
	--Hitbox size. Bottom-center-bound to sprite size.
	width = 32,
	height = 32,
	--Sprite offset from hitbox for adjusting hitbox anchor on sprite.
	gfxoffsetx = 0,
	gfxoffsety = 0,
	--Frameloop-related
	frames = 2,
	framestyle = 1,
	framespeed = 8, --# frames between frame change
	--Movement speed. Only affects speedX by default.
	speed = 0,
	--Collision-related
	npcblock = true,
	npcblocktop = true, --Misnomer, affects whether thrown NPCs bounce off the NPC.
	playerblock = true,
	playerblocktop = true, --Also handles other NPCs walking atop this NPC.

	nohurt=false,
	nogravity = true,
	noblockcollision = true,
	nofireball = true,
	noiceball = true,
	noyoshi= true,
	nowaterphysics = true,
	--Various interactions
	jumphurt = true, --If true, spiny-like
	spinjumpsafe = false, --If true, prevents player hurt when spinjumping
	harmlessgrab = false, --Held NPC hurts other NPCs if false
	harmlessthrown = false, --Thrown NPC hurts other NPCs if false

	grabside=false,
	grabtop=false,

	--Identity-related flags. Apply various vanilla AI based on the flag:
	--iswalker = false,
	--cliffturn = false,
	--isbot = false,
	--isvegetable = false,
	--isshoe = false,
	--isyoshi = false,
	--isinteractable = false,
	--iscoin = false,
	--isvine = false,
	--iscollectablegoal = false,
	--isflying = false,
	--iswaternpc = false,
	--isshell = false,

	--Emits light if the Darkness feature is active:
	--lightradius = 100,
	--lightbrightness = 1,
	--lightoffsetx = 0,
	--lightoffsety = 0,
	--lightcolor = Color.white,

	--Define custom properties below
 	deathEffectID = deathEffectID, -- The ID of the effect spawned when the enemy is killed outright(as by hammer), or can be nil for none.
}

--Applies NPC settings
npcManager.setNpcSettings(config)

--Register the vulnerable harm types for this NPC. The first table defines the harm types the NPC should be affected by, while the second maps an effect to each, if desired.
npcManager.registerHarmTypes(npcID,
	{
		--HARM_TYPE_JUMP,
		--HARM_TYPE_FROMBELOW,
		HARM_TYPE_NPC,
		--HARM_TYPE_PROJECTILE_USED,
		HARM_TYPE_LAVA,
		--HARM_TYPE_HELD,
		--HARM_TYPE_TAIL,
		--HARM_TYPE_SPINJUMP,
		--HARM_TYPE_OFFSCREEN,
		--HARM_TYPE_SWORD,
	}, 
	{
		--[HARM_TYPE_JUMP]=10,
		--[HARM_TYPE_FROMBELOW]= 10,
		[HARM_TYPE_NPC]= deathEffectID,
		--[HARM_TYPE_PROJECTILE_USED]= 10,
		[HARM_TYPE_LAVA]={id=13, xoffset=0.5, xoffsetBack = 0, yoffset=1, yoffsetBack = 1.5},
		--[HARM_TYPE_HELD]= 10,
		--[HARM_TYPE_TAIL]=10,
		--[HARM_TYPE_SPINJUMP]=10,
		--[HARM_TYPE_OFFSCREEN]=10,
		--[HARM_TYPE_SWORD]= 10,
		[HARM_TYPE_EXT_HAMMER] = deathEffectID,
	}
);

function smwfuzzy.onTickEndNPC(v)
    if Defines.levelFreeze then return end

    if v:mem(0x12A, FIELD_WORD) <= 0 then
        return
    end

    for k,p in ipairs(Player.get()) do
        if Colliders.speedCollide(p, v) then
            p:harm()
        end
    end
end

function smwfuzzy.onNPCHarm(killEvent, killedNPC, killReason, culprit)
	if killedNPC.id == npcID then
		if type(culprit) == "NPC" and culprit.id ~= 176 then
			killEvent.cancelled = true
		end
	end
end

return smwfuzzy

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

Re: Trying to make a pseudo-block NPC(SMM style Muncher) killable

Postby Emral » Sun Jul 05, 2020 5:57 am

You never register your events onTickEndNPC and onNPCHarm anywhere. Add this to the file:

Code: Select all

function onInitAPI()
    npcManager.registerEvent(npcID, smwfuzzy, "onTickEndNPC")
    registerEvent(smwfuzzy, "onNPCHarm")
end

Lithobraker
Fighter Fly
Fighter Fly
Posts: 31
Joined: Sat Mar 09, 2019 1:41 am

Re: Trying to make a pseudo-block NPC(SMM style Muncher) killable

Postby Lithobraker » Sun Jul 05, 2020 6:09 am

Enjl wrote:
Sun Jul 05, 2020 5:57 am
You never register your events onTickEndNPC and onNPCHarm anywhere. Add this to the file:

Code: Select all

function onInitAPI()
    npcManager.registerEvent(npcID, smwfuzzy, "onTickEndNPC")
    registerEvent(smwfuzzy, "onNPCHarm")
end
This doesn't seem to have any effect. I've included that code, but the Munchers still die to shells exactly like before.

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

Re: Trying to make a pseudo-block NPC(SMM style Muncher) killable

Postby Emral » Sun Jul 05, 2020 6:10 am

Ahh dang I had a typo. Should be smwfuzzy.onInitAPI()
See if that works. If not, try putting Misc.dialog("Test") in various places to see what code runs.
If you find that it does run onNPCHarm, but not the contents of the if statement, try replacing type(culprit) with culprit.__type.

Lithobraker
Fighter Fly
Fighter Fly
Posts: 31
Joined: Sat Mar 09, 2019 1:41 am

Re: Trying to make a pseudo-block NPC(SMM style Muncher) killable

Postby Lithobraker » Sun Jul 05, 2020 6:15 am

Enjl wrote:
Sun Jul 05, 2020 6:10 am
Ahh dang I had a typo. Should be smwfuzzy.onInitAPI()
See if that works. If not, try putting Misc.dialog("Test") in various places to see what code runs.
That does seem to work, but the shells aren't bouncing off the munchers like they do when munchers are immune to all NPC harmtypes. Any way to fix that?
I might end up removing their hammer vulnerability, since it doesn't seem like there will be that many uses for it.

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

Re: Trying to make a pseudo-block NPC(SMM style Muncher) killable

Postby Emral » Sun Jul 05, 2020 6:20 am

Lithobraker wrote:
Sun Jul 05, 2020 6:15 am
Enjl wrote:
Sun Jul 05, 2020 6:10 am
Ahh dang I had a typo. Should be smwfuzzy.onInitAPI()
See if that works. If not, try putting Misc.dialog("Test") in various places to see what code runs.
That does seem to work, but the shells aren't bouncing off the munchers like they do when munchers are immune to all NPC harmtypes. Any way to fix that?
I might end up removing their hammer vulnerability, since it doesn't seem like there will be that many uses for it.
Mh... the shell just thinks it killed the NPC and continues on its merry way. You can try to turn NPCs where NPC.SHELL_MAP[culprit.id] returns true around. There may be further edge cases with different NPC types, though. In the long run it might be easier to not expose the harmtype and instead do a getColliding call between hammers and munchers.
for _, npcPairs in ipairs(Colliders.getColliding(a=hammerID, b = muncherID, atype = Colliders.NPC, btype = Colliders.npc} do
npcPairs[1] is the first npc of the collision, npcPairs[2] is the second.
end
Last edited by Emral on Sun Jul 05, 2020 6:23 am, edited 2 times in total.

Lithobraker
Fighter Fly
Fighter Fly
Posts: 31
Joined: Sat Mar 09, 2019 1:41 am

Re: Trying to make a pseudo-block NPC(SMM style Muncher) killable

Postby Lithobraker » Sun Jul 05, 2020 6:21 am

Enjl wrote:
Sun Jul 05, 2020 6:20 am
Lithobraker wrote:
Sun Jul 05, 2020 6:15 am
Enjl wrote:
Sun Jul 05, 2020 6:10 am
Ahh dang I had a typo. Should be smwfuzzy.onInitAPI()
See if that works. If not, try putting Misc.dialog("Test") in various places to see what code runs.
That does seem to work, but the shells aren't bouncing off the munchers like they do when munchers are immune to all NPC harmtypes. Any way to fix that?
I might end up removing their hammer vulnerability, since it doesn't seem like there will be that many uses for it.
Mh... the shell just thinks it killed the NPC and continues on its merry way. You can try to turn NPCs where NPC.SHELL_MAP[culprit.id] returns true around. There may be further edge cases with different NPC types, though.
It'd probably be best not to bother with this hammer thing, then. Thank you anyway, though! I learned something, at least.


Return to “LunaLua Help”

Who is online

Users browsing this forum: No registered users and 2 guests

SMWCentralTalkhausMario Fan Games GalaxyKafukaMarioWikiSMBXEquipoEstelari