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; } }
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); } }
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; }