GearBull Posted April 30, 2016 Share Posted April 30, 2016 (edited) Hello! I've already made a couple of characters for you and your friend to play (actually, it is a pair of Royal Guards from Undertale) And I need to add a perk to Royal Guard 01 - making him unable to kill rabbits in any case - if rabbit is on the run or is in the invertory. Because, you know... RG 01 is a rabbit himself, so he can't kill his own brothers. c: So now, I've did only two things: Rabbits aren't afraid of him He can't kill them with bare hands, he can only examine them Please, help me, then I will able to add this mod to Workshop c: Thank you!!! Edited April 30, 2016 by GearBull Just adding thanks c: Link to comment Share on other sites More sharing options...
DarkXero Posted May 1, 2016 Share Posted May 1, 2016 3 hours ago, GearBull said: making him unable to kill rabbits in any case - if rabbit is on the run Use this on your character prefab file. local function UpdateCanTarget(inst) local _CanTarget = inst.replica.combat.CanTarget inst.replica.combat.CanTarget = function(self, target) return _CanTarget(self, target) and not target:HasTag("rabbit") end end local function common_postinit(inst) -- Put this line inside common_postinit to apply the UpdateCanTarget function inst:DoTaskInTime(0, UpdateCanTarget) end Rabbits should be untargetable now. Link to comment Share on other sites More sharing options...
GearBull Posted May 1, 2016 Author Share Posted May 1, 2016 7 hours ago, DarkXero said: Use this on your character prefab file. Thank you very much! I will try your suggestion Link to comment Share on other sites More sharing options...
GearBull Posted May 1, 2016 Author Share Posted May 1, 2016 8 hours ago, DarkXero said: Rabbits should be untargetable now. It worked! Thank you! Link to comment Share on other sites More sharing options...
KainMorgen Posted July 6, 2016 Share Posted July 6, 2016 Instead of just making rabbits untargetable, could something similar be achieved without discarding the attack option completely? I would like to have my character a mind of it's own and refuse certain actions given by the player. It works for cooking and murdering rabbits, where I have a new COOK or MURDER function, which checks for the players prefab and the prefab of the involved object. If it's a rabbit, the function returns false and a data for a custom actionfailure message. If I do the same with the ATTACK function, the character first runs to the rabbit, attacks with whatever weapon is equipped if close enough but deals no damage (even if the rabbit is sleeping and the character strikes multiple times) and says his custom actionfailure message that is also returned. But also, every couple of seconds the character also says his "attack prey" dialogue line. It would be better, if the character would just stay where it is and tell the player that the character is not going to hurt the rabbit. (To be fair, for the cooking part, the character also walks to the fire first. If that behaviour could be eliminated as well, that would be awesome.) Here is the code I am using: old_cook_fn = GLOBAL.ACTIONS.COOK.fn function GLOBAL.ACTIONS.COOK.fn(act) print (act.doer) print (act.doer.prefab) if (act.doer ~= nil and act.doer.prefab == "jessica") then -- do either return false if the action should fail, or return old_cook_fn(act) if the target can be cooked print (tostring(act.invobject)) if act.invobject ~= nil and act.invobject.prefab == "rabbit" then return false, "NOCOOKRABBIT" -- or whatever the string is identified as (ACTIONFAIL.COOK.NOCOOKRABBIT) else return old_cook_fn(act) end else return old_cook_fn(act) end end ------------------------------------------------------------------------------- old_murder_fn = GLOBAL.ACTIONS.MURDER.fn function GLOBAL.ACTIONS.MURDER.fn(act) print (act.doer) print (act.doer.prefab) if (act.doer ~= nil and act.doer.prefab == "jessica") then -- do either return false if the action should fail, or return old_murder_fn(act) if the target can be murdered print (tostring(act.invobject)) if act.invobject ~= nil and act.invobject.prefab == "rabbit" then return false, "NOMURDERRABBIT" -- (ACTIONFAIL.MURDER.NOMURDERRABBIT) else return old_murder_fn(act) end else return old_murder_fn(act) end end ------------------------------------------------------------------------------- old_attack_fn = GLOBAL.ACTIONS.ATTACK.fn function GLOBAL.ACTIONS.ATTACK.fn(act) print (act.doer) print (act.doer.prefab) if (act.doer ~= nil and act.doer.prefab == "jessica") then -- do either return false if the action should fail, or return old_attack_fn(act) if the target can be attacked print (tostring(act.target)) if act.target ~= nil and act.target.prefab == "rabbit" then return false, "NOATTACKRABBIT" -- (ACTIONFAIL.ATTACK.NOATTACKRABBIT) else return old_attack_fn(act) end else return old_attack_fn(act) end end Link to comment Share on other sites More sharing options...
DarkXero Posted July 6, 2016 Share Posted July 6, 2016 3 hours ago, KainMorgen said: (To be fair, for the cooking part, the character also walks to the fire first. If that behaviour could be eliminated as well, that would be awesome.) Honestly everything was easy except for this god forsaken part. Curse movement prediction. local REASONS = { NOCOOKRABBIT = "NOCOOKRABBIT", NOMURDERRABBIT = "NOMURDERRABBIT", NOATTACKRABBIT = "NOATTACKRABBIT", } local ACTIONS = GLOBAL.ACTIONS local function BufferedActionEvaluation(ba) local act = ba.action local reason = nil if act == ACTIONS.COOK then local victim = ba.invobject and ba.invobject.prefab if victim == "rabbit" then reason = "NOCOOKRABBIT" end elseif act == ACTIONS.MURDER then local victim = ba.invobject and ba.invobject.prefab if victim == "rabbit" then reason = "NOMURDERRABBIT" end elseif act == ACTIONS.ATTACK then local victim = ba.target and ba.target.prefab if victim == "rabbit" then reason = "NOATTACKRABBIT" end end return reason == nil, reason end local BufferedAction = GLOBAL.BufferedAction local _TestForStart = BufferedAction.TestForStart BufferedAction.TestForStart = function(self) if self.doer and self.doer:HasTag("rabbitmercy") then local success, reason = _TestForStart(self) local mysuccess, myreason = BufferedActionEvaluation(self) success = success and mysuccess reason = myreason or reason return success, reason end return _TestForStart(self) end -- For the people that enables movement prediction... AddComponentPostInit("locomotor", function(self) if self.inst:HasTag("rabbitmercy") then local _PreviewAction = self.PreviewAction self.PreviewAction = function(self, bufferedaction, run, try_instant) if bufferedaction == nil then return end local success, reason = bufferedaction:TestForStart() if not success and REASONS[reason] ~= nil then self.inst.bufferedaction = bufferedaction self.inst:PerformPreviewBufferedAction() return end _PreviewAction(self, bufferedaction, run, try_instant) end end end) But here you go. Add the "rabbitmercy" tag to your common_postinit. Link to comment Share on other sites More sharing options...
GearBull Posted July 6, 2016 Author Share Posted July 6, 2016 On 01.05.2016 at 6:12 AM, DarkXero said: Add the "rabbitmercy" tag to your common_postinit. Link to comment Share on other sites More sharing options...
GearBull Posted July 6, 2016 Author Share Posted July 6, 2016 I've already completed that mod, but yeah, perhaps this would be even better. If my new thread is up again (instead of new one), may I ask about Sanity (Or damage bust) aura, when two sertain characters are together? Is it possible to be made? Link to comment Share on other sites More sharing options...
KainMorgen Posted July 6, 2016 Share Posted July 6, 2016 Thank you very much, DarkXero! This code is exactly what I was looking for and it is working fine. And for the best part: while I couldn't have written that down myself, I think I understand what you did there and I will be able to further enhance it in case of I get more ideas. Link to comment Share on other sites More sharing options...
DarkXero Posted July 6, 2016 Share Posted July 6, 2016 12 hours ago, GearBull said: may I ask about Sanity (Or damage bust) aura, when two sertain characters are together? Is it possible to be made? inst.components.combat.damagemultiplier = 1 inst.aura_activated = false inst:DoPeriodicTask(1, function(inst) local dist_sq = 10 * 10 local should_aura = false for i, v in ipairs(AllPlayers) do if v:HasTag("compadre") and v:GetDistanceSqToInst(inst) < dist_sq then should_aura = true break end end if should_aura then if not inst.aura_activated then inst.aura_activated = true inst.components.sanity.dapperness = inst.components.sanity.dapperness + TUNING.DAPPERNESS_MED inst.components.combat.damagemultiplier = inst.components.combat.damagemultiplier * 2 end else if inst.aura_activated then inst.aura_activated = false inst.components.sanity.dapperness = inst.components.sanity.dapperness - TUNING.DAPPERNESS_MED inst.components.combat.damagemultiplier = inst.components.combat.damagemultiplier / 2 end end end) A character with this on its master_postinit will gain tophat sanity and 2x damage multiplier while standing near a player that has the "compadre" tag. So you can have two characters with this code, have one with "compadre_one" and the other with "compadre_two", change "compadre" to one of those, respectively, and they will benefit from standing close. Link to comment Share on other sites More sharing options...
AkaiNight Posted July 7, 2016 Share Posted July 7, 2016 I try to do this but not work from me. I'm new at coding what's wrong 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/azura.zip" ), } local prefabs = {} local start_inv = { -- Custom starting items } local function UpdateCanTarget(inst) local _CanTarget = inst.replica.combat.CanTarget inst.replica.combat.CanTarget = function(self, target) return _CanTarget(self, target) and not target:HasTag("rabbit") end end local function common_postinit(inst) -- Put this line inside common_postinit to apply the UpdateCanTarget function inst:DoTaskInTime(0, UpdateCanTarget) end local fn = function(inst) -- choose which sounds this character will play inst.soundsname = "wendy" -- Minimap icon inst.MiniMapEntity:SetIcon( "azura.tex" ) -- Stats inst.components.health:SetMaxHealth(200) inst.components.hunger:SetMax(120) inst.components.sanity:SetMax(200) -- Damage multiplier (optional) inst.components.combat.damagemultiplier = 1 -- Hunger rate (optional) inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE -- Movement speed (optional) inst.components.locomotor.walkspeed = 4 inst.components.locomotor.runspeed = 6 end return MakePlayerCharacter("azura", prefabs, assets, fn, start_inv) Link to comment Share on other sites More sharing options...
DarkXero Posted July 7, 2016 Share Posted July 7, 2016 6 hours ago, AkaiNight said: I try to do this but not work from me. I'm new at coding what's wrong This code is incompatible with Don't Starve. It only works for Don't Starve Together. 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