Jump to content

(SOLVED) PerformBufferedAction not working / How to change server side variable with an action?


Recommended Posts

I'm trying to update my shields mod with an equip slot and blocking action. At the moment, the animation plays, but the buffered action isn't performed, meaning the player still takes damage while blocking.
 

Below is all the code relating to this. 

Spoiler

GLOBAL.EQUIPSLOTS.SHIELD = "shield"

AddGlobalClassPostConstruct("widgets/inventorybar", "Inv", function(self, owner)													
	self:AddEquipSlot(GLOBAL.EQUIPSLOTS.SHIELD, "images/shield_slot.xml", "shield_slot.tex",0)
end)

local shield_block_client = State{
        name = "shield_block",
        tags = { "blocking" },

        onenter = function(inst)
            inst.components.locomotor:Stop()
            inst.components.locomotor:Clear()
			local shield = inst.replica.inventory:GetEquippedItem(GLOBAL.EQUIPSLOTS.SHIELD)
			inst.AnimState:SetMultiSymbolExchange("swap_object", "hand")
			inst.AnimState:OverrideSymbol("swap_object", "swap_"..shield.prefab, "swap_"..shield.prefab)
			inst.AnimState:Show("ARM_carry")
			
			inst.AnimState:PlayAnimation("parry_pre")
			inst.AnimState:PushAnimation("parry_loop", true)
			inst.sg:SetTimeout(inst.AnimState:GetCurrentAnimationLength())
        end,

        events =
        {
			EventHandler("animover", function(inst)
                if inst.AnimState:AnimDone() then
                    inst.sg:GoToState("idle")
                end
            end),
        },

        onexit = function(inst)
			inst.AnimState:SetMultiSymbolExchange("hand", "swap_object")
			local weapon = inst.replica.inventory:GetEquippedItem(GLOBAL.EQUIPSLOTS.HANDS)
			if weapon then
				inst.AnimState:OverrideSymbol("swap_object", "swap_"..weapon.prefab, "swap_"..weapon.prefab)
			else
				inst.AnimState:ClearSymbolExchanges()
				inst.AnimState:Hide("ARM_carry")
			end
			
        end,
    }

local shield_block = State{
        name = "shield_block",
        tags = { "blocking" },

        onenter = function(inst)
            inst.components.locomotor:Stop()
            inst.components.locomotor:Clear()
			inst:PerformBufferedAction()
			
			inst.AnimState:PlayAnimation("parry_pre")
			inst.AnimState:PushAnimation("parry_loop", true)
			inst.sg:SetTimeout(inst.AnimState:GetCurrentAnimationLength())
        end,

        events =
        {
			EventHandler("animover", function(inst)
                if inst.AnimState:AnimDone() then
                    inst.sg:GoToState("idle")
                end
            end),
        },

        onexit = function(inst)
			
        end,
    }

AddStategraphState("wilson", shield_block)
AddStategraphState("wilson_client", shield_block_client)

local DOSHIELD = GLOBAL.Action({ priority= 10 })	
DOSHIELD.str = "Block"
DOSHIELD.id = "DOSHIELD"
DOSHIELD.fn = function(act)
	local shield = act.doer.components.inventory:GetEquippedItem(GLOBAL.EQUIPSLOTS.SHIELD)
	shield.components.armor:SetAbsorption(1)
    return act.doer:ListenForEvent("animqueueover", function()
		local shield = act.doer.components.inventory:GetEquippedItem(GLOBAL.EQUIPSLOTS.SHIELD)
		if shield then
			shield.components.armor:SetAbsorption(0)
		end
	end)
end
AddAction(DOSHIELD)

local DOSHIELD_handler = ActionHandler(ACTIONS.DOSHIELD, "shield_block")
AddStategraphActionHandler("wilson", DOSHIELD_handler)
AddStategraphActionHandler("wilson_client", DOSHIELD_handler)

AddComponentAction("SCENE", "combat", function(inst, doer, actions, right)
    if right and doer.replica.inventory:EquipHasTag("shield") then
        table.insert(actions, ACTIONS.DOSHIELD)
    end
end)

 

For a better explanation of what it's supposed to do:
When the player right clicks on any prefab with the combat component, they will play a special animation, holding the shield while any and all incoming damage is absorbed by the shield. If the player is not doing this action when hit, the shield absorbs 0% of damage dealt to the player. 
What is happening:
When the player right clicks on any prefab with the combat component, they will play a special animation, holding the shield. No damage is blocked by the shield even when they're doing this action. It all hits the player.

This is with caves enabled, so that I can test by myself while being considered a client.

Edited by Eusong
Removed unnecessary code
Link to comment
Share on other sites

Ok so apparently when movement prediction was OFF, the shield was invisible but it blocked damage. When movement prediction was ON, the shield was visible but didn't block damage.

I was able to fix the shield be invisible when it's OFF by adding the client stategraph's code to the server's and changing replica to components.
The problem with it not blocking when it's ON was fixed by adding inst:PerformPreviewBufferedAction() to the client side stategraph.

Thank you so much for @Zarklord for helping me with my issues over Discord.

Link to comment
Share on other sites

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
 Share

×
  • Create New...