Jump to content

How do I make my player mod tell Walter's stories at the campfire?


Recommended Posts

I want my character to be able to tell stories at the campfire. I tried yoinking some of his code and putting them in the correct spaces, but it didn't work and had the following error:
string "../mods/OrangERework/scripts/prefabs/orange.lua"]:228: '<eof>' expected near 'Prefab'
I dont know how to fix it. Any help? 

My character.lua code:

local MakePlayerCharacter = require "prefabs/player_common"
 
local assets = {
    Asset("SCRIPT", "scripts/prefabs/player_common.lua"),
    Asset("ANIM", "anim/orange_idle.zip"),
}
 
local prefabs =
{
    "walter_campfire_story_proxy",
}
 
-- Your character's stats
TUNING.ORANGE_HEALTH = 200
TUNING.ORANGE_HUNGER = 150
TUNING.ORANGE_SANITY = 150
 
-- Custom starting inventory
TUNING.GAMEMODE_STARTING_ITEMS.DEFAULT.ORANGE = {
    "gears",
}
 
local start_inv = {}
for k, v in pairs(TUNING.GAMEMODE_STARTING_ITEMS) do
    start_inv[string.lower(k)] = v.ORANGE
end
local prefabs = FlattenTree(start_inv, true)
 
local function StoryTellingDone(inst, story)
    if inst._story_proxy ~= nil and inst._story_proxy:IsValid() then
        inst._story_proxy:Remove()
        inst._story_proxy = nil
    end
end
 
local function StoryToTellFn(inst, story_prop)
    if not TheWorld.state.isnight then
        return "NOT_NIGHT"
    end
 
    local fueled = story_prop ~= nil and story_prop.components.fueled or nil
    if fueled ~= nil and story_prop:HasTag("campfire") then
        if fueled:IsEmpty() then
            return "NO_FIRE"
        end
 
        local campfire_stories = STRINGS.STORYTELLER.WALTER["CAMPFIRE"]
        if campfire_stories ~= nil then
            if inst._story_proxy ~= nil then
                inst._story_proxy:Remove()
                inst._story_proxy = nil
            end
            inst._story_proxy = SpawnPrefab("walter_campfire_story_proxy")
            inst._story_proxy:Setup(inst, story_prop)
 
            local story_id = GetRandomKey(campfire_stories)
            return { style = "CAMPFIRE", id = story_id, lines = campfire_stories[story_id].lines }
        end
    end
 
    return nil
end
 
-- When the character is revived from human
local function onbecamehuman(inst)
    -- Set speed when not a ghost (optional)
    inst.components.locomotor:SetExternalSpeedMultiplier(inst, "orange_speed_mod", 1)
end
 
local function onbecameghost(inst)
    -- Remove speed modifier when becoming a ghost
   inst.components.locomotor:RemoveExternalSpeedMultiplier(inst, "orange_speed_mod")
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
 
-- This initializes for both the server and client. Tags can be added here.
local common_postinit = function(inst)
    inst:AddTag("chess")
    inst:AddTag("storyteller")
    -- Minimap icon
    inst.MiniMapEntity:SetIcon( "orange.tex" )
 
    inst.foleysound = "dontstarve/movement/foley/wx78"
 
    inst.customidleanim = "orange_idle"
end
 
-- This initializes for the server only. Components are added here.
local master_postinit = function(inst)
 
    --Storyteller Orange
    inst:AddComponent("storyteller")
    inst.components.storyteller:SetStoryToTellFn(StoryToTellFn)
    inst.components.storyteller:SetOnStoryOverFn(StoryTellingDone)
 
    -- Set starting inventory
    inst.starting_inventory = start_inv[TheNet:GetServerGameMode()] or start_inv.default
 
    if inst.components.eater ~= nil then
        inst.components.eater:SetCanEatGears()
    end
   
    -- choose which sounds this character will play
    inst.soundsname = "orange"
   
    -- Uncomment if "wathgrithr"(Wigfrid) or "webber" voice is used
    --inst.talker_path_override = "dontstarve_DLC001/characters/"
   
    -- Stats    
    inst.components.health:SetMaxHealth(TUNING.ORANGE_HEALTH)
    inst.components.hunger:SetMax(TUNING.ORANGE_HUNGER)
    inst.components.sanity:SetMax(TUNING.ORANGE_SANITY)
   
    -- Damage multiplier (optional)
    inst.components.combat.damagemultiplier = 1
   
    -- Hunger rate (optional)
    inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE
   
    -- DoPeriodicTask calls the given function every X seconds.
    -- I set it to 1.0. You can set it to e.g. 0.5 seconds if you want.
    inst:DoPeriodicTask(1.0, function(inst)
        -- Do nothing if the player is dead.
        if inst.components.health:IsDead() or inst:HasTag("playerghost") then
            return
        end
       
        -- Store the position of the player in x, y, z variables.
        local x,y,z = inst.Transform:GetWorldPosition()
   
        -- Description of important function, which finds specific entities within a range:
        -- TheSim:FindEntities(x, y, z, radius, mustHaveTags, cantHaveTags, mustHaveOneOfTheseTags)
       
        -- We have limited it to any player that is not a ghost or in limbo.
        -- I have set the radius to be the one used for standard negative auras. You can set it to whatever radius you want.
        local ents = TheSim:FindEntities(x, y, z, TUNING.SANITY_EFFECT_RANGE, {"player"}, {"playerghost", "INLIMBO"}, nil)
 
        for i, v in ipairs(ents) do
            if v and v:IsValid() and v.prefab == "wortox" then
                inst.components.sanity:DoDelta(-1, true) -- "true" disables the pulse on the badge and disables that it plays a sound.
            end
        end
    end)
 
    inst.OnLoad = onload
    inst.OnNewSpawn = onload
   
end
 
--Storyteller
local function CampfireStory_OnNotNight(inst, isnight)
    if not isnight and inst.storyteller ~= nil and inst.storyteller:IsValid() and inst.storyteller.components.storyteller ~= nil then
        inst.storyteller.components.storyteller:AbortStory(GetString(inst.storyteller, "ANNOUNCE_STORYTELLING_ABORT_NOT_NIGHT"))
    end
end
 
local function CampfireStory_CheckFire(inst, data)
    if data ~= nil and data.newsection == 0 and inst.storyteller:IsValid() and inst.components.storyteller ~= nil then
        inst.storyteller.components.storyteller:AbortStory(GetString(inst.storyteller, "ANNOUNCE_STORYTELLING_ABORT_FIREWENTOUT"))
    end
end
 
local function CampfireStory_aurafallofffn(inst, observer, distsq)
    return 1
end
 
local function CampfireStory_ActiveFn(params, parent, best_dist_sq)
    local pan_gain, heading_gain, distance_gain = TheCamera:GetGains()
    TheCamera:SetGains(1.5, heading_gain, distance_gain)
    TheCamera:SetDistance(18)
end
 
local function SetupCampfireStory(inst, storyteller, prop)
    inst.entity:SetParent(prop.entity)
 
    inst.storyteller = storyteller
 
    inst:ListenForEvent("onfueldsectionchanged", function(i, data) CampfireStory_CheckFire(inst, data) end, prop)
end
 
local function walter_campfire_story_proxy_fn()
    local inst = CreateEntity()
 
    inst.entity:AddTransform()
    inst.entity:AddNetwork()
 
    inst:AddTag("NOBLOCK")
 
    if Profile:IsCampfireStoryCameraEnabled() then
        TheFocalPoint.components.focalpoint:StartFocusSource(inst, nil, nil, 3, 4, -1, { ActiveFn = CampfireStory_ActiveFn })
    end
 
    inst.entity:SetCanSleep(false)
    inst.persists = false
 
    inst.entity:SetPristine()
    if not TheWorld.ismastersim then
        return inst
    end
 
    inst:AddComponent("sanityaura")
    inst.components.sanityaura.max_distsq = 16 -- radius of 4
    inst.components.sanityaura.aura = TUNING.SANITYAURA_SMALL_TINY
    inst.components.sanityaura.fallofffn = CampfireStory_aurafallofffn
 
    ---
    inst:WatchWorldState("isnight", CampfireStory_OnNotNight)
 
    inst.Setup = SetupCampfireStory
 
    return inst
end
 
return MakePlayerCharacter("orange", prefabs, assets, common_postinit, master_postinit, prefabs)
    Prefab("walter_campfire_story_proxy", walter_campfire_story_proxy_fn)
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...