Jump to content

[Scripting] Changing the efficiency of tools used by a character


Recommended Posts

So I'm looking to add a perk to my character that makes him use tools like Axes and Pickaxes at half the speed of other characters. I looked at Woodie's code and found that his increased chopping speed is part of his axe, but is there a way to make it affect all tools wielded by a character?

 

I would also like to decrease his swing speed when attacking monsters, but if that's not possible I'll just half his attack damage.

Link to comment
Share on other sites

Look at SGwilson, the frames indicators for Woodie's chop action in the timeline.

If Woodie, then 2, 5, 10 for a chop. If not Woodie, then 5, 9, 14 for a chop.

 

You will have to change the states named chop_start, chop, and mine_start, mine for axe and pickaxe tools. For the other tools you will have to see the actions they require and edit the states accordingly.

 

The attack is a bit different, since you would have to do like how Klei made Woodie here: clone the current timeline, and add ifs to distinguish your character from others. Then clone the code on the onenter, put some ifs for your character prefab to make the variable cooldowns larger.

 

I'm not sure what is the most efficient way to proceed here: override the entire stategraph, override a part of it, make a new action (a special chop, attack for the character)?

 

Amazing all the code Klei went through with Woodie.

Link to comment
Share on other sites

Ok, so modifying the animation speed is overcomplicated. But then there's a mod on the Workshop called "Zinnia the dismantler" that makes mining/chopping less effective by making it take more swings. A large tree, for instance, takes 15 hits with an axe, but with the tool she starts with it takes 20.

 

As far as I can tell this is the part of the script that does it:

    inst:AddComponent("tool")    inst.components.tool:SetAction(ACTIONS.HAMMER, 1.5)    inst.components.tool:SetAction(ACTIONS.MINE, 0.5)     inst.components.tool:SetAction(ACTIONS.CHOP, 0.75)

Would it be possible to put this into a character's script instead of a tool? There's some similar code in Woodie's script under the Werebeaver code that sets his chop speed while he's without and axe:

	inst:AddComponent("worker")	inst.components.worker:SetAction(ACTIONS.DIG, 1)	inst.components.worker:SetAction(ACTIONS.CHOP, 4)	inst.components.worker:SetAction(ACTIONS.MINE, 1)	inst.components.worker:SetAction(ACTIONS.HAMMER, 1)

But I'm not entirely sure how the "worker" component fits into this or if tools override these values with their own. Is it possible to override the tool's stats with my own values for this?

Edited by Zoshiru
Link to comment
Share on other sites

You can put the worker component in your character, but that's the equivalent of giving him stats as if he was a tool himself. IF he could behave like a tool.

 

The worker component exists in Woodie when he is a werebeaver and can't hold tools, so there is no clash.

 

Regardless, if you just add the worker component to a player, just like that, nothing would happen because the player doesn't have the left or right click action to perform a dig, a chop, a mine, or a hammer (a workable action) by himself. Nor the animations or stategraph states.

 

A worker:SetAction doesn't overwrite a tool:SetAction.

 

But you can override the tool.SetAction function:

AddComponentPostInit("tool", function(t)     local old = SetAction     function Tool:SetAction(action, effectiveness)          if self.inst and self.inst.components.inventoryitem and self.inst.components.inventoryitem.owner and self.inst.components.inventoryitem.owner.prefab == "MyCharacter" then               effectiveness = effectiveness / 2          end          old(self, action, effectiveness)     endend)

Now all tools require double the uses.

Edited by DarkXero
Link to comment
Share on other sites

Added that to my character's prefab, now the game just crashes. Not even an error message. If I add it to modmain, it crashes with the error "Unexpected symbol near )"

 

Edit: For some reason the function stretches all the way to the bottom of the script in Notepad++, as if it's missing an end. Are there some syntax errors in there I'm not seeing?

Edited by Zoshiru
Link to comment
Share on other sites

Ok, you've fixed the syntax error, but now I'm getting THIS error:

 

e7a004c406.jpg

 

The lines it's mentioning:

local master_postinit = function(inst)	-- choose which sounds this character will play	inst.soundsname = "willow"		-- Stats		inst.components.health:SetMaxHealth(150)	inst.components.hunger:SetMax(150)	inst.components.sanity:SetMax(80)		inst.components.sanity.night_drain_mult = 0	inst.components.combat.damagemultiplier = 0.5	AddComponentPostInit("tool", function(t)		local old = SetAction		function Tool:SetAction(action, effectiveness)			if self.inst and self.inst.components.inventoryitem and self.inst.components.inventoryitem.owner and self.inst.components.inventoryitem.owner.prefab == "timothy" then				effectiveness = effectiveness / 2			end		old(self, action, effectiveness)		end	end)end	
Edited by Zoshiru
Link to comment
Share on other sites

Why not go by the good ol' AddComponentPostInit and modyfing the WorkedBy function?

AddComponentPostInit("workable", function (Workable, inst)    Workable.old_WorkedBy = Workable.WorkedBy         function Workable:WorkedBy(worker, numworks)            if worker.prefab == "mycharacter" and (Workable.action == GLOBAL.ACTIONS.CHOP or Workable.action == GLOBAL.ACTIONS.MINE) then            numworks = numworks/2 or 0.5        end                return Workable:old_WorkedBy(worker, numworks)    endend)

Also, that error is caused because you are using AddComponentPostInit inside a character's prefab file. All PostInit functions (and variations) should go inside modmain.

Edited by Ryuushu
Link to comment
Share on other sites

Also, that error is caused because you are using AddComponentPostInit inside a character's prefab file. All PostInit functions (and variations) should go inside modmain.

If I put it in the modmain, the game just goes "Click" and freezes on load.

Link to comment
Share on other sites

You can put the worker component in your character, but that's the equivalent of giving him stats as if he was a tool himself. IF he could behave like a tool.

The worker component exists in Woodie when he is a werebeaver and can't hold tools, so there is no clash.

Regardless, if you just add the worker component to a player, just like that, nothing would happen because the player doesn't have the left or right click action to perform a dig, a chop, a mine, or a hammer (a workable action) by himself. Nor the animations or stategraph states.

A worker:SetAction doesn't overwrite a tool:SetAction.

But you can override the tool.SetAction function:

AddComponentPostInit("tool", function(t)     local old = SetAction     function Tool:SetAction(action, effectiveness)          if self.inst and self.inst.components.inventoryitem and self.inst.components.inventoryitem.owner and self.inst.components.inventoryitem.owner.prefab == "MyCharacter" then               effectiveness = effectiveness / 2          end          old(self, action, effectiveness)     endend)
Now all tools require double the uses.

Heyy anyway I can use this to lessen the effectiveness of normal tools and increase the effectiveness of gold tools for my character? :)

Link to comment
Share on other sites

AddPrefabPostInit("axe", function(inst)	inst:AddTag("normal")endAddPrefabPostInit("goldenaxe", function(inst)	inst:AddTag("golden")end-- Repeat the above for normal tools and golden toolsAddComponentPostInit("tool", function(self)	local old = self.SetAction	function self:SetAction(action, effectiveness)		if self.inst.components.inventoryitem.owner.prefab == "MyCharacter" then			if self.inst:HasTag("normal") then				effectiveness = (effectiveness or 1) / 2			elsif self.inst:HasTag("golden") then				effectiveness = (effectiveness or 1) * 2			end		end		old(self, action, effectiveness)	endend

Or you can try tuning Ryuushu's.

Link to comment
Share on other sites

@DarkXero, I'm not sure this would work, actually. My guess is that the component's postinit would run before the prefab's postinit (since a postinit runs after something is initialized, and the components get initialized during the prefab's initialization), so it'll be trying to check for the tags before they get added.

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...