public void Punch_Mechanic(float force)
    {
        m_Agent.m_StatCollector.Count_Punch();
        m_AudioSource.PlayOneShot(m_PunchSound);
        foreach (GameObject item in m_PunchHitbox.m_Items)
        {
            // Get the items rigidbody
            Rigidbody rb = item.GetComponent <Rigidbody>();
            // Punch it at a force depending on the punch
            Vector3 dir = Custom_Math_Utils.FindTargetAngle(item.transform.position, m_Agent.Get_Position());
            Vector3 f   = dir * (force * GLOBAL_VALUES.KNOCKBACK_PUNCH_ITEM_MULTIPLIER);
            rb.AddForce(f);
            //GameObject.Find("GameManagerObject").GetComponent<GameManager>().Get_MatchManager().Get_RoundManager().Get_Camera_Manager().AddForce(GLOBAL_VALUES.CAMERA_FORCE_TIME_DELAY, f);
        }
        foreach (GameObject agent in m_PunchHitbox.m_Agents)
        {
            // Get the agentmanager
            AgentManager vic = agent.GetComponent <CollisionDetection>().m_Manager;
            if (!vic.GetPunchControl().inGroundSlam())
            {
                vic.Drop(false);
                Vector3 dir = Custom_Math_Utils.FindTargetAngle(agent.transform.position, m_Agent.Get_Position());
                Vector3 f   = dir * force;
                vic.AddForce(0.2f, f);

                Vector3 punchImpact = agent.transform.Find("Impact_Punch").transform.rotation.eulerAngles;
                punchImpact.y = m_Agent.Get_Object().transform.rotation.eulerAngles.y;
                vic.ImpactParticles("punch", punchImpact);
                vic.Stun_Agent(GLOBAL_VALUES.STUN_TIME_PUNCH);

                if (vic.isSecurityAI())
                {
                    SecurityAI_Control sec_brain = vic.Get_Input() as SecurityAI_Control;
                    sec_brain.Agro(m_Agent);
                    sec_brain.Stun_Flag = false;
                    m_Agent.m_StatCollector.Count_AI_Stunned();
                }
                if (vic.isPlayer())
                {
                    m_Agent.m_StatCollector.Count_Player_Stun();
                    vic.Get_Input().Controller_Rumble(rumble, rumble);
                }
            }
        }
        foreach (GameObject destruct in m_PunchHitbox.m_Desctructables)
        {
            destruct.GetComponent <Destructable>().DealDamage(1, m_Agent);
        }
        m_Agent.NotifySubscribers(AgentAction.Punch);
    }
    // Update is called once per frame
    public void Update()
    {
        m_PowerupTimer.Update();
        if (m_PowerupTimer.isComplete())
        {
            Set_State(PowerupState.None);
        }
        switch (m_state)
        {
        case PowerupState.Magnet:
        {
            foreach (Item i in m_GameManager.Get_MatchManager().Get_RoundManager().Get_ItemManager().m_Items)
            {
                if (!i.BeingCarried())
                {
                    i.itemBody.AddForce(Custom_Math_Utils.FindTargetAngle(m_Agent.Get_Position(), i.transform.position) * GLOBAL_VALUES.POWERUP_MAGNET_STRENGTH);
                }
            }
            break;
        }

        case PowerupState.Earthquake:
        {
            // lights flicker?
            break;
        }

        case PowerupState.Shield:
        {
            // check the shield strength
            break;
        }

        default:
        {
            break;
        }
        }
    }
 private void OnCollisionEnter(Collision collision)
 {
     try
     {
         // get the object you collided with
         GameObject Other = collision.gameObject;
         //hit by item
         if ((Other.GetComponent <Rigidbody>() != null) &&
             (Other.CompareTag(GLOBAL_VALUES.PICKUP_ITEM)) &&
             (Other.GetComponent <Item>().prev_owner != m_Manager) &&
             (Other.GetComponent <Item>().GetItemState() == ItemState.thrown))
         {
             GameObject.Find("GameManagerObject").GetComponent <GameManager>().Get_MatchManager().Get_RoundManager().Get_Camera_Manager().AddForce(GLOBAL_VALUES.CAMERA_FORCE_TIME_DELAY, collision.relativeVelocity);
             // Collided with a thrown pickup item
             if (m_Manager.isPlayer())
             {
                 Other.GetComponent <Item>().prev_owner.m_StatCollector.Count_Player_Stun();
                 m_Manager.Get_Input().Controller_Rumble(rumble, rumble);
             }
             else if (m_Manager.isAI())
             {
                 Other.GetComponent <Item>().prev_owner.m_StatCollector.Count_AI_Stunned();
                 if (m_Manager.isSecurityAI())
                 {
                     SecurityAI_Control sec_brain = m_Manager.Get_Input() as SecurityAI_Control;
                     sec_brain.m_Last_Collided_Item = Other.GetComponent <Item>();
                     sec_brain.Stun_Flag            = false;
                 }
             }
             Vector3 targetAngle = Custom_Math_Utils.FindTargetAngle(m_Manager.Get_Position(), Other.gameObject.transform.position);
             m_Manager.ImpactParticles("throw", targetAngle);
             m_Manager.m_StatCollector.Count_Stunned_By_Item();
             m_Manager.Stun_Agent(GLOBAL_VALUES.STUN_TIME_ITEM);
             m_Manager.Play_Impact_Particles(Other.GetComponent <Item>().prev_owner.Get_Color());
         }
         else if ((Other.GetComponent <Rigidbody>() != null) &&
                  (Other.CompareTag(GLOBAL_VALUES.TAG_PLAYER) || Other.CompareTag(GLOBAL_VALUES.TAG_AI_SECURITY)) &&
                  (Other.GetComponent <CollisionDetection>().m_Manager.isDashing()))
         {
             // Collided with dashing player
             if (m_Manager.isSecurityAI())
             {
                 SecurityAI_Control sec_brain = m_Manager.Get_Input() as SecurityAI_Control;
                 sec_brain.Agro(Other.GetComponent <CollisionDetection>().m_Manager);
                 sec_brain.Stun_Flag = false;
             }
             //player hit by another player
             if (m_Manager.isPlayer() || Other.CompareTag(GLOBAL_VALUES.TAG_DESTRUCTABLE_PARENT))
             {
                 m_Manager.Get_Input().Controller_Rumble(rumble, rumble);
             }
             m_Manager.Play_Impact_Particles(Other.GetComponent <CollisionDetection>().m_Manager.Get_Color());
             Vector3 targetAngle = Custom_Math_Utils.FindTargetAngle(m_Manager.Get_Position(), Other.GetComponent <CollisionDetection>().m_Manager.Get_Position());
             m_Manager.ImpactParticles("dash", targetAngle);
             m_Manager.AddForce(0.1f, (targetAngle * GLOBAL_VALUES.KNOCKBACK_DASH));
             Vector3 f = (targetAngle * GLOBAL_VALUES.KNOCKBACK_DASH);
             m_Manager.AddForce(0.1f, f);
             m_Manager.Drop();
             //Other.GetComponent<CollisionDetection>().m_Manager.Drop();
         }
     }
     catch
     {
         Debug.Log("Collision Failed on Agent [" + m_Manager.Get_Object().name + "]");
     }
 }
    public void Groundslam_Mechanic()
    {
        m_Agent.Unfreeze_Agent();
        m_Agent.NotifySubscribers(AgentAction.GroundSlam);
        groundSlam = false;
        GameObject.Find("GameManagerObject").GetComponent <GameManager>().Get_MatchManager().Get_RoundManager().Get_Camera_Manager().AddForce(GLOBAL_VALUES.CAMERA_FORCE_TIME_DELAY);
        m_Agent.m_StatCollector.Count_Groundslam();
        m_AudioSource.PlayOneShot(m_GroundSlamSound);
        foreach (ParticleSystem p in m_Effect.GetComponentsInChildren <ParticleSystem>())
        {
            p.Play();
        }
        // turn off item and agent raycasts
        foreach (GameObject item in m_GroundslamHitbox.m_Items)
        {
            item.layer = GLOBAL_VALUES.LAYER_IGNORE_RAYCAST;
        }
        foreach (GameObject agent in m_GroundslamHitbox.m_Agents)
        {
            agent.layer = GLOBAL_VALUES.LAYER_IGNORE_RAYCAST;
        }
        // push back items
        foreach (GameObject item in m_GroundslamHitbox.m_Items)
        {
            // turn raycast for this item back on
            item.layer = GLOBAL_VALUES.LAYER_DEFAULT;
            // raycast to see if we have a los
            RaycastHit hit;
            Vector3    l_pos = m_Agent.Get_Position();
            // if raycast hit returns and you can hit the object
            if ((
                    (Physics.Raycast(l_pos, item.transform.position - l_pos, out hit)) &&
                    (hit.transform.gameObject == item))
                )
            {
                // Get the items rigidbody
                Rigidbody rb = item.GetComponent <Rigidbody>();
                // Punch it at a force depending on the punch
                // direction is the direction away from the point of ground slam and up a bit
                Vector3 dir = Custom_Math_Utils.FindTargetAngle(item.transform.position, m_Agent.Get_Position());
                Vector3 f   = dir * (GLOBAL_VALUES.KNOCKBACK_GROUNDSLAM * GLOBAL_VALUES.KNOCKBACK_PUNCH_ITEM_MULTIPLIER);
                rb.AddForce(f);
            }
        }

        // Jump all items
        if (m_ItemManager != null)
        {
            float base_up_force = 200;
            foreach (Item i in m_ItemManager.m_Items)
            {
                if (!i.BeingCarried())
                {
                    i.itemBody.AddForce(new Vector3(0, base_up_force - Vector3.Distance(i.transform.position, m_Agent.Get_Position()), 0));
                }
            }
        }

        // push back agents
        foreach (GameObject agent in m_GroundslamHitbox.m_Agents)
        {// turn raycast for this item back on
            agent.layer = GLOBAL_VALUES.LAYER_DEFAULT;
            // raycast to see if we have a los
            RaycastHit hit;
            Vector3    l_pos = m_Agent.Get_Position();
            // if raycast hit returns and you can hit the object
            if ((
                    (Physics.Raycast(l_pos, agent.transform.position - l_pos, out hit)) &&
                    (hit.transform.gameObject == agent))
                )
            {
                // Get the agentmanager
                AgentManager vic = agent.GetComponent <CollisionDetection>().m_Manager;
                vic.Drop(false);
                Vector3 dir = Custom_Math_Utils.FindTargetAngle(agent.transform.position, m_Agent.Get_Position());
                Vector3 f   = dir * GLOBAL_VALUES.KNOCKBACK_GROUNDSLAM;
                vic.AddForce(0.2f, f);


                // Add in after agent refactor
                vic.Stun_Agent(GLOBAL_VALUES.STUN_TIME_GROUND_SLAM);
                if (vic.isPlayer())
                {
                    m_Agent.m_StatCollector.Count_Player_Stun();
                    vic.Get_Input().Controller_Rumble(rumble, rumble);
                }
                else if (vic.isAI())
                {
                    if (vic.isSecurityAI())
                    {
                        SecurityAI_Control sec_brain = vic.Get_Input() as SecurityAI_Control;
                        sec_brain.Agro(m_Agent);
                        sec_brain.Stun_Flag = false;
                    }
                    m_Agent.m_StatCollector.Count_AI_Stunned();
                }
            }
        }
        // turn on item and agent raycasts
        foreach (GameObject item in m_GroundslamHitbox.m_Items)
        {
            item.layer = GLOBAL_VALUES.LAYER_DEFAULT;
        }
        foreach (GameObject agent in m_GroundslamHitbox.m_Agents)
        {
            agent.layer = GLOBAL_VALUES.LAYER_DEFAULT;
        }
        foreach (GameObject destruct in m_PunchHitbox.m_Desctructables)
        {
            destruct.GetComponent <Destructable>().DealDamage(2, m_Agent);
        }
    }