DarkXero

Registered Users
  • Content count

    2,937
  • Joined

  • Last visited


Community Reputation

2669 Excellent

About DarkXero

  • Rank
    Senior Member

Recent Profile Visitors

7,070 profile views
  1. Garland. You probably forgot it existed.
  2. local TUNING = GLOBAL.TUNING -- no domestication decay TUNING.BEEFALO_DOMESTICATION_LOSE_DOMESTICATION = 0 -- no domestication loss on overfeed TUNING.BEEFALO_DOMESTICATION_OVERFEED_DOMESTICATION = 0 -- no domestication loss on player attack TUNING.BEEFALO_DOMESTICATION_ATTACKED_BY_PLAYER_DOMESTICATION = 0 -- you dont have to give ornery beef one stick every time you want a ride TUNING.BEEFALO_MIN_BUCK_OBEDIENCE = 0.4 local require = GLOBAL.require local rideable = require("components/rideable") local _Buck = rideable.Buck -- never tossed down when beefalo is domesticated rideable.Buck = function(self, gentle) local dom = self.inst.components.domesticatable if dom and dom:IsDomesticated() then return end return _Buck(self, gentle) end The salt lick situation was really awful some patches ago, where the beef weren't properly licking them during certain circumnstances (sleeping, or unloaded) and losing domestication no matter what. Right now the race condition still exists (getting salted vs getting the decay): a beef might lose domestication while standing near a salt lick, and you can test it on your own too. But it's not as awful as it was. As long as I know that beefalo might lose domestication while near a salt lick, I will never be comfortable domesticating them.
  3. local AURA_RADIUS = 15 local SANITY_BONUS = GLOBAL.TUNING.DAPPERNESS_MED local SPEED_MULTIPLIER = 1.25 local COMBAT_MULTIPLIER = 1.25 local AURA_NAME = "akaimodaura" local function UpdateAuras(inst) for i, v in ipairs(GLOBAL.AllPlayers) do if v ~= inst then local prev = v[AURA_NAME] or false local activate = v:IsNear(inst, AURA_RADIUS) if prev ~= activate then if activate then v.components.sanity.dapperness = v.components.sanity.dapperness + SANITY_BONUS v.components.locomotor:SetExternalSpeedMultiplier(inst, "superspeed", SPEED_MULTIPLIER) v.components.combat.damagemultiplier = (v.components.combat.damagemultiplier or 1) * COMBAT_MULTIPLIER else v.components.sanity.dapperness = v.components.sanity.dapperness - SANITY_BONUS v.components.locomotor:RemoveExternalSpeedMultiplier(inst, "superspeed") v.components.combat.damagemultiplier = v.components.combat.damagemultiplier / COMBAT_MULTIPLIER end end v[AURA_NAME] = activate end end end AddPrefabPostInit("wilson", function(inst) if GLOBAL.TheWorld.ismastersim then inst:DoPeriodicTask(2, UpdateAuras) end end) Here's a convenient package. Sanity, walk speed, and damage aura. You put it in modmain and you change "wilson" to the prefab your character is. Forget it.
  4. Don't implement it client side. Put inst:SetStateGraph("SGminion") after the TheWorld.ismastersim check. The only client side stategraphs are the player related ones, since those are useful to determine in advance the animations a client with movement prediction is going to do.
  5. TOADSTOOL_DARK_HEALTH = 99999
  6. local musicbandrec = AddRecipe("onemanband_alt", {Ingredient("goldnugget", 2), Ingredient("nightmarefuel", 2), Ingredient("papyrus", 1)}, GLOBAL.CUSTOM_RECIPETABS.MUSIC, GLOBAL.TECH.SCIENCE_ONE, nil, nil, nil, nil, "musician") musicbandrec.image = "onemanband.tex" musicbandrec.product = "onemanband" GLOBAL.STRINGS.RECIPE_DESC.ONEMANBAND_ALT = "The vegan alternative." GLOBAL.STRINGS.NAMES.ONEMANBAND_ALT = "One-Man Band"
  7. local musicbandrec = AddRecipe("onemanband_alt", {Ingredient("goldnugget", 3), Ingredient("nightmarefuel", 3)}, music_tab, TECH.SCIENCE_ONE, nil, nil, nil, nil, "musician") musicbandrec.image = "onemanband.tex" musicbandrec.product = "onemanband"
  8. Most likely. Try this: local require = GLOBAL.require local Action = GLOBAL.Action local ActionHandler = GLOBAL.ActionHandler local State = GLOBAL.State local EventHandler = GLOBAL.EventHandler local STRINGS = GLOBAL.STRINGS AddStategraphState("wilson", State { name = "modfreerez", tags = {"busy", "freerezacthand", "pausepredict"}, onenter = function(inst) local sX, sY, sZ = inst.Transform:GetScale() inst.Transform:SetScale(-sX, sY, sZ) local sX, sY, sZ = inst.Transform:GetRotation() inst.Transform:SetRotation(-sX, sY, sZ) inst.AnimState:PlayAnimation("emoteXL_kiss") if inst.components.playercontroller ~= nil then inst.components.playercontroller:RemotePausePrediction() end inst:PerformBufferedAction() end, events = { EventHandler("animqueueover", function(inst) local sX, sY, sZ = inst.Transform:GetScale() inst.Transform:SetScale(-sX, sY, sZ) local sX, sY, sZ = inst.Transform:GetRotation() inst.Transform:SetRotation(-sX, sY, sZ) inst.sg:GoToState("idle") end), }, }) -- Revive action -- The actual happening -- Stuff checked does not have to be networked, this is server side local FREEREZACT = AddAction("MODFREEREZ", "Kiss of Life", function(act) local doer = act.doer local target = act.target local valid_doer = doer and doer.components.modfreerez and not doer:HasTag("playerghost") local valid_target = target and target.components.modfreerez and target:HasTag("playerghost") if valid_doer and valid_target then target:PushEvent("respawnfromghost", {user = doer}) return true end end) -- Relate the action to a state name local freerezacthand = ActionHandler(FREEREZACT, "modfreerez") -- Add the action handler to the player stategraph -- Now Wilson will go to the "give" state to try and perform the freerez buffered action AddStategraphActionHandler("wilson", freerezacthand) -- Wilson can right click on stuff (entities on the scene) with the modfreerez component -- Remember to use networked stuff (like tags, prefab names, replicas) inside component actions -- This makes the prompts on stuff appear AddComponentAction("SCENE", "modfreerez", function(inst, doer, actions, right) if right and doer.components.modfreerez and inst:HasTag("playerghost") then table.insert(actions, FREEREZACT) end end) -- Now Willow can be revived by Wilson AddPrefabPostInit("willow", function(inst) inst:AddComponent("modfreerez") end) AddPrefabPostInit("wilson", function(inst) inst:AddComponent("modfreerez") end) Since the component is added server and client side, there's no need for extra tag. Also the state is now server only, it pauses the prediction and sends the corresponding animation (automatically).
  9. @Eusong, is the tex element for rainbowfeather (inside inventoryfeatherrainbow.xml) called rainbowfeather.tex? Not the texture filename, the element.
  10. @Eusong, did you remember to add the assets to the assets table in modmain?
  11. The opaque parts are the "active" clickable parts. Doesn't really matter how precisely you chop the image. Well, if you don't manually chop opaque parts that is. If you have several images though, you want to have atlas values that care about chopping each image separately, but I don't think ktech supports getting dumped a whole bunch of differently sized pngs.
  12. Are you keeping the same dimensions as the ones in the character template? How are you generating the tex files? You also have this:
  13. -- Speech strings and chat (not the actual chat text) strings converted local function OneLine(old_message) return "AAA" end AddPrefabPostInit("wilson", function(inst) inst.components.talker.mod_str_fn = OneLine end) -- Speech strings only local function OneLine() return "AAA" end local _GetSpecialCharacterString = GLOBAL.GetSpecialCharacterString GLOBAL.GetSpecialCharacterString = function(character) if character == nil then return nil end character = string.lower(character) return (character == "wilson" and OneLine()) or _GetSpecialCharacterString(character) end local pos = inst:GetPosition() local ents = TheSim:FindEntities(pos.x, pos.y, pos.z, 10, {"playerghost"}) for i, v in ipairs(ents) do v:PushEvent("respawnfromghost") end AddPrefabPostInit("wilson", function(inst) local _Eat = inst.components.eater.Eat inst.components.eater.Eat = function(self, food, feeder) local foodtype = food and food.components.edible and food.components.edible.foodtype if foodtype == "MEAT" then self:SetAbsorptionModifiers(1, 0.5, 1) elseif foodtype == "VEGGIE" then self:SetAbsorptionModifiers(1.5, 1, 1) else self:SetAbsorptionModifiers(1, 1, 1) end return _Eat(self, food, feeder) end end)
  14. Do local rainbowfeather = GLOBAL.Ingredient("rainbowfeather", 1) rainbowfeather.atlas = GLOBAL.resolvefilepath("images/inventoryimages/inventoryfeatherrainbow.xml") or local rainbowfeather = GLOBAL.Ingredient("rainbowfeather", 1, "images/inventoryimages/inventoryfeatherrainbow.xml") or local rf_atlas = "images/inventoryimages/inventoryfeatherrainbow.xml" local rainbowfeather = GLOBAL.Ingredient("rainbowfeather", 1, rf_atlas) Whatever is most visually pleasing. But the resolvefilepath function has to go somewhere. The Ingredient class constructor applies it to its atlas argument. Same for the recipe.
  15. You are forgetting inst:PerformBufferedAction() to carry out the action. You can check for doer:HasTag("modrezzer"). On both the component action and the action function. And then do inst:AddTag("modrezzer") on both Wilson and Willow. And also add the component to both of them.