Jump to content

Recommended Posts

Hey everyone, I'm going to preface this by saying I don't actually know how to code but I do find my way around modding DST mostly by copying and pasting :D So, what I would like to know is how to add the following abilities to a character, because my usual method of looking through the files and finding a Tag/Component I can add or a Tuning line I can tweak didn't bear fruit: 

- woodie's quickpicking stuff
- wolf's mighty work chance / efficient use of tools / expert sailor (without depending on mightiness!)
- wilson's torch throwing

Hello. It's been quite a bit since you posted this, but if you still need help, here is how I would do it.

If you haven't made characters before, check out this guide on how to setup your mod.

Here is a modified example character that has all the attributes you listed:

Spoiler

Character prefab file. ("scripts\prefabs\esctemplate.lua")

Spoiler
local MakePlayerCharacter = require("prefabs/player_common")

local assets = {
	Asset("SCRIPT", "scripts/prefabs/player_common.lua"),
}

TUNING.ESCPTEMPLATE_QUICKPICK_TIMEOUT = 0.55

TUNING.ESCTEMPLATE_WORK_EFFECTIVENESS = 1.5

TUNING.ESCTEMPLATE_ROWER_MULT = 1.33
TUNING.ESCTEMPLATE_ROWER_EXTRA_MAX_VELOCITY = 0.5
TUNING.ESCTEMPLATE_ANCHOR_SPEED = 2
TUNING.ESCTEMPLATE_SAIL_BOOST_STRENGTH = 18

--Work chance
local function SpecialWorkMultiplierFn(inst, action, target, tool, numworks, recoil)
	if not recoil and numworks ~= 0 then
		local chance = 0.85

		if math.random() >= chance then
			inst.SoundEmitter:PlaySound("meta2/wolfgang/critical_work")
			return 99999
		end
	end
end
--

--Torch throwing
local function GetPointSpecialActions(inst, pos, useitem, right)
	if right then
		if useitem == nil then
			local inventory = inst.replica.inventory
			if inventory ~= nil then
				useitem = inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
			end
		end
		if useitem ~= nil and useitem:HasTag("special_action_toss") then
			return { ACTIONS.TOSS }
		end
	end
	return {}
end

local function ReticuleTargetFn()
	local player = ThePlayer
	local ground = TheWorld.Map
	local pos = Vector3()
	--Toss range is 8
	for r = 6.5, 1, -0.25 do
		pos.x, pos.y, pos.z = player.entity:LocalToWorldSpace(r, 0, 0)
		if ground:IsPassableAtPoint(pos:Get()) and not ground:IsGroundTargetBlocked(pos) then
			return pos
		end
	end
	pos.x, pos.y, pos.z = player.Transform:GetWorldPosition()
	return pos
end

local function OnSetOwner(inst)
	if inst.components.playeractionpicker ~= nil then
		inst.components.playeractionpicker.pointspecialactionsfn = GetPointSpecialActions
	end
end
--

local common_postinit = function(inst)
	--Quick picking
	inst:AddTag("woodiequickpicker")
	--

	--Torch throwing
	inst:AddComponent("reticule")
	inst.components.reticule.targetfn = ReticuleTargetFn
	inst.components.reticule.ease = true

	inst:ListenForEvent("setowner", OnSetOwner)
	--
end

local master_postinit = function(inst)
	--Work chance
	inst.components.workmultiplier:SetSpecialMultiplierFn(SpecialWorkMultiplierFn)
	--

	--Efficient tool usage
	if inst.components.efficientuser == nil then
		inst:AddComponent("efficientuser")
	end

	inst.components.efficientuser:AddMultiplier(ACTIONS.CHOP, TUNING.ESCTEMPLATE_WORK_EFFECTIVENESS, inst)
	inst.components.efficientuser:AddMultiplier(ACTIONS.MINE, TUNING.ESCTEMPLATE_WORK_EFFECTIVENESS, inst)
	inst.components.efficientuser:AddMultiplier(ACTIONS.HAMMER, TUNING.ESCTEMPLATE_WORK_EFFECTIVENESS, inst)

	inst.components.workmultiplier:AddMultiplier(ACTIONS.CHOP, TUNING.ESCTEMPLATE_WORK_EFFECTIVENESS, inst)
	inst.components.workmultiplier:AddMultiplier(ACTIONS.MINE, TUNING.ESCTEMPLATE_WORK_EFFECTIVENESS, inst)
	inst.components.workmultiplier:AddMultiplier(ACTIONS.HAMMER, TUNING.ESCTEMPLATE_WORK_EFFECTIVENESS, inst)
	--

	--Expert sailor
	inst:AddComponent("expertsailor")

	inst.components.expertsailor:SetRowForceMultiplier(TUNING.ESCTEMPLATE_ROWER_MULT)
	inst.components.expertsailor:SetRowExtraMaxVelocity(TUNING.ESCTEMPLATE_ROWER_EXTRA_MAX_VELOCITY)
	inst.components.expertsailor:SetAnchorRaisingSpeed(TUNING.ESCTEMPLATE_ANCHOR_SPEED)
	inst.components.expertsailor:SetLowerSailStrength(TUNING.ESCTEMPLATE_SAIL_BOOST_STRENGTH)
	--
end

return MakePlayerCharacter("esctemplate", prefabs, assets, common_postinit, master_postinit, prefabs)

 

 

Main file. "modmain.lua"

Spoiler
-- . . .
-- unrelated and unchanged code here


AddStategraphPostInit("wilson", function(sg)
	sg.states["dowoodiefastpick"].onenter = function(inst)
		local timeout = 1

		--Absolutely not the best way to do this, but sure is the simplest.
		if inst.prefab ~= "esctemplate" then
			local skill_level = inst.components.skilltreeupdater:CountSkillTag("quickpicker")
			timeout = skill_level > 0 and TUNING.SKILLS.WOODIE.QUICKPICK_TIMEOUT[skill_level] or 1
		else
			timeout = TUNING.ESCPTEMPLATE_QUICKPICK_TIMEOUT
		end

		inst.sg:GoToState("dolongaction", timeout)
	end
end)

 

This isn't the full character. It's only the modified bits. I have tested it and it works for me.

 

How to find the code of what you're looking for? Simply use the "Find in files" and look things up. When you know Lua sufficiently you can understand logic at a glance. Everyone started by just coping and pasting.

Here are some code snippets with unrelated bits cut, and their file directions. Look up the files if you want to see in full detail.

"-- . . ." means unrelated code in between bits.

Woodie quick picking

Spoiler

Snippet from "SGwilson.lua"

Spoiler
-- . . .

local actionhandlers =
{
	-- . . .
	
	ActionHandler(ACTIONS.PICK,
		function(inst, action)
			return
				(inst:HasTag("farmplantfastpicker") and action.target ~= nil and action.target:HasTag("farm_plant") and "domediumaction") or
				(inst.components.rider ~= nil and inst.components.rider:IsRiding() and (
					(inst:HasTag("woodiequickpicker") and "dowoodiefastpick") or
					"dolongaction"
				)) or
				(
					action.target ~= nil and
					action.target.components.pickable ~= nil and
					(
						(action.target.components.pickable.jostlepick and "dojostleaction") or
						(action.target.components.pickable.quickpick and "doshortaction") or
						(inst:HasTag("fastpicker") and "doshortaction") or
						(inst:HasTag("woodiequickpicker") and "dowoodiefastpick") or
						(inst:HasTag("quagmire_fasthands") and "domediumaction") or
						"dolongaction"
					)
				)
				or nil
		end),
	
	-- . . .
}

-- . . .

local states =
{
	-- . . .

	State{
		name = "dowoodiefastpick",

		onenter = function(inst)
			local skill_level = inst.components.skilltreeupdater:CountSkillTag("quickpicker")
			local timeout = skill_level > 0 and TUNING.SKILLS.WOODIE.QUICKPICK_TIMEOUT[skill_level] or 1

			inst.sg:GoToState("dolongaction", timeout)
		end,
	},

	-- . . .
}

-- . . .

 

Wolfgang mighty work chance

Spoiler

Snippet from "prefabs\wolfgang.lua"

Spoiler
local function SpecialWorkMultiplierFn(inst, action, target, tool, numworks, recoil)
	if not recoil and numworks ~= 0 and inst.components.mightiness:IsMighty() then
		local chance =
			(inst.components.skilltreeupdater:IsActivated("wolfgang_critwork_3") and TUNING.SKILLS.WOLFGANG_MIGHTY_WORK_CHANCE_3) or
			(inst.components.skilltreeupdater:IsActivated("wolfgang_critwork_2") and TUNING.SKILLS.WOLFGANG_MIGHTY_WORK_CHANCE_2) or
			(inst.components.skilltreeupdater:IsActivated("wolfgang_critwork_1") and TUNING.SKILLS.WOLFGANG_MIGHTY_WORK_CHANCE_1) or
			TUNING.MIGHTY_WORK_CHANCE

		if math.random() >= chance then
			inst.SoundEmitter:PlaySound("meta2/wolfgang/critical_work")
			return 99999
		end
	end
end

-- . . .

local function master_postinit(inst)
	-- . . .
  
	inst.components.workmultiplier:SetSpecialMultiplierFn(SpecialWorkMultiplierFn)
  
  	-- . . .
end

 

 

Snippet from "tuning.lua"

Spoiler
MIGHTY_WORK_CHANCE = 0.99,

-- . . .

WOLFGANG_MIGHTY_WORK_CHANCE_1 = 0.95,
WOLFGANG_MIGHTY_WORK_CHANCE_2 = 0.90,
WOLFGANG_MIGHTY_WORK_CHANCE_3 = 0.85,

Smaller number = more chance

Wolfgang efficient tool usage and expert sailor

Spoiler

 Snippet from "components\mightiness.lua"

Spoiler
local STATE_DATA = 
{
	["wimpy"] = { 
		-- . . .
		
		work_effectiveness = TUNING.WIMPY_WORK_EFFECTIVENESS,
		
		-- . . .
	},
	
	["normal"] = { 
		-- . . .
	},
	
	["mighty"] = { 
		-- . . .

		row_force_mult = TUNING.MIGHTY_ROWER_MULT,
		row_extra_max_velocity = TUNING.MIGHTY_ROWER_EXTRA_MAX_VELOCITY,
		anchor_raise_speed = TUNING.MIGHTY_ANCHOR_SPEED,
		lower_sail_strength = TUNING.MIGHTY_SAIL_BOOST_STRENGTH,
		
		-- . . .
		
		work_effectiveness = TUNING.MIGHTY_WORK_EFFECTIVENESS,
	},
}

-- . . .

function Mightiness:BecomeState(state, --[[ . . . ]])
	local state_data = STATE_DATA[state]

	-- . . .
  
	self.inst.components.expertsailor:SetRowForceMultiplier(state_data.row_force_mult)
	self.inst.components.expertsailor:SetRowExtraMaxVelocity(state_data.row_extra_max_velocity)
	self.inst.components.expertsailor:SetAnchorRaisingSpeed(state_data.anchor_raise_speed)
	self.inst.components.expertsailor:SetLowerSailStrength(state_data.lower_sail_strength)

	if  state_data.work_effectiveness then    
		self.inst.components.workmultiplier:AddMultiplier(ACTIONS.CHOP,    state_data.work_effectiveness, self.inst)
		self.inst.components.workmultiplier:AddMultiplier(ACTIONS.MINE,    state_data.work_effectiveness, self.inst)
		self.inst.components.workmultiplier:AddMultiplier(ACTIONS.HAMMER,  state_data.work_effectiveness, self.inst)

		self.inst.components.efficientuser:AddMultiplier(ACTIONS.CHOP,     state_data.work_effectiveness, self.inst)
		self.inst.components.efficientuser:AddMultiplier(ACTIONS.MINE,     state_data.work_effectiveness, self.inst)
		self.inst.components.efficientuser:AddMultiplier(ACTIONS.HAMMER,   state_data.work_effectiveness, self.inst)
	else
		self.inst.components.workmultiplier:RemoveMultiplier(ACTIONS.CHOP,   self.inst)
		self.inst.components.workmultiplier:RemoveMultiplier(ACTIONS.MINE,   self.inst)
		self.inst.components.workmultiplier:RemoveMultiplier(ACTIONS.HAMMER, self.inst)

		self.inst.components.efficientuser:RemoveMultiplier(ACTIONS.CHOP,    self.inst)
		self.inst.components.efficientuser:RemoveMultiplier(ACTIONS.MINE,    self.inst)
		self.inst.components.efficientuser:RemoveMultiplier(ACTIONS.HAMMER,  self.inst)
	end
  
	-- . . .
end

 

 

Snippet from "tuning.lua"

Spoiler
WIMPY_WORK_EFFECTIVENESS = 0.75,
-- . . .
MIGHTY_WORK_EFFECTIVENESS = 1.5,
MIGHTY_ROWER_MULT = 1.33,
MIGHTY_ROWER_EXTRA_MAX_VELOCITY = 0.5,
MIGHTY_ANCHOR_SPEED = 2,
MIGHTY_SAIL_BOOST_STRENGTH = 18,

Wilson torch throwing

Spoiler

Snippet from "prefabs\wilson.lua"

Spoiler
local function GetPointSpecialActions(inst, pos, useitem, right)
	if right then
		if useitem == nil then
			local inventory = inst.replica.inventory
			if inventory ~= nil then
				useitem = inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
			end
		end
		if useitem ~= nil and useitem:HasTag("special_action_toss") and inst.components.skilltreeupdater:IsActivated("wilson_torch_7") then
			return { ACTIONS.TOSS }
		end
	end
	return {}
end

local function ReticuleTargetFn()
	local player = ThePlayer
	local ground = TheWorld.Map
	local pos = Vector3()
	--Toss range is 8
	for r = 6.5, 1, -.25 do
		pos.x, pos.y, pos.z = player.entity:LocalToWorldSpace(r, 0, 0)
		if ground:IsPassableAtPoint(pos:Get()) and not ground:IsGroundTargetBlocked(pos) then
			return pos
		end
	end
	pos.x, pos.y, pos.z = player.Transform:GetWorldPosition()
	return pos
end

local function OnSetOwner(inst)
	if inst.components.playeractionpicker ~= nil then
		inst.components.playeractionpicker.pointspecialactionsfn = GetPointSpecialActions
	end
end

local function common_postinit(inst)
	-- . . .

	inst:AddComponent("reticule")
	inst.components.reticule.targetfn = ReticuleTargetFn
	inst.components.reticule.ease = true

	inst:ListenForEvent("setowner", OnSetOwner)
end

 

 

Snippet from "components\reticule.lua"

Spoiler
--[[
Add this component to items that need a targetting reticule
during use with a controller. Creation of the reticule is handled by
playercontroller.lua equip and unequip events.
--]]

-- . . .

Reticule component is only for controllers - probably. I haven't modded anything related to controllers ever.

The actual tossing code is in "prefabs\torch.lua", but since you only want another character to be able to toss torches, this should be sufficient.

 

Good luck!

Edited by Hamurlik
  • Health 1

Thank you so much, I'll try them out!! I don't actually make new characters, rather I modify existing ones! I'll try finding out how to plant Moon Shrooms too! :3 Cheers!

Edited by devourerofsugar

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
×
  • Create New...