Jump to content

Recommended Posts

This is all for DST.

As the title says I am trying to make a character that upgrades his health/hunger/sanity/damage by eating Moon Rocks. I am using the template to create my character so it has a model and is moving in game and all of that. But I'm having trouble setting up the actual mechanic.

Could anyone help me in setting this up? I am trying to get my character to have a maximum upgrade of 20 Moon Rocks. Each moon rock should provide an upgrade of +2.5 Health, +5 Hunger, +5 Sanity and +5% damage. I think I made the code for that ok? Although I'm not sure since it crashes before I can know. And the character should lose 75% of all upgrades on death.

I of course tried to implement the WX-78 gear eating mechanic and transform it to what I need but he has a lot of extra stuff inside and I am not sure which parts I need to implement. I did try to place inside only the parts that I needed and my character actually manages to eat the gears but it crashes the server... I've provided my current william.lua file with my edits inside and the wx78.lua for easier comparing.

I would greatly appreciate any help or (if possible) the working code. I would of course provide all the credits to the person that made it once I publish the mod.

I figured out how to upgrade my character with Moon rocks and I got the stats per moon rock working and basically everything works... BUT now everyone can eat Moonrocks... because the modmain.lua modifications apply Globaly apparently. Is there a way I can make only my character be able to eat moonrocks?

Ok so I managed to get everything up and running so I'll give a rundown to anyone that will want to attempt this in the future.
I dislike the lack of specific things listed online.

If you want to have your character upgrade by eating stuff like WX-78 and you don't want it to be gears but something like Rocks, Moonrocks or anything else not edible you will first need to define a couple of things inside the modmain.lua like this:

Spoiler

local require = GLOBAL.require
local STRINGS = GLOBAL.STRINGS

-- this part defines the initial variables we will need later on, your character values and the new foodtype
TUNING.WILLIAM_HEALTH = 50
TUNING.WILLIAM_HUNGER = 150
TUNING.WILLIAM_SANITY = 150
GLOBAL.FOODTYPE.MOONROCK = "MOONROCK"

-- lava arena settings
if GLOBAL.TheNet:GetServerGameMode() == "lavaarena" then
TUNING.LAVAARENA_STARTING_HEALTH.WILLIAM = 50
TUNING.GAMEMODE_STARTING_ITEMS.LAVAARENA.WILLIAM = { "spear_lance", "reedtunic" }
end

-- creates a function that will: give the item it is applied to the component "edible" and add the FOODTYPE = MOONROCK, additionally gives it minor healing properties on eating
local function eat_moon(inst)
	inst:AddComponent("edible")
	inst.components.edible.foodtype = GLOBAL.FOODTYPE.MOONROCK
	inst.components.edible.healthvalue = GLOBAL.TUNING.HEALING_TINY*10
	inst.components.edible.hungervalue = GLOBAL.TUNING.CALORIES_TINY
	inst.components.edible.sanityvalue = GLOBAL.TUNING.SANITY_TINY
end

-- adds the above function to the prefab "moonrocknugget" post initialisation
AddPrefabPostInit("moonrocknugget", eat_moon)

 


As for the file that modifies your character, mine is called "william.lua" you will need to basically copy a lot of the stuff from "wx78.lua" and edit it to suit the new variables we defined inside modmain.lua. It should be done like so:

Spoiler

-- Custom starting inventory
TUNING.GAMEMODE_STARTING_ITEMS.DEFAULT.william = {
	"glasscutter",
	"moonglassaxe",
}

-- Change the v:WILLIAM variable to suit your char
local start_inv = {}
for k, v in pairs(TUNING.GAMEMODE_STARTING_ITEMS) do
    start_inv[string.lower(k)] = v.william
end
local prefabs = FlattenTree(start_inv, true)

-- Max upgrades, hunger, health, sanity, damage upgrade calculations, change the calculations to your variables and desired amounts
local function applyupgrades(inst)
    local max_upgrades = 20
    inst.level = math.min(inst.level, max_upgrades)

    local hunger_percent = inst.components.hunger:GetPercent()
    local health_percent = inst.components.health:GetPercent()
    local sanity_percent = inst.components.sanity:GetRealPercent()

    inst.components.hunger.max = math.ceil(TUNING.WILLIAM_HUNGER + (5 * inst.level))
    inst.components.health.maxhealth = math.ceil(TUNING.WILLIAM_HEALTH + (2.5 * inst.level))
    inst.components.sanity.max = math.ceil(TUNING.WILLIAM_SANITY + (5 * inst.level))
	inst.components.combat.damagemultiplier = (2 + (0.05 * inst.level))
	
    inst.components.hunger:SetPercent(hunger_percent)
    inst.components.health:SetPercent(health_percent)

    local ignoresanity = inst.components.sanity.ignore
    inst.components.sanity.ignore = false
    inst.components.sanity:SetPercent(sanity_percent)
    inst.components.sanity.ignore = ignoresanity
end

-- What happens after you eat your new foodtype, your upgrade level increases and your upgrades apply to your character
local function oneat(inst, food)
    if food and food.components.edible and food.components.edible.foodtype == FOODTYPE.MOONROCK then
        --give an upgrade!
        inst.level = inst.level + 1
		--apply the upgrade!
        applyupgrades(inst)
    end
end

-- Pretty sure this loads your saved data for health/hunger/sanity upgrades
local function onpreload(inst, data)
    if data ~= nil and data.level ~= nil then
        inst.level = data.level
        applyupgrades(inst)
        --re-set these from the save data, because of load-order clipping issues
        if data.health ~= nil and data.health.health ~= nil then
            inst.components.health:SetCurrentHealth(data.health.health)
        end
        if data.hunger ~= nil and data.hunger.hunger ~= nil then
            inst.components.hunger.current = data.hunger.hunger
        end
        if data.sanity ~= nil and data.sanity.current ~= nil then
            inst.components.sanity.current = data.sanity.current
        end
        inst.components.health:DoDelta(0)
        inst.components.hunger:DoDelta(0)
        inst.components.sanity:DoDelta(0)
    end
end

-- When the character is revived from human
local function onbecamehuman(inst)
	-- Set speed when not a ghost (optional)
	inst.components.locomotor:SetExternalSpeedMultiplier(inst, "william_speed_mod", 1.25)
end

local function onbecameghost(inst)
	-- Remove speed modifier when becoming a ghost
   inst.components.locomotor:RemoveExternalSpeedMultiplier(inst, "william_speed_mod")
end

-- Drops (in my case) some moonrocks on death, if you want to change to your item simply change the ("moonrocknugget") to the thing you want to drop
local function ondeath(inst)
    if inst.level > 0 then
        local dropgears = math.random(math.floor(inst.level / 3), math.ceil(inst.level / 2))
        if dropgears > 0 then
            for i = 1, dropgears do
                local gear = SpawnPrefab("moonrocknugget")
                if gear ~= nil then
                    local x, y, z = inst.Transform:GetWorldPosition()
                    if gear.Physics ~= nil then
                        local speed = 2 + math.random()
                        local angle = math.random() * 2 * PI
                        gear.Transform:SetPosition(x, y + 1, z)
                        gear.Physics:SetVel(speed * math.cos(angle), speed * 3, speed * math.sin(angle))
                    else
                        gear.Transform:SetPosition(x, y, z)
                    end
                    if gear.components.propagator ~= nil then
                        gear.components.propagator:Delay(5)
                    end
                end
            end
        end
        inst.level = 0
        applyupgrades(inst)
    end
end

-- When loading or spawning the character
local function onload(inst)
    inst:ListenForEvent("ms_respawnedfromghost", onbecamehuman)
    inst:ListenForEvent("ms_becameghost", onbecameghost)

    if inst:HasTag("playerghost") then
        onbecameghost(inst)
    else
        onbecamehuman(inst)
    end
end

-- Save function
local function onsave(inst, data)
    data.level = inst.level > 0 and inst.level or nil
end

-- This initializes for both the server and client. Tags can be added here.
local common_postinit = function(inst) 
	-- Minimap icon
	inst.MiniMapEntity:SetIcon( "william.tex" )
end

-- This initializes for the server only. Components are added here.
local master_postinit = function(inst)
	-- Set starting inventory
    inst.starting_inventory = start_inv[TheNet:GetServerGameMode()] or start_inv.default
	
	-- Initial level of your upgrades
	inst.level = 0
	
	-- Enables the character to eat moonrocks
	if inst.components.eater ~= nil then
		local caneat = inst.components.eater.caneat
		local preferseating = inst.components.eater.preferseating
		table.insert(inst.components.eater.preferseating, FOODTYPE.MOONROCK)
		table.insert(inst.components.eater.caneat, FOODTYPE.MOONROCK)
		inst.components.eater:SetDiet(caneat, preferseating)
		inst.components.eater:SetOnEatFn(oneat)
    end
	
	-- Applies the initial upgrades on initialisation (level 0)
	  applyupgrades(inst)
	
	-- Listens (aka, waits) for specific events to happen and then applies the appropriate functions
    inst:ListenForEvent("death", ondeath)
    inst:ListenForEvent("ms_playerreroll", ondeath) --delevel, give back some gears
	
	-- Choose which sounds this character will play
	inst.soundsname = "willow"
	
	-- Uncomment if "wathgrithr"(Wigfrid) or "webber" voice is used
    --inst.talker_path_override = "dontstarve_DLC001/characters/"
	
	-- Damage multiplier (optional)
    inst.components.combat.damagemultiplier = 2
	
	-- Hunger rate (optional)
	inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE
	
	-- Save/load functions
	inst.OnSave = onsave
	inst.OnLoad = onload
	inst.OnPreLoad = onpreload
	
end

 


Congrats. You now have a new FOODTYPE, a new edible item (moonrocknugget) with that FOODTYPE, edible only for your character and you upgrade your character stats by eating it.


 

Edited by devon752
Updated the code because it didn't listen to events happening, now it does

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