Jump to content

[SOLVED] Need a little help with character mod (retrieving mod config in character prefab)


Recommended Posts

tl;dr:

How to make GetModConfigData(config_option_name,ModIndex:GetModActualName(name_of_a_mod_as_in_modinfo)) work in scripts/prefab/character_prefab.lua or load user config to it other way?

Hello there :)

I'm working on a simple character mod tweak - not really for myself (at least for now) but it'll surely come in handy in future. I want to implement options allowing users to change all character stats (health, hunger, sanity, movement speed, resistance, should it get starting items).

What I struggle with is the issue of retrieving configuration_options from character prefab - I know at to load configuration option you use function

GetModConfigData(config_option_name)

The issue is - obviously:

Quote

modname must be supplied manually if calling GetModConfigData from outside of modmain or modworldgenmain. Use ModIndex:GetModActualName(fancyname) function [fancyname is name string from modinfo].

I understand that from places other than modmain or modworldgenmain I should retrieve configuration options with

GetModConfigData(config_option_name,ModIndex:GetModActualName(name_of_a_mod_as_in_modinfo))

Now then - here the issue. Doing that will result with

Spoiler

[00:05:13]: [string "../mods/character_mods/scripts/prefabs/character_prefab.lua"]:58: variable 'ModIndex' is not declared
LUA ERROR stack traceback:
=[C]:-1 in (global) error (C) <-1--1>
scripts/strict.lua:23 in () ? (Lua) <21-26>
   t = table: 11340518
   n = ModIndex
../mods/sweepy/scripts/prefabs/sweepy.lua:58 in (upvalue) master_postinit (Lua) <50-75>
   inst = 109881 -  (valid:true)
scripts/prefabs/player_common.lua:1917 in (field) fn (Lua) <1623-1958>
   inst = 109881 -  (valid:true)
scripts/mainfunctions.lua:175 in () ? (Lua) <164-206>
   name = sweepy
   prefab = Prefab sweepy - 
=[C]:-1 in (method) SendSpawnRequestToServer (C) <-1--1>
scripts/mainfunctions.lua:1289 in (local) cb (Lua) <1287-1290>

Adding this

local ModIndex:GetModActualName = require "modindex"

to character prefab results with

Spoiler

[string "../mods/character_mod/scripts/prefabs/character_prefab.lua"]:2: unexpected symbol near ':'

LUA ERROR stack traceback:
        =[C] in function 'assert'
        scripts/mainfunctions.lua(119,1)
        =(tail call) ?
        =[C] in function 'xpcall'
        scripts/mods.lua(154,1)
        scripts/mods.lua(593,1) in function 'RegisterPrefabs'
        scripts/gamelogic.lua(226,1) in function 'LoadAssets'
        scripts/gamelogic.lua(840,1) in function 'LoadSlot'
        scripts/gamelogic.lua(896,1) in function 'DoResetAction'
        scripts/gamelogic.lua(942,1) in function 'complete_callback'
        scripts/upsell.lua(27,1) in function 'UpdateGamePurchasedState'
    ...
        =[C] in function 'GetPersistentString'
        scripts/saveindex.lua(250,1) in function 'Load'
        scripts/gamelogic.lua(982,1) in function 'callback'
        scripts/playerprofile.lua(853,1) in function 'Set'
        scripts/playerprofile.lua(714,1)
        =[C] in function 'GetPersistentString'
        scripts/playerprofile.lua(712,1) in function 'Load'
        scripts/gamelogic.lua(981,1) in main chunk
        =[C] in function 'require'
        scripts/mainfunctions.lua(836,1)    


Which is understandable (that's how Lua works, right?)

Here comes my question: how to use GetModActualName in scripts/prefab/character_prefab.lua or how to pass mod config values to it, in a way that starting items and stats of character could be configured?

 

Edited by Hekkaryk
Link to comment
Share on other sites

Almost right. I don't retrieve it in modmain.lua since it would be useless for me - I'm asking how to retrieve it in prefab script (of character).

What for: I want character to have customizable stats and starting items (true/false for items) ^_^"

EDIT: I tried retrieving them in modmain.lua and adding:

function statsload (inst)
    if IsServer then
        inst.cohp = GetModConfigData("oheatlh")
        inst.cohu = GetModConfigData("ohunger")
        inst.cosa = GetModConfigData("osanity")
        inst.cosi = GetModConfigData("ostinve")
    end
end
AddPrefabPostInit("character_prefab", statsload)

and then retrieving it by calling within scripts/prefabs/character_prefab.lua:

local function master_postinit(inst)
    inst.components.health:SetMaxHealth(inst.cohp)
    inst.components.hunger:SetMax(inst.cohu)
    inst.components.sanity:SetMax(inst.cosa)
    if inst.cosi and inst.cosi == false then --was set previously
        start_inv = { }
    end
end
return MakePlayerCharacter("character_prefab", prefabs, assets, common_postinit, master_postinit, start_inv)

but, unfortunately, AddPrefabPostInit() is called AFTER prefab is initialized so inst.cohp, inst.cohu, inst.cosa and inst.cosi were all nil at master_postinit() (at least that's why I think they were nil).

Also, this forum post editor is kind of unfriendly so I always have to manually remove weird formatting by copy-pasting to-from Notepad++... :p

Edited by Hekkaryk
Link to comment
Share on other sites

Easy fix but maybe not the smartest.

In your modmain.lua create a new global empty table, i.e.MushaModConfig. Then retrieve the mod config and store it in this new global table.

Retrieve this global table in your prefab script and access the values.

Link to comment
Share on other sites

First of all: sorry about using prefab name "musha" - I was writing my previous attempts from memory and used postmaster_init found in Musha mod ^_^"

Thank you, ZupaleX! This was so simple (although I didn't understand you for like 15 minutes - I'm a total lua beginner)...

Working code for future visitors (hopefuly now properly obfuscated):

modinfo.lua:

name = "<your mod name here>"
description = "<your mod description here>"
author = "<your name here>"
version = "<mod version here - use x.y.z format like 1.2.3>"
forumthread = "/files/file/<your mod file page on forum here>"
api_version = 10
dst_compatible = true
dont_starve_compatible = false
reign_of_giants_compatible = false
all_clients_require_mod = true
icon_atlas = "modicon.xml"
icon = "modicon.tex"
server_filter_tags = { "character_prefab" }
configuration_options =
{
  {
    name = "config_option_health",
    label = "Health",
    hover = "Set character_prefab health",
    options = {
      {description = "100", data = 100},
      {description = "130", hover = "default", data = 130},
      {description = "150", data = 150},
      {description = "175", data = 175},
    },
    default = 130,
  },
  {
    name = "config_option_hunger",
    label = "Hunger",
    hover = "Set character_prefab health",
    options = {
      {description = "150", data = 150},
      {description = "180", hover = "default", data = 180},
      {description = "200", data = 200},
      {description = "250", data = 250},
    },
    default = 180,
  },
  {
    name = "config_option_sanity",
    label = "Sanity",
    hover = "Set character_prefab health",
    options = {
      {description = "150", data = 150},
      {description = "200", data = 200},
      {description = "250", hover = "default", data = 250},
      {description = "300", data = 300},
    },
    default = 250,
  },
  {
    name = "config_option_items",
    label = "Starts with items",
    hover = "character_prefab will start game with items",
    options = {
      {description = "yes", hover = "default", data = 1},
      {description = "no", data = 0},
    },
    default = 1,
  },
}

modmain.lua:

PrefabFiles = {
    "character_prefab",
    "character_prefab_none",
}

Assets = {
    Asset( "IMAGE", "images/saveslot_portraits/character_prefab.tex" ),
    Asset( "ATLAS", "images/saveslot_portraits/character_prefab.xml" ),
    Asset( "IMAGE", "images/selectscreen_portraits/character_prefab.tex" ),
    Asset( "ATLAS", "images/selectscreen_portraits/character_prefab.xml" ),    
    Asset( "IMAGE", "images/selectscreen_portraits/character_prefab.tex" ),
    Asset( "ATLAS", "images/selectscreen_portraits/character_prefab.xml" ),
    Asset( "IMAGE", "bigportraits/character_prefab.tex" ),
    Asset( "ATLAS", "bigportraits/character_prefab.xml" ),    
    Asset( "IMAGE", "images/map_icons/character_prefab.tex" ),
    Asset( "ATLAS", "images/map_icons/character_prefab.xml" ),    
    Asset( "IMAGE", "images/avatars/avatar_character_prefab.tex" ),
    Asset( "ATLAS", "images/avatars/avatar_character_prefab.xml" ),    
    Asset( "IMAGE", "images/avatars/avatar_ghost_character_prefab.tex" ),
    Asset( "ATLAS", "images/avatars/avatar_ghost_character_prefab.xml" ),    
    Asset( "IMAGE", "images/avatars/self_inspect_character_prefab.tex" ),
    Asset( "ATLAS", "images/avatars/self_inspect_character_prefab.xml" ),    
    Asset( "IMAGE", "images/names_character_prefab.tex" ),
    Asset( "ATLAS", "images/names_character_prefab.xml" ),    
    Asset( "IMAGE", "bigportraits/character_prefab_none.tex" ),
    Asset( "ATLAS", "bigportraits/character_prefab_none.xml" ),
}

local require = GLOBAL.require
local STRINGS = GLOBAL.STRINGS
local TUNING = GLOBAL.TUNING
STRINGS.CHARACTER_TITLES.character_prefab = "Character_prefab"
STRINGS.CHARACTER_NAMES.character_prefab = "Character_prefab"
STRINGS.CHARACTER_DESCRIPTIONS.character_prefab = "<your character description here>"
STRINGS.CHARACTER_QUOTES.character_prefab = "\"Character_prefab\""
STRINGS.CHARACTERS.CHARACTER_PREFAB = require "speech_character_prefab"
STRINGS.NAMES.character_prefab = "Esc"
AddMinimapAtlas("images/map_icons/character_prefab.xml")
TUNING.CHARACTER_PREFAB_MODCONFIGDATA = {}
TUNING.CHARACTER_PREFAB_MODCONFIGDATA["health"] = GetModConfigData("config_option_health")
TUNING.CHARACTER_PREFAB_MODCONFIGDATA["hunger"] = GetModConfigData("config_option_hunger")
TUNING.CHARACTER_PREFAB_MODCONFIGDATA["sanity"] = GetModConfigData("config_option_sanity")
TUNING.CHARACTER_PREFAB_MODCONFIGDATA["sitems"] = GetModConfigData("config_option_items")
-- Add mod character to mod character list. Also specify a gender. Possible genders are MALE, FEMALE, ROBOT, NEUTRAL, and PLURAL.
AddModCharacter("character_prefab", "NEUTRAL")

scripts/prefabs/character_prefab.lua:

local MakePlayerCharacter = require "prefabs/player_common"
local assets = {
    Asset("SCRIPT", "scripts/prefabs/player_common.lua")
}
local prefabs = {}
local start_inv = {"spear", "bandage", "bandage"}
local function onbecamehuman(inst)
    -- Set speed when reviving from ghost (optional)
    inst.components.locomotor:SetExternalSpeedMultiplier(inst, "character_prefab_speed_mod", 1)
    inst.components.locomotor.walkspeed = 7
    inst.components.locomotor.runspeed = 8    
end
local function onbecameghost(inst)
   inst.components.locomotor:RemoveExternalSpeedMultiplier(inst, "character_prefab_speed_mod")
end
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
local common_postinit = function(inst) 
    -- Minimap icon
    inst.MiniMapEntity:SetIcon( "character_prefab.tex" )
    inst:AddTag("houndfriend")
end
local master_postinit = function(inst)
    inst.soundsname = "willow"
    inst.components.health:SetMaxHealth(TUNING.CHARACTER_PREFAB_MODCONFIGDATA["health"])
    inst.components.hunger:SetMax(TUNING.CHARACTER_PREFAB_MODCONFIGDATA["hunger"])
    inst.components.sanity:SetMax(TUNING.CHARACTER_PREFAB_MODCONFIGDATA["sanity"])
    inst.components.temperature.maxtemp = 60
    inst.components.combat.damagemultiplier = 1
    inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE    
    inst.OnLoad = onload
    inst.OnNewSpawn = onload    
    if TUNING.CHARACTER_PREFAB_MODCONFIGDATA["sitems"] == 0 then
        for k,v in pairs(start_inv) do start_inv[k]=nil end -- this removes all items for start_inv table without breaking its pointer
    else
        inst.components.talker:Say("Starting with items")
    end
end
return MakePlayerCharacter("character_prefab", prefabs, assets, common_postinit, master_postinit, start_inv)

Again - many thanks for help ^_^

Edited by Hekkaryk
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...