/// <summary> /// 造成伤害 /// </summary> /// <param name="attackHurtStruct"></param> public override CalculateHurt.Result GiveAttackHurtStruct(AttackHurtStruct attackHurtStruct) { MonsterControl monsterControl = GetComponent <MonsterControl>(); if (monsterControl != null && monsterControl.monsterDataInfo != null && monsterControl.monsterDataInfo.MonsterBaseAttribute != null) { PhysicDefenseFactor physicDefenseFactor = monsterControl.monsterDataInfo.PhysicDefenseFactor; //物理防御系数 MagicDefenseFactor magicDefenseFactor = monsterControl.monsterDataInfo.MagicDefenseFactor; //魔法防御系数 CalculateHurt.Result result = CalculateHurt.Calculate(attackHurtStruct, monsterControl.thisAttribute, physicDefenseFactor, magicDefenseFactor); monsterControl.GiveHit(); //显示伤害 base.ShowHurt(result, gameObject); //显示怪物的血条 iGameState.ShowMonsterHP = new MonsterHPUIStruct() { monsterName = monsterControl.monsterDataInfo.monsterPrefabName, maxHP = monsterControl.thisAttribute.MaxHP, nowHP = monsterControl.thisAttribute.HP, monsterObj = gameObject }; return(result); } return(default(CalculateHurt.Result)); }
/// <summary> /// 造成伤害 /// </summary> /// <param name="attackHurtStruct"></param> public override CalculateHurt.Result GiveAttackHurtStruct(AttackHurtStruct attackHurtStruct) { IPlayerState iPlayerState = GameState.Instance.GetEntity <IPlayerState>(); IAttributeState playerAttribute = iPlayerState.GetResultAttribute(); PhysicDefenseFactor physicDefenseFactor = new PhysicDefenseFactor()//物理防御系数 { CoefficientRatioReducingDamageFactor = iPlayerState.SelfRoleOfRaceInfoStruct.physicDefenseToHurtRateRatio, ImmunityInjury = iPlayerState.SelfRoleOfRaceInfoStruct.physicQuickToHurtExemptRatio }; MagicDefenseFactor magicDefenseFactor = new MagicDefenseFactor() //魔法防御系数 { CoefficientRatioReducingDamageFactor = iPlayerState.SelfRoleOfRaceInfoStruct.magicDefenseToHurtRateRatio }; CalculateHurt.Result calculateHurtResult = CalculateHurt.Calculate(attackHurtStruct, playerAttribute, physicDefenseFactor, magicDefenseFactor); if (calculateHurtResult.hurt >= 0) { if (calculateHurtResult.hurt != 0) { //减血(因为这里是整合的属性,必须在外部将自身血量减去) iPlayerState.HP -= calculateHurtResult.hurt; //终端咏唱 ISkillState iSkillState = GameState.Instance.GetEntity <ISkillState>(); iSkillState.GetHitToSkillState(); //手柄震动 iPlayerState.SetVibration(0.1f, 0.7f, 0.7f); } //显示伤害 base.ShowHurt(calculateHurtResult, iPlayerState.PlayerObj); } return(calculateHurtResult); }
/// <summary> /// 检测到攻击触发到对象(注意通过该函数实现的都是物理攻击,魔法攻击请在各自的子类中独立实现) /// </summary> /// <param name="iOjbInteractive"></param> protected virtual void CheckTargetResult(IObjInteractive iOjbInteractive) { if (NowCheckFrame == null) { return; } if (attackAnimationTime > NowCheckFrame.endTime || attackAnimationTime < NowCheckFrame.startTime) { return; } if (tempCheckedTargetList.Contains(iOjbInteractive)) { return; } tempCheckedTargetList.Add(iOjbInteractive); //计算伤害 MonsterControl monsterControl = GetComponent <MonsterControl>(); if (monsterControl == null) { return; } IAttributeState iAttributeState = monsterControl.GetMonsterAttributeState(); if (iAttributeState == null) { return; } iAttributeState.PhysicsAttacking *= NowCheckFrame.magnification; AttackHurtStruct attackHurtStruct = new AttackHurtStruct() { attributeState = iAttributeState, hurtFromObj = gameObject, hurtType = EnumHurtType.NormalAction, //怪物的伤害都依照普通攻击来计算(普通攻击和技能的区别暂时不知道) statusLevelDataInfos = new StatusDataInfo.StatusLevelDataInfo[0], //暂时没有附加状态 hurtTransferNum = 0, thisUsedMana = 0 //物理技能没有耗魔 }; iOjbInteractive.GiveAttackHurtStruct(attackHurtStruct); }
/// <summary> /// 具体的计算 /// </summary> /// <param name="from">伤害来自于</param> /// <param name="to">伤害指向</param> /// <param name="physicDefenseFactor">物理防御系数</param> /// <param name="magicDefenseFactor">魔法防御系数</param> public static Result Calculate(AttackHurtStruct from, IAttributeState to, PhysicDefenseFactor physicDefenseFactor, MagicDefenseFactor magicDefenseFactor) { //计算本次伤害造成的结果 Result calculateHurtResult; calculateHurtResult.IsCrit = false; float maxHP = to.MaxHP; //先判断是否命中 float isHitRate = from.attributeState.HitRate - to.EvadeRate; //本次攻击是否命中的概率(0-?(1)) if (isHitRate < 1 && Random.Range(0, 1) > isHitRate) //如果本次攻击有几率命中且本次攻击没有命中则返回 { return(default(Result)); } isHitRate = 1; float baseDamage = 0; //根据攻击防御计算初步的基础伤害 switch (from.hurtType) { case EnumHurtType.Magic: { float hurtRate = 1 + from.attributeState.MagicAttacking * from.MagicAttackFactor.IncreaseRatioInjuryFactor; //伤害倍率 float defenceRate = 1 / (1 + to.MagicResistance * magicDefenseFactor.CoefficientRatioReducingDamageFactor); //减伤倍率 float baseHurt = from.thisUsedMana * from.attributeState.BaseMagicDamage / 25; float otherHurt = (from.attributeState.MagicAttacking - to.MagicResistance) * 0.1f; otherHurt = Mathf.Clamp(otherHurt, 0, float.MaxValue); baseDamage = (baseHurt * defenceRate + otherHurt) * hurtRate; //如果是信仰系魔法还要计算信仰差值..... //暂时空 } break; case EnumHurtType.PhysicSkill: case EnumHurtType.NormalAction: { float hurtExempt = to.Quick * physicDefenseFactor.ImmunityInjury; //额外豁免=敏捷*额外豁免系数 float baseHurt = from.attributeState.BasePhysicDamage - to.BasePhysicDefense - hurtExempt; //基础伤害值= 装备基础伤害-装备基础护甲-额外豁免 baseHurt = Mathf.Clamp(baseHurt, 0, float.MaxValue); //如果小于0则取制为0 float minHurt = from.attributeState.Quick * from.PhysicAttackFactor.MinimumDamageFactor; //最低伤害=敏捷*最低伤害系数 float baseDefHurtRate = 1 / (1 + physicDefenseFactor.CoefficientRatioReducingDamageFactor * to.PhysicsResistance); //受到伤害倍率= 1/(1+减伤倍率系数*防御力) float baseHurtRate = 1 + from.attributeState.PhysicsAttacking * from.PhysicAttackFactor.IncreaseRatioInjuryFactor; //伤害倍率=1+物理攻击力*增伤倍率系数 baseDamage = (baseHurt * baseDefHurtRate + minHurt) * baseHurtRate; //根据公式计算出的最初伤害 = (伤害基础值*受伤害倍率+最低伤害值)*伤害倍率 } break; } //计算暴击 float isCrit = from.attributeState.CritRate; if (from.hurtType != EnumHurtType.Magic && isHitRate >= 1 && Random.Range(0f, 1f) < isCrit)//如果命中并且本次攻击随机到了暴击概率阶段 { calculateHurtResult.IsCrit = true; float critDamageRatio = from.attributeState.CritDamageRatio - to.CriticalDef; critDamageRatio = Mathf.Clamp(critDamageRatio, 0.2f, 10);//将暴击倍率倍率范围限定在0.2到10之间,也就是有可能暴击伤害可能会更低 baseDamage *= critDamageRatio; } //计算格挡 float isEquipBlock = to.EquipBlock; if (isHitRate >= 1 && Random.Range(0f, 1f) < isEquipBlock)//如果命中并且本次随机到了格挡概率阶段 { baseDamage *= 0.7f; } //计算浮动之 float hurtDrift = Random.Range(1f, 1.15f); baseDamage *= hurtDrift; //附加或倍率等处理 //....... to.HP -= baseDamage; calculateHurtResult.hurtRate = baseDamage / maxHP; calculateHurtResult.hurt = baseDamage; if (from.statusLevelDataInfos != null && from.statusLevelDataInfos.Length > 0) { float specialRate = from.attributeState.EffectAffine - to.AbnormalStateResistance; List <StatusDataInfo.StatusLevelDataInfo> tempStatusLevelDataInfos = new List <StatusDataInfo.StatusLevelDataInfo>(); foreach (StatusDataInfo.StatusLevelDataInfo tempStatusLevelDataInfo in from.statusLevelDataInfos) { float tempSpecialRate = Random.Range(0, 100); if (tempSpecialRate < specialRate) { tempStatusLevelDataInfos.Add(tempStatusLevelDataInfo); } } calculateHurtResult.statusDatas = tempStatusLevelDataInfos.ToArray(); } else { calculateHurtResult.statusDatas = new StatusDataInfo.StatusLevelDataInfo[0]; } return(calculateHurtResult); }
public override CalculateHurt.Result GiveAttackHurtStruct(AttackHurtStruct attackHurtStruct) { throw new NotImplementedException(); }
/// <summary> /// 计算物理技能伤害 /// </summary> /// <param name="skillType">技能类型</param> /// <param name="weaponTypeByPlayerState">武器类型</param> /// <param name="physicsSkillStateStruct">物理技能数据</param> /// <param name="innerOrder">当前攻击的阶段</param> /// <param name="target">攻击的目标</param> private bool CalculatePhysicSkillHurt(EnumSkillType skillType, EnumWeaponTypeByPlayerState weaponTypeByPlayerState, PhysicsSkillStateStruct physicsSkillStateStruct, int innerOrder, GameObject target) { if (target == null) { return(true); } InteractiveAsMonster interactiveAsMonster = target.GetComponent <InteractiveAsMonster>(); if (interactiveAsMonster == null) { return(true); } IPlayerState iPlayerState = GameState.Instance.GetEntity <IPlayerState>(); AttackHurtStruct attackHurtStruct = new AttackHurtStruct() { hurtTransferNum = 0, hurtType = EnumHurtType.PhysicSkill, attributeState = physicsSkillStateStruct.AttributeState, hurtFromObj = iPlayerState.PlayerObj, PhysicAttackFactor = new PhysicAttackFactor() { IncreaseRatioInjuryFactor = iPlayerState.SelfRoleOfRaceInfoStruct.physicAttackToDamageRateRatio, MinimumDamageFactor = iPlayerState.SelfRoleOfRaceInfoStruct.physicQuickToMinDamageRatio } }; CalculateHurt.Result hurtResult = interactiveAsMonster.GiveAttackHurtStruct(attackHurtStruct); if (hurtResult.IsCrit || hurtResult.hurtRate > 0.2f) { iPlayerState.SetVibration(0.1f, 0.7f, 0.7f);//设置手柄震动 } //如果命中了则自身的动画造成0.1秒的延迟 IAnimatorState iAnimatorState = GameState.Instance.GetEntity <IAnimatorState>(); if (weaponTypeByPlayerState != EnumWeaponTypeByPlayerState.Arch) { iAnimatorState.PhysicHitMonsterAnimDelay = true; } //停止持续 iAnimatorState.SkillSustainable = false; //如果是冲锋则停止任务 switch (skillType) { case EnumSkillType.ZS03: runTaskStruct_Charge.StopTask(); break; } //设置命中声音 WeaponPhysicHit = (int)weaponTypeByPlayerState; //判断技能类型,有些紧只需要判断一次 switch (skillType) { case EnumSkillType.GJS03: case EnumSkillType.SSS03: case EnumSkillType.ZS03: return(false); default: return(true); } }
/// <summary> /// 计算物理普通攻击伤害 /// </summary> /// <param name="weaponTypeByPlayerState">武器类型</param> /// <param name="iAttribute">攻击时的状态数据</param> /// <param name="innerOrder">当前攻击的阶段</param> /// <param name="target">攻击的目标</param> private bool CalculateNormalActionHurt(EnumWeaponTypeByPlayerState weaponTypeByPlayerState, IAttributeState _iAttribute, int innerOrder, GameObject target) { if (target == null) { return(true); } InteractiveAsMonster interactiveAsMonster = target.GetComponent <InteractiveAsMonster>(); if (interactiveAsMonster == null) { return(true); } IPlayerState iPlayerState = GameState.Instance.GetEntity <IPlayerState>(); IAttributeState iAttribute = ((AttributeStateAdditional)_iAttribute).Clone(); switch (weaponTypeByPlayerState) { case EnumWeaponTypeByPlayerState.SingleHandedSword: if (innerOrder == 3) { iAttribute.PhysicsAttacking *= 1.2f; } break; case EnumWeaponTypeByPlayerState.TwoHandedSword: if (innerOrder == 3) { iAttribute.PhysicsAttacking *= 0.7f; } break; case EnumWeaponTypeByPlayerState.Arch: if (innerOrder == 3) { iAttribute.PhysicsAttacking *= 2f; } break; } AttackHurtStruct attackHurtStruct = new AttackHurtStruct() { hurtTransferNum = 0, hurtType = EnumHurtType.NormalAction, attributeState = iAttribute, hurtFromObj = iPlayerState.PlayerObj, PhysicAttackFactor = new PhysicAttackFactor() { IncreaseRatioInjuryFactor = iPlayerState.SelfRoleOfRaceInfoStruct.physicAttackToDamageRateRatio, MinimumDamageFactor = iPlayerState.SelfRoleOfRaceInfoStruct.physicQuickToMinDamageRatio } }; CalculateHurt.Result hurtResult = interactiveAsMonster.GiveAttackHurtStruct(attackHurtStruct); if (hurtResult.IsCrit || hurtResult.hurtRate > 0.2f) { iPlayerState.SetVibration(0.1f, 0.6f, 0.6f);//设置手柄震动 } //如果命中了则自身的动画造成0.1秒的延迟 IAnimatorState iAnimatorState = GameState.Instance.GetEntity <IAnimatorState>(); if (weaponTypeByPlayerState != EnumWeaponTypeByPlayerState.Arch) { iAnimatorState.PhysicHitMonsterAnimDelay = true; } //停止持续 iAnimatorState.SkillSustainable = false; //设置命中声音 WeaponPhysicHit = (int)weaponTypeByPlayerState; //判断武器类型 switch (weaponTypeByPlayerState)//根据武器类型判断是否还需要下次检测 { case EnumWeaponTypeByPlayerState.Arch: return(false); default: return(true); } }
/// <summary> /// 计算魔法组合技能的伤害 /// </summary> /// <param name="_iAttributeState">伤害计算时使用的属性</param> /// <param name="collisionHitCallbackStruct">碰撞到的对象</param> /// <param name="thisUsedMana">本次技能的耗魔值</param> /// <param name="statusLevelDataInfos">本次技能附加的特殊效果数组</param> /// <param name="skills">本次技能组合</param> /// <returns></returns> private bool CalculateCombineMagicHurt(IAttributeState _iAttributeState, CollisionHitCallbackStruct collisionHitCallbackStruct, float thisUsedMana, StatusDataInfo.StatusLevelDataInfo[] statusLevelDataInfos, EnumSkillType[] skills) { if (collisionHitCallbackStruct.targetObj == null) { return(false); } InteractiveAsMonster interactiveAsMonster = collisionHitCallbackStruct.targetObj.GetComponent <InteractiveAsMonster>(); if (interactiveAsMonster == null) { return(false); } IPlayerState iPlayerState = GameState.Instance.GetEntity <IPlayerState>(); IAttributeState iAttributeState = ((AttributeStateAdditional)_iAttributeState).Clone(); //根据技能设置平摊伤害 if (skills.Length >= 2) { switch (skills[1]) { case EnumSkillType.YSX01: //火元素 switch (skills[0]) { case EnumSkillType.FS02: iAttributeState.BaseMagicDamage /= 4; break; case EnumSkillType.MFS05: iAttributeState.BaseMagicDamage /= 2.5f; break; } break; case EnumSkillType.YSX02: //水元素 switch (skills[0]) { case EnumSkillType.FS02: iAttributeState.BaseMagicDamage /= 1.8f; break; case EnumSkillType.MFS05: iAttributeState.BaseMagicDamage /= 0.85f; break; } break; case EnumSkillType.YSX03: //土元素 switch (skills[0]) { case EnumSkillType.FS02: iAttributeState.BaseMagicDamage /= 1.4f; break; case EnumSkillType.MFS05: iAttributeState.BaseMagicDamage /= 2.5f; break; } break; case EnumSkillType.YSX04: //风元素 switch (skills[0]) { case EnumSkillType.FS02: iAttributeState.BaseMagicDamage /= 4; break; case EnumSkillType.MFS05: iAttributeState.BaseMagicDamage /= 4; break; } break; case EnumSkillType.SM06: //冰元素 switch (skills[0]) { case EnumSkillType.FS02: iAttributeState.BaseMagicDamage /= 1.2f; break; case EnumSkillType.MFS05: iAttributeState.BaseMagicDamage /= 1.2f; break; } break; case EnumSkillType.SM07: //雷元素 switch (skills[0]) { case EnumSkillType.FS02: iAttributeState.BaseMagicDamage /= 5.5f; break; case EnumSkillType.MFS05: iAttributeState.BaseMagicDamage /= 6; break; } break; case EnumSkillType.DSM03: //光元素 switch (skills[0]) { case EnumSkillType.FS02: iAttributeState.BaseMagicDamage /= 1; break; case EnumSkillType.MFS05: iAttributeState.BaseMagicDamage /= 1; break; } break; case EnumSkillType.DSM04: //暗元素 switch (skills[0]) { case EnumSkillType.FS02: iAttributeState.BaseMagicDamage /= 1; break; case EnumSkillType.MFS05: iAttributeState.BaseMagicDamage /= 1; break; } break; } } AttackHurtStruct attackHurtStruct = new AttackHurtStruct() { hurtTransferNum = 0, hurtType = EnumHurtType.Magic, attributeState = iAttributeState, thisUsedMana = thisUsedMana, hurtFromObj = iPlayerState.PlayerObj, statusLevelDataInfos = statusLevelDataInfos, MagicAttackFactor = new MagicAttackFactor() { IncreaseRatioInjuryFactor = iPlayerState.SelfRoleOfRaceInfoStruct.magicAttackToDamageRateRatio } }; CalculateHurt.Result hurtResult = interactiveAsMonster.GiveAttackHurtStruct(attackHurtStruct); if (hurtResult.IsCrit || hurtResult.hurtRate > 0.2f) { iPlayerState.SetVibration(0.1f, 0.8f, 0.8f);//设置手柄震动 } //设置声音 if (skills.Length >= 2)//说明有二阶段技能 { MagicTypeHit = (int)skills[1]; } else { MagicTypeHit = (int)EnumSkillType.MagicCombinedLevel2Start; } return(true); }
public abstract CalculateHurt.Result GiveAttackHurtStruct(AttackHurtStruct attackHurtStruct);