the best and cleanest solution to this is to create a custom coin npc. if i recall correctly, it shouldn't be that difficult to do using the "iscoin" configuration.
but, if it's absolutely necessary to use the vanilla coins, here's some code i wrote some time ago for a scrapped library that should do the trick:
Code: Select all
local coinIDs = { 10 } -- add/remove coin ids here, comma-separated
local function checkNPCSection(n)
if(n:mem(0x12C, FIELD_WORD) > 0) then
n.section = Player(n:mem(0x12C, FIELD_WORD)).section
return
end
for i = 0, Section.count() - 1 do
if(n.x >= Section(i).boundary.left and
n.x + n.width <= Section(i).boundary.right and
n.y >= Section(i).boundary.top and
n.y + n.height <= Section(i).boundary.bottom) then
n.section = i
return
end
end
local min_section = -1
local min_dist = -1
local nch = (n.x + n.width * 0.5)
local ncv = (n.y + n.height * 0.5)
for i = 0, Section.count() - 1 do
local disth = 0.5 * (Section(i).boundary.left + Section(i).boundary.right) - nch
local distv = 0.5 * (Section(i).boundary.top + Section(i).boundary.bottom) - ncv
local cdist = disth*disth + distv*distv
if(min_dist == -1 or cdist < min_dist) then
min_section = i
min_dist = cdist
end
end
n.section = min_section
end
function onPostEventDirect(e)
if(e == "P Switch - Start") then
for _, v in Block.iterate() do
for _, cid in ipairs(coinIDs) do
if(v.isValid and v.layerName ~= "Destroyed Blocks" and v:mem(0x5C, FIELD_WORD) == cid) then
local newnpc = NPC.spawn(cid, v.x, v.y, 0, true)
checkNPCSection(newnpc)
newnpc.layerName = v.layerName
newnpc.deathEventName = v:mem(0x10, FIELD_STRING)
newnpc.noMoreObjInLayer = v:mem(0x14, FIELD_STRING)
newnpc.x = newnpc.x + (v.width - newnpc.width) * 0.5
newnpc.isHidden = v.isHidden
v:remove(false)
break
end
end
end
end
end
just a warning though that this is not only a little hacky (though it's not too different from what happens in the vanilla code when the p-switch effect ends) but also hasn't been extensively tested in a while so there might be some jank i don't remember.