Jump to content

Need help with food preference of characters.


Recommended Posts

--hunger, health, sanitylocal function applyupgrades(inst)    local max_upgrades = 150    local upgrades = 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:GetPercent()	inst.components.hunger.max = math.ceil (90 + upgrades * 1.50) --325?	inst.components.health.maxhealth = math.ceil (90 + upgrades * 1.50) --325?	inst.components.sanity.max = math.ceil (90 + upgrades * 1) --250		inst.components.talker:Say("I feel stronger!")	if inst.level >150 then		inst.components.talker:Say("I have reached my limit!")	end	    inst.components.hunger:SetPercent(hunger_percent)    inst.components.health:SetPercent(health_percent)    inst.components.sanity:SetPercent(sanity_percent)endlocal function oneat(inst, food)    if food and food.components.edible and food.components.edible.foodtype == FOODTYPE.GOLDEN then        --give an upgrade!        inst.level = inst.level + 1        applyupgrades(inst)         inst.SoundEmitter:PlaySound("dontstarve/characters/wx78/levelup")		    endend
-- This initializes for the server only. Components are added here.local master_postinit = function(inst)	-- 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/"		inst.level = 0		inst:AddComponent("edible")    inst.components.edible.hungervalue = TUNING.CALORIES_SMALL    inst.components.edible.healthvalue = TUNING.HEALING_MEDSMALL    inst.components.edible.sanityvalue = TUNING.SANITY_TINY    inst.components.edible.foodtype = "GOLDEN"	    inst.components.eater.foodprefs = FOODTYPE.GOLDEN	inst.components.eater:SetDiet({ FOODGROUP.GOLDEN }, { FOODTYPE.GOLDEN }, { FOODTYPE.MEAT })    inst.components.eater:SetOnEatFn(oneat)		inst:AddComponent("eater")	inst.components.eater:SetCanEatRaw()	inst.components.eater.strongstomach = true	inst.components.eater.ignoresspoilage = true    applyupgrades(inst)    inst.components.playerlightningtarget:SetHitChance(1)    inst.components.playerlightningtarget:SetOnStrikeFn(onlightingstrike)    inst.OnPreLoad = onpreload		-- Stats		inst.components.health:SetMaxHealth(100)	inst.components.hunger:SetMax(100)	inst.components.sanity:SetMax(100)	-- Sanity draims	inst.components.sanity.night_drain_mult = 1.3

The codes above are located in my prefab

 

GLOBAL.FOODGROUP.GOLDEN =     {        name = "GOLDEN",        types =        {            GLOBAL.FOODTYPE.GOLDNUGGET,			GLOBAL.FOODTYPE.MEAT,        },    }GLOBAL.FOODTYPE.GOLDEN = "GOLDEN"AddPrefabPostInit("goldnugget", function(inst)    inst:AddComponent("edible")    inst.components.edible.foodtype = GLOBAL.FOODTYPE.GOLDEN    inst.components.edible.healthvalue = 10    inst.components.edible.sanityvalue = 10    inst.components.edible.hungervalue = 10	end)

While this is located in modmain,

I tried different approaches but it seems all to be a failure. At first my character would eat goldnuggets, then i started tinkering with the code because my character won't eat anything besides the goldnuggets. Now my character will not eat goldnuggets and will eat the default food. The leveling is fine, no problem with the codes there. I'm just having trouble with the use of functions. If anyone can help or even just clarify what is wrong with the code, I'l gladly fix it. Thank you very much.

tldr; character should eat goldnuggets and meat, nothing else.

P.S. I've looked at a lot of topics and even tried inst.components.eater:SetCarnivore(true)

Link to comment
Share on other sites

function SetCanEatGold(player)    table.insert(player.components.eater.preferseating, GLOBAL.FOODTYPE.GOLDEN)    table.insert(player.components.eater.caneat, GLOBAL.FOODTYPE.GOLDEN)    player:AddTag(FOODTYPE.HORRIBLE.."_eater")end

Also you have eater and edible components in one prefab. Are you sure with your code?

Link to comment
Share on other sites

function SetCanEatGold(player)    table.insert(player.components.eater.preferseating, GLOBAL.FOODTYPE.GOLDEN)    table.insert(player.components.eater.caneat, GLOBAL.FOODTYPE.GOLDEN)    player:AddTag(FOODTYPE.HORRIBLE.."_eater")end

Also you have eater and edible components in one prefab. Are you sure with your code?

 

That is what I've been trying to say though, I wasn't really sure what the problem was in the code so I just started mashing up different things trying to make it work. The eater wasn't supposed to be there. Just forgot to take it out. Frustration got the better of me. :|

I'll sleep it off for now. My head hurts with all this coding. -_-

Edited by Valkyrie19k
Link to comment
Share on other sites

FOODGROUP = GLOBAL.FOODGROUP
FOODTYPE = GLOBAL.FOODTYPE
 
GLOBAL.FOODGROUP.OMNI_GOLDEN = {
   name = "OMNI_GOLDEN",
    types = {
        GLOBAL.FOODTYPE.MEAT,
        GLOBAL.FOODTYPE.GOLDNUGGET,
    }
}
GLOBAL.FOODTYPE.GOLDEN = "OMNI_GOLDEN"
 
AddPrefabPostInit("goldnugget", function(inst)
    inst.components.edible.foodtype = GLOBAL.FOODTYPE.GOLDEN
    inst.components.edible.healthvalue = 10
    inst.components.edible.sanityvalue = -10
    inst.components.edible.hungervalue = -10
end)
 
modmain.lua ^

inst.components.eater:SetDiet({FOODGROUP.OMNI}, {FOODGROUP.OMNI_GOLDEN})

character.lua ^


I'm about to give up this eating gold thing. Headache -_-
Edited by Valkyrie19k
Link to comment
Share on other sites

@Valkyrie19k, instead of breaking gold for other mods, I suggest the following:

local function setCanEatMeatGold(inst)    local self = inst.components.eater    self:SetDiet({ FOODGROUP.OMNI }, { FOODTYPE.MEAT })    self:SetCanEatRaw()    self.strongstomach = true    self.ignoresspoilage = true    table.insert(self.preferseating, FOODTYPE.ELEMENTAL)    table.insert(self.caneat, FOODTYPE.ELEMENTAL)    self.inst:AddTag(FOODTYPE.ELEMENTAL.."_eater")    local _tf = self.TestFood    self.TestFood = function(self, food, testvalues)        if food and food:HasTag("edible_"..FOODTYPE.ELEMENTAL) and food.prefab ~= "goldnugget" then            return        end        return _tf(self, food, testvalues)    end    inst:ListenForEvent("oneat", function(inst, data)        if data.food.prefab == "goldnugget" then            inst.components.health:DoDelta(10)            inst.components.sanity:DoDelta(-10)            inst.components.hunger:DoDelta(-12) -- -12 + 2 = -10        end    end)end

put this in your character's prefab and

setCanEatMeatGold(inst)

inside the master_postinit.

 

It would look like

-- This initializes for the server only. Components are added here.local master_postinit = function(inst)    -- 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/"         inst.level = 0	setCanEatMeatGold(inst)	    applyupgrades(inst)     inst.components.playerlightningtarget:SetHitChance(1)    inst.components.playerlightningtarget:SetOnStrikeFn(onlightingstrike)     inst.OnPreLoad = onpreload         -- Stats        inst.components.health:SetMaxHealth(100)    inst.components.hunger:SetMax(100)    inst.components.sanity:SetMax(100)    -- Sanity draims    inst.components.sanity.night_drain_mult = 1.3

Change your oneat function for

local function oneat(inst, food)    if food and food.prefab == "goldnugget" then        --give an upgrade!        inst.level = inst.level + 1        applyupgrades(inst)         inst.SoundEmitter:PlaySound("dontstarve/characters/wx78/levelup")    endend

and all of this

FOODGROUP = GLOBAL.FOODGROUPFOODTYPE = GLOBAL.FOODTYPE GLOBAL.FOODGROUP.OMNI_GOLDEN = {   name = "OMNI_GOLDEN",    types = {        GLOBAL.FOODTYPE.MEAT,        GLOBAL.FOODTYPE.GOLDNUGGET,    }}GLOBAL.FOODTYPE.GOLDEN = "OMNI_GOLDEN" AddPrefabPostInit("goldnugget", function(inst)    inst.components.edible.foodtype = GLOBAL.FOODTYPE.GOLDEN    inst.components.edible.healthvalue = 10    inst.components.edible.sanityvalue = -10    inst.components.edible.hungervalue = -10end)

remove it.

Link to comment
Share on other sites

Thank you so much DarkXero. I'm beginning to understand a lot more with regards to the construction of codes for lua.
Just to clarify, if you input the codes in modmain instead of putting it in character prefabs. Will it have a higher chance of being incompatible with other mods. ie. breaking other mods? or is it just my coding?

Thanks again!

Link to comment
Share on other sites

if you input the codes in modmain instead of putting it in character prefabs. Will it have a higher chance of being incompatible with other mods. ie. breaking other mods? or is it just my coding?

 

You had wrong and extra pointless code.

 

Lets assume you have your code working your way.

 

This is:

- in modmain

local FOODGROUP = GLOBAL.FOODGROUPlocal FOODTYPE = GLOBAL.FOODTYPEFOODTYPE.GOLDEN = "GOLDEN"FOODGROUP.MEAT_GOLDEN = {    name = "MEAT_GOLDEN",    types = {        FOODTYPE.MEAT,        FOODTYPE.GOLDEN,    }}AddPrefabPostInit("goldnugget", function(inst)    if not GLOBAL.TheWorld.ismastersim then return end    inst.components.edible.foodtype = FOODTYPE.GOLDEN    inst.components.edible.healthvalue = 10    inst.components.edible.sanityvalue = -10    inst.components.edible.hungervalue = -10end)

- in your prefab

-- First table is what gives you the eat prompt-- Second table is what you don't spit out when trying to eatinst.components.eater:SetDiet({ FOODGROUP.OMNI, FOODGROUP.MEAT_GOLDEN }, { FOODGROUP.MEAT_GOLDEN })

Which is all that is needed to get the eat prompt on everything OMNI, and goldnuggets, eating only meat and goldnuggets, like how Wigfrid spits out veggies.

 

 

My gripe with this is the following: what if somebody else wants to make their own character eat gold?

 

Imagine they want to use your mod and theirs.

If they do like you, and try to eat gold by making it FOODTYPE.MEGAGOLDY, then when you change it to FOODTYPE.GOLDEN, you break their character.

The same applies vice-versa.

 

And you don't want to create a standard for all characters that want to eat gold.

 

Regardless of the incompatibility, changing the gold foodtype to GOLDEN means now you can't give it to rock lobsters to make them follow you, since rock lobsters eat ELEMENTAL types, not GOLDEN. Moleworms also eat ELEMENTAL, so you affect those too.

Link to comment
Share on other sites

You had wrong and extra pointless code.

 

Lets assume you have your code working your way.

 

This is:

- in modmain

local FOODGROUP = GLOBAL.FOODGROUPlocal FOODTYPE = GLOBAL.FOODTYPEFOODTYPE.GOLDEN = "GOLDEN"FOODGROUP.MEAT_GOLDEN = {    name = "MEAT_GOLDEN",    types = {        FOODTYPE.MEAT,        FOODTYPE.GOLDEN,    }}AddPrefabPostInit("goldnugget", function(inst)    if not GLOBAL.TheWorld.ismastersim then return end    inst.components.edible.foodtype = FOODTYPE.GOLDEN    inst.components.edible.healthvalue = 10    inst.components.edible.sanityvalue = -10    inst.components.edible.hungervalue = -10end)

- in your prefab

-- First table is what gives you the eat prompt-- Second table is what you don't spit out when trying to eatinst.components.eater:SetDiet({ FOODGROUP.OMNI, FOODGROUP.MEAT_GOLDEN }, { FOODGROUP.MEAT_GOLDEN })

Which is all that is needed to get the eat prompt on everything OMNI, and goldnuggets, eating only meat and goldnuggets, like how Wigfrid spits out veggies.

 

 

My gripe with this is the following: what if somebody else wants to make their own character eat gold?

 

Imagine they want to use your mod and theirs.

If they do like you, and try to eat gold by making it FOODTYPE.MEGAGOLDY, then when you change it to FOODTYPE.GOLDEN, you break their character.

The same applies vice-versa.

 

And you don't want to create a standard for all characters that want to eat gold.

 

Regardless of the incompatibility, changing the gold foodtype to GOLDEN means now you can't give it to rock lobsters to make them follow you, since rock lobsters eat ELEMENTAL types, not GOLDEN. Moleworms also eat ELEMENTAL, so you affect those too.

I never imagined you'd be explaining it so clearly. Very informative I must say. Thank you very much DarkXero :) I'll make sure to keep my code clean as best as I could in the possible future.

Thank you very much again. :)

Link to comment
Share on other sites

Follow up question with the eating thingy. Is it possible to modify the damage output of the character if it eats a different element say a moonrock for example.
Will it have the same level up code? or will it break the first one since it will override the level up of the character since I have already used inst.level?

I am thinking of something like this:

 

EDIT: 
I did it :grin:
 

local MakePlayerCharacter = require "prefabs/player_common"local assets = {        Asset( "ANIM", "anim/player_basic.zip" ),        Asset( "ANIM", "anim/player_idles_shiver.zip" ),        Asset( "ANIM", "anim/player_actions.zip" ),        Asset( "ANIM", "anim/player_actions_axe.zip" ),        Asset( "ANIM", "anim/player_actions_pickaxe.zip" ),        Asset( "ANIM", "anim/player_actions_shovel.zip" ),        Asset( "ANIM", "anim/player_actions_blowdart.zip" ),        Asset( "ANIM", "anim/player_actions_eat.zip" ),        Asset( "ANIM", "anim/player_actions_item.zip" ),        Asset( "ANIM", "anim/player_actions_uniqueitem.zip" ),        Asset( "ANIM", "anim/player_actions_bugnet.zip" ),        Asset( "ANIM", "anim/player_actions_fishing.zip" ),        Asset( "ANIM", "anim/player_actions_boomerang.zip" ),        Asset( "ANIM", "anim/player_bush_hat.zip" ),        Asset( "ANIM", "anim/player_attacks.zip" ),        Asset( "ANIM", "anim/player_idles.zip" ),        Asset( "ANIM", "anim/player_rebirth.zip" ),        Asset( "ANIM", "anim/player_jump.zip" ),        Asset( "ANIM", "anim/player_amulet_resurrect.zip" ),        Asset( "ANIM", "anim/player_teleport.zip" ),        Asset( "ANIM", "anim/wilson_fx.zip" ),        Asset( "ANIM", "anim/player_one_man_band.zip" ),        Asset( "ANIM", "anim/shadow_hands.zip" ),        Asset( "SOUND", "sound/sfx.fsb" ),        Asset( "SOUND", "sound/wilson.fsb" ),        Asset( "ANIM", "anim/beard.zip" ),        Asset( "ANIM", "anim/jodi.zip" ),        Asset( "ANIM", "anim/ghost_jodi_build.zip" ),}local prefabs = {}-- Custom starting itemslocal start_inv = {	"monstermeat",	"monstermeat",	"monstermeat",	"monstermeat",}-- When the character is revived from humanlocal function onbecamehuman(inst)	-- Set speed when loading or reviving from ghost (optional)	inst.components.locomotor.walkspeed = 5	inst.components.locomotor.runspeed = 7end-- When loading or spawning the characterlocal function onload(inst)    inst:ListenForEvent("ms_respawnedfromghost", onbecamehuman)    if not inst:HasTag("playerghost") then        onbecamehuman(inst)    endendlocal function onsave(inst, data)end--hunger, health, sanitylocal function applyupgrades(inst)    local max_upgrades = 75    local upgrades = 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:GetPercent()	inst.components.hunger.max = math.ceil (90 + upgrades * 1.75) --315?	inst.components.health.maxhealth = math.ceil (90 + upgrades * 1.75) --315?	inst.components.sanity.max = math.ceil (90 + upgrades * 1.50) --245?		inst.components.talker:Say("I feel stronger!")	if inst.level >75 then		inst.components.talker:Say("Who dared put a limit to my power!")	end	    inst.components.hunger:SetPercent(hunger_percent)    inst.components.health:SetPercent(health_percent)    inst.components.sanity:SetPercent(sanity_percent)endlocal function applyupgrades2(inst)    --local max_upgrades2 = 5	--inst.components.talker:Say("An unusual power surges through my body!")	if inst.ctr == 1 then		inst.components.combat.damagemultiplier = 1.3		inst.components.talker:Say("An unusual power surges through my body!")	elseif inst.ctr == 2 then		inst.components.combat.damagemultiplier = 1.6		inst.components.talker:Say("An unusual power surges through my body!")	elseif inst.ctr == 3 then		inst.components.combat.damagemultiplier = 1.9		inst.components.talker:Say("An unusual power surges through my body!")	elseif inst.ctr == 4 then		inst.components.combat.damagemultiplier = 2.2		inst.components.talker:Say("An unusual power surges through my body!")	elseif inst.ctr == 5 then		inst.components.combat.damagemultiplier = 2.5		inst.components.talker:Say("This power is at its limit!")	endendlocal function oneat(inst, food)    if food and food.prefab == "goldnugget" then        --give an upgrade!        inst.level = inst.level + 1        applyupgrades(inst)		inst.SoundEmitter:PlaySound("dontstarve/characters/wolfgang/shrink_lrgtomed")	elseif food and food.prefab == "moonrocknugget" then	    --give an upgrade!        inst.ctr = inst.ctr + 1        applyupgrades2(inst)		inst.SoundEmitter:PlaySound("dontstarve/characters/wolfgang/grow_smtomed")    endendlocal 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 and data.health.health then inst.components.health:SetCurrentHealth(data.health.health) end        if data.hunger and data.hunger.hunger then inst.components.hunger.current = data.hunger.hunger end        if data.sanity and data.sanity.current then inst.components.sanity.current = data.sanity.current end        inst.components.health:DoDelta(0)        inst.components.hunger:DoDelta(0)        inst.components.sanity:DoDelta(0)    endendlocal function ondeath(inst)    if inst.level > 0 then        local dropgold = math.random(math.floor(inst.level / 3), math.ceil(inst.level / 2))        if dropgold > 0 then            for i = 1, dropgold do                local gear = SpawnPrefab("gold")                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)    endend-- This initializes for both the server and client. Tags can be added here.local common_postinit = function(inst) 	-- Minimap icon	inst.MiniMapEntity:SetIcon( "jodi.tex" )endlocal function setCanEatMeatGoldMoon(inst)    local self = inst.components.eater     self:SetDiet({ FOODGROUP.OMNI }, { FOODTYPE.MEAT })     self:SetCanEatRaw()    self.strongstomach = true    self.ignoresspoilage = true     table.insert(self.preferseating, FOODTYPE.ELEMENTAL)    table.insert(self.caneat, FOODTYPE.ELEMENTAL)    self.inst:AddTag(FOODTYPE.ELEMENTAL.."_eater")     local _tf = self.TestFood    self.TestFood = function(self, food, testvalues)        if food and food:HasTag("edible_"..FOODTYPE.ELEMENTAL) and food.prefab ~= "goldnugget" and food.prefab ~= "moonrocknugget" then            return        end        return _tf(self, food, testvalues)    end     inst:ListenForEvent("oneat", function(inst, data)        if data.food.prefab == "goldnugget" then            inst.components.health:DoDelta(10)            inst.components.sanity:DoDelta(-10)            inst.components.hunger:DoDelta(-12) -- -12 + 2 = -10		elseif data.food.prefab == "moonrocknugget" then            inst.components.health:DoDelta(10)            inst.components.sanity:DoDelta(10)            inst.components.hunger:DoDelta(8) -- -8 + 2 = -10        end    end)end-- This initializes for the server only. Components are added here.local master_postinit = function(inst)	-- 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/"		inst.level = 0	inst.ctr = 0			setCanEatMeatGoldMoon(inst)		applyupgrades(inst)	applyupgrades2(inst)		inst.OnPreLoad = onpreload	    inst.components.eater:SetOnEatFn(oneat)		-- Stats		inst.components.health:SetMaxHealth(100)	inst.components.hunger:SetMax(100)	inst.components.sanity:SetMax(100)	-- Sanity drains	inst.components.sanity.night_drain_mult = 1		-- Hunger rate (optional)	inst.components.hunger.hungerrate = 1.25 * TUNING.WILSON_HUNGER_RATE	    inst.OnNewSpawn = onload	inst.OnPreload = onpreload	inst.OnLoad = onload	inst.OnSave = onsaveendreturn MakePlayerCharacter("jodi", prefabs, assets, common_postinit, master_postinit, start_inv)

Only remaining problem is that it doesn't save the damage multiplier when you get disconnected or exit the game. So I am guessing it is in the preload but I don't know how to do it. Help? @DarkXero

Edited by Valkyrie19k
Link to comment
Share on other sites

@DarkXero,  So this meansI can't save the ctr function I made? Shucks.... :|

I actually tried doing this but failed 
 

    if data ~= nil and data.ctr ~= nil then
        inst.ctr = data.ctr
        applyupgrades2(inst)
        --re-set these from the save data, because of load-order clipping issues
        if data.damagemultiplier and data.damagemultiplier.damagemultiplier then inst.components.damagemultiplier:SetCurrentDamageMultiplier(data.damagemultiplier.damagemultiplier) end
        inst.components.damagemultiplier:DoDelta(0)
    end

warning, dumb code above ^

-------------------------
if saving the ctr would by any chance not work. Can there be a code where there is a set duration a power-up can last say for example.
Eating a moonrock increases damage x2 for 1 day? then goes back to normal damage output. 
-------------------------
BTW, I don't know if that was a rhetorical question or you are testing me or there isn't a code to do it.... lol
Edited by Valkyrie19k
Link to comment
Share on other sites

if saving the ctr would by any chance not work. Can there be a code where there is a set duration a power-up can last say for example.

Eating a moonrock increases damage x2 for 1 day? then goes back to normal damage output. 

You can look at the glowberry and see how it makes you light up for a specified time, as a suggestion. There's better ways to do it I'm sure, but I'm not really a coder, I'm more of a cobbler :p

Link to comment
Share on other sites

This is a lot harder than I thought.... eater component is confusing as hell...

@DarkXero, I've been needing your help a lot and I greatly appreciate it.
If it isn't too much, I'd like to ask some of insight of these.. things..

I've seen a couple of these from different sources but I feel I know too little about them.

 

 

inst

onsave
onload
onpreload
DoDelta
Edited by Valkyrie19k
Link to comment
Share on other sites

UPDATE: @DarkXero, I got everything working, even the load and save part. Thank you so much.

I'll be posting the code for people who want to study it or correct me. :D

 

local MakePlayerCharacter = require "prefabs/player_common"local assets = {        Asset( "ANIM", "anim/player_basic.zip" ),        Asset( "ANIM", "anim/player_idles_shiver.zip" ),        Asset( "ANIM", "anim/player_actions.zip" ),        Asset( "ANIM", "anim/player_actions_axe.zip" ),        Asset( "ANIM", "anim/player_actions_pickaxe.zip" ),        Asset( "ANIM", "anim/player_actions_shovel.zip" ),        Asset( "ANIM", "anim/player_actions_blowdart.zip" ),        Asset( "ANIM", "anim/player_actions_eat.zip" ),        Asset( "ANIM", "anim/player_actions_item.zip" ),        Asset( "ANIM", "anim/player_actions_uniqueitem.zip" ),        Asset( "ANIM", "anim/player_actions_bugnet.zip" ),        Asset( "ANIM", "anim/player_actions_fishing.zip" ),        Asset( "ANIM", "anim/player_actions_boomerang.zip" ),        Asset( "ANIM", "anim/player_bush_hat.zip" ),        Asset( "ANIM", "anim/player_attacks.zip" ),        Asset( "ANIM", "anim/player_idles.zip" ),        Asset( "ANIM", "anim/player_rebirth.zip" ),        Asset( "ANIM", "anim/player_jump.zip" ),        Asset( "ANIM", "anim/player_amulet_resurrect.zip" ),        Asset( "ANIM", "anim/player_teleport.zip" ),        Asset( "ANIM", "anim/wilson_fx.zip" ),        Asset( "ANIM", "anim/player_one_man_band.zip" ),        Asset( "ANIM", "anim/shadow_hands.zip" ),        Asset( "SOUND", "sound/sfx.fsb" ),        Asset( "SOUND", "sound/wilson.fsb" ),        Asset( "ANIM", "anim/beard.zip" ),        Asset( "ANIM", "anim/jodi.zip" ),        Asset( "ANIM", "anim/ghost_jodi_build.zip" ),}local prefabs = {}-- Custom starting itemslocal start_inv = {	"monstermeat",	"monstermeat",	"monstermeat",	"monstermeat",}-- When the character is revived from humanlocal function onbecamehuman(inst)	-- Set speed when loading or reviving from ghost (optional)	inst.components.locomotor.walkspeed = 5	inst.components.locomotor.runspeed = 6.5end--hunger, health, sanitylocal function applyupgrades(inst)    local max_upgrades = 20    local upgrades = 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:GetPercent()	inst.components.hunger.max = math.ceil (100 + upgrades * 8) --260?	inst.components.health.maxhealth = math.ceil (100 + upgrades * 8) --260?	inst.components.sanity.max = math.ceil (100 + upgrades * 5) --200?		inst.components.talker:Say("I feel stronger!")	if inst.level >20 then		inst.components.talker:Say("Who dared put a limit to my power!")	end	    inst.components.hunger:SetPercent(hunger_percent)    inst.components.health:SetPercent(health_percent)    inst.components.sanity:SetPercent(sanity_percent)endlocal function applyupgrades2(inst)    --local max_upgrades2 = 5	--inst.components.talker:Say("An unusual power surges through my body!")	if inst.ctr == 1 then		inst.components.combat.damagemultiplier = 1.2		inst.components.talker:Say("An unusual power surges through my body!")	elseif inst.ctr == 2 then		inst.components.combat.damagemultiplier = 1.4		inst.components.talker:Say("I can destroy a titan with this power!")	elseif inst.ctr == 3 then		inst.components.combat.damagemultiplier = 1.6		inst.components.talker:Say("Now my opponent will tremble before me!")	elseif inst.ctr == 4 then		inst.components.combat.damagemultiplier = 1.8		inst.components.talker:Say("This power coursing through my veins!")	elseif inst.ctr == 5 then		inst.components.combat.damagemultiplier = 2.2		inst.components.talker:Say("This is the last, I am at my limit.")	endendlocal function oneat1(inst, food)    if food and food.prefab == "goldnugget" then        --give an upgrade!        inst.level = inst.level + 1        applyupgrades(inst)		inst.SoundEmitter:PlaySound("dontstarve/characters/wolfgang/shrink_lrgtomed")	elseif food and food.prefab == "moonrocknugget" then		inst.ctr = inst.ctr + 1        applyupgrades2(inst)		inst.SoundEmitter:PlaySound("dontstarve/characters/wolfgang/grow_smtomed")		endend-- When loading or spawning the characterlocal function onload(inst, data)    inst:ListenForEvent("ms_respawnedfromghost", onbecamehuman)	if data ~= nil and data.level ~= nil then        inst.level = data.level        applyupgrades(inst)		if data ~= nil and data.ctr ~= nil then			inst.ctr = data.ctr			applyupgrades2(inst)				if not inst:HasTag("playerghost") then				onbecamehuman(inst)				end		end	endendlocal function onsave(inst, data)    data.level = inst.level	data.ctr = inst.ctrendlocal function onlightingstrike(inst)    if inst.components.health ~= nil and not (inst.components.health:IsDead() or inst.components.health:IsInvincible()) then        if inst.components.inventory:IsInsulated() then            inst:PushEvent("lightningdamageavoided")        else            inst.components.health:DoDelta(TUNING.HEALING_LARGE, false, "lightning")            inst.components.sanity:DoDelta(TUNING.SANITY_LARGE)			inst.components.talker:Say("That felt strangely good...")        end    endendlocal function ondeath(inst)    if inst.level > 0 then        local dropgold = math.random(math.floor(inst.level / 3), math.ceil(inst.level / 2))        if dropgold > 0 then            for i = 1, dropgold do                local gear = SpawnPrefab("goldnugget")                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)    endend--Gain sanity in rainlocal function doraincheck(inst) --, dt)	--insects	local x,y,z = inst.Transform:GetWorldPosition()	local e = TheSim:FindEntities(x,y,z,5,nil,nil,{"bee","mosquito"})	local dapp = TUNING.DAPPERNESS_MED_LARGE * 3 * #e		--rain	local w = TheWorld.state    if w.israining then		if inst.components.sanity.current > 50 then			dapp = dapp + TUNING.DAPPERNESS_MED_LARGE * 1.5 * w.precipitationrate		elseif inst.components.sanity.current > 30 then			dapp = dapp + TUNING.DAPPERNESS_MED_LARGE*2* w.precipitationrate		else			dapp = dapp + TUNING.DAPPERNESS_MED_LARGE*2.5* w.precipitationrate		end	end		--moisture	if inst.components.moisture and inst.components.moisture:GetMoisture() > 0 and inst.components.moisture:GetMoisturePercent() < 0.15  then		dapp = dapp + TUNING.DAPPERNESS_SMALL  + TUNING.MOISTURE_SANITY_PENALTY_MAX/4	end		inst.components.sanity.dapperness = dappend-- This initializes for both the server and client. Tags can be added here.local common_postinit = function(inst) 	-- Minimap icon	inst.MiniMapEntity:SetIcon( "jodi.tex" )	inst:AddTag("electricdamageimmune")endlocal function setCanEatMeatGoldMoon(inst)    local self = inst.components.eater     self:SetDiet({ FOODGROUP.OMNI }, { FOODTYPE.MEAT })     self:SetCanEatRaw()    self.strongstomach = true    self.ignoresspoilage = true     table.insert(self.preferseating, FOODTYPE.ELEMENTAL)    table.insert(self.caneat, FOODTYPE.ELEMENTAL)    self.inst:AddTag(FOODTYPE.ELEMENTAL.."_eater")     local _tf = self.TestFood    self.TestFood = function(self, food, testvalues)        if food and food:HasTag("edible_"..FOODTYPE.ELEMENTAL) and food.prefab ~= "goldnugget" and food.prefab ~= "moonrocknugget" then            return        end        return _tf(self, food, testvalues)    end     inst:ListenForEvent("oneat", function(inst, data)        if data.food.prefab == "goldnugget" then            inst.components.health:DoDelta(5)            inst.components.sanity:DoDelta(5)            inst.components.hunger:DoDelta(8) -- -12 + 2 = -10        end    end)end-- This initializes for the server only. Components are added here.local master_postinit = function(inst)	-- 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/"		inst.level = 0	inst.ctr = 0			setCanEatMeatGoldMoon(inst)		applyupgrades(inst)	applyupgrades2(inst)		inst.components.playerlightningtarget:SetHitChance(1)    inst.components.playerlightningtarget:SetOnStrikeFn(onlightingstrike)			    inst.components.eater:SetOnEatFn(oneat1)		-- Stats		inst.components.health:SetMaxHealth(100)	inst.components.hunger:SetMax(100)	inst.components.sanity:SetMax(100)	-- Sanity drains	inst.components.sanity.night_drain_mult = 1		-- Temperature	-- inst.components.temperature.inherentinsulation = TUNING.INSULATION_LARGE	-- withstands cold 4x more than wilson	--inst.components.temperature.hurtrate = (TUNING.WILSON_HEALTH / TUNING.FREEZING_KILL_TIME) / 4			--Sanity in rain check	inst:DoPeriodicTask(0.3 + math.random()*0.1, doraincheck )		-- Works faster	inst:AddComponent("worker")	inst.components.worker:SetAction(ACTIONS.CHOP, 2)	inst.components.worker:SetAction(ACTIONS.MINE, 2)	inst.components.worker:SetAction(ACTIONS.HAMMER, 2)		-- Damage multiplier (optional)    --inst.components.combat.damagemultiplier = 1		-- Hunger rate (optional)	inst.components.hunger.hungerrate = 1.10 * TUNING.WILSON_HUNGER_RATE		inst.OnSave = onsave	inst.OnLoad = onload	inst.OnNewSpawn = onloadendreturn MakePlayerCharacter("jodi", prefabs, assets, common_postinit, master_postinit, start_inv)
Link to comment
Share on other sites

inst onsave onload onpreload DoDelta

 

inst

Usually a variable referring to an entity. inst is the variable the prefab entity uses to pass the entity being created.

 

 

onsave(inst, data)

This function triggers on serialization of players (stuff gets saved via saving... or closing the server).

You load your own stuff on data (table passed) so you can load it later.

 

 

onload(inst, data)

This function triggers when a player respawns/rejoins a game. Only time this doesn't run is when the player spawns for first time.

You have OnNewSpawn for that. OnNewSpawn(inst) doesn't take a data argument because it doesn't need it.

 

 

onpreload(inst, data)

When loading saved data, the game does this

-- preload stuff-- load the saved data from components-- run the onload

This is why in WX, in the preload, says

--re-set these from the save data, because of load-order clipping issues

they load the max health before the current health value kicks in.

 

 

DoDelta

A typical method on most components, like hunger, health, sanity, moisture, temperature.

It does a delta variation on a variable/variables depending on the DoDelta you are looking at.

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