Sign in to follow this  
ColombianCam

Postinit for woodie, lucy

Recommended Posts

Last time I made a thread, it was about the woodie rework, a user named serpens pointed to me out I should use modmain whenever directly changing a pre-existing game file, in this case woodie scripts; However I have no clue how to do so, I'm gonna post some code that it's in the woodie and that I want it to be in the modmain, if someone could help me, because I had to redo my whole mod because a new update bricked it, I don't wanna be updating each time they update the woodie script.

I used a compare plugin on notepad +++ to easily spot these changes from the woodie original script to my modded one.

.

        if not TheWorld.ismastersim then
            inst.CanExamine = CannotExamine
            SetWereActions(inst, mode)
            SetWereVision(inst, mode)
            if inst.components.locomotor ~= nil then
                inst.components.locomotor.runspeed =
                    (mode == WEREMODES.BEAVER and TUNING.BEAVER_RUN_SPEED) or
                    (mode == WEREMODES.MOOSE and TUNING.WEREMOOSE_RUN_SPEED) or
                    (--[[mode == WEREMODES.GOOSE and]] TUNING.WEREGOOSE_RUN_SPEED*2.5)
            end
        end
    else

what I changed was insert the *2.5 for the weregoose run speed. I'm thinking that maybe I should just use global.tuning and make that value just equal that of *2.5

[SPOILER/]

 

 else--if mode == WEREMODES.GOOSE then
        t = t * TUNING.WEREGOOSE_DRAIN_TIME
        if inst.sg:HasStateTag("moving") then
            if inst._gooserunning ~= nil then
                inst._gooserunning:Cancel()
            end
            inst._gooserunning = inst:DoTaskInTime(TUNING.WEREGOOSE_RUN_DRAIN_TIME_DURATION, OnGooseRunningOver, CalculateWerenessDrainRate)
            inst._gooserunninglevel = 2
			inst.components.wereness:DoDelta(TUNING.BEAVER_GNAW_GAIN*0.25)		
            inst.components.sanity:DoDelta(TUNING.BEAVER_GNAW_GAIN*0.25)	

           I added underneath inst._gooserunninglevel = 2

inst.components.wereness:DoDelta(TUNING.BEAVER_GNAW_GAIN*0.25)        
            inst.components.sanity:DoDelta(TUNING.BEAVER_GNAW_GAIN*0.25)   

I read recezibs guide about postinit

local OldGetPosition = inst.GetPosition
inst.GetPosition = function(thing)
    local pos = OldGetPosition(thing)
    pos.x = math.floor(pos.x+0.5)  
    pos.y = math.floor(pos.y+0.5)  
    pos.z = math.floor(pos.z+0.5) 
    return pos
end
local OldCalculateWerenessDrainRate = inst.CalculateWerenessDrainRate inst.CalculateWerenessDrainRate = function(inst) OldCalculateWerenessDrainRate(inst) end

maybe it's something like this, I dunno.

[SPOILER/]

Then, I want to revert back woodie's sanity boost for planting trees, but I made it literally anything green-ish, for example bushes.

	local function ondeployitem(inst, data)
    if data.prefab == "pinecone" or data.prefab == "acorn" or data.prefab == "twiggy_nut" or data.prefab == "dug_berrybush" or 
	data.prefab == "dug_grass" or data.prefab == "dug_sapling" or data.prefab == "butterfly" or data.prefab == "dug_sapling" or 
    data.prefab == "lureplantbulb" or data.prefab == "berrybush_juicy" then
        --inst.components.beaverness:DoDelta(TUNING.WOODIE_PLANT_TREE_GAIN)
        inst.components.sanity:DoDelta(TUNING.SANITY_TINY)
    end
end		

it's a totally new function so maybe it's  postinit function or something?

but then looking back, on the older woodie it was mentioned as a function also:

local function onrespawnedfromghost(inst)
    if inst._wasnomorph == nil then
        inst._wasnomorph = inst.sg:HasStateTag("nomorph") or inst.sg:HasStateTag("silentmorph")
		inst:ListenForEvent("deployitem", ondeployitem)										 
        inst:ListenForEvent("werenessdelta", onwerenesschange)
        inst:ListenForEvent("newstate", onnewstate)
        inst:WatchWorldState("isfullmoon", OnIsFullmoon)
    end

inst:ListenForEvent("deployitem", ondeployitem) and then afterwards in another function called onbecameghost it's mentioned.

local function onbecameghost(inst, data)
    if not IsWereMode(inst.weremode:value()) then
        --clear any queued transformations
        inst.components.wereness:SetPercent(0, true)
    elseif data == nil or not data.corpse then
        CustomSetSkinMode(inst, "ghost_were"..WEREMODE_NAMES[inst.weremode:value()].."_skin")
    end

    inst.components.wereeater:ResetFoodMemory()
    inst.components.wereness:StopDraining()
    inst.components.wereness:SetWereMode(nil)

    if inst._wasnomorph ~= nil then
        inst._wasnomorph = nil
        inst:RemoveEventCallback("werenessdelta", onwerenesschange)
        inst:RemoveEventCallback("newstate", onnewstate)
		inst:RemoveEventCallback("deployitem", ondeployitem)											  
        inst:StopWatchingWorldState("isfullmoon", OnIsFullmoon)
    end

inst:RemoveEventCallback("deployitem", ondeployitem)

[SPOILER/]

Finally the last code for this prefab is from the component tackler:

        inst:AddComponent("tackler")
        inst.components.tackler:SetOnStartTackleFn(OnTackleStart)
        inst.components.tackler:SetDistance(.5)
        inst.components.tackler:SetRadius(.75)
        inst.components.tackler:SetStructureDamageMultiplier(2)
        inst.components.tackler:AddWorkAction(ACTIONS.CHOP, 15)
        inst.components.tackler:AddWorkAction(ACTIONS.MINE, 4)
        inst.components.tackler:AddWorkAction(ACTIONS.HAMMER, 6)
        inst.components.tackler:SetOnCollideFn(OnTackleCollide)
        inst.components.tackler:SetOnTrampleFn(OnTackleTrample)
        inst.components.tackler:SetEdgeDistance(5)

what I changed was inst.components.tackler:AddWorkAction(ACTIONS.HAMMER, 6)  and inst.components.tackler:AddWorkAction(ACTIONS.CHOP, 15)

their numeric values.

[SPOILER/]

I got another script I would like to edit and it's the were idols, I want to remove the perish component from it. wereitems.lua

        inst:AddComponent("perishable")
        inst.components.perishable:SetPerishTime(TUNING.PERISH_FASTISH)
        inst.components.perishable:StartPerishing()
        inst.components.perishable.onperishreplacement = "spoiled_food"

So I couldn't, so I set a ridiculous perish time under mod main.

AddPrefabPostInit ("wereitem_beaver",function(inst)
        inst.components.edible.healthvalue = 0
        inst.components.edible.hungervalue = 0
        inst.components.edible.sanityvalue = 0
		inst.components.stackable.maxsize = TUNING.STACK_SIZE_SMALLITEM
inst.components.perishable:SetPerishTime(2000)
end) 

AddPrefabPostInit ("wereitem_moose",function(inst)
        inst.components.edible.healthvalue = 0
        inst.components.edible.hungervalue = 0
        inst.components.edible.sanityvalue = 0
		inst.components.stackable.maxsize = TUNING.STACK_SIZE_SMALLITEM
inst.components.perishable:SetPerishTime(2000)
end) 

AddPrefabPostInit ("wereitem_goose",function(inst)
        inst.components.edible.healthvalue = 0
        inst.components.edible.hungervalue = 0
        inst.components.edible.sanityvalue = 0
		inst.components.stackable.maxsize = TUNING.STACK_SIZE_SMALLITEM
inst.components.perishable:SetPerishTime(2000)
end) 

Still, I want the perish component to be removed completely. I figured it by borrowing code from a mod that changes food values:

https://steamcommunity.com/sharedfiles/filedetails/?id=1208383973

[SPOILER/]

The other script is lucy, where I made her deal 1

0 times more damage against treeguards.

local function onattack(inst, attacker, target)
    if target:HasTag("leif") then
    inst.components.weapon:SetDamage(TUNING.AXE_DAMAGE*10)
    else
	inst.components.weapon:SetDamage(TUNING.AXE_DAMAGE)
    end
	end
	    inst.components.weapon:SetDamage(TUNING.AXE_DAMAGE)
	inst.components.weapon:SetOnAttack(onattack)
end) 

Finally I wanted to add the following to lucy:

    inst:AddInherentAction(ACTIONS.TERRAFORM)
	inst.components.tool:SetAction(ACTIONS.DIG, 2)
	inst.components.tool:SetAction(ACTIONS.HAMMER, 2)
	inst.components.tool:SetAction(ACTIONS.MINE, 2)
	inst:AddComponent("terraformer")
	inst:AddComponent("shaver")

however it returins a nil value on "actions" if I try to incorporate it in modmain.

[SPOILER/]

Help.

woodie.lua

lucy.lua

modmain.lua

Share this post


Link to post
Share on other sites
Ultroman    539
2 hours ago, ColombianCam said:

what I changed was insert the *2.5 for the weregoose run speed. I'm thinking that maybe I should just use global.tuning and make that value just equal that of *2.5

When you change TUNING variables, you change it for anything else that uses that variable, in this case Weregoose, so it's not a good idea to change them.

Woodie is an incredibly complex character in terms of code, and what you're trying to do is almost impossible because all the functions are local, so you have to go through each one to see where they're called and where they're referenced, to see if you can replace them at some point. It looks rather difficult, TBH. I think you'll have a much easier time, if you just made a new character mod and steal woodie's code. That way you have full control over the code. I don't see an easy way to get this to work properly. Mostly because of all the server/client communication happening everywhere in the code.

I hope someone else can take a look at find a loophole I didn't see.

Share this post


Link to post
Share on other sites
Serpens    516

The reason to put as much code you can into modmain and not change original game files is mostly to stay compatible to game updates and also get them. There are many old mods out there that use very old modified game files, so if you enable them you will lack much new content or even get a crash, because another script is trying to call one of the new funcitons that are not included in your own.

But sometimes it is better to overwrite the original file:
1) if you want to change nearly everything within the file
2) if you dont want any game updates to add new stuff to the files
3) if there is too much you can not do in modmain (eg. because everything is "local"). Oftens there are workarounds for this, but if 1) or 2) is also true, it is not worth the affort).
But then you should compare the new original file with your old modfile from time to time, to see if the devs made changes to the original file you also want/need to include in your modified file.
Usually the need to update your mod frequently is lower if you use modmain.

I case of your spoiler-code, you see that this is the value for "components.locomotor.runspeed". So all you have to change is this value. In your previous thread I already gave you code to see if woodie is weregoose or sth else. And there you also can put the new runspeed:

-- # BEFORE adding runspeed:

            inst:ListenForEvent("transform_wereplayer",function(inst,data) -- transforms from woodie to data.mode
                if inst~=nil and data~=nil then
                    if data.mode=="goose" then -- if we transform into goose, change our collision, so we can go over the world edges
                        inst.Physics:ClearCollidesWith(GLOBAL.COLLISION.LIMITS)
                    end
                end
            end)

-- # after adding runspeed:

            inst:ListenForEvent("transform_wereplayer",function(inst,data) -- transforms from woodie to data.mode
                if inst~=nil and data~=nil then
                    if data.mode=="goose" then -- if we transform into goose, change our collision, so we can go over the world edges
                        inst.Physics:ClearCollidesWith(GLOBAL.COLLISION.LIMITS)
                        if inst.components.locomotor ~= nil then
                            inst.components.locomotor.runspeed = TUNING.WEREGOOSE_RUN_SPEED*2.5
                        end
                    end
                end
            end)


 

Edited by Serpens
  • Like 1

Share this post


Link to post
Share on other sites

it doesn't work. I tried putting the parenthesis around the runspeed value, going back before runspeed and just pasting underneath

 inst.Physics:ClearCollidesWith(GLOBAL.COLLISION.LIMITS)
inst.components.locomotor.runspeed = TUNING.WEREGOOSE_RUN_SPEED*2.5)

Share this post


Link to post
Share on other sites
Ultroman    539

You can't  have a closing parenthesis without a starting parenthesis.

inst.components.locomotor.runspeed = TUNING.WEREGOOSE_RUN_SPEED * 2.5

You seem to be missing key knowledge about the Lua language. To spare yourself much pain and trial and error, take the time to go through the Lua Crash Course linked in this post and perhaps some more tutorials on the language. I promise, it will ease the work for you.

Share this post


Link to post
Share on other sites

I've solved most problems by directly changing the tuning values by using requires tuning, however I can't still change exactly the weremoose and beaver workable actions to be more efficent, it crashes when I use workmultiplier.lua,  The value of tackle work 2 is equivalent to honeycristals.

    AddStategraphPostInit("wilson",function(sg)
        if sg.states.tackle_pre~=nil then
            local old_onexit = sg.states.tackle_pre.onexit
            local function new_onexit(inst,...)
                -- print("tackle_pre")
                inst.components.combat.externaldamagemultipliers:SetModifier("TackleDamage", 1.5)
				if inst.components.workmultiplier ~= nil then
				inst.components.workmultiplier:AddMultiplier:SetModifier("TackleWork", 2)
                return old_onexit(inst,...)
            sg.states.tackle_pre.onexit = new_onexit
        end
        if sg.states.tackle_stop~=nil then
            local old_onexit = sg.states.tackle_stop.onexit
            local function new_onexit(inst,...)
                -- print("tackle_stop")
                inst.components.workmultiplier:RemoveMultiplier:RemoveModifier("TackleWork")
                inst.components.combat.externaldamagemultipliers:RemoveModifier("TackleDamage")
			elseif inst.components.workmultiplier ~= nil then
			inst.components.workmultiplier:RemoveMultiplier:RemoveModifier("TackleWork")
			end
                return old_onexit(inst,...)
            sg.states.tackle_stop.onexit = new_onexit
        end
        if sg.states.tackle_collide~=nil then -- when colliding with something, tackle_stop is not called, so we have to revert the damage to normal here
            local old_onexit = sg.states.tackle_collide.onexit
            local function new_onexit(inst,...)
                -- print("tackle_collide")
			elseif inst.components.workmultiplier ~= nil then
			inst.components.workmultiplier:RemoveMultiplier:RemoveModifier("TackleWork")
                return old_onexit(inst,...)
            sg.states.tackle_collide.onexit = new_onexit
        end
    end)

 

I couldn't get it to work so I just used directly the honey crystals buff; It's exactly what I intended in relation to work values, where I wanted the tackle to go from 8 - to 15, but instead with honey crystals it goes to 16.

    AddStategraphPostInit("wilson",function(sg)
        if sg.states.tackle_pre~=nil then
            local old_onexit = sg.states.tackle_pre.onexit
            local function new_onexit(inst,...)
                -- print("tackle_pre")
				inst.components.debuffable:AddDebuff("buff_workeffectiveness", "buff_workeffectiveness")
                inst.components.combat.externaldamagemultipliers:SetModifier("TackleDamage", 1.5)
                return old_onexit(inst,...)
            end
            sg.states.tackle_pre.onexit = new_onexit
        end
        if sg.states.tackle_stop~=nil then
            local old_onexit = sg.states.tackle_stop.onexit
            local function new_onexit(inst,...)
                -- print("tackle_stop")
				inst.components.debuffable:RemoveDebuff("buff_workeffectiveness", "buff_workeffectiveness")
                inst.components.combat.externaldamagemultipliers:RemoveModifier("TackleDamage")
                return old_onexit(inst,...)
            end
            sg.states.tackle_stop.onexit = new_onexit
        end
        if sg.states.tackle_collide~=nil then -- when colliding with something, tackle_stop is not called, so we have to revert the damage to normal here
            local old_onexit = sg.states.tackle_collide.onexit
            local function new_onexit(inst,...)
                -- print("tackle_collide")
				inst.components.debuffable:RemoveDebuff("buff_workeffectiveness", "buff_workeffectiveness")
                inst.components.combat.externaldamagemultipliers:RemoveModifier("TackleDamage")
                return old_onexit(inst,...)
            end
            sg.states.tackle_collide.onexit = new_onexit
        end
    end)

 

Share this post


Link to post
Share on other sites
Serpens    516
On 23.9.2019 at 4:18 PM, ColombianCam said:

it doesn't work. I tried putting the parenthesis around the runspeed value, going back before runspeed and just pasting underneath


 inst.Physics:ClearCollidesWith(GLOBAL.COLLISION.LIMITS)

inst.components.locomotor.runspeed = TUNING.WEREGOOSE_RUN_SPEED*2.5)

sry the parenthesis was my mistake when copy pasting from your code where the parenthesis was right :D

yes, your workmultiplier code is wrong:

Quote

workmultiplier:AddMultiplier:SetModifier("TackleWork", 2)

this should also look strange to you.
1) 2 times a ":", you use ":" when calling a function. and when calling a function there must be (...) after the next word, just like you see it everywhere. But in this case adding () would still be wrong, because we dont want to call 2 functions. AddMultiplier and SetModifier already sounds like it would do mostly the ame, and so it is. So oyu can only use one of them. In this case you have to use AddMultiplier. Just open workmultiplier.lua and you will see those functions (same for Remove...)
But to be fair, it is not that easy to see when to use which of them, if you are a beginner. But you should have learned to not use both of them for the same thing and not within the same statement. A try of explanation when to use what:
You use Set/Remove-Modifier whenever you are directly accessing a SourceModifierList. To see if that is the case you have to read the component code. In case of the combat component and the externaldamagemultipler you will find "self.externaldamagemultipliers = SourceModifierList(self.inst)" . so when dealing with the externaldamagemultipliers, you have to use SetModifier.
And now look at the code of workmultiplier. We have SourceModifierList there, but it is packed into "self.actions[action] = SourceModifierList..." and you see that there are already functions like "AddMultiplier" that already does SetModifier at the bottom of said function. So AddMultiplier is a helper function, to make it easier for you to deal with this self.actions[action] construction. So dont use SetModifier in this case, but the helper functions of workmultiplier.

You should read and try to understand the error messages. Go to the line that is mentioned in the error message (within your logfile) and then try to find the error there. Most of the time it is easy, sometimes it is more difficult, then you can ask here. But after we told you the problem, try to understand it, so the next time you have the same issue, you will know the solution yourself :)

Share this post


Link to post
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

Sign in to follow this