Jump to content

Prefab Functions on Modmain


Recommended Posts

Hello! I'm reworking my Webber mod: 

 

Note: the non-steam link on that post is outdated as of now.

 

So instead of doing everything on the modmain file, I was basically overwriting the prefabs' scripts that I needed to change a thing or two.

Of course, that makes so it's not compatible with some mods. I studied Lua and DST's files a bit better and began to move everything that I needed from the prefab files to my modmain. So far so good. Nearly everything works as it should, as I'm using AddPrefabPostInit to change/add functions to the prefabs that I need.

However, I came across a problem. I'm changing the bat prefab in this way:

 

AddPrefabPostInit("bat", function(inst)
local function RetargetMod(inst)
    local ta = inst.components.teamattacker

    local newtarget = GLOBAL.FindEntity(inst, TUNING.BAT_TARGET_DIST, function(guy)
            return inst.components.combat:CanTarget(guy)
        end,
        nil,
        {"bat", "spider"},
        {"character", "monster"}
    )

    if newtarget and not ta.inteam and not ta:SearchForTeam() then
        MakeTeamMod(inst, newtarget)
    end

    if ta.inteam and not ta.teamleader:CanAttack() then
        return newtarget
    end
end
local function ShouldAcceptItem(inst, item, giver)
	return giver:HasTag("batwhisperer") and inst.components.eater:CanEat(item)
end
local function OnGetItemFromPlayer(inst, giver, item)
	if inst.components.eater:CanEat(item) then  
        inst.sg:GoToState("eat_loop", true)
		
		for i = GetModConfigData("poopbats"),1,-1 
		do 
		GLOBAL.SpawnPrefab("guano").Transform:SetPosition(inst.Transform:GetWorldPosition())
		end
	end
end
local function MakeTeamMod(inst, attacker)
    local leader = GLOBAL.SpawnPrefab("teamleader")
    leader.components.teamleader:SetUp(attacker, inst)
    leader.components.teamleader:BroadcastDistress(inst)
end
if GetModConfigData("dietbats") == 0 then inst.components.eater:SetDiet({ GLOBAL.FOODTYPE.MEAT }, { GLOBAL.FOODTYPE.MEAT })
elseif GetModConfigData("dietbats") == 1 then inst.components.eater:SetDiet({ GLOBAL.FOODTYPE.MEAT , GLOBAL.FOODTYPE.VEGGIE , GLOBAL.FOODTYPE.SEEDS, GLOBAL.FOODTYPE.GENERIC }, { GLOBAL.FOODTYPE.MEAT , GLOBAL.FOODTYPE.VEGGIE , GLOBAL.FOODTYPE.SEEDS, GLOBAL.FOODTYPE.GENERIC })
elseif GetModConfigData("dietbats") == 2 then inst.components.eater:SetDiet({ GLOBAL.FOODGROUP.VEGGIE , GLOBAL.FOODTYPE.SEEDS}, { GLOBAL.FOODGROUP.VEGGIE , GLOBAL.FOODTYPE.SEEDS})
end

inst:AddComponent("sanityaura")
inst.components.sanityaura.aurafn = CalcSanityAura
inst.components.sanityaura.aura = -TUNING.SANITYAURA_MED

inst:AddComponent("trader")
inst.components.trader:SetAcceptTest(ShouldAcceptItem)
inst.components.trader.onaccept = OnGetItemFromPlayer

inst.components.combat:SetRetargetFunction(3, RetargetMod)
end)

 

It nearly works 100%. The only issue I came across is within the RetargetMod function. The default bat function is this:

local function MakeTeam(inst, attacker)
    local leader = SpawnPrefab("teamleader")
    leader.components.teamleader:SetUp(attacker, inst)
    leader.components.teamleader:BroadcastDistress(inst)
end

local function Retarget(inst)
    local ta = inst.components.teamattacker

    local newtarget = FindEntity(inst, TUNING.BAT_TARGET_DIST, function(guy)
            return inst.components.combat:CanTarget(guy)
        end,
        nil,
        {"bat"},
        {"character", "monster"}
    )

    if newtarget and not ta.inteam and not ta:SearchForTeam() then
        MakeTeam(inst, newtarget)
    end

    if ta.inteam and not ta.teamleader:CanAttack() then
        return newtarget
    end
end

So I created the RetargetMod function as an attempt to replace it, since I don't want to add something to the Retarget function, but actually change something from it. I'm trying to replace "newtarget" segment where it checks if the target it found is a bat, a character or monster. All I want to do is add spiders to said checking, so bats wont attack spiders. This is what I did: 

local function RetargetMod(inst)
    local ta = inst.components.teamattacker

    local newtarget = GLOBAL.FindEntity(inst, TUNING.BAT_TARGET_DIST, function(guy)
            return inst.components.combat:CanTarget(guy)
        end,
        nil,
        {"bat", "spider"},
        {"character", "monster"}
    )

    if newtarget and not ta.inteam and not ta:SearchForTeam() then
        MakeTeamMod(inst, newtarget)
    end

    if ta.inteam and not ta.teamleader:CanAttack() then
        return newtarget
    end
end

inst.components.combat:SetRetargetFunction(3, RetargetMod)

 

However, somehow it fails at calling the MakeTeamMod function, which is a local function within the bat prefab. This is the error it gives me: Error.thumb.png.531eecf8f53cf945645a6f8724374872.png

For some reasons it tries calling for MakeTeam as if it was global, rather than a function from the prefab I'm modifying.

I'm very sorry if this is a silly mistake, but I'm not very used to Lua.

 

I'd appreciate any help you guys can give me.

Edited by RedTarantula
Link to comment
Share on other sites

Yeah, that's because MakeTeam is a local function, and you can't access those. You have to copy it into your mod, above the part where you use it. The only way around copying them to your mod is to use Rezecib's API, which can expose these local functions.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...