code4240 Posted July 21, 2017 Share Posted July 21, 2017 (edited) I'm trying to give my character an ability that triggers when the X key is pressed (because there are already too many actions tbh and this ability doesn't use an item, it's just always there passively), targeting whatever the mouse is over. The ability in this case is the ability to haunt things. She's supposed to walk towards the target if not in range, just like normal actions. It works perfectly on host but on server she will be delayed for a bit, then teleport in the direction she's supposed to be walking and then start sliding towards her destination. I tried making the client just play the run animation at the start but it doesn't fix the initial teleporting issue. Trying to change her state to run or run_start or anything doesn't work either. I've spent a good two days just digging through the files for playercontroller, locomotor, actions, etc. trying just about every change I can think of and it seems like I can't get anything to work, I can only ever get halfway. Whenever I try running the locomotor on only the client, I can't get the action to proc at the end. If I try running the locomotor on both client and server, the action instantly fails on the server if she's not already in range to use the ability. If I set act as the action for bufferedaction instead of using ACTIONS.WALKTO, it doesn't run when she reaches her destination. ModMain.lua: Spoiler -- haunt; the serverside code for receiving the RPC local function YuyuHaunt(player, x, y, z) if player.prefab == "yuyuko" and not player.sg:HasStateTag("busy") and not player.sg:HasStateTag("sleeping") then local ents = TheSim:FindEntities(x, y, z, 5) if ents then for i, target in ipairs(ents) do print(target.name) if target ~= player then player:haunt(target) return end end --print("no ents found on server") end else --print("Not Yuyuko, or was busy / sleeping.") end end -- Add RPC AddModRPCHandler("yuyuko_rpc", "YuyuHaunt", YuyuHaunt) -- The keypress (x for now) GLOBAL.TheInput:AddKeyDownHandler(120, function() local player = GLOBAL.ThePlayer if player and not player.HUD:IsChatInputScreenOpen() and not player.HUD:IsConsoleScreenOpen() and IsDefaultScreen() then if player.prefab == "yuyuko" then local target = GLOBAL.TheInput:GetWorldEntityUnderMouse() if target and target ~= player then if not GLOBAL.TheWorld.ismastersim then local x, y, z = target.Transform:GetWorldPosition() SendModRPCToServer(MOD_RPC["yuyuko_rpc"]["YuyuHaunt"], x, y, z) else --host code; will do this when client/server code is fixed. end end end end end) yuyuko.lua: Spoiler --The code for haunting local function haunt(inst, target) if inst.prefab == "yuyuko" then local act = ACTIONS.HAUNT act.doer = inst act.target = target act.ghost_exclusive = false local function haunt_do() print("trying") inst.sg:GoToState("give") inst:DoTaskInTime(0.4, function() if act.rangecheckfn(inst, target) then act.fn(act) else print("too far for act.fn") end end) end local buffaction = BufferedAction(inst, target, ACTIONS.WALKTO) buffaction.distance = 3 buffaction:AddSuccessAction(haunt_do) buffaction:AddFailAction(function () print("Failed") end) inst.components.playercontroller.locomotor:GoToEntity(target, buffaction, false) end end This is what happens: http://i.imgur.com/JuQ1KUV.gifv Edited July 21, 2017 by code4240 Link to comment Share on other sites More sharing options...
ZupaleX Posted July 21, 2017 Share Posted July 21, 2017 (edited) EDIT: nothing I read too fast. This kind of issue is usually quite unerving. I'll take a closer look at it later if I can be of any help. Could you post more though? Like, everything which is connected to what you want to achieve? Edited July 21, 2017 by ZupaleX Link to comment Share on other sites More sharing options...
ZupaleX Posted July 21, 2017 Share Posted July 21, 2017 (edited) Sorry for double post but decided it will be better for clarity sake This worked for me. I obviously removed the part which were referring to your character since I don't have it. Oh and I removed the function IsDefaultScreen() because you defined it locally but did not post it. It display the message "I cannot do that" because I just hacked that together in 10 minutes using the HAUNT action so it is probably due to the fact that the HAUNT is intended to be used by a ghost but other than that the host AND client moves to the target before making it "haunted". You can probably change a few stuffs to make it look more elegant but this is functional. Spoiler local ACTIONS = GLOBAL.ACTIONS local MYHAUNT = GLOBAL.Action({ rmb=false, mindistance=2, ghost_valid=true, canforce=true, rangecheckfn=DefaultRangeCheck }) MYHAUNT.str = "MYHAUNT" MYHAUNT.id = "MYHAUNT" MYHAUNT.fn = function(act) print("ouuuuuuuh") ACTIONS.HAUNT.fn(act) end AddAction(MYHAUNT) AddStategraphActionHandler("wilson", ActionHandler(ACTIONS.MYHAUNT)) AddStategraphActionHandler("wilson_client", ActionHandler(ACTIONS.MYHAUNT)) -- haunt; the serverside code for receiving the RPC local function YuyuHaunt(player, x, y, z) if not player.sg:HasStateTag("busy") and not player.sg:HasStateTag("sleeping") then local ents = GLOBAL.TheSim:FindEntities(x, y, z, 1) if ents then for i, target in ipairs(ents) do print(target.name) if target ~= player and player.components and player.components.locomotor then local buffAction = GLOBAL.BufferedAction(player, target, ACTIONS.MYHAUNT) player.components.locomotor:PushAction(buffAction) return end end end --print("no ents found on server") end end -- Add RPC AddModRPCHandler("yuyuko_rpc", "YuyuHaunt", YuyuHaunt) -- The keypress (x for now) GLOBAL.TheInput:AddKeyDownHandler(GLOBAL.KEY_X, function() local player = GLOBAL.ThePlayer if player and not player.HUD:IsChatInputScreenOpen() and not player.HUD:IsConsoleScreenOpen() then local target = GLOBAL.TheInput:GetWorldEntityUnderMouse() if target and target ~= player then local x, y, z = target.Transform:GetWorldPosition() local buffAction = GLOBAL.BufferedAction(player, target, ACTIONS.MYHAUNT) if not GLOBAL.TheWorld.ismastersim then buffAction.preview_cb = function() SendModRPCToServer(MOD_RPC["yuyuko_rpc"]["YuyuHaunt"], x, y, z) end player.components.locomotor:PreviewAction(buffAction, true) else YuyuHaunt(player, x, y, z) --host code; will do this when client/server code is fixed. end end end end) Edited July 21, 2017 by ZupaleX Link to comment Share on other sites More sharing options...
code4240 Posted July 21, 2017 Author Share Posted July 21, 2017 Thanks! Besides the "I can't do that" thing it pretty much works. (I had to add the give state to it but that pretty much worked) Strangely, she didn't say "I can' do that" in my original code, and the fn for haunt doesn't have any reference to the line, so I'm not sure where that's happening. Link to comment Share on other sites More sharing options...
code4240 Posted July 21, 2017 Author Share Posted July 21, 2017 (edited) On second thought, it seems that using the give state triggers a stack overflow error originating in preview_cb if I use the ability a couple times. I am slightly dumbfounded by this. EDIT: just replacing the state entry with animation calls seems to fix the issue. Also, console has confirmed to me that the bufferedAction is calling both its success actions and its fail actions when I use it, which is probably what's triggering the "I can't do that" thing even though the ability works. EDIT2: The fix for her saying "I can't do that" is just to make the new action's fn return true. EDIT3: Ignore what I said about the animations and states. The actual solution is just to do this: AddStategraphActionHandler("wilson", GLOBAL.ActionHandler(ACTIONS.MYHAUNT, "give")) AddStategraphActionHandler("wilson_client", GLOBAL.ActionHandler(ACTIONS.MYHAUNT, "give")) -telling it to add that action handler to the "give" state makes it work perfectly. Edited July 21, 2017 by code4240 Link to comment Share on other sites More sharing options...
ZupaleX Posted July 21, 2017 Share Posted July 21, 2017 Hi, glad you got it sorted out. Sorry about the return true which was missing I don't know how I missed that. For the destination state for the AddStategraphActionHandler, at first I put "doshortaction" and did my initial testing on that. It worked ok even when performing the action several times in a row but decided that maybe you don't want a generic animation and just remove the deststate completely. As far as I saw in the stategraph.lua, if the deststate is missing it sends to a default function which just performs the action immediately when available and do not display anything. I tested it again quickly, like using the action once or twice, and did not get an error so I assume it would be fine ^^. But I guess it's more complicated than that. The most elegant way would be to write your own state (but "give" or "doshortaction" would do just fine if you did not have a specific wish for the animation played when performing your action). Link to comment Share on other sites More sharing options...
code4240 Posted July 21, 2017 Author Share Posted July 21, 2017 55 minutes ago, ZupaleX said: The most elegant way would be to write your own state (but "give" or "doshortaction" would do just fine if you did not have a specific wish for the animation played when performing your action). Well, only real reason for me to make a custom state for this would be if I had a custom animation, which I don't. The actual executed code is pretty simple. Course, if you think there's an animation that fits better than give/standingaction, I'm open for suggestions.. Link to comment Share on other sites More sharing options...
ZupaleX Posted July 21, 2017 Share Posted July 21, 2017 5 hours ago, code4240 said: Well, only real reason for me to make a custom state for this would be if I had a custom animation, which I don't. The actual executed code is pretty simple. Course, if you think there's an animation that fits better than give/standingaction, I'm open for suggestions.. Make your own Just joking, but I would maybe use the "doshortaction" which is the animation use to plant things or put stuffs in the fire, instead of the "give" one? I guess it would match better for small objects? But that's just a detail 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