BeansInMyLean Posted May 19, 2016 Share Posted May 19, 2016 Hey all, me again! Still hard at work on my modded character. He loves bees, and I'm having trouble giving the bees a small positive sanity aura for him. I have been rooting around the evil flower files as well as the pigman files to understand how exactly sanity auras affect the player character. I also couldn't find any relevant information with google searches/previous mods. I figure the code will go somewhere in the "name".lua file under his master_postinit but I'm just getting my feet wet in the modding/coding world so I could be totally wrong. Any help is really appreciated :). Link to comment Share on other sites More sharing options...
DarkXero Posted May 20, 2016 Share Posted May 20, 2016 1 hour ago, BeansInMyLean said: Still hard at work on my modded character. He loves bees, and I'm having trouble giving the bees a small positive sanity aura for him. I have been rooting around the evil flower files as well as the pigman files to understand how exactly sanity auras affect the player character. I also couldn't find any relevant information with google searches/previous mods. Every tick of the game, the sanity component of each entity in the game updates. Here's what happens while calculating the sanity rate: local aura_delta = 0 local x, y, z = self.inst.Transform:GetWorldPosition() local ents = TheSim:FindEntities(x, y, z, TUNING.SANITY_EFFECT_RANGE, nil, { "FX", "NOCLICK", "DECOR","INLIMBO" }) for i, v in ipairs(ents) do if v.components.sanityaura ~= nil and v ~= self.inst then local aura_val = v.components.sanityaura:GetAura(self.inst) / math.max(1, self.inst:GetDistanceSqToInst(v)) aura_delta = aura_delta + (aura_val < 0 and aura_val * self.neg_aura_mult or aura_val) end end //... self.rate = dapper_delta + moisture_delta + light_delta + aura_delta + ghost_delta x, y, z get the player position. ents gets all entities within a 10 units range of x, y, z (1 turf = 4 units) that aren't special effects, unclickable, or in your inventory (limbo). For each of those entities, do the following: - if entity has a sanity aura, and the entity isn't the guy doing the sanity calculation then -- get the aura value, divide it by the max between 1 or, the distance squared between sanity guy and entity -- if aura value is negative, and sanity guy has a neg_aura_mult attribute, apply it before doing the sum sum the aura delta to the total rate. Now, what is sanityaura? This short component: local SanityAura = Class(function(self, inst) self.inst = inst self.aura = 0 self.aurafn = nil end) function SanityAura:GetAura(observer) return self.aurafn == nil and self.aura or self.aurafn(self.inst, observer) end return SanityAura SanityAura has the members, inst (guy who receives component), aura (a number), aurafn (a function). SanityAura.GetAura is another member function, which does the following: return aura number if aurafn is nil, return the result of the function called with sanityaura guy and observer as arguments. So, back to sanity: v.components.sanityaura:GetAura(self.inst) v is one of the entities the sanity component picked up in FindEntities, and will be the self.inst of the aurafn, if called. self.inst, the sanity guy (the player), will be the observer. Evil flowers have a number for aura: inst:AddComponent("sanityaura") inst.components.sanityaura.aura = -TUNING.SANITYAURA_SMALL So it pretty much affects all characters with sanity and a neg_aura_mult different of 0. Pigmen have a function for aura: local function CalcSanityAura(inst, observer) return (inst.components.werebeast ~= nil and inst.components.werebeast:IsInWereState() and -TUNING.SANITYAURA_LARGE) or (inst.components.follower ~= nil and inst.components.follower.leader == observer and TUNING.SANITYAURA_SMALL) or 0 end inst:AddComponent("sanityaura") inst.components.sanityaura.aurafn = CalcSanityAura With inst being the pig, observer being the guy with sanity. So the function returns a debuff is pig is werepig, a buff if observer is friend of pig, or 0 if nothing else. All of this being said. There are two ways of doing what you want: 1) Give a sanityaura for bees (since they don't have any) that benefits your character. In modmain.lua: -- The PostInit only needs to run server side, on the master simulation if GLOBAL.TheNet:GetIsMasterSimulation() then -- If observer is not nil, and observer prefab is "wilson", return a positive number for the aura -- Other cases, return 0 local function AuraFn(inst, observer) if observer and observer.prefab == "wilson" then return GLOBAL.TUNING.SANITYAURA_SMALL end return 0 end local function BeePostInit(inst) -- If there isn't a sanity aura, make our own, and give it our function -- Else, we need to override it! Other modder gave the bee a sanity aura too! -- We need to save the old function, then use it on the new function we will put if not inst.components.sanityaura then inst:AddComponent("sanityaura") inst.components.sanityaura.aurafn = AuraFn else -- We save the old function local old_aurafn = inst.components.sanityaura.aurafn inst.components.sanityaura.aurafn = function(inst, observer) -- If observer is ourselves, return positive sanity aura -- Very much like or function if observer and observer.prefab == "wilson" then return GLOBAL.TUNING.SANITYAURA_SMALL end -- If the modder gave the bee a new function for the aura if old_aurafn then -- Then let the old function handle it return old_aurafn(inst, observer) end -- Else, he gave the bee a number for the aura -- So we should return that return inst.components.sanityaura.aura end end end -- Make the function BeePostInit run on each prefab named "bee" -- The function BeePostInit is given the prefab entity to modify, which we will call inst, short of instance AddPrefabPostInit("bee", BeePostInit) end 2) Very much like how the game calculates the aura, you do the same. There's this part in the sanity rate calculations: if self.custom_rate_fn ~= nil then self.rate = self.rate + self.custom_rate_fn(self.inst) end Which means that if your sanity component has a function custom_rate_fn, you can apply your own delta to the sanity rate. As such, you put in your master_postinit function of your character: -- We copy paste the aura code, mostly -- We look for entities with the "bee" tag, and entities without any of those 4 tags -- Entities with "bee" can be either bees or killer bees, or any other thing with "bee" tag -- So we check that the prefab of each entity in ents table is, in fact, a bee -- Instead of depending on a sanity aura component, we feed directly the aura value we want per bee -- We return the sum local function SanityFn(inst) local aura_delta = 0 local x, y, z = inst.Transform:GetWorldPosition() local ents = TheSim:FindEntities(x, y, z, TUNING.SANITY_EFFECT_RANGE, {"bee"}, {"FX", "NOCLICK", "DECOR", "INLIMBO"}) for i, v in ipairs(ents) do if v.prefab == "bee" then local aura_val = TUNING.SANITYAURA_SMALL / math.max(1, inst:GetDistanceSqToInst(v)) aura_delta = aura_delta + aura_val end end return aura_delta end inst.components.sanity.custom_rate_fn = SanityFn Link to comment Share on other sites More sharing options...
BeansInMyLean Posted May 20, 2016 Author Share Posted May 20, 2016 (edited) 1 hour ago, DarkXero said: All of this being said. There are two ways of doing what you want: 1) Give a sanityaura for bees (since they don't have any) that benefits your character. 2) Very much like how the game calculates the aura, you do the same. Thank you so much for such an awesome, in-depth and detailed guide on this! You really went above and beyond explaining and breaking down the parts :). I could cry its so user friendly with the comments and all. The second way of doing this seems like the best way to go about it, but I think I'll use the first method with creating an aura; I think it will help me understand a little more of whats going on "behind the scenes" in the code rather than just giving the bees a custom aura value for my character. Thanks again!! Klei should really think about hiring you for your coding prowess. ---- I updated a picture; look at that nice little sanity buff! Edited May 20, 2016 by BeansInMyLean Picture 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