DrSmugleaf Posted March 9, 2015 Share Posted March 9, 2015 So, since a month and some ago I have been making a mod which modifies existing mod characters when detected. It mostly worked for all characters, but today I found an issue with the character Tamamo by @rons0n, it doesn't work no matter what I do or try, mostly for clients. And rons0n if you are reading this, please insight on why your character breaks all logic in this world because I have been at it for 2 days now. Tamamo's mod pageMy mod page Please note before reading any of my code that it probably varies from the release on the workshop since everything is moved around to try and make Tamamo worked. I would recommend downloading my modmain.lua from the workshop too. The objective is to add a "Feral" mode to Tamamo, which modifies her stats, and to modify other stats no matter of what mode she is in. Now as for Tamamo's prefab code: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/tamamo.zip" ), Asset( "ANIM", "anim/ghost_tamamo_build.zip" ), Asset( "ANIM", "anim/tamamo_ball.zip" )}local prefabs = {}local start_inv = { -- Custom starting items}local function OnKeyPressed(inst, data) if data.inst == ThePlayer then if data.key == KEY_Z then print("KEY_Z has been pressed.") if TheWorld.ismastersim then BufferedAction(inst, inst, ACTIONS.BALL):Do() -- Since we are the server, do the action on the server. else SendRPCToServer(RPC.DoWidgetButtonAction, ACTIONS.BALL.code, inst, ACTIONS.BALL.mod_name) end end endend -- This initializes for both clients and the hostlocal common_postinit = function(inst) -- Minimap icon inst.MiniMapEntity:SetIcon( "tamamo.tex" ) inst.transformed = false inst:AddComponent("keyhandler") inst:ListenForEvent("keypressed", OnKeyPressed)end-- This initializes for the host onlylocal master_postinit = function(inst) -- choose which sounds this character will play inst.soundsname = "willow" -- Stats inst.components.health:SetMaxHealth(150) inst.components.hunger:SetMax(150) inst.components.sanity:SetMax(150) inst.components.sanity.dapperness = (TUNING.DAPPERNESS_SMALL) inst:AddTag('<span class="searchlite">birdwhisperer</span>') local eater = inst.components.eater eater.ignoresspoilage = true inst.components.eater.Eat_orig = inst.components.eater.Eatfunction inst.components.eater:Eat( food ) if self:CanEat(food) then if food.components.edible.sanityvalue < 0 then food.components.edible.sanityvalue = 1 end if food.components.edible.healthvalue < 0 then food.components.edible.healthvalue = 3 endendreturn inst.components.eater:Eat_orig(food)end inst:RemoveTag("scarytoprey") inst:ListenForEvent("equip", function(inst, data) print("I'm wearing something.") inst.AnimState:ClearOverrideSymbol("swap_body") end)endreturn MakePlayerCharacter("tamamo", prefabs, assets, common_postinit, master_postinit, start_inv) And my modmain.lua code as of right now:local require = GLOBAL.requirelocal STRINGS = GLOBAL.STRINGSlocal MOD_NAME = "Mod Character Rebalancing"---------------------------------- Load Starting Items config ----------------------------------local enableStartingItems = GetModConfigData("ENABLE_STARTING_ITEMS") local amountOfFlint = GetModConfigData("AMOUNT_OF_FLINT") local amountOfGrass = GetModConfigData("AMOUNT_OF_GRASS") local amountOfLogs = GetModConfigData("AMOUNT_OF_LOGS") local amountOfMeat = GetModConfigData("AMOUNT_OF_MEAT") local amountOfTwigs = GetModConfigData("AMOUNT_OF_TWIGS") local giveThermalStone = GetModConfigData("GIVE_THERMAL_STONE") local startingItems = {} --------------------------------------- Load Character Balancing config ---------------------------------------local modBalancingEnabled = GetModConfigData("MOD_BALANCING_ENABLED") local crashBandicootBalanced = GetModConfigData("CRASHBANDICOOT_BALANCED") local darkSakuraBalanced = GetModConfigData("DARKSAKURA_BALANCED") --local devonBalanced = GetModConfigData("DEVON_BALANCED") local drokBalanced = GetModConfigData("DROK_BALANCED") local endiaBalanced = GetModConfigData("ENDIA_BALANCED") local farozBalanced = GetModConfigData("FAROZ_BALANCED") local filiaBalanced = GetModConfigData("FILIA_BALANCED") --local fionnaBalanced = GetModConfigData("FIONNA_BALANCED") local freeSpiritBalanced = GetModConfigData("FREESPIRIT_BALANCED") --local gabenBalanced = GetModConfigData("GABEN_BALANCED") --local girBalanced = GetModConfigData("GIR_BALANCED") local haruzBalanced = GetModConfigData("HARUZ_BALANCED") --local hellaMerdurialBalanced = GetModConfigData("HELLAMERDURIAL_BALANCED") local luffyBalanced = GetModConfigData("LUFFY_BALANCED") local madeleineBalanced = GetModConfigData("MADELEINE_BALANCED") local michaelTheFoxBalanced = GetModConfigData("MICHAELTHEFOX_BALANCED") local mikuHatsuneBalanced = GetModConfigData("MIKUHATSUNE_BALANCED") local mitsuruBalanced = GetModConfigData("MITSURU_BALANCED") --local neptuniaBalanced = GetModConfigData("NEPTUNIA_BALANCED") local serasBalanced = GetModConfigData("SERAS_BALANCED") local sollyzBalanced = GetModConfigData("SOLLYZ_BALANCED") local shovelKnightBalanced = GetModConfigData("SHOVELKNIGHT_BALANCED") local tamamoBalanced = GetModConfigData("TAMAMO_BALANCED") --local thanaBalanced = GetModConfigData("THANA_BALANCED") --local theMedicBalanced = GetModConfigData("THEMEDIC_BALANCED") local warkBalanced = GetModConfigData("WARK_BALANCED") local wolfBalanced = GetModConfigData("WOLF_BALANCED") local woodieBalanced = GetModConfigData("WOODIE_BALANCED") --local zimBalanced = GetModConfigData("ZIM_BALANCED") --------------------------------------------------------------------------- Load Leveling System config and assign base max levels difficulties ---------------------------------------------------------------------------local levelSetting = GetModConfigData("LEVEL_SETTING")if levelSetting then if levelSetting == 1 then levelDifficulty = 30 elseif levelSetting == 2 then levelDifficulty = 50 elseif levelSetting == 3 then levelDifficulty = 75 elseif levelSetting == 4 then levelDifficulty = 100 end end --------------------------------- Load Special Modes config ---------------------------------local nerfSpeed = GetModConfigData("NERF_SPEED")local hardcoreMode = GetModConfigData("HARDCORE_MODE")---------------------------------------------------------------- Printing to console functions with mod name and prefixes ----------------------------------------------------------------local function printDebug(message) if message then print("[".. (MOD_NAME).. "] ".. "[DEBUG] ".. (message)) end endlocal function printError(message) if message then print("[".. (MOD_NAME).. "] ".. "[ERROR] ".. (message)) end endlocal function printFatal(message) if message then print("[".. (MOD_NAME).. "] ".. "[FATAL] ".. (message)) end endlocal function printInfo(message) if message then print("[".. (MOD_NAME).. "] ".. "[INFO] ".. (message)) end endlocal function printWarn(message) if message then print("[".. (MOD_NAME).. "] ".. "[WARN] ".. (message)) end end------------------------------------------------------ Check config settings and add items to a table ------------------------------------------------------if enableStartingItems == 1 then -- If starting items is enabled printInfo("Starting Items enabled") for _= 1, amountOfFlint do -- For the amount of flint specified in the config table.insert(startingItems, "flint") -- Insert it into the table "startingItems" end for _= 1, amountOfGrass do table.insert(startingItems, "cutgrass") end for _= 1, amountOfLogs do table.insert(startingItems, "log") end for _= 1, amountOfMeat do table.insert(startingItems, "meat") end for _= 1, amountOfTwigs do table.insert(startingItems, "twigs") end if giveThermalStone == 1 then table.insert(startingItems, "heatrock") end else printInfo("Starting Items disabled") end---------------------------------------------------- Put starting items in the player's inventory ----------------------------------------------------AddPlayerPostInit(function(inst) -- Add to every player if inst.OnNewSpawn then -- Store old function inst.old_OnNewSpawn = inst.OnNewSpawn end inst.OnNewSpawn = function(inst) -- On spawn, do the following function if inst.components.inventory ~= nil then inst.components.inventory.ignoresound = true for i, v in ipairs(startingItems) do -- For each value inserted above into the table inst.components.inventory:GiveItem(GLOBAL.SpawnPrefab(v)) -- Give that amount of items to the player end inst.components.inventory.ignoresound = false end if inst.old_OnNewSpawn then return inst:old_OnNewSpawn(inst) end endend)---------------------------------------------------- Delete and add items to a player's inventory ----------------------------------------------------local function changeStartingInventory(inst, start_inv) local oldSpawn = inst.OnNewSpawn start_inv = start_inv or {} for _,v in pairs(startingItems) do -- Load starting items too since this deletes inventories table.insert(start_inv, v) end inst.OnNewSpawn = function() if oldSpawn ~= nil then oldSpawn() end if inst.components.inventory ~= nil then inst.components.inventory.ignoresound = true for i = 1, inst.components.inventory:GetNumSlots() do inst.components.inventory:RemoveItemBySlot(i) -- Remove all items end for _, v in ipairs(start_inv) do inst.components.inventory:GiveItem(GLOBAL.SpawnPrefab(v)) -- Give new items end inst.components.inventory.ignoresound = false end endend--local function modifyPrefab(inst, stats)--end------------------------------------------------------------------------- Add a leveling system to a character or plainly modify it's stats -------------------------------------------------------------------------local function modifyStats(inst, stats) -- Load the given stats if nerfSpeed == 0 then health = stats.health hunger = stats.hunger sanity = stats.sanity damage = stats.damage insulation = stats.insulation walkSpeed = stats.walkSpeed runSpeed = stats.runSpeed dapperness = stats.dapperness nightDrain = stats.nightDrain monsterDrain = stats.monsterDrain strongStomach = stats.strongStomach hungerRate = stats.hungerRate elseif nerfSpeed == 1 then health = stats.healthNerf hunger = stats.hungerNerf sanity = stats.sanityNerf damage = stats.damageNerf insulation = stats.insulationNerf walkSpeed = stats.walkSpeedNerf runSpeed = stats.runSpeedNerf dapperness = stats.dappernessNerf nightDrain = stats.nightDrainNerf monsterDrain = stats.monsterDrainNerf strongStomach = stats.strongStomachNerf hungerRate = stats.hungerRateNerf end if hardcoreMode == 0 then levelNerf = stats.levelNerf elseif hardcoreMode == 1 then levelNerf = stats.hardcoreMode end local foodType = stats.foodType local foodPrefab1 = stats.foodPrefab1 local foodPrefab2 = stats.foodPrefab2 local foodPrefab3 = stats.foodPrefab3 local foodPrefab4 = stats.foodPrefab4 local foodPrefab5 = stats.foodPrefab5 local levelPerFood1 = stats.levelPerFood1 local levelPerFood2 = stats.levelPerFood2 local levelPerFood3 = stats.levelPerFood3 local levelPerFood4 = stats.levelPerFood4 local levelPerFood5 = stats.levelPerFood5 if nerfSpeed == 0 then initialHealth = stats.initialHealth initialHunger = stats.initialHunger initialSanity = stats.initialSanity initialDamage = stats.initialDamage initialInsulation = stats.initialInsulation initialWalk = stats.initialWalk initialRun = stats.initialRun finalHealth = stats.finalHealth finalHunger = stats.finalHunger finalSanity = stats.finalSanity finalDamage = stats.finalDamage finalInsulation = stats.finalInsulation finalWalk = stats.finalWalk finalRun = stats.finalRun elseif nerfSpeed == 1 then initialHealth = stats.initialHealthNerf initialHunger = stats.initialHungerNerf initialSanity = stats.initialSanityNerf initialDamage = stats.initialDamageNerf initialInsulation = stats.initialInsulationNerf initialWalk = stats.initialWalkNerf initialRun = stats.initialRunNerf finalHealth = stats.finalHealthNerf finalHunger = stats.finalHungerNerf finalSanity = stats.finalSanityNerf finalDamage = stats.finalDamageNerf finalInsulation = stats.finalInsulationNerf finalWalk = stats.finalWalkNerf finalRun = stats.finalRunNerf end if levelSetting > 0 and initialHealth or initialHunger or initialSanity or initialDamage or initialInsulation or initialWalk or initialRun then if not levelNerf then levelNerf = 0 end maxUpgrades = levelDifficulty+levelNerf function applyUpgrades(inst) local upgrades = math.min(inst.level, maxUpgrades) local hunger_percent = inst.components.hunger:GetPercent() local health_percent = inst.components.health:GetPercent() local sanity_percent = inst.components.sanity:GetPercent() if initialHealth and finalHealth and upgrades and maxUpgrades then inst.components.health.maxhealth = math.ceil (initialHealth + upgrades * (finalHealth - initialHealth) / maxUpgrades) end if initialHunger and finalHunger and upgrades and maxUpgrades then inst.components.hunger.max = math.ceil (initialHunger + upgrades * (finalHunger - initialHunger) / maxUpgrades) end if initialSanity and finalSanity and upgrades and maxUpgrades then inst.components.sanity.max = math.ceil (initialSanity + upgrades * (finalSanity - initialSanity) / maxUpgrades) end if initialDamage and finalDamage and upgrades and maxUpgrades then inst.components.combat.damagemultiplier = math.ceil (initialDamage + upgrades * (finalDamage - initialDamage) / maxUpgrades) end if initialInsulation and finalInsulation and upgrades and maxUpgrades then inst.components.temperature.inherentinsulation = math.ceil (initialInsulation + upgrades * (finalInsulation - initialInsulation) / maxUpgrades) end if initialWalk and finalWalk and initialRun and finalRun and upgrades and maxUpgrades then inst.components.locomotor.walkspeed = math.ceil (TUNING.WILSON_WALK_SPEED * (initialWalk + upgrades * (finalWalk - initialWalk) / maxUpgrades)) inst.components.locomotor.runspeed = math.ceil (TUNING.WILSON_RUN_SPEED * (initialRun + upgrades * (finalRun - initialRun) / maxUpgrades)) end inst.components.talker:Say("Level : ".. (inst.level)) if inst.level > math.ceil (maxUpgrades-1) then inst.components.talker:Say("Level : Max!") end inst.components.hunger:SetPercent(hunger_percent) inst.components.health:SetPercent(health_percent) inst.components.sanity:SetPercent(sanity_percent) end if foodType then local function oneat(inst, food) if food and food.components.edible and food.components.edible.foodtype=="foodType" then inst.level = inst.level + 1 applyUpgrades(inst) inst.SoundEmitter:PlaySound("dontstarve/characters/wx78/levelup") end end end function oneat(inst, food) if foodPrefab1 and levelPerFood1 then -- If the variables exist if food and food.components.edible and food.prefab == foodPrefab1 then -- If its a food, edible and has the specified prefab inst.level = inst.level + levelPerFood1 -- Level up according to the variable levelPerFood applyUpgrades(inst) -- Set the stats inst.SoundEmitter:PlaySound("dontstarve/characters/wx78/levelup") -- Play a sound end end if foodPrefab2 and levelPerFood2 then if food and food.components.edible and food.prefab == foodPrefab2 then inst.level = inst.level + levelPerFood2 applyUpgrades(inst) inst.SoundEmitter:PlaySound("dontstarve/characters/wx78/levelup") end end if foodPrefab3 and levelPerFood3 then if food and food.components.edible and food.prefab == foodPrefab3 then inst.level = inst.level + levelPerFood3 applyUpgrades(inst) inst.SoundEmitter:PlaySound("dontstarve/characters/wx78/levelup") end end if foodPrefab4 and levelPerFood4 then if food and food.components.edible and food.prefab == foodPrefab4 then inst.level = inst.level + levelPerFood4 applyUpgrades(inst) inst.SoundEmitter:PlaySound("dontstarve/characters/wx78/levelup") end end if foodPrefab5 and levelPerFood5 then if food and food.components.edible and food.prefab == foodPrefab5 then inst.level = inst.level + levelPerFood5 applyUpgrades(inst) inst.SoundEmitter:PlaySound("dontstarve/characters/wx78/levelup") end end end local function onpreload(inst, data) if data then if data.level then inst.level = data.level applyUpgrades(inst) if data.health and data.health.health then inst.components.health.currenthealth = 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) end end end local function onsave(inst, data) data.level = inst.level data.charge_time = inst.charge_time end inst.level = 0 inst.components.eater:SetOnEatFn(oneat) applyUpgrades(inst) inst.OnSave = onsave inst.OnPreLoad = onpreload end if health then inst.components.health:SetMaxHealth(health) end if hunger then inst.components.hunger:SetMax(hunger) end if sanity then inst.components.sanity:SetMax(sanity) end if damage then inst.components.combat.damagemultiplier = damage end if insulation then inst.components.temperature.inherentinsulation = insulation end if walkSpeed and runSpeed then inst.components.locomotor.walkspeed = TUNING.WILSON_WALK_SPEED * walkSpeed inst.components.locomotor.runspeed = TUNING.WILSON_RUN_SPEED * runSpeed end if dapperness then inst.components.sanity.dapperness = dapperness end if nightDrain then inst.components.sanity.night_drain_mult = nightDrain end if monsterDrain then inst.components.sanity.neg_aura_mult = monsterDrain end if strongStomach then inst.components.eater.strongstomach = strongStomach end if hungerRate then inst.components.hunger:SetRate(TUNING.WILSON_HUNGER_RATE * hungerRate) end end------------------------------------------- Function to add modes to characters -------------------------------------------local function CRAddMode(inst, CRKey, CRAction) local function OnKeyPressed(inst, data) if data.inst == GLOBAL.ThePlayer then if data.key == CRKey then --Welcome to GLOBAL ville if GLOBAL.TheWorld.ismastersim then GLOBAL.BufferedAction(inst, inst, GLOBAL.ACTIONS[CRAction]):Do() else GLOBAL.SendRPCToServer(GLOBAL.RPC.DoWidgetButtonAction, GLOBAL.ACTIONS[CRAction].code, inst, GLOBAL.ACTIONS[CRAction].mod_name) end end end end inst:AddComponent("CRkeyhandler") inst:ListenForEvent("CRkeypressed", OnKeyPressed)end---------------------------------------------------------------------------------- Component to make certain items undroppable when given the tag undroppable ----------------------------------------------------------------------------------AddComponentPostInit("inventory", function(self) -- Add the function to the component inventory local DropItem_base = self.DropItem function self:DropItem(item, ...) if item:HasTag("undroppable") then -- Check for the tag return false -- Can't be dropped else return DropItem_base(self, item, ...) end endend)-------------------------------------------------- Component to make items character specific --------------------------------------------------AddComponentPostInit("inventory", function(self) local old_Equip = self.Equip -- Store old function function self:Equip(item, ...) -- Checks if item is character specific, and if the player isn't the owner, make it say so if item.components.characterspecific and item.components.characterspecific.character ~= self.inst.prefab then self.inst.components.talker:Say("This isn't mine") self:DropItem(item) return false -- Prevents item from being obtained end return old_Equip(self, item, ...) -- Normal function execution endend)--[[Add the characterspecific component to the items:inst:AddComponent("characterspecific")inst.components.characterspecific:SetOwner(inst.prefab)]]------------------------------------------------------- Make functions to change each character's stats -------------------------------------------------------local function balanceCrashBandicootStats(inst) local crashBandicootStats = { levelNerf = 50, levelNerfHardcore = 250, foodPrefab1 = "wumpa", foodPrefab2 = "wumpa_cooked", foodPrefab3 = "carrot", levelPerFood1 = 2, levelPerFood2 = 2, levelPerFood3 = 1, initialHealth = 75, initialHunger = 75, initialSanity = 100, initialWalkNerf = 1, initialRunNerf = 1, finalHealth = 100, finalHunger = 125, finalSanity = 150, finalRunNerf = 1, finalWalkNerf = 1, } modifyStats(inst, crashBandicootStats) endlocal function balanceDarkSakuraStats(inst) local darkSakuraStats = { health = 75, hunger = 100, } modifyStats(inst, darkSakuraStats)end--local function balanceDevonStats(inst)--endlocal function balanceDrokStats(inst) local drokStats = { health = 175, hunger = 200, damage = 1.5, } modifyStats(inst, drokStats) endlocal function balanceEndiaStats(inst) local endiaStats = { health = 75, hunger = 100, sanity = 75, } modifyStats(inst, endiaStats) endlocal function balanceFarozStats(inst) local farozStats = { dapperness = -0.25, nightDrain = 1.25, monsterDrain = 1.25, } modifyStats(inst, farozStats) endlocal function balanceFarozGlasses(inst) inst:AddTag("undroppable") inst:AddComponent("characterspecific") inst.components.characterspecific:SetOwner("faroz") endlocal function balanceFiliaStats(inst) local filiaStats = { health = 75, hunger = 100, sanity = 150, damage = 1.5, walkSpeed = 1.5, runSpeed = 1.5, } modifyStats(inst, filiaStats) end--local function balanceFionnaStats(inst)--endlocal function balanceFreeSpiritStats(inst) local freeSpiritStats = { health = 150, hunger = 100, sanity = 150, } modifyStats(inst, freeSpiritStats) end--local function balanceGabenStats(inst)--end--local function balanceGirStats(inst)--endlocal function balanceHaruzStats(inst) inst.components.sanity.dapperness = TUNING.DAPPERNESS_TINY*-1if levelSetting > 0 then local oldPreLoad = inst.OnPreLoad local oldEat = inst.components.eater.oneatfn local levelNerf = 25 local initialHealth = 75 local initialHunger = 75 local initialSanity = 75 local finalHealth = 150 local finalHunger = 200 local finalSanity = 125 inst.components.health:SetMaxHealth(initialHealth) inst.components.hunger:SetMax(initialHunger) inst.components.sanity:SetMax(initialSanity) local function newUpg(inst) max_upgrades = levelDifficulty+levelNerf 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.health.maxhealth = math.ceil (initialHealth + upgrades * (finalHealth - initialHealth) / max_upgrades) inst.components.hunger.max = math.ceil (initialHunger + upgrades * (finalHunger - initialHunger) / max_upgrades) inst.components.sanity.max = math.ceil (initialSanity + upgrades * (finalSanity - initialSanity) / max_upgrades) inst.components.talker:Say("Level : ".. (inst.level)) if inst.level > math.ceil (max_upgrades-1) then inst.components.talker:Say("Level : Max!") end inst.components.hunger:SetPercent(hunger_percent) inst.components.health:SetPercent(health_percent) inst.components.sanity:SetPercent(sanity_percent) end local function newEat(inst, food) oldEat(inst, food) if food and food.components.edible and food.components.edible.foodtype=="MEAT" then newUpg(inst) endend local function newPreLoad(inst, data) oldPreLoad(inst, data) newUpg(inst) inst.components.health:DoDelta(0) inst.components.hunger:DoDelta(0) inst.components.sanity:DoDelta(0) end inst.components.eater:SetOnEatFn(newEat) inst.OnPreLoad = newPreLoadendend--local function balanceHellaMerdurialStats(inst)--endlocal function balanceLuffyStats(inst) local luffyStats = { health = 100, sanity = 100, hungerRate = 2.0, } modifyStats(inst, luffyStats)endlocal function balanceMadeleineStats(inst) changeStartingInventory(inst, {"goldnugget", "redgem", "redgem", "bluegem", "bluegem", "purplegem"})endlocal function balanceMichaelTheFoxStats(inst) local michaelTheFoxStats = { health = 75, hunger = 125, sanity = 75, damage = 0.75, nightDrain = 1.25, monsterDrain = 1.25, dapperness = TUNING.DAPPERNESS_TINY*-1, healthNerf = 100, hungerNerf = 150, sanityNerf = 100, damageNerf = 0.85, nightDrainNerf = 1.10, monsterDrainNerf = 1.10, dappernessNerf = TUNING.DAPPERNESS_TINY*0.5, walkSpeedNerf = 1.25, runSpeedNerf = 1.25, } modifyStats(inst, michaelTheFoxStats) inst:AddTag("insomniac")endlocal function balanceMikuHatsuneStats(inst) local mikuHatsuneStats = { health = 100, hunger = 100, sanity = 100, damage = 0.75, } modifyStats(inst, mikuHatsuneStats)endlocal function balanceMitsuruStats(inst) inst.components.sanity.dapperness = TUNING.DAPPERNESS_TINY*-1if levelSetting > 0 then local oldPreLoad = inst.OnPreLoad local oldEat = inst.components.eater.oneatfn local levelNerf = 50 local initialHealth = 75 local initialHunger = 75 local initialSanity = 50 local initialDamage = 1.0 local initialInsulation = 0 local finalHealth = 100 local finalHunger = 150 local finalSanity = 125 local finalDamage = 1.5 local finalInsulation = 75 inst.components.health:SetMaxHealth(initialHealth) inst.components.hunger:SetMax(initialHunger) inst.components.sanity:SetMax(initialSanity) local function newUpg(inst) max_upgrades = levelDifficulty+levelNerf 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.health.maxhealth = math.ceil (initialHealth + upgrades * (finalHealth - initialHealth) / max_upgrades) inst.components.hunger.max = math.ceil (initialHunger + upgrades * (finalHunger - initialHunger) / max_upgrades) inst.components.sanity.max = math.ceil (initialSanity + upgrades * (finalSanity - initialSanity) / max_upgrades) inst.components.combat.damagemultiplier = math.ceil (initialDamage + upgrades * (finalDamage - initialDamage) / max_upgrades) inst.components.temperature.inherentinsulation = math.ceil (initialInsulation + upgrades * (finalInsulation - initialInsulation) / max_upgrades) inst.components.talker:Say("Level : ".. (inst.level)) if inst.level > math.ceil (max_upgrades-1) then inst.components.talker:Say("Level : Max!") end inst.components.hunger:SetPercent(hunger_percent) inst.components.health:SetPercent(health_percent) inst.components.sanity:SetPercent(sanity_percent) end local function newEat(inst, food) oldEat(inst, food) if food and food.components.edible and food.prefab == "corn" or food.prefab == "carrot" or food.prefab == "eggplant" or food.prefab == "dragonfruit" then newUpg(inst) end end local function newPreLoad(inst, data) oldPreLoad(inst, data) newUpg(inst) inst.components.health:DoDelta(0) inst.components.hunger:DoDelta(0) inst.components.sanity:DoDelta(0) end inst.components.eater:SetOnEatFn(newEat) inst.OnPreLoad = newPreLoadendend--local function balanceNeptuniaStats(inst)--endlocal function balanceSerasStats(inst) changeStartingInventory(inst, {"smallmeat", "smallmeat"}) endlocal function balanceShovelKnightStats(inst)endlocal function balanceShovelKnightBlades(inst) inst:AddTag("undroppable") inst:AddComponent("characterspecific") inst.components.characterspecific:SetOwner("winston") endlocal function balanceSollyzStats(inst)if levelSetting > 0 then local oldPreLoad = inst.OnPreLoad local oldEat = inst.components.eater.oneatfn local levelNerf = 0 local initialHealth = 50 local initialHunger = 75 local initialSanity = 50 local finalHealth = 100 local finalHunger = 150 local finalSanity = 90 inst.components.health:SetMaxHealth(initialHealth) inst.components.hunger:SetMax(initialHunger) inst.components.sanity:SetMax(initialSanity) local function newUpg(inst) max_upgrades = levelDifficulty+levelNerf 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.health.maxhealth = math.ceil (initialHealth + upgrades * (finalHealth - initialHealth) / max_upgrades) inst.components.hunger.max = math.ceil (initialHunger + upgrades * (finalHunger - initialHunger) / max_upgrades) inst.components.sanity.max = math.ceil (initialSanity + upgrades * (finalSanity - initialSanity) / max_upgrades) inst.components.talker:Say("Level : ".. (inst.level)) if inst.level > math.ceil (max_upgrades-1) then inst.components.talker:Say("Level : Max!") end inst.components.hunger:SetPercent(hunger_percent) inst.components.health:SetPercent(health_percent) inst.components.sanity:SetPercent(sanity_percent) end local function newEat(inst, food) oldEat(inst, food) if food and food.components.edible and food.prefab == "fish" then newUpg(inst) end end local function newPreLoad(inst, data) oldPreLoad(inst, data) newUpg(inst) inst.components.health:DoDelta(0) inst.components.hunger:DoDelta(0) inst.components.sanity:DoDelta(0) end inst.components.eater:SetOnEatFn(newEat) inst.OnPreLoad = newPreLoadendendlocal function balanceTamamoStats(inst) local DefaultEater = require("components/eater") local FERAL = GLOBAL.Action() FERAL.str = "Feral" FERAL.id = "FERAL" FERAL.fn = function(act) local silent = true --act.target.Light:Enable(true) --inst. -> not assigned act.target is. if act.target.transformed then --act.target.Light:Enable(false) local tamamoStats = { health = 125, damage = 1, walkSpeed = 1, runSpeed = 1, dapperness = 0, hungerRate = 1, } modifyStats(act.target, tamamoStats) else --act.target.Light:Enable(true) local tamamoStats = { health = 125, damage = 1.5, walkSpeed = 1.5, runSpeed = 1.5, dapperness = -2*TUNING.DAPPERNESS_LARGE, hungerRate = 1.5, } modifyStats(act.target, tamamoStats) end act.target.transformed = not act.target.transformed return true end AddAction(FERAL) --local tamamoStats = { --health = 125, --walkSpeed = 1, --runSpeed = 1, --damage = 1, --dapperness = 0, --hungerRate = 1, --} --modifyStats(inst, tamamoStats) CRAddMode(inst, GLOBAL.KEY_X, "FERAL") --inst:RemoveTag('<span class="searchlite">birdwhisperer</span>') --inst:AddTag("scarytoprey") --inst.components.eater.ignorespoilage = false --function inst.components.eater:Eat(food) --return DefaultEater.Eat(self, food) --end end--local function balanceThanaStats(inst)--end--local function balanceTheMedicStats(inst)--endlocal function balanceWarkStats(inst) local warkStats = { health = 125, hunger = 150, damage = 0.8, healthNerf = 150, hungerNerf = 150, damageNerf = 1, walkSpeedNerf = 1, runSpeedNerf = 1, } modifyStats(inst, warkStats) endlocal function balanceWolfStats(inst) inst.components.sanity.dapperness = TUNING.DAPPERNESS_TINY*-0.75 endlocal function balanceWoodieStats(inst) local woodieStats = { levelNerf = 0, foodPrefab1 = "butterflymuffin", levelPerFood1 = 1, initialHealth = 75, initialHunger = 100, initialSanity = 100, finalHealth = 175, finalHunger = 200, finalSanity = 175, } modifyStats(inst, woodieStats) endlocal function balanceWoodieAxe(inst) inst:AddTag("undroppable") inst:AddComponent("characterspecific") inst.components.characterspecific:SetOwner("woodie") end--[[local function balanceZimStats(inst)end]]----------------------------------------------------------------------------------- Add the previously set functions to each character or character item prefab -----------------------------------------------------------------------------------if modBalancingEnabled == 1 then -- TODO: Replace with a function printInfo("Mod Balancing enabled") if GLOBAL.KnownModIndex:IsModEnabled("workshop-382501575") then if crashBandicootBalanced == 1 then AddPrefabPostInit("crashbandi", balanceCrashBandicootStats) printInfo("Balancing Crash Bandicoot") else printInfo("Ignoring Crash Bandicoot") end end if GLOBAL.KnownModIndex:IsModEnabled("workshop-384048428") then if devonBalanced == 1 then AddPrefabPostInit("devon", balanceDarkSakuraStats) printInfo("Balancing Dark Sakura Matou") else printInfo("Ignoring Dark Sakura Matou") end end --[[if GLOBAL.KnownModIndex:IsModEnabled("workshop-366048578") then if devonBalanced == 1 then AddPrefabPostInit("devon", balanceDevonStats) printInfo("Balancing Devon") else printInfo("Ignoring Devon") end end]] if GLOBAL.KnownModIndex:IsModEnabled("workshop-373622746") then if drokBalanced == 1 then AddPrefabPostInit("drok", balanceDrokStats) printInfo("Balancing Drok the Caveman") else printInfo("Ignoring Drok the Caveman") end end if GLOBAL.KnownModIndex:IsModEnabled("workshop-363966651") then if endiaBalanced == 1 then AddPrefabPostInit("endia", balanceEndiaStats) printInfo("Balancing Endia") --printInfoToConsole(info, "Balancing Endia") end end if GLOBAL.KnownModIndex:IsModEnabled("workshop-364491382") then if farozBalanced == 1 then AddPrefabPostInit("faroz", balanceFarozStats) AddPrefabPostInit("faroz_gls", balanceFarozGlasses) printInfo("Balancing Faroz") else printInfo("Ignoring Faroz") end end if GLOBAL.KnownModIndex:IsModEnabled("workshop-398833909") then if filiaBalanced == 1 then AddPrefabPostInit("filia", balanceFiliaStats) printInfo("Balancing Filia") else printInfo("Ignoring Filia") end end --[[if GLOBAL.KnownModIndex:IsModEnabled("workshop-374341561") then if fionnaBalanced == 1 then AddPrefabPostInit("fionna", balanceFionnaStats) printInfo("Balancing Fionna") else printInfo("Ignoring Fionna") end end]] if GLOBAL.KnownModIndex:IsModEnabled("workshop-359318959") then if freeSpiritBalanced == 1 then AddPrefabPostInit("freebre", balanceFreeSpiritStats) printInfo("Balancing FreeSpirit the Umbreon") else printInfo("Ignoring FreeSpirit the Umbreon") end end --[[if GLOBAL.KnownModIndex:IsModEnabled("workshop-381660473") then if gabenBalanced == 1 then AddPrefabPostInit("gbe", balanceGabenStats) printInfo("Releasing HL3") else printInfo("Delaying HL3") end end]] --[[if GLOBAL.KnownModIndex:IsModEnabled("workshop-363819976") then if girBalanced == 1 then AddPrefabPostInit("gir", balanceGirStats) printInfo("Balancing Gir") else printInfo("Ignoring Gir") end end]] if GLOBAL.KnownModIndex:IsModEnabled("workshop-359821133") then if haruzBalanced == 1 then AddPrefabPostInit("haruz", balanceHaruzStats) printInfo("Balancing Haruz") else printInfo("Ignoring Haruz") end end --[[if GLOBAL.KnownModIndex:IsModEnabled("workshop-369898161") then if hellaMerdurialBalanced == 1 then AddPrefabPostInit("hella", balanceHellaMerdurialStats) printInfo("Balancing Hella") else printInfo("Ignoring Hella") end end]] if GLOBAL.KnownModIndex:IsModEnabled("workshop-380079744") then if luffyBalanced == 1 then AddPrefabPostInit("luffy", balanceLuffyStats) printInfo("Balancing Luffy") else printInfo("Ignoring Luffy") end end if GLOBAL.KnownModIndex:IsModEnabled("workshop-369228986") then if madeleineBalanced == 1 then AddPrefabPostInit("madeleine", balanceMadeleineStats) printInfo("Balancing Madeleine") else printInfo("Ignoring Madeleine") end end if GLOBAL.KnownModIndex:IsModEnabled("workshop-357013795") then if michaelTheFoxBalanced == 1 then AddPrefabPostInit("fox", balanceMichaelTheFoxStats) printInfo("Balancing Michael the Fox") else printInfo("Ignoring Michael the Fox") end end if GLOBAL.KnownModIndex:IsModEnabled("workshop-368321978") then if mikuHatsuneBalanced == 1 then AddPrefabPostInit("miku", balanceMikuHatsuneStats) printInfo("Balancing Miku Hatsune") else printInfo("Ignoring Miku Hatsune") end end if GLOBAL.KnownModIndex:IsModEnabled("workshop-364189966") then if mitsuruBalanced == 1 then AddPrefabPostInit("mitsuru", balanceMitsuruStats) printInfo("Balancing Mitsuru") else printInfo("Ignoring Mitsuru") end end --[[if GLOBAL.KnownModIndex:IsModEnabled("workshop-351877222") then if neptuniaBalanced == 1 then AddPrefabPostInit("nep", balanceNeptuniaStats) printInfo("Balancing Neptunia") else printInfo("Ignoring Neptunia") end end]] if GLOBAL.KnownModIndex:IsModEnabled("workshop-360319890") then if serasBalanced == 1 then AddPrefabPostInit("seras", balanceSerasStats) printInfo("Balancing Seras") else printInfo("Ignoring Seras") end end if GLOBAL.KnownModIndex:IsModEnabled("workshop-359479220") then if sollyzBalanced == 1 then AddPrefabPostInit("sollyz", balanceSollyzStats) printInfo("Balancing Sollyz") else printInfo("Ignoring Sollyz") end end if GLOBAL.KnownModIndex:IsModEnabled("workshop-369544255") then if shovelKnightBalanced == 1 then AddPrefabPostInit("winston", balanceShovelKnightStats) AddPrefabPostInit("skweaponshovelbladebasic", balanceShovelKnightBlades) AddPrefabPostInit("skweaponshovelbladechargehandle", balanceShovelKnightBlades) AddPrefabPostInit("skweaponshovelbladetrenchblade", balanceShovelKnightBlades) AddPrefabPostInit("skweaponshovelbladedropspark", balanceShovelKnightBlades) printInfo("Balancing Shovel Knight") else printInfo("Ignoring Shovel Knight") end end if GLOBAL.KnownModIndex:IsModEnabled("workshop-399799824") then if tamamoBalanced == 1 then AddPrefabPostInit("tamamo", balanceTamamoStats) printInfo("Balancing Tamamo") else printInfo("Ignoring Tamamo") end end --[[if GLOBAL.KnownModIndex:IsModEnabled("workshop-368541793") then if thanaBalanced == 1 then AddPrefabPostInit("thana", balanceThanaStats) printInfo("Balancing Thana") else printInfo("Ignoring Thana") end end]] --[[if GLOBAL.KnownModIndex:IsModEnabled("workshop-379628839") then if theMedicBalanced == 1 then AddPrefabPostInit("medic", balanceTheMedicStats) printInfo("Balancing The Medic") else printInfo("Ignoring The Medic") end end]] if GLOBAL.KnownModIndex:IsModEnabled("workshop-369518979") then if warkBalanced == 1 then AddPrefabPostInit("wark", balanceWarkStats) printInfo("Balancing Wark") else printInfo("Ignoring Wark") end end if GLOBAL.KnownModIndex:IsModEnabled("workshop-369435452") then if wolfBalanced == 1 then AddPrefabPostInit("wolft", balanceWolfStats) printInfo("Balancing Wolf") else printInfo("Ignoring Wolf") end end if GLOBAL.KnownModIndex:IsModEnabled("workshop-384633033") then if woodieBalanced == 1 then AddPrefabPostInit("woodie", balanceWoodieStats) AddPrefabPostInit("lucy", balanceWoodieAxe) printInfo("Balancing PrzemoLSZ's Woodie") else printInfo("Ignoring PrszemoLSZ's Woodie") end end --[[if GLOBAL.KnownModIndex:IsModEnabled("workshop-357209437") then if zimBalanced == 1 then AddPrefabPostInit("izim", balanceZimStats) printInfo("Balancing Zim") else printInfo("Ignoring Zim") end end]] else printInfo("Mod Balancing disabled") end And my keyhandler:local CRKeyHandler = Class(function(self, inst) self.inst = inst self.handler = TheInput:AddKeyHandler(function(key, down) self:OnRawKey(key, down) end )end)function CRKeyHandler:OnRawKey(key, down) local player = ThePlayer if (key and not down) and not IsPaused() then player:PushEvent("CRkeypressed", {inst = self.inst, player = player, key = key}) elseif key and down and not IsPaused() then player:PushEvent("CRkeydown", {inst = self.inst, player = player, key = key}) endendreturn CRKeyHandler And my modinfo.lua:-- This information tells other players more about the modname = "Mod Character Balancing"description = "Configure everything! Balance your characters, new leveling systems, items for new players, customize your experience. Basically GregTech."author = "DrSmugleaf"version = "2.0.0"priority = -100-- This is the URL name of the mod's thread on the forum; the part after the ? and before the first & in the urlforumthread = ""-- This lets other players know if your mod is out of date, update it to match the current version in the gameapi_version = 10dst_compatible = truedont_starve_compatible = falsereign_of_giants_compatible = trueall_clients_require_mod = falseicon_atlas = "modicon.xml"icon = "modicon.tex"server_filter_tags = {"mod character rebalancing"}configuration_options ={ { name = "TEST_OF_TESTIES_OF_USELESS_PLACEHOLDER_PANCAKES", label = "Hover over me!", hover = "Hover over any config option for details!", options = { {description = "And me!", data = 1, hover = "You can hover over these for information too!"}, {description = "hey", data = 0, hover = "Do you want to build a snoowmaan"}, }, default = 1, }, { name = "MOD_BALANCING_ENABLED", label = "Balance Mod Characters", hover = "Balance modded characters", options = { {description = "Enabled", data = 1}, {description = "Disabled", data = 0}, }, default = 1, }, { name = "LEVEL_SETTING", label = "Character leveling", hover = "Needs balance mod characters enabled. New leveling or not, and difficulty", options = { {description = "Disabled", data = 0, hover = "Keeps all leveling systems as is"}, {description = "Easy", data = 1, hover = "Keeps all leveling systems as is, and adds more"}, {description = "Normal", data = 2, hover = "Adds more leveling systems, 50 max lvl base"}, {description = "Hard", data = 3, hover = "Adds more leveling systems, 75 max lvl base"}, {description = "Very Hard", data = 4, hover = "Adds more leveling systems, 100 max lvl base"}, }, default = 2, }, { name = "HARDCORE_MODE", label = "Ultrahard Mode", hover = "Make everything terrible. Will override most config settings", options = { {description = "No", data = 0, hover = "Don't turn on ultrahard mode, I preffer living"}, {description = "Yes", data = 1, hover = "HOLD ONTO YOUR PANTS"}, }, default = 0, }, { name = "NERF_SPEED", label = "Nerf speed", hover = "Nerf characters speed to be more default. NOTE: Will buff other stats", options = { {description = "No", data = 0, hover = "Don't nerf speed"}, {description = "Yes", data = 1, hover = "Nerf speed but buff other stats to compensate"}, }, default = 0, }, { name = "ENABLE_STARTING_ITEMS", label = "Starting Items", hover = "Enable Starting Items for new players", options = { {description = "Yes", data = 1, hover = "Enable spawning with resources"}, {description = "No", data = 0, hover = "Disable spawning with resources"}, }, default = 1, }, { name = "AMOUNT_OF_FLINT", label = "Amount of flint", hover = "Amount of flint new players spawn with", options = { {description = "Disabled", data = 0, hover = "Disable spawning with flint"}, {description = "1", data = 1}, {description = "2", data = 2}, {description = "3", data = 3}, {description = "4", data = 4}, {description = "5", data = 5}, {description = "6", data = 6}, {description = "7", data = 7}, {description = "8", data = 8}, {description = "9", data = 9}, {description = "10", data = 10}, }, default = 5, }, { name = "AMOUNT_OF_GRASS", label = "Amount of grass", hover = "Amount of grass new players spawn with", options = { {description = "Disabled", data = 0, hover = "Disable spawning with grass"}, {description = "1", data = 1}, {description = "2", data = 2}, {description = "3", data = 3}, {description = "4", data = 4}, {description = "5", data = 5}, {description = "6", data = 6}, {description = "7", data = 7}, {description = "8", data = 8}, {description = "9", data = 9}, {description = "10", data = 10}, }, default = 5, }, { name = "AMOUNT_OF_LOGS", label = "Amount of logs", hover = "Amount of logs new players spawn with", options = { {description = "Disabled", data = 0, hover = "Disable spawning with logs"}, {description = "1", data = 1}, {description = "2", data = 2}, {description = "3", data = 3}, {description = "4", data = 4}, {description = "5", data = 5}, {description = "6", data = 6}, {description = "7", data = 7}, {description = "8", data = 8}, {description = "9", data = 9}, {description = "10", data = 10}, }, default = 5, }, { name = "AMOUNT_OF_MEAT", label = "Amount of meat", hover = "Amount of meat new players spawn with", options = { {description = "Disabled", data = 0, hover = "Disable spawning with meat"}, {description = "1", data = 1}, {description = "2", data = 2}, {description = "3", data = 3}, {description = "4", data = 4}, {description = "5", data = 5}, {description = "6", data = 6}, {description = "7", data = 7}, {description = "8", data = 8}, {description = "9", data = 9}, {description = "10", data = 10}, }, default = 5, }, { name = "AMOUNT_OF_TWIGS", label = "Amount of twigs", hover = "Amount of twigs new players spawn with", options = { {description = "Disabled", data = 0, hover = "Disable spawning with twigs"}, {description = "1", data = 1}, {description = "2", data = 2}, {description = "3", data = 3}, {description = "4", data = 4}, {description = "5", data = 5}, {description = "6", data = 6}, {description = "7", data = 7}, {description = "8", data = 8}, {description = "9", data = 9}, {description = "10", data = 10}, }, default = 5, }, { name = "GIVE_THERMAL_STONE", label = "Give thermal stone", hover = "Whether or not to give new players a thermal stone", options = { {description = "Yes", data = 1, hover = "Give new players a thermal stone"}, {description = "No", data = 0, hover = "Don't give new players a thermal stone"}, }, default = 1, }, { name = "CRASHBANDICOOT_BALANCED", label = "Crash Bandicoot", hover = "Balance Crash Bandicoot, the Experiment", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, }, { name = "DARKSAKURA_BALANCED", label = "Dark Sakura", hover = "Balance Dark Sakura Matou", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, }, --[[{ name = "DEVON_BALANCED", label = "Devon", hover = "Balance Devon, the Hunter", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, },]] { name = "DROK_BALANCED", label = "Drok", hover = "Balance Drok, the Caveman", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, }, { name = "ENDIA_BALANCED", label = "Endia", hover = "Balance Endia, the Paranoid Elf", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, }, { name = "FAROZ_BALANCED", label = "Faroz", hover = "Balance Faroz, the Little Scholar", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, }, { name = "FILIA_BALANCED", label = "Filia", hover = "Balance Filia, the forgetful schoolgirl", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, }, --[[{ name = "FIONNA_BALANCED", label = "Fionna", hover = "Balance Fionna", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, },]] { name = "FREESPIRIT_BALANCED", label = "FreeSpirit", hover = "Balance Umbreon, the FreeSpirit", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, }, --[[{ name = "GABEN_BALANCED", label = "Gaben", hover = "Release HL3", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, },]] --[[{ name = "GIR_BALANCED", label = "Gir", hover = "Balance Purswader's Gir", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, },]] { name = "HARUZ_BALANCED", label = "Haruz", hover = "Balance Haruz, the Cowardly Dog", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, }, --[[{ name = "HELLAMERDURIAL_BALANCED", label = "Hella Merdurial", hover = "Balance Hella Merdurial", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, },]] { name = "LUFFY_BALANCED", label = "Luffy", hover = "Balance Luffy", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, }, { name = "MADELEINE_BALANCED", label = "Madeleine", hover = "Balance Madeleine, the Rich Cat", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, }, { name = "MICHAELTHEFOX_BALANCED", label = "Michael the Fox", hover = "Balance Michael the Fox, the Scaredy Cat", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, }, { name = "MIKUHATSUNE_BALANCED", label = "Miku Hatsune", hover = "Balance Miku Hatsune", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, }, { name = "MITSURU_BALANCED", label = "Mitsuru", hover = "Balance Mitsuru, the Winter Wolfy", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, }, --[[{ name = "NEPTUNIA_BALANCED", label = "Neptunia", hover = "Balance Hyperdimension Neptunia: Neptune", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, },]] { name = "SERAS_BALANCED", label = "Seras", hover = "Balance Seras, the Fledgling Vampire", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, }, { name = "SOLLYZ_BALANCED", label = "Sollyz", hover = "Balance Sollyz, the Cat Slap", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, }, { name = "SHOVELKNIGHT_BALANCED", label = "Shovel Knight", hover = "Balance Shovel Knight, the Blue Burrower", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, }, { name = "TAMAMO_BALANCED", label = "Tamamo", hover = "Balance Tamamo, Queen of Kitsunes", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, }, --[[{ name = "THANA_BALANCED", label = "Thana", hover = "Balance Thana, the Nightstalker", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, },]] --[[{ name = "THEMEDIC_BALANCED", label = "The Medic", hover = "Balance The Medic", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, },]] { name = "WARK_BALANCED", label = "Wark, the Chocobo", hover = "Balance Wark, the Chocobo", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, }, { name = "WOLF_BALANCED", label = "Wolf", hover = "Balance Wolf, the Lone Wolf", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, }, { name = "WOODIE_BALANCED", label = "Woodie", hover = "Balance Woodie, the Lumberjack", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, }, --[[{ name = "ZIM_BALANCED", label = "Zim", hover = "Balance Purswader's Zim", options = { {description = "Balanced", data = 1}, {description = "Ignored", data = 0}, }, default = 1, },]]} And my GitHub Problem is, at first my character would say that health did not exist on Tamamo, and throw a nil on modifyStats.Next, it would say eat was also nil.Then, it would work but crash soon after all the players in the server but the host. Most of the time it worked for the host but no client ever. Every other character modification works for host and clients with no problems. So then, we deleted EVERYTHING FROM THE BALANCE TAMAMO STATS FUNCTION, but this: modifyStats(inst, { health = 125, walkSpeed = 1, runSpeed = 1, damage = 1, dapperness = 0, hungerRate = 1, }) And it would still crash. Would still say health is nil at the same line from modifystats where it tries to use it.local hunger_percent = inst.components.hunger:GetPercent()Or somewhere around there. Since honestly after 2 days of absolutely filling up Tamamo with **** I'm pretty lost as to what crashed where. For comparison here's Endia's prefab code if anyone wants to look at it, since me changing stats about endia actually work: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" ), -- Don't forget to include your character's custom assets! Asset( "ANIM", "anim/endia.zip" ), Asset( "ANIM", "anim/ghost_endia_build.zip" ),}local prefabs = { "endiaamulet" }local start_inv = { "endiaamulet" }local friendly_tags = {"smallcreature", "animal", "pig", "berrythief"}local nonfriendly_tags = {"hostile", "killer", "frog", "mosquito"}local common_postinit = function(inst) -- choose which sounds this character will play inst.soundsname = "wendy" -- a minimap icon must be specified inst.MiniMapEntity:SetIcon( "endia.png" ) -- todo: Add an example special power here.end-- Sanity gain from friendly creatures (rabbits, birds, bees, beefalo, etc)local function sanityfn(inst) local x,y,z = inst.Transform:GetWorldPosition() local delta = 0 local max_rad = 10 local ents = TheSim:FindEntities(x,y,z, max_rad, nil, nonfriendly_tags, friendly_tags) for k,v in pairs(ents) do local distsq = inst:GetDistanceSqToInst(v) delta = delta + TUNING.SANITYAURA_TINY/math.max(1, distsq) end return math.min(delta, TUNING.SANITYAURA_TINY) + inst.components.sanity.rateend-- Flat burnrate reduction (not overwriting burnrate because certain items would reset it to 1)local function hungerfn(self, dt, ignore_damage) local old = self.current if self.burning then if self.current <= 0 then if not ignore_damage then self.inst.components.health:DoDelta(-self.hurtrate*dt, true, "hunger") end else self:DoDelta(math.max(0, self.burnrate-0.5)*(-self.hungerrate*dt), true) end endendlocal function onkilledother(inst, data) if data ~= nil and data.victim ~= nil then local isfriendly = false local ishostile = false for k,v in pairs(friendly_tags) do if data.victim:HasTag(v) then isfriendly = true break end end if isfriendly then for k,v in pairs(nonfriendly_tags) do if data.victim:HasTag(v) then ishostile = true break end end if not ishostile then -- killed a friendly creature, you should feel bad! inst.components.sanity:DoDelta(-8) if inst.components.talker ~= nil then inst.components.talker:Say(GetString(inst, "ANNOUNCE_KILL_INNOCENT_CREATURE")) end end end endendlocal function OnAttackOther(inst, data) if data.target ~= nil then -- Birds AI don't really care about being hit so force them to fly away if data.target:HasTag("bird") then data.target:PushEvent("flyaway") end -- Turkey AI doesn't care about being attacked either, force them to panic if data.target:HasTag("berrythief") and data.target.components.hauntable ~= nil then data.target.components.hauntable:Panic() end end endlocal master_postinit = function(inst) -- Stats inst.components.health:SetMaxHealth(200) inst.components.hunger:SetMax(115) inst.components.sanity:SetMax(75) inst.components.hunger.DoDec = hungerfn inst.components.sanity.custom_rate_fn = sanityfn -- Rabbits dont run away inst:RemoveTag("scarytoprey") inst:ListenForEvent("killed", function(inst, data) onkilledother(inst, data) end) inst:ListenForEvent("onattackother", OnAttackOther)endreturn MakePlayerCharacter("endia", prefabs, assets, common_postinit, master_postinit, start_inv) So in the end, add a mode to tamamo with a function that can also be applied to other characters, which can modify stats in that mode or whatever about them, and also remove other things. It mostly seems to flip out on tamamo since it doesn't even recognize health as a thing that exists in this world, or eater, or anything really. Also the function according to a friend can't add more than one mode to one character, so if that changes that would be great too. Also tried in the end making the mod not required on clients to see what happened. Everything worked, BUT TAMAMO! So anyone that has the greater insights about everything, please. Im absolutely lost on this. Link to comment Share on other sites More sharing options...
DrSmugleaf Posted March 9, 2015 Author Share Posted March 9, 2015 (edited) Also the function according to a friend can't add more than one mode to one character, so if that changes that would be great too. to be politically correct Thanks good guy saeldur for doing it in 5 minutes after being linked this post EDIT: Also as a quick edit if anyone wants to fix a more minor problem, mod sometimes crashes when equipping or deequipping some mod character items like shovel knight's armorThought I kind of care less about that one. EDIT: Found a couple of screenshots, this is when a friend joined as tamamo:Tamamo ( also another one which is the same just me moving things around in the code )FriendI (host) didn't crash Edited March 9, 2015 by DrSmugleaf Link to comment Share on other sites More sharing options...
DrSmugleaf Posted March 12, 2015 Author Share Posted March 12, 2015 (edited) Think I figured out the problem, any character with Ksizor's mode changing code simply won't work with changing or reading stats (gir, tamamo...), from an outside mod or from the own mod itself. Think the only way to fix it is to change the base mod so that instead of a key toggle it is some other kind of toggle. Heres a bunch of crash logs for anyone that feels like continuing my effort, after 6 days of achieving nothinghttp://pastebin.com/Vt7sFXc1http://pastebin.com/rxEXNRJEhttp://pastebin.com/xb4rVHDAhttp://pastebin.com/z9Gf20d9 The hunger nil and such always happens clientside, never to the host. That will happen for any stat in my mod or the base mod as it will say that the thing exists, but that it is nil. Removing Ksizor's mode code solves it, but not exactly what I was looking for. Edited March 12, 2015 by DrSmugleaf Link to comment Share on other sites More sharing options...
Kzisor Posted March 12, 2015 Share Posted March 12, 2015 (edited) @DrSmugleaf, geez, thanks for tossing me under the bus there mate. Based on the information you've provided; it seems that you are misunderstanding how to properly network the code. If you'd like some assistance hit me up on Steam (Ysovuka) and I will try to explain how it works and how to get yours to work with it. Edit:I put this code in my test mod and it worked flawlessly to adjust Tamamo's stats. local function OnKeyPressed(inst, data) if data.inst == ThePlayer then if data.key == KEY_Z then if TheWorld.ismastersim then BufferedAction(inst, inst, ACTIONS.FERAL):Do() -- Since we are the server, do the action on the server. else SendRPCToServer(RPC.DoWidgetButtonAction, ACTIONS.FERAL.code, inst, ACTIONS.FERAL.mod_name) end end endendAddPrefabPostInit("tamamo", function(inst) inst:ListenForEvent("keypressed", OnKeyPressed) return instend)local FERAL = GLOBAL.Action()FERAL.str = "Feral"FERAL.id = "FERAL"FERAL.fn = function(act) print("Feral action called.") if act.target.transformed then print("We're transformed.") act.target.components.health:SetMaxHealth(250) act.target.components.health:DoDelta(0) print("Health: "..act.target.components.health.maxhealth) else print("We're not transformed.") act.target.components.health:SetMaxHealth(1) act.target.components.health:DoDelta(0) print("Health: "..act.target.components.health.maxhealth) end return trueend AddAction(FERAL) Edited March 13, 2015 by Kzisor Link to comment Share on other sites More sharing options...
DrSmugleaf Posted March 13, 2015 Author Share Posted March 13, 2015 @Kzisor, didn't mean to be rude, just a little tired of bashing my head against a wall for 6 days lol.Will get in contact with you, probably tomorrow though as its already 3AM for me, but thanks for offering to help, I don't doubt I'm doing something wrong, but out of 4 friends and me none of us knew what was going wrong. Also, did you try that code with someone joining the server? Because, yes, it works flawlessly for the host, but crashes anyone connecting that isnt the host. If you managed to make that work then I'm amazed and will make 10 mental notes to talk to you tomorrow. Link to comment Share on other sites More sharing options...
Kzisor Posted March 13, 2015 Share Posted March 13, 2015 @Kzisor, didn't mean to be rude, just a little tired of bashing my head against a wall for 6 days lol.Will get in contact with you, probably tomorrow though as its already 3AM for me, but thanks for offering to help, I don't doubt I'm doing something wrong, but out of 4 friends and me none of us knew what was going wrong. Also, did you try that code with someone joining the server? Because, yes, it works flawlessly for the host, but crashes anyone connecting that isnt the host. If you managed to make that work then I'm amazed and will make 10 mental notes to talk to you tomorrow. I used a dedicated server and joined as a client, so yes it worked flawlessly as a client without crashing. Link to comment Share on other sites More sharing options...
DrSmugleaf Posted March 13, 2015 Author Share Posted March 13, 2015 (edited) I used a dedicated server and joined as a client, so yes it worked flawlessly as a client without crashing.Well if you managed to do that AND to make my mod (EDIT: by my mod I mean part of what it does) work on a dedicated server then we might as well start firing happiness fireworks right about now. You have permission to kill me if I forget to contact you tomorrow then. (Though mod not working on dedicated servers was probably Kuldiin's fault) Edited March 13, 2015 by DrSmugleaf Link to comment Share on other sites More sharing options...
Kzisor Posted March 13, 2015 Share Posted March 13, 2015 (edited) @DrSmugleaf, Case closed. Case closed. Edited March 13, 2015 by Kzisor Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now