Jump to content

Recommended Posts

Hello everyone, I'm working on casting spells with read book animation. 

Here's current working code, it just casts spell after animation:

AddAction("CASTJUTSU_SCROLL", STRINGS.ACTIONS.JUTSU_CAST, function(act)
    local target = act.target or act.invobject
    if target ~= nil and target.components.jutsu_scroll ~= nil then
        target.components.jutsu_scroll:Cast()
    end
    return true
end)

AddComponentAction("INVENTORY", "jutsu_scroll", function(inst, doer, actions, right)
    table.insert(actions, ACTIONS.CASTJUTSU_SCROLL)
end)

local ActionHandler = GLOBAL.ActionHandler

AddStategraphActionHandler("wilson", ActionHandler(ACTIONS.CASTJUTSU_SCROLL, "book"))
AddStategraphActionHandler("wilson_client", ActionHandler(ACTIONS.CASTJUTSU_SCROLL, "book"))

AddReplicableComponent("jutsu_scroll")

But I want to add server check before animation to check if spell is on cooldown.

I've tried to achieve this using custom state and actions:

 
AddAction("PRECHECKJUTSU_SCROLL", "Read", function(act)
    local target = act.target or act.invobject
    if target and target.components.jutsu_scroll and target.components.jutsu_scroll:Precheck() then
        act.doer.sg:GoToState("cast_jutsu", { target = target })
        return true
    end
    return false
end)

AddAction("CASTJUTSU_SCROLL", "Cast", function(act)
    local target = act.target or act.invobject
    if target and target.components.jutsu_scroll then
        target.components.jutsu_scroll:Cast()
        return true
    end
    return false
end)

AddComponentAction("INVENTORY", "jutsu_scroll", function(inst, doer, actions, right)
    if right then
        table.insert(actions, ACTIONS.PRECHECKJUTSU_SCROLL)
    end
end)

AddStategraphActionHandler("wilson_client", ActionHandler(ACTIONS.PRECHECKJUTSU_SCROLL, "precheck_jutsu"))

AddStategraphActionHandler("wilson", ActionHandler(ACTIONS.CASTJUTSU_SCROLL, "book"))
AddStategraphActionHandler("wilson_client", ActionHandler(ACTIONS.CASTJUTSU_SCROLL, "book"))

local precheck_client = State{
    name = "precheck_jutsu",
    tags = {"doing"},
    onenter = function(inst)
        inst:PerformPreviewBufferedAction()
        inst.sg:GoToState("idle")
    end,
}
AddStategraphState("wilson_client", precheck_client)

local cast_state_server = State{
    name = "cast_jutsu",
    tags = {"busy", "doing"},
    onenter = function(inst, data)
        inst.AnimState:PlayAnimation("book")
        inst.AnimState:PushAnimation("book_pst", false)
        inst.sg.statemem.target = data and data.target or nil
        inst.sg:SetTimeout(2)
    end,
    timeline =
    {
        TimeEvent(15*FRAMES, function(inst)
            if inst.sg.statemem.target then
                local new_action = BufferedAction(inst, inst.sg.statemem.target, ACTIONS.CASTJUTSU_SCROLL)
                inst:PushBufferedAction(new_action)
            end
        end),
    },
    ontimeout = function(inst)
        inst.sg:GoToState("idle")
    end,
}
AddStategraphState("wilson", cast_state_server)

But using this approach PRECHECKJUTSU_SCROLL handler is not fired on the server side.

I found this pretty difficult to implement though.:wickerbottomthanks:

To sum up, I want to achieve the following:

1. Player uses jutsu_scroll from inventory using right click

2. Server runs target.components.jutsu_scroll:Precheck()

3. If Precheck return true, client starts read book animation

3. When animation is done, server runs target.components.jutsu_scroll:Cast()

Here's the code of jutsu_scroll component:
jutsu_scroll.lua:

local Jutsu_scroll = Class(function(self, inst)
    self.inst = inst
    self.spell = nil
    self.precheck = nil
end)
function Jutsu_scroll:Cast() 
    if self.spell then
      self.spell(self.inst) 
    end
end
function Jutsu_scroll:Precheck()
    if self.precheck then return self.precheck(self.inst) end
      return true
end
return Jutsu_scroll

jutsu_scroll_replica.lua:

local Jutsu_scroll = Class(function(self, inst) self.inst = inst end)
function Jutsu_scroll:Cast()
    self.inst:PushEvent("castjutsu_scroll_request", {jutsu_scroll = self.inst})
end
function Jutsu_scroll:Precheck()
    self.inst:PushEvent("castjutsu_scroll_precheck_request",
                        {jutsu_scroll = self.inst})
end
return Jutsu_scroll

It's ok to use "read" state, but I couldn't fine a way to add server check before the read animation.

why not just check it in here

AddAction("CASTJUTSU_SCROLL", STRINGS.ACTIONS.JUTSU_CAST, function(act)
    local target = act.target or act.invobject
    if target ~= nil and target.components.jutsu_scroll ~= nil then
        target.components.jutsu_scroll:Cast()
    end
    return true
end)

 

1 hour ago, Edible Coal said:

why not just check it in here

AddAction("CASTJUTSU_SCROLL", STRINGS.ACTIONS.JUTSU_CAST, function(act)
    local target = act.target or act.invobject
    if target ~= nil and target.components.jutsu_scroll ~= nil then
        target.components.jutsu_scroll:Cast()
    end
    return true
end)

 

Because this action handler runs after read animation. I want precheck before animation and cast after animation.

The problem is solved, grok inspired me:wilson_blush:

So the solution is to create net_var in jutsu_scroll component and check this variable on the client side in AddComponentAction handler.

Solution:

modmain.lua:

AddComponentAction("INVENTORY", "jutsu_scroll", function(inst, doer, actions, right)
    if inst.replica.jutsu_scroll and inst.replica.jutsu_scroll:Precheck() then
	    table.insert(actions, ACTIONS.CASTJUTSU_SCROLL)
    end
end)

jutsu_scroll_replica.lua:

local Jutsu_scroll = Class(function(self, inst)
    self.inst = inst
    self.cooldown = net_uint(inst.GUID, "cooldown", "cooldowndirty")
end)

function Jutsu_scroll:Precheck()
    if self.cooldown:value() == 0 then
        return true
    end
    return false
end

return Jutsu_scroll

The complete mod code is available at https://steamcommunity.com/sharedfiles/filedetails/?id=1488954434 or https://github.com/nebrosarth/JutsuModDST.

Edited by nebrosarth

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
  • Create New...