Beispiel #1
0
        protected virtual void ApplySkill(Skill skill, short level, bool isLeftHand, CharacterItem weapon, DamageInfo damageInfo, Dictionary <DamageElement, MinMaxFloat> allDamageAmounts, bool hasAimPosition, Vector3 aimPosition)
        {
            // Quit function when on apply skill will override default apply skill functionality
            if (skill.OnApplySkill(this, level, isLeftHand, weapon, damageInfo, allDamageAmounts, hasAimPosition, aimPosition))
            {
                return;
            }

            switch (skill.skillType)
            {
            case SkillType.Active:
                ApplySkillBuff(skill, level);
                ApplySkillSummon(skill, level);
                if (skill.skillAttackType != SkillAttackType.None)
                {
                    CharacterBuff debuff = CharacterBuff.Empty;
                    if (skill.isDebuff)
                    {
                        debuff = CharacterBuff.Create(BuffType.SkillDebuff, skill.DataId, level);
                    }
                    // TODO: some skill type will not able to change aim position by controller
                    if (!hasAimPosition && HasAimPosition)
                    {
                        hasAimPosition = true;
                        aimPosition    = AimPosition;
                    }
                    LaunchDamageEntity(isLeftHand, weapon, damageInfo, allDamageAmounts, debuff, skill.hitEffects.Id, hasAimPosition, aimPosition, Vector3.zero);
                }
                break;
            }
        }
Beispiel #2
0
        public virtual void GetUsingSkillData(
            Skill skill,
            short level,
            ref bool isLeftHand,
            out AnimActionType animActionType,
            out int skillOrWeaponTypeDataId,
            out int animationIndex,
            out CharacterItem weapon,
            out float triggerDuration,
            out float totalDuration,
            out DamageInfo damageInfo,
            out Dictionary <DamageElement, MinMaxFloat> allDamageAmounts)
        {
            // Initialize data
            animActionType          = AnimActionType.None;
            skillOrWeaponTypeDataId = 0;
            animationIndex          = 0;
            weapon           = this.GetAvailableWeapon(ref isLeftHand);
            triggerDuration  = 0f;
            totalDuration    = 0f;
            damageInfo       = null;
            allDamageAmounts = new Dictionary <DamageElement, MinMaxFloat>();
            // Prepare skill data
            if (skill == null)
            {
                return;
            }
            // Prepare weapon data
            Item       weaponItem = weapon.GetWeaponItem();
            WeaponType weaponType = weaponItem.WeaponType;
            SkillActivateAnimationType useSkillActivateAnimationType = CharacterModel.UseSkillActivateAnimationType(skill);

            // Prepare animation
            if (useSkillActivateAnimationType == SkillActivateAnimationType.UseAttackAnimation && skill.skillAttackType != SkillAttackType.None)
            {
                // If there is no cast animations
                // Assign data id
                skillOrWeaponTypeDataId = weaponType.DataId;
                // Assign animation action type
                animActionType = !isLeftHand ? AnimActionType.AttackRightHand : AnimActionType.AttackLeftHand;
                // Random animation
                if (!isLeftHand)
                {
                    CharacterModel.GetRandomRightHandAttackAnimation(skillOrWeaponTypeDataId, out animationIndex, out triggerDuration, out totalDuration);
                }
                else
                {
                    CharacterModel.GetRandomLeftHandAttackAnimation(skillOrWeaponTypeDataId, out animationIndex, out triggerDuration, out totalDuration);
                }
            }
            else if (useSkillActivateAnimationType == SkillActivateAnimationType.UseActivateAnimation)
            {
                // Assign data id
                skillOrWeaponTypeDataId = skill.DataId;
                // Assign animation action type
                animActionType = AnimActionType.Skill;
                // Random animation
                CharacterModel.GetSkillActivateAnimation(skillOrWeaponTypeDataId, out triggerDuration, out totalDuration);
            }
            // If it is attack skill
            if (skill.skillAttackType != SkillAttackType.None)
            {
                switch (skill.skillAttackType)
                {
                case SkillAttackType.Normal:
                    // Assign damage data
                    damageInfo = skill.damageInfo;
                    // Calculate all damages
                    allDamageAmounts = weaponItem.GetDamageAmountWithInflictions(weapon.level, weapon.GetEquipmentBonusRate(), this, skill.GetWeaponDamageInflictions(level));
                    // Sum damage with additional damage amounts
                    allDamageAmounts = GameDataHelpers.CombineDamages(
                        allDamageAmounts,
                        skill.GetDamageAmount(level, this));
                    // Sum damage with skill damage
                    allDamageAmounts = GameDataHelpers.CombineDamages(
                        allDamageAmounts,
                        skill.GetAdditionalDamageAmounts(level));
                    break;

                case SkillAttackType.BasedOnWeapon:
                    // Assign damage data
                    damageInfo = weaponType.damageInfo;
                    // Calculate all damages
                    allDamageAmounts = weaponItem.GetDamageAmountWithInflictions(weapon.level, weapon.GetEquipmentBonusRate(), this, skill.GetWeaponDamageInflictions(level));
                    // Sum damage with additional damage amounts
                    allDamageAmounts = GameDataHelpers.CombineDamages(
                        allDamageAmounts,
                        skill.GetAdditionalDamageAmounts(level));
                    break;
                }
                allDamageAmounts = GameDataHelpers.CombineDamages(
                    allDamageAmounts,
                    CacheIncreaseDamages);
            }
        }
Beispiel #3
0
        private IEnumerator UseSkillRoutine(
            Skill skill,
            short level,
            AnimActionType animActionType,
            int skillOrWeaponTypeDataId,
            int animationIndex,
            float triggerDuration,
            float totalDuration,
            bool isLeftHand,
            CharacterItem weapon,
            DamageInfo damageInfo,
            Dictionary <DamageElement, MinMaxFloat> allDamageAmounts,
            bool hasAimPosition,
            Vector3 aimPosition)
        {
            if (onUseSkillRoutine != null)
            {
                onUseSkillRoutine.Invoke(skill, level, animActionType, skillOrWeaponTypeDataId, animationIndex, triggerDuration, totalDuration, isLeftHand, weapon, damageInfo, allDamageAmounts, hasAimPosition, aimPosition);
            }

            // Set doing action data
            isCastingSkillCanBeInterrupted = skill.canBeInterruptedWhileCasting;
            isCastingSkillInterrupted      = false;

            float castDuration = skill.GetCastDuration(level);

            if (castDuration > 0f)
            {
                // Play casting effects on clients
                RequestPlayEffect(skill.castEffects.Id);

                // Tell clients that character is casting
                RequestSkillCasting(skill.DataId, castDuration);

                yield return(new WaitForSecondsRealtime(castDuration));
            }

            // If skill casting not interrupted, continue doing action
            if (!isCastingSkillInterrupted || !isCastingSkillCanBeInterrupted)
            {
                // Play animation on clients
                RequestPlayActionAnimation(animActionType, skillOrWeaponTypeDataId, (byte)animationIndex);

                // Update skill usage states
                CharacterSkillUsage newSkillUsage = CharacterSkillUsage.Create(SkillUsageType.Skill, skill.DataId);
                newSkillUsage.Use(this, level);
                skillUsages.Add(newSkillUsage);

                yield return(new WaitForSecondsRealtime(triggerDuration));

                // Reduce ammo amount
                if (skill.skillAttackType != SkillAttackType.None)
                {
                    Dictionary <DamageElement, MinMaxFloat> increaseDamages;
                    ReduceAmmo(weapon, isLeftHand, out increaseDamages);
                    if (increaseDamages != null)
                    {
                        allDamageAmounts = GameDataHelpers.CombineDamages(allDamageAmounts, increaseDamages);
                    }
                }

                ApplySkill(skill, level, isLeftHand, weapon, damageInfo, allDamageAmounts, hasAimPosition, aimPosition);
                yield return(new WaitForSecondsRealtime(totalDuration - triggerDuration));
            }
            isAttackingOrUsingSkill = false;
        }
        private IEnumerator AttackRoutine(
            AnimActionType animActionType,
            int weaponTypeDataId,
            int animationIndex,
            float triggerDuration,
            float totalDuration,
            bool isLeftHand,
            CharacterItem weapon,
            DamageInfo damageInfo,
            Dictionary <DamageElement, MinMaxFloat> allDamageAmounts,
            bool hasAimPosition,
            Vector3 aimPosition)
        {
            if (onAttackRoutine != null)
            {
                onAttackRoutine.Invoke(animActionType, weaponTypeDataId, animationIndex, triggerDuration, totalDuration, isLeftHand, weapon, damageInfo, allDamageAmounts);
            }

            // Play animation on clients
            RequestPlayActionAnimation(animActionType, weaponTypeDataId, (byte)animationIndex);

            yield return(new WaitForSecondsRealtime(triggerDuration));

            // Reduce ammo amount
            Dictionary <DamageElement, MinMaxFloat> increaseDamages;

            ReduceAmmo(weapon, isLeftHand, out increaseDamages);
            if (increaseDamages != null)
            {
                allDamageAmounts = GameDataHelpers.CombineDamages(allDamageAmounts, increaseDamages);
            }

            // If no aim position set with attack function get aim position which set from client-controller if existed
            if (!hasAimPosition && HasAimPosition)
            {
                hasAimPosition = true;
                aimPosition    = AimPosition;
            }

            byte    fireSpread  = 0;
            Vector3 fireStagger = Vector3.zero;

            if (weapon != null && weapon.GetWeaponItem() != null)
            {
                Item weaponItem = weapon.GetWeaponItem();
                // For monsters, their weapon can be null so have to avoid null exception
                fireSpread  = weaponItem.fireSpread;
                fireStagger = weaponItem.fireStagger;
            }

            Vector3 stagger;

            for (int i = 0; i < fireSpread + 1; ++i)
            {
                stagger = new Vector3(Random.Range(-fireStagger.x, fireStagger.x), Random.Range(-fireStagger.y, fireStagger.y));
                LaunchDamageEntity(
                    isLeftHand,
                    weapon,
                    damageInfo,
                    allDamageAmounts,
                    CharacterBuff.Empty,
                    0,
                    hasAimPosition,
                    aimPosition,
                    stagger);
            }
            RequestPlayWeaponLaunchEffect(isLeftHand);
            yield return(new WaitForSecondsRealtime(totalDuration - triggerDuration));

            isAttackingOrUsingSkill = false;
        }