public SkillParam(SkillAimType aimType, E_Unit target, Vector2 direciton, Vector2 position) { m_aimType = aimType; m_target = target; m_direction = direciton; m_position = position; }
/// <summary> /// client的角色开始释放技能 /// server需要通知视野内其他client播放动画 /// 并添加待结算技能计时, 计时结束后进入技能结算 /// </summary> public void CommandApplyCastSkillBegin(int netId, short skillId, NO_SkillParam parmNo, int[] hitTargetNetIdArr) { // 获取释放者, 技能, 技能参数, 作用目标列表 E_Character charObj = EM_Character.s_instance.GetCharacterByNetworkId(netId); E_Skill skill = EM_Skill.s_instance.GetCharacterSkillByIdAndNetworkId(skillId, netId); E_Unit targetObj = EM_Sight.s_instance.GetUnitVisibleByNetworkId(parmNo.m_targetNetworkId); if (charObj == null || skill == null) { return; } if (skill.m_skillLevel == 0) { return; } List <E_Unit> targetList = new List <E_Unit> (); for (int i = 0; i < hitTargetNetIdArr.Length; i++) { var target = EM_Sight.s_instance.GetUnitVisibleByNetworkId(hitTargetNetIdArr[i]); if (target == null) { continue; } targetList.Add(target); } GL_Skill.s_instance.NotifyCastSkill(charObj, skill, targetList); // 向Client发送CastBegin事件 var otherList = EM_Sight.s_instance.GetInSightCharacterNetworkId(netId, true); m_networkService.SendServerCommand(SC_ApplyAllCastSkillBegin.Instance(otherList, netId, skillId, parmNo)); }
public void NotifySkillSettle(E_Unit self, E_MonsterSkill skill, IReadOnlyList <E_Unit> targetList) { for (int i = 0; i < targetList.Count; i++) { GL_UnitBattleAttribute.s_instance.NotifyApplyEffect(skill.m_SkillEffect, skill.m_SkillId, self, targetList[i]); } }
public IReadOnlyList <E_Unit> GetTargetList(E_Unit self, E_MonsterSkill skill, SkillParam skillParm) { EffectTargetChooserBase targetChooser = m_targetChooserDict[skill.m_AimType]; targetChooser.Reset(skill.m_TargetCamp, skill.m_TargetNumber, skill.m_DamageParamList); targetChooser.GetEffectTargets(self, skillParm, m_targetList); return(m_targetList); }
public CampType GetCampType(E_Unit self, E_Unit target) { if (self == target) { return(CampType.SELF); } return(CampType.ENEMY); }
public void NotifyApplyEffect(DE_Effect effectDe, short animId, E_Unit caster, E_Unit target) { if (target.m_IsDead) { return; } m_effectStage.InitWithCasterAndTarget(effectDe, animId, caster, target); // Client m_networkService.SendServerCommand(SC_ApplyAllEffect.Instance( EM_Sight.s_instance.GetInSightCharacterNetworkId(target.m_networkId, true), target.m_networkId, m_effectStage.GetNo())); // 若命中 if (m_effectStage.m_hit) { AttachHatred(target, caster, m_effectStage.m_hatred); AttachHpAndMpChange(target, caster, m_effectStage.m_deltaHp, m_effectStage.m_deltaMp); AttachStealHp(target, caster, m_effectStage.m_deltaHp); AttachStatus(target, caster, m_effectStage.m_statusIdAndValueAndTimeArr); } }
public override SkillParam GetSkillParam(E_Unit self, E_Unit aimedTarget) { return(new SkillParam(m_AimType, aimedTarget, Vector2.Zero, aimedTarget.m_position)); }
private void AttachHpAndMpChange(E_Unit target, E_Unit caster, int dHp, int dMp) { target.m_curHp = Math.Max(0, Math.Min(target.m_MaxHp, target.m_curHp + dHp)); target.m_curMp = Math.Max(0, Math.Min(target.m_MaxMp, target.m_curMp + dMp)); if (dHp >= 0 && dMp >= 0) { return; } // 统计伤害量 int newDmg = -dHp; target.m_isAttackedTimer = MyTimer.s_CurTime.Ticked(c_isAttackedLastTime); int oriDmg; if (!target.m_dmgDict.TryGetValue(caster.m_networkId, out oriDmg)) { oriDmg = 0; } target.m_dmgDict[caster.m_networkId] = oriDmg + newDmg; if (caster.m_UnitType == ActorUnitType.PLAYER && target.m_UnitType == ActorUnitType.MONSTER && ((target as E_Monster).m_MonsterType == MonsterType.BOSS || (target as E_Monster).m_MonsterType == MonsterType.FINAL_BOSS)) { GL_BossDamage.s_instance.NotifyBossAttacked(target.m_networkId, caster as E_Character, newDmg); } // 若单位死亡 if (target.m_IsDead) { target.Dead(); // 处理物品掉落 if (target.m_UnitType == ActorUnitType.MONSTER) { GL_Item.s_instance.NotifyMonsterDropLegacy(target as E_Monster, caster); } if (target.m_UnitType == ActorUnitType.PLAYER) { GL_Item.s_instance.NotifyCharacterDropLegacy(target as E_Character, caster); } // client m_networkService.SendServerCommand(SC_ApplyAllDead.Instance( EM_Sight.s_instance.GetInSightCharacterNetworkId(target.m_networkId, true), caster.m_networkId, target.m_networkId )); // log if (target.m_UnitType == ActorUnitType.MONSTER && caster.m_UnitType == ActorUnitType.PLAYER) { GL_MissionLog.s_instance.NotifyLogKillMonster(caster.m_networkId, ((E_Monster)target).m_MonsterId); } // 通知 CharacterAttr 与 钱 if (caster.m_UnitType == ActorUnitType.PLAYER) { int expGain = 0; expGain += target.m_Level * 10; expGain += target.m_Defence / 10; expGain += target.m_Resistance / 10; if (expGain > 0) { GL_CharacterAttribute.s_instance.NotifyGainExperience(caster as E_Character, expGain); } long cyGain = 0; cyGain += target.m_Level * 2; cyGain += target.m_Attack / 20; cyGain += target.m_Magic / 20; if (cyGain > 0) { GL_Wallet.s_instance.NotifyUpdateVirtualCurrencyOnline(caster.m_networkId, (caster as E_Character).m_characterId, cyGain); } } } }
public void TickPerSecond(E_Status status, E_Unit target) { target.m_curMp += (int)status.m_value; }
public void NotifySkillSettle(E_Unit self, E_MonsterSkill skill, SkillParam parm) { NotifySkillSettle(self, skill, m_targetStage.GetTargetList(self, skill, parm)); }
private void AttachStatus(E_Unit target, E_Unit caster, (short, float, float) [] statusIdAndValueAndTimeArr)
public override void Tick(float dT) { // 每秒变化 (仇恨消失) (每秒回血回蓝) (Status) m_secondTimer += dT; if (m_secondTimer >= 1.0f) { m_secondTimer -= 1.0f; // 处理仇恨消失 var unitEn = EM_Sight.s_instance.GetUnitVisibleEnumerator(); while (unitEn.MoveNext()) { // 无伤害信息 if (unitEn.Current.m_dmgDict.Count == 0) { continue; } // 若已死亡 if (unitEn.Current.m_IsDead) { unitEn.Current.m_dmgDict.Clear(); continue; } // 若不在被攻击状态 if (MyTimer.CheckTimeUp(unitEn.Current.m_isAttackedTimer)) { unitEn.Current.m_dmgDict.Clear(); continue; } var hatredEn = unitEn.Current.m_dmgDict.GetEnumerator(); var hTarRemoveList = new List <int> (); while (hatredEn.MoveNext()) { // 仇恨目标下线或死亡 var tar = EM_Sight.s_instance.GetUnitVisibleByNetworkId(hatredEn.Current.Key); if (tar == null || tar.m_IsDead) { hTarRemoveList.Add(hatredEn.Current.Key); continue; } } for (int i = 0; i < hTarRemoveList.Count; i++) { unitEn.Current.m_dmgDict.Remove(hTarRemoveList[i]); } } // 每秒回血回蓝 unitEn = EM_Sight.s_instance.GetUnitVisibleEnumerator(); while (unitEn.MoveNext()) { if (unitEn.Current.m_IsDead) { continue; } int newHP = unitEn.Current.m_curHp + unitEn.Current.m_DeltaHpPerSecond; int newMP = unitEn.Current.m_curMp + unitEn.Current.m_DeltaMpPerSecond; unitEn.Current.m_curHp = Math.Max(Math.Min(newHP, unitEn.Current.m_MaxHp), 0); unitEn.Current.m_curMp = Math.Max(Math.Min(newMP, unitEn.Current.m_MaxMp), 0); } // 移除超时的状态 计算状态 var allUnitStatusEn = EM_Status.s_instance.GetAllUnitStatusEn(); while (allUnitStatusEn.MoveNext()) { int netId = allUnitStatusEn.Current.Key; var statusList = allUnitStatusEn.Current.Value; E_Unit unit = EM_Sight.s_instance.GetUnitVisibleByNetworkId(netId); if (unit == null) { continue; } var statusToRemoveList = new List <int> (); for (int i = 0; i < statusList.Count; i++) { if (MyTimer.CheckTimeUp(statusList[i].m_endTime)) { statusToRemoveList.Add(i); } else { m_statusHandlerDict[statusList[i].m_Type].TickPerSecond(statusList[i], unit); } } for (int i = 0; i < statusToRemoveList.Count; i++) { m_statusHandlerDict[statusList[statusToRemoveList[i]].m_Type].Remove(statusList[statusToRemoveList[i]], unit); } EM_Status.s_instance.RemoveOrderedStatus(unit.m_networkId, statusToRemoveList); } } }
public void AttachHatred(E_Unit target, E_Unit caster, float hatred) { // 仇恨 (伤害列表) // xjb 仇恨 现在暂时使用 E_Unit.m_netIdAndDamageDict 来记录 }
/// <summary> /// 根据目标完善技能参数 /// </summary> /// <returns></returns> public abstract SkillParam GetSkillParam(E_Unit self, E_Unit aimedTarget);
public void Attach(E_Status status, E_Unit target, E_Unit caster) { }
public void TickPerSecond(E_Status status, E_Unit target) { }
public void Remove(E_Status status, E_Unit target) { }
public void InitWithCasterAndTarget(DE_Effect effectDe, short animId, E_Unit caster, E_Unit target) { m_de = effectDe; m_animId = animId; // 计算命中 float hitRate = (100 + effectDe.m_hitRate) * caster.m_HitRate * 0.01f; m_hit = MyRandom.NextInt(1, 101) <= hitRate; if (m_hit) { // 计算基础伤害 (或能量剥夺) m_deltaHp = effectDe.m_deltaHp; m_deltaMp = effectDe.m_deltaMp; for (int i = 0; i < effectDe.m_attrBonus.Count; i++) { switch (effectDe.m_attrBonus[i].Item1) { case ActorUnitConcreteAttributeType.ATTACK: m_deltaHp = m_deltaHp + (int)(caster.m_Attack * effectDe.m_attrBonus[i].Item2); break; case ActorUnitConcreteAttributeType.MAGIC: m_deltaHp = m_deltaHp + (int)(caster.m_Magic * effectDe.m_attrBonus[i].Item2); break; case ActorUnitConcreteAttributeType.MAX_HP: m_deltaHp = m_deltaHp + (int)(caster.m_MaxHp * effectDe.m_attrBonus[i].Item2); break; case ActorUnitConcreteAttributeType.MAX_MP: m_deltaHp = m_deltaHp + (int)(caster.m_MaxMp * effectDe.m_attrBonus[i].Item2); break; } } // 计算暴击 float criticalRate = effectDe.m_criticalRate * caster.m_CriticalRate * 0.01f; float bonus = criticalRate > 1?criticalRate - 1:0; m_critical = MyRandom.NextInt(1, 101) <= criticalRate; if (m_critical) { m_deltaHp = (int)(m_deltaHp * (1f + (float)caster.m_CriticalBonus * 0.01f + 2 * bonus)); } if (m_deltaHp < 0) { switch (effectDe.m_type) { case EffectType.PHYSICS: m_deltaHp = GetDamage(m_deltaHp, target.m_Defence); break; case EffectType.MAGIC: m_deltaHp = GetDamage(m_deltaHp, target.m_Resistance); break; } } // 减伤+易伤 if (m_deltaHp < 0) { if (effectDe.m_type == EffectType.PHYSICS) { m_deltaHp = (int)(m_deltaHp * (target.m_PhysicsVulernability * 0.01f + 1) * (1 - target.m_DamageReduction * 0.01f)); } else { m_deltaHp = (int)(m_deltaHp * (target.m_MagicVulernability * 0.01f + 1) * (1 - target.m_DamageReduction * 0.01f)); } } // 计算状态 m_statusIdAndValueAndTimeArr = new (short, float, float) [effectDe.m_statusIdAndValueAndTimeList.Count];
public virtual bool InCastRange(E_Unit self, float castRange, E_Unit aimedTarget) { return((self.m_position - aimedTarget.m_position).LengthSquared() <= castRange * castRange); }