/// <summary>
        /// start hit reaction animation
        /// </summary>
        /// <param name="attacker"></param>
        /// <param name="hitType"></param>
        /// <param name="applyHitReaction"></param>
        /// <param name="attackSource"></param>
        private void _startHitReaction(IGameCharacter attacker, int hitType, bool applyHitReaction, int attackSource)
        {
            if (hitType == -1)
            {
                return;
            }

            if (m_Blocking)
            {
                if (m_DefaultWeaponSounds)
                {
                    GameUtils.PlayRandomClipAtPosition(m_DefaultWeaponSounds.blockSounds, transform.position);
                }
                if (applyHitReaction)
                {
                    _end_attack_combo();
                    Vector3 toAttacker = attacker.stats.transform.position - transform.position;
                    m_BodyLookDir      = toAttacker;
                    m_BodyLookDir.y    = 0.0f;
                    transform.rotation = Quaternion.LookRotation(m_BodyLookDir.normalized);


                    string stateName = "BlockHit" + hitType;
                    int    stateID   = Animator.StringToHash(stateName);

                    if (m_Character.animator.HasState(0, stateID))
                    {
                        m_Character.animator.CrossFade(stateID, 0.05f, 0, 0.0f);
                    }
                    else
                    {
                        Debug.LogWarning("state '" + stateName + "' dont exist");
                        m_Character.animator.CrossFade("BlockHit0", 0.05f, 0, 0.0f);
                    }
                }
            }
            else
            {
                if (applyHitReaction)
                {
                    _end_attack_combo();
                    Vector3 toAttacker = attacker.stats.transform.position - transform.position;
                    m_BodyLookDir      = toAttacker;
                    m_BodyLookDir.y    = 0.0f;
                    transform.rotation = Quaternion.LookRotation(m_BodyLookDir.normalized);

                    string stateName = "TakeHit" + hitType;
                    int    stateID   = Animator.StringToHash(stateName);
                    if (m_Character.animator.HasState(0, stateID))
                    {
                        m_Character.animator.CrossFade(stateID, 0.05f, 0, 0.0f);
                    }
                    else
                    {
                        Debug.LogWarning("state '" + stateName + "' dont exist");
                        m_Character.animator.CrossFade("TakeHit", 0.05f, 0, 0.0f);
                    }
                }
            }
        }
        public Quaternion rot_offset = Quaternion.identity;     // rotation offset

        /// <summary>
        /// arrow constructor
        /// </summary>
        /// <param name="_arrowObject"></param>
        public Arrow(GameObject _arrowObject, IGameCharacter _owner)
        {
            if (!_arrowObject)
            {
                Debug.LogError("_arrowObject cannot be null");
            }

            // set to default values
            lifetime        = 0.0f;
            maxLifetime     = 12.0f;
            advanceLifetime = false;
            gobject         = _arrowObject;
            trailObj        = null;
            parent          = null;

            if (_arrowObject.transform.childCount > 0)
            {
                trailObj = _arrowObject.transform.GetChild(0);
                trailObj.gameObject.SetActive(false);
            }
            RigidBody  = gobject.GetComponent <Rigidbody>();
            Collider   = gobject.GetComponent <Collider>();
            owner      = _owner;
            OnArrowHit = null;
        }
        /// <summary>
        /// notify npc that he is attacked
        /// </summary>
        /// <param name="attacker">attacker transform</param>
        /// <param name="hitType">current hit type</param>
        /// <param name="damage">attackers damage</param>
        /// <param name="blocking">ref notify attacker that npc has blocked attack</param>
        /// <returns>success</returns>
        public bool attack_hit_notify(IGameCharacter attacker, int hitType, int attackSource, ref bool blocking,
                                      bool applyHitReaction = true, Vector3?hitVelocity = null, int[] hitParts = null)
        {
            if (!m_Initialized)
            {
                Debug.LogError("component not initialized" + " < " + this.ToString() + ">");
                return(false);
            }

            if (isDead)
            {
                return(false);
            }

            if (!m_Blocking)
            {
                int rnd = Random.Range(0, blockOdds);
                m_Blocking = rnd == 0;
                if (m_Blocking)
                {
                    m_Animator.SetBool(HashIDs.BlockBool /*"pBlock"*/, true);
                    m_BlockTimer = 0.0f;
                }
            }



            _end_attack_combo();
            m_InCombat = true;
            blocking   = m_Blocking;

            m_Character.fullStop();

            _startHitReaction(attacker, hitType, applyHitReaction, attackSource);

            int damageReceived = GameUtils.CalculateDamage(this, attacker, m_Blocking);

            if (m_Stats.currentHealth <= 0)
            {
                m_Player.attack_end_notify(this, m_CurrentAttackType);

                m_InCombat = false;
                m_Character.animator.SetBool(/*"pAttack1"*/ HashIDs.Attack1Bool, false);
                m_Attack_combo_started = false;
                m_Kooldown             = true;
                m_AttackTimer          = 0.0f;
                attackSweepBody.gameObject.SetActive(false);
                m_Ragdoll.startRagdoll(hitParts, hitVelocity, hitVelocity * 0.025f);
            }
            if (!blocking)
            {
                if (m_DamageUI)
                {
                    m_DamageUI.setText("-" + damageReceived);
                }
            }

            return(true);
        }
        /// <summary>
        /// unity Awake method
        /// is called when the script instance is being loaded
        /// </summary>
        void Awake()
        {
            if (!ParentObject)
            {
                Debug.LogError("BodyColliderScript has not assigned 'ParentObject'"); return;
            }

            // get game character interface
            m_GCharacterOwner = ParentObject.GetComponent <IGameCharacter>();
        }
 /// <summary>
 ///  OnStateExit is called when a transition ends and the state machine finishes evaluating this state
 /// </summary>
 /// <param name="animator">current animator</param>
 /// <param name="stateInfo">state info struct</param>
 /// <param name="layerIndex">animator layer index</param>
 override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
 {
     if (character == null)
     {
         character = animator.gameObject.GetComponent <IGameCharacter>();
     }
     if (character != null)
     {
         character.takingHit = false;
     }
 }
Пример #6
0
        /// <summary>
        /// calculte damage received based on player and attacker stats
        /// </summary>
        /// <param name="defenderStats"></param>
        /// <param name="attackerStats"></param>
        /// <param name="blocking"></param>
        /// <param name="perHitAdditionalDamage"></param>
        public static int CalculateDamage(IGameCharacter defender, IGameCharacter attacker, bool blocking /*, int damage*/)
        {
            if (blocking)
            {
                return(0);          //blocking 伤害为0
            }
            int damageAccum   = attacker.stats.currentDamage + attacker.stats.attack;
            int damageReduced = Mathf.Max((damageAccum - defender.stats.defence), 1);

            defender.stats.decreaseHealth(damageReduced);
            return(damageReduced);
        }
        /// <summary>
        /// attack procedure
        /// </summary>
        /// <param name="attack"></param>
        private void _attackCombo(bool attack)
        {
#if DEBUG_INFO
            if (!m_Initialized)
            {
                Debug.LogError("Component not initialized < " + this.ToString() + " >");
                return;
            }
#endif

            bool isAttacking = m_Animator.GetBool(/*"pAttack1"*/ HashIDs.Attack1Bool);

            if (attack)
            {
                if (m_Character.isOnGround)
                {
                    if (!m_Attack_combo_started && !isAttacking && !m_AttackStateUnderway)
                    {
                        IGameCharacter npc = m_PrimaryTargetNPC;
#if TESTING_USE_ALL_NPC_ARRAY
                        m_PrimaryTargetNPC = _getPrimaryTarget();
#else
                        m_PrimaryTargetNPC = _getPrimaryTargetInZone();
#endif
                        if (m_PrimaryTargetNPC != npc)
                        {
                            if (npc != null)
                            {
                                npc.attack_end_notify(this, 1);
                            }
                        }
                        m_BreakCombo = false;
                        m_Character.turnTransformToDirection(m_TargetDirection);
                        m_Animator.SetBool(/*"pAttack1"*/ HashIDs.Attack1Bool, true);
                        m_Attack_combo_started = true;
                        if (m_PrimaryTargetNPC != null)
                        {
                            m_InCombat = true;
                            if (enableJumpToTarget)
                            {
                                _jumpToTarget();
                            }
                        }
                    }
                    else
                    {
                        m_BreakCombo = false;
                    }
                }
            }
        }
 /// <summary>
 /// start trigger interaction
 /// </summary>
 /// <param name="character">character interacting with trigger</param>
 /// <param name="limbsIK">ik helper</param>
 /// <param name="use">use flag</param>
 /// <param name="jump">jump flag</param>
 /// <param name="v">vertical value</param>
 /// <param name="h">horizontal value</param>
 /// <returns>all succeded</returns>
 public override bool start(TPCharacter character, IKHelper limbsIK, bool use, bool secondaryUse, bool jump, float v, float h)
 {
     if (use)
     {
         IGameCharacter icharacter = character.GetComponent <IGameCharacter>();
         if (icharacter != null)
         {
             icharacter.setNewItem(item);
         }
     }
     if (secondaryUse)
     {
         IGameCharacter icharacter = character.GetComponent <IGameCharacter>();
         if (icharacter != null)
         {
             icharacter.setSecondaryItem(item);
         }
     }
     return(false);
 }
Пример #9
0
        /// <summary>
        /// creates arrow and sets it up in hand
        /// </summary>
        /// <param name="arrowPrefab">arrow prefab to instantiate</param>
        /// <param name="arrowAttachBone">transform on which to attach arrow</param>
        /// <returns></returns>
        public static Arrow CreateArrow(
            GameObject arrowPrefab,
            Transform arrowAttachBone,
            float maxLifetime,
            float arrowLength,
            LayerMask layers,
            IGameCharacter _owner)
        {
#if DEBUG_INFO
            if (m_arrowPool == null)
            {
                Debug.LogError("object cannot be null"); return(null);
            }
            if (m_active_arrows == null)
            {
                Debug.LogError("object cannot be null"); return(null);
            }
            if (!arrowPrefab)
            {
                Debug.LogError("_currentArrowPrefab is null. Cannot create arrow"); return(null);
            }
            if (!arrowAttachBone)
            {
                Debug.LogError("object cannot be null"); return(null);
            }
#endif

            ArrowUnit newArrowUnit = null;

            // try to find available arrow
            for (int i = 0; i < m_arrowPool.Count; i++)
            {
                if (!m_arrowPool[i].inUse)
                {
                    newArrowUnit       = m_arrowPool[i];
                    newArrowUnit.inUse = true;

                    break;
                }
            }

            // if not create new
            if (newArrowUnit == null)
            {
                GameObject arrowObject =
                    (GameObject)MonoBehaviour.Instantiate(arrowPrefab);
                Arrow newArrow = new Arrow(arrowObject, _owner);
                newArrowUnit = new ArrowUnit(newArrow);
                m_arrowPool.Add(newArrowUnit);

                newArrow.gobject.name = arrowPrefab.name + m_arrowPool.Count;

#if DEBUG_ARROW_PATH
                arrow_debug_paths[newArrow] = new List <Vector3>();
#endif
            }


#if DEBUG_INFO
            if (newArrowUnit == null)
            {
                Debug.LogError("creating arrow failed."); return(null);
            }
#endif
            newArrowUnit.arrow.gobject.transform.position = Vector3.zero;
            newArrowUnit.arrow.gobject.transform.rotation = Quaternion.identity;
            newArrowUnit.arrow.gobject.transform.SetParent(arrowAttachBone, false);
            newArrowUnit.arrow.gobject.SetActive(true);
            newArrowUnit.arrow.position                   = Vector3.zero;
            newArrowUnit.arrow.prevPosition               = Vector3.zero;
            newArrowUnit.arrow.direction                  = Vector3.zero;
            newArrowUnit.arrow.fly_time                   = 0.0f;
            newArrowUnit.arrow.state                      = Arrow.STATES.READY;
            newArrowUnit.arrow.speed                      = 0.0f;
            newArrowUnit.arrow.advanceLifetime            = false;
            newArrowUnit.arrow.RigidBody.detectCollisions = false;
            newArrowUnit.arrow.RigidBody.isKinematic      = true;
            newArrowUnit.arrow.Collider.enabled           = false;
            newArrowUnit.arrow.layers                     = layers;
            newArrowUnit.arrow.length                     = arrowLength;
            newArrowUnit.arrow.maxLifetime                = maxLifetime;


            m_active_arrows.Add(newArrowUnit.arrow);

            return(newArrowUnit.arrow);
        }
Пример #10
0
 public void SetMaster(IGameCharacter master)
 {
     _someoneWhoShotThisProjectile = master;
 }
 /// <summary>
 /// notify npc to attack combo end
 /// </summary>
 /// <param name="attacker">attacker transform</param>
 /// <param name="hitType">current attack type</param>
 public void attack_end_notify(IGameCharacter attacker, int hitType)
 {
     m_InCombat = false;
 }
 /// <summary>
 /// notify npc of start attack
 /// </summary>
 /// <param name="attacker">attacker game character</param>
 /// <param name="hitType">attack hit type</param>
 public void attack_start_notify(IGameCharacter attacker, int hitType)
 {
 }
Пример #13
0
 public void SetMaster(IGameCharacter master)
 {
     _master = master;
 }
        /// <summary>
        /// attack procedure
        /// </summary>
        /// <param name="attack"></param>
        /// <param name="direction2cursor"></param>
        private void _attackCombo(bool attack, Vector3 direction2cursor)
        {
#if DEBUG_INFO
            if (!m_Initialized)
            {
                Debug.LogError("Component not initialized < " + this.ToString() + " >");
                return;
            }
#endif

            bool isAttacking = m_TopDownPlayer.animator.GetBool(/*"pAttack1"*/ HashIDs.Attack1Bool);

            if (attack)
            {
                if (m_TopDownPlayer.character.isOnGround)
                {
                    m_TopDownPlayer.stop();

                    m_TargetDirection = direction2cursor;
                    float angleDiff = Vector3.Angle(m_PrevTargetDirection, m_TargetDirection);
                    if (angleDiff > CHANGE_TARGET_ANGLE_BUFFER)
                    {
                        m_ChangeTarget = true;
                    }
                    m_PrevTargetDirection = m_TargetDirection;

                    bool attackState = m_TopDownPlayer.animator.GetCurrentAnimatorStateInfo(0).IsName("AttackCombo");

                    if (!m_Attack_combo_started && !isAttacking && !attackState)
                    {
                        IGameCharacter npc = m_PrimaryTargetNPC;
#if TESTING_USE_ALL_NPC_ARRAY
                        m_PrimaryTargetNPC = _getPrimaryTarget();
#else
                        m_PrimaryTargetNPC = _getPrimaryTargetInZone();
#endif
                        if (m_PrimaryTargetNPC != npc)
                        {
                            if (npc != null)
                            {
                                npc.attack_end_notify(this, 1);
                            }
                        }
                        m_BreakCombo = false;
                        m_TopDownPlayer.character.turnTransformToDirection(m_TargetDirection);
                        m_TopDownPlayer.animator.SetBool(/*"pAttack1"*/ HashIDs.Attack1Bool, true);
                        m_Attack_combo_started = true;
                        if (m_PrimaryTargetNPC != null)
                        {
                            m_InCombat = true;
                            if (enableJumpToTarget)
                            {
                                _jumpToTarget();
                            }
                        }
                    }
                    else
                    {
                        m_BreakCombo = false;
                    }
                }
            }
        }