local playerManager = sdk.get_managed_singleton("snow.player.PlayerManager")
local masterPlayer = nil
local motionControl
local refPlayerBase
local action_id
local action_bank_id
local PlayerQuestBase
local GPEnabler = false
local GPTimer = 0
local masterPlayerObj
local ti = sdk.create_instance("via.effect.script.EffectManager.WwiseTriggerInfo", true):add_ref()
sdk.hook(sdk.find_type_definition("snow.player.PlayerQuestBase"):get_method("update"),
    function(args)
        local tmp = sdk.to_managed_object(args[2])
        local curPlayerIndex = tmp:get_field("_PlayerIndex")
        local masterPlayerIndex = masterPlayer:get_field("_PlayerIndex")
        if curPlayerIndex == masterPlayerIndex then
            PlayerQuestBase = tmp
        end
    end,
    function(retval)
        return retval;
    end
)
sdk.hook(sdk.find_type_definition("snow.player.PlayerQuestBase"):get_method("checkDamageReflexNoDamageHitEnable(snow.player.DamageReflexInfo.Type, snow.DamageReceiver.HitInfo, snow.hit.userdata.BaseHitAttackRSData, snow.hit.DamageFlowInfoBase)")
    ,
    function(args)
        if not masterPlayer then return end
        local eff_Player = sdk.create_instance("via.effect.script.EffectID", true):add_ref()
        eff_Player.ContainerID = 150
        eff_Player.ElementID = 310
        EffManeger:call("requestEffect(via.effect.script.EffectID, via.vec3, via.Quaternion, via.GameObject, System.String, via.effect.script.EffectManager.WwiseTriggerInfo)"
            ,
            eff_Player, PlayerPos, PlayerPos:cross(Vector3f.new(0, 1, 0)):to_quat(), nil, nil, ti)
        masterPlayerObj = masterPlayer:call("get_GameObject")
        local mPlBHVT = masterPlayerObj:call("getComponent(System.Type)", sdk.typeof("via.behaviortree.BehaviorTree"))
        mPlBHVT:call("setCurrentNode(System.UInt64, System.UInt32, via.behaviortree.SetNodeInfo)", 141465730, nil, nil)
        GPEnabler = false
        GPTimer = 0
    end)

sdk.hook(sdk.find_type_definition("snow.player.PlayerMotionControl"):get_method("lateUpdate"),
    function(args)
        motionControl = sdk.to_managed_object(args[2])
        refPlayerBase = motionControl:get_field("_RefPlayerBase")
        local curPlayerIndex = refPlayerBase:get_field("_PlayerIndex")
        local masterPlayerIndex = masterPlayer:get_field("_PlayerIndex")
        if GPEnabler == true then
            GPTimer = GPTimer + 1
        end
        if curPlayerIndex == masterPlayerIndex then
            action_id = motionControl:get_field("_OldMotionID")
            action_bank_id = motionControl:get_field("_OldBankID")
            local currentAction = action_id
            if action_bank_id == 100 and action_id == 120 and not (LastFrameMotion == currentAction) then
                DamageReflexInfo = sdk.create_instance("snow.player.DamageReflexInfo", true):add_ref()
                DamageReflexInfo:set_field("<CheckType>k__BackingField", 1)
                DamageReflexInfo:set_field("_IsChecking", true)
                local eff_Player = sdk.create_instance("via.effect.script.EffectID", true):add_ref()
                eff_Player.ContainerID = 150
                eff_Player.ElementID = 300
                local eff=EffManeger:call("requestEffect(via.effect.script.EffectID, via.vec3, via.Quaternion, via.GameObject, System.String, via.effect.script.EffectManager.WwiseTriggerInfo)"
                    ,
                    eff_Player, PlayerPos, PlayerPos:cross(Vector3f.new(0, 1, 0)):to_quat(), nil, nil, ti)
                if eff then
                    eff:update()
                    eff:setPlaySpeed(2.0)
                end
                PlayerQuestBase:set_DamageReflex(DamageReflexInfo)
                GPEnabler = true
            end
            if GPEnabler == true and GPTimer > 15 then
                DamageReflexInfo:set_field("_IsChecking", false)
                GPEnabler = false
                GPTimer = 0
            end
            LastFrameMotion = currentAction
        end
    end
)
re.on_frame(
    function()
        if not masterPlayer then masterPlayer = playerManager:findMasterPlayer() end
        if not masterPlayer then return end
        PlayerPos = masterPlayer:call("get_Pos()")
        PlayerPos.y = PlayerPos.y + 0.75
        EffManeger = masterPlayer:call("getObjectEffectManager")
    end
)
