TigerPrascire Posted May 25, 2017 Share Posted May 25, 2017 I have completed my mod, however, the action my character can do is available to ALL characters when the mod is installed. How do I make it so only this one character can perform that action instead of anyone. Is there a code I can use to identify the character by name and say that only that character can then perform the listed action? Link to comment https://forums.kleientertainment.com/forums/topic/79142-issue-with-character-specific-actions/ Share on other sites More sharing options...
alainmcd Posted May 25, 2017 Share Posted May 25, 2017 Either add a specific component for your character (like the Reader component for waxwell and wickerbottom), or check for your character in the action (if act.doer and act.doer.prefab == "yourcharacter"). Link to comment https://forums.kleientertainment.com/forums/topic/79142-issue-with-character-specific-actions/#findComment-925006 Share on other sites More sharing options...
TigerPrascire Posted May 25, 2017 Author Share Posted May 25, 2017 19 minutes ago, alainmcd said: Either add a specific component for your character (like the Reader component for waxwell and wickerbottom), or check for your character in the action (if act.doer and act.doer.prefab == "yourcharacter"). Not sure where to add the act.doer check in the code. Should I add it in the components file for the throwable or should I add it in the modmain somewhere? Link to comment https://forums.kleientertainment.com/forums/topic/79142-issue-with-character-specific-actions/#findComment-925014 Share on other sites More sharing options...
alainmcd Posted May 25, 2017 Share Posted May 25, 2017 (edited) No, I meant if you were creating a whole new action for your character. Take a brief look at actions.lua to see what I meant. Or don't. If you want your item to only be available to your character, make your life easier and just make it character-specific. Add this to your item definition: inst:AddComponent("characterspecific") inst.components.characterspecific:SetOwner("yourcharacter") If you want your item to be available to all characters and to make it so only your character throw it, try using something like this in your modmain.lua: local function Throw(self, pt, thrower) if (self.specialuseby ~= nil and thrower and thrower.prefab ~= self.specialuseby) then return false end self:OldThrow(pt, thrower) end local function ThrowablePostInit(self) self.OldThrow = self.Throw self.Throw = Throw function self:SpecialUseBy(prefab) self.specialuseby = prefab end end AddComponentPostInit("throwable", ThrowablePostInit) and this in your item file: inst:AddComponent("throwable") inst.components.throwable:SpecialUseBy("yourcharacter") Note: it might work, but I wouldn't count on it. It's untested and I'm not reliable to begin with. Hopefully the intent is clear and helps you find a solution. Feel free to ask if anything isn't obvious or if you have any issues. Edited May 25, 2017 by alainmcd Link to comment https://forums.kleientertainment.com/forums/topic/79142-issue-with-character-specific-actions/#findComment-925027 Share on other sites More sharing options...
TigerPrascire Posted May 25, 2017 Author Share Posted May 25, 2017 2 hours ago, alainmcd said: No, I meant if you were creating a whole new action for your character. Take a brief look at actions.lua to see what I meant. Or don't. If you want your item to only be available to your character, make your life easier and just make it character-specific. Add this to your item definition: inst:AddComponent("characterspecific") inst.components.characterspecific:SetOwner("yourcharacter") If you want your item to be available to all characters and to make it so only your character throw it, try using something like this in your modmain.lua: local function Throw(self, pt, thrower) if (self.specialuseby ~= nil and thrower and thrower.prefab ~= self.specialuseby) then return false end self:OldThrow(pt, thrower) end local function ThrowablePostInit(self) self.OldThrow = self.Throw self.Throw = Throw function self:SpecialUseBy(prefab) self.specialuseby = prefab end end AddComponentPostInit("throwable", ThrowablePostInit) and this in your item file: inst:AddComponent("throwable") inst.components.throwable:SpecialUseBy("yourcharacter") Note: it might work, but I wouldn't count on it. It's untested and I'm not reliable to begin with. Hopefully the intent is clear and helps you find a solution. Feel free to ask if anything isn't obvious or if you have any issues. I can't get it to work and I've been at this for hours. It seems like wherever I add an exception for one character to have this action, it breaks EVERYTHING. Here is my code, without the exceptions added in, so you can see what I'm dealing with and sorry for how much of a spaghetti mess this is. TUNING.TIGERSPEAR_DAMAGE = 50 TUNING.TIGERHUNGER = 3 TUNING.TIGERSANITY = 1 local SMALL_USES = GetModConfigData("SMALL_USES") local LARGE_USES = GetModConfigData("LARGE_USES") local RANGE_CHECK = GetModConfigData("RANGE_CHECK") PrefabFiles = { "tiger", "tigerspear", "spear_projectile", } Assets = { Asset( "IMAGE", "images/saveslot_portraits/tiger.tex" ), Asset( "ATLAS", "images/saveslot_portraits/tiger.xml" ), Asset( "IMAGE", "images/selectscreen_portraits/tiger.tex" ), Asset( "ATLAS", "images/selectscreen_portraits/tiger.xml" ), Asset( "IMAGE", "images/selectscreen_portraits/tiger_silho.tex" ), Asset( "ATLAS", "images/selectscreen_portraits/tiger_silho.xml" ), Asset( "IMAGE", "bigportraits/tiger.tex" ), Asset( "ATLAS", "bigportraits/tiger.xml" ), Asset( "IMAGE", "images/map_icons/tiger.tex" ), Asset( "ATLAS", "images/map_icons/tiger.xml" ), Asset("ATLAS", "images/inventoryimages/tigerspear.xml"), Asset("ANIM", "anim/spear_projectile.zip"), } local require = GLOBAL.require local Ingredient = GLOBAL.Ingredient local RECIPETABS = GLOBAL.RECIPETABS local STRINGS = GLOBAL.STRINGS local TECH = GLOBAL.TECH local State = GLOBAL.State local TimeEvent = GLOBAL.TimeEvent local EventHandler = GLOBAL.EventHandler local FRAMES = GLOBAL.FRAMES GLOBAL.STRINGS.CHARACTER_TITLES.tiger = "The Bestial Huntress" GLOBAL.STRINGS.CHARACTER_NAMES.tiger = "Tiger" GLOBAL.STRINGS.CHARACTER_DESCRIPTIONS.tiger = "*Isn't afraid of the dark\n*Can move quickly\n*Dislikes Dogs" GLOBAL.STRINGS.CHARACTER_QUOTES.tiger = "\"Meow?\"" GLOBAL.STRINGS.NAMES.TIGERSPEAR = "Tiger's Spear" GLOBAL.STRINGS.RECIPE_DESC.TIGERSPEAR = "An Unbreakable Spear" GLOBAL.STRINGS.CHARACTERS.GENERIC.DESCRIBE.TIGERSPEAR = "An Unbreakable Spear" AddPrefabPostInit("spear", function(inst) local spear = inst local function onattack(inst, attacker, target, skipsanity) attacker.components.hunger:DoDelta(-TUNING.TIGERHUNGER) attacker.components.sanity:DoDelta(TUNING.TIGERSANITY) local smalltarget = target:HasTag("smallcreature") if target.components.combat then target.components.combat:GetAttacked(attacker, attacker.components.combat:CalcDamage(target, spear), weapon) end local newspear = GLOBAL.SpawnPrefab('spear') newspear.Transform:SetPosition(inst:GetPosition():Get()) if newspear.components.finiteuses then newspear.components.finiteuses:SetUses(spear.components.finiteuses:GetUses()) newspear.components.finiteuses:Use((smalltarget and not missed) and GLOBAL.TUNING.SPEAR_USES/SMALL_USES or GLOBAL.TUNING.SPEAR_USES/LARGE_USES) end newspear:AddTag("scarytoprey") newspear:DoTaskInTime(1, function(inst) inst:RemoveTag("scarytoprey") end) inst:Remove() spear:Remove() attacker.SoundEmitter:PlaySound("dontstarve/wilson/attack_weapon", nil, nil, true) end inst:AddComponent('spearthrowable') inst.components.spearthrowable:SetRange(8, 10) inst.components.spearthrowable:SetOnAttack(onattack) inst.components.spearthrowable:SetProjectile("spear_projectile") end) AddPrefabPostInit("tigerspear", function(inst) local tigerspear = inst local function onattack(inst, attacker, target, skipsanity) attacker.components.hunger:DoDelta(-TUNING.TIGERHUNGER) attacker.components.sanity:DoDelta(TUNING.TIGERSANITY) local smalltarget = target:HasTag("smallcreature") if target.components.combat then target.components.combat:GetAttacked(attacker, attacker.components.combat:CalcDamage(target, tigerspear), weapon) end local newtigerspear = GLOBAL.SpawnPrefab('tigerspear') newtigerspear.Transform:SetPosition(inst:GetPosition():Get()) if newtigerspear.components.finiteuses then newtigerspear.components.finiteuses:SetUses(spear.components.finiteuses:GetUses()) newtigerspear.components.finiteuses:Use((smalltarget and not missed) and GLOBAL.TUNING.SPEAR_USES/SMALL_USES or GLOBAL.TUNING.SPEAR_USES/LARGE_USES) end newtigerspear:AddTag("scarytoprey") newtigerspear:DoTaskInTime(1, function(inst) inst:RemoveTag("scarytoprey") end) inst:Remove() tigerspear:Remove() attacker.SoundEmitter:PlaySound("dontstarve/wilson/attack_weapon", nil, nil, true) end inst:AddComponent('spearthrowable') inst.components.spearthrowable:SetRange(8, 10) inst.components.spearthrowable:SetOnAttack(onattack) inst.components.spearthrowable:SetProjectile("spear_projectile") end) local SPEARTHROW = GLOBAL.Action(4, -- priority false, -- instant (set to not instant) true, -- right mouse button 10, -- distance check false, -- ghost valid (set to not ghost valid) false, -- can force (false) nil) -- range check function SPEARTHROW.str = "Throw spear" SPEARTHROW.id = "SPEARTHROW" SPEARTHROW.fn = function(act) if act.invobject then local target = act.target if target == nil then for k,v in pairs(GLOBAL.TheSim:FindEntities(act.pos.x, act.pos.y, act.pos.z, 20)) do if v.components and v.components.combat and v.components.combat:CanBeAttacked(act.doer) and act.doer.components and act.doer.components.combat and act.doer.components.combat:CanTarget(v) and (not v:HasTag("wall")) then target = v break end end end if target then local prefab = act.invobject.prefab act.invobject.components.spearthrowable:LaunchProjectile(act.doer, target) local newspear = act.doer.components.inventory:FindItem( function(item) return item.prefab == prefab end) if newspear then act.doer.components.inventory:Equip(newspear) end end return true end end AddAction(SPEARTHROW) local throw_spear = State({ name = "throw_spear", tags = { "attack", "notalking", "abouttoattack", "autopredict" }, onenter = function(inst) local buffaction = inst:GetBufferedAction() local target = buffaction ~= nil and buffaction.target or nil inst.components.combat:SetTarget(target) inst.components.combat:StartAttack() inst.components.locomotor:Stop() inst.AnimState:PlayAnimation("throw") inst.sg:SetTimeout(2) if target ~= nil and target:IsValid() then inst:FacePoint(target.Transform:GetWorldPosition()) inst.sg.statemem.attacktarget = target elseif buffaction ~= nil and buffaction.pos ~= nil then inst:FacePoint(buffaction.pos) end end, timeline = { TimeEvent(7 * FRAMES, function(inst) inst:PerformBufferedAction() inst.sg:RemoveStateTag("abouttoattack") end), }, ontimeout = function(inst) inst.sg:RemoveStateTag("attack") inst.sg:AddStateTag("idle") end, events = { EventHandler("animqueueover", function(inst) if inst.AnimState:AnimDone() then inst.sg:GoToState("idle") end end), }, onexit = function(inst) inst.components.combat:SetTarget(nil) if inst.sg:HasStateTag("abouttoattack") then inst.components.combat:CancelAttack() end end,}) AddStategraphState("wilson", throw_spear) AddStategraphActionHandler("wilson", GLOBAL.ActionHandler(SPEARTHROW, function(inst, action) if not inst.sg:HasStateTag("attack") then return "throw_spear" end end)) local tigerspear = GLOBAL.Recipe("tigerspear", { Ingredient("twigs", 4)}, RECIPETABS.WAR, TECH.SCIENCE_ZERO) tigerspear.atlas = "images/inventoryimages/tigerspear.xml" GLOBAL.STRINGS.CHARACTERS.TIGER = require "speech_tiger" table.insert(GLOBAL.CHARACTER_GENDERS.FEMALE, "tiger") AddMinimapAtlas("images/map_icons/tiger.xml") AddModCharacter("tiger") Link to comment https://forums.kleientertainment.com/forums/topic/79142-issue-with-character-specific-actions/#findComment-925071 Share on other sites More sharing options...
alainmcd Posted May 25, 2017 Share Posted May 25, 2017 Am I correct to understand that this code works (no crashes) and lets any character throw both regular spears and tiger's spears, and you want to change it to only allow your character to throw spears? If that's the case, try adding this right after SPEARTHROW.fn = function(act): if (act.invobject and (act.invobject.prefab == "spear" or act.invobject.prefab == "tigerspear")) and not (act.doer and act.doer.prefab == "yourcharacter") then return false end Link to comment https://forums.kleientertainment.com/forums/topic/79142-issue-with-character-specific-actions/#findComment-925087 Share on other sites More sharing options...
TigerPrascire Posted May 25, 2017 Author Share Posted May 25, 2017 15 minutes ago, alainmcd said: Am I correct to understand that this code works (no crashes) and lets any character throw both regular spears and tiger's spears, and you want to change it to only allow your character to throw spears? If that's the case, try adding this right after SPEARTHROW.fn = function(act): if (act.invobject and (act.invobject.prefab == "spear" or act.invobject.prefab == "tigerspear")) and not (act.doer and act.doer.prefab == "yourcharacter") then return false end It works! It's a little clunky but.. it works! The other characters still try to throw the spear, it says "I can't do that", then the spear appears in their hand again. But it never leaves their inventory. Amazing! Whenever I tried that, either every character couldn't do it or it'd just crash Link to comment https://forums.kleientertainment.com/forums/topic/79142-issue-with-character-specific-actions/#findComment-925094 Share on other sites More sharing options...
alainmcd Posted May 25, 2017 Share Posted May 25, 2017 I guess that's better than nothing. Sorry, I can't think of any "cleaner" solution other than making the items exclusive to your character. Link to comment https://forums.kleientertainment.com/forums/topic/79142-issue-with-character-specific-actions/#findComment-925100 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