/// <summary> /// /// </summary> /// <param name="type"></param> /// <param name="activeType"></param> /// <param name="fight"></param> /// <param name="caster"></param> /// <param name="castInfos"></param> /// <param name="cell"></param> /// <param name="duration"></param> /// <param name="actionId"></param> /// <param name="canGoThrough"></param> /// <param name="canStack"></param> /// <param name="hide"></param> protected AbstractActivableObject(FightObstacleTypeEnum type, ActiveType activeType, AbstractFight fight, AbstractFighter caster, CastInfos castInfos, int cell, int duration, int actionId, bool canGoThrough, bool canStack, bool hide = false) { m_fight = fight; m_caster = caster; m_spellId = castInfos.SpellId; m_actionSpell = SpellManager.Instance.GetTemplate(castInfos.Value1); m_actionEffect = m_actionSpell.GetLevel(castInfos.Value2); Cell = fight.GetCell(cell); ObstacleType = type; ActivationType = activeType; CanGoThrough = canGoThrough; CanStack = canStack; Color = castInfos.Value3; Targets = new List<AbstractFighter>(); Length = Pathfinding.GetDirection(castInfos.RangeType[1]); AffectedCells = new List<FightCell>(); Duration = duration; ActionId = actionId; Hide = hide; foreach(var effect in m_actionEffect.Effects) { if(CastInfos.IsDamageEffect(effect.TypeEnum)) { Priority--; } } // On ajout l'objet a toutes les cells qu'il affecte foreach (var cellId in CellZone.GetCircleCells(fight.Map, cell, Length)) { var fightCell = m_fight.GetCell(cellId); if (fightCell != null) { fightCell.AddObject(this); AffectedCells.Add(fightCell); } } if (Hide) Appear(caster.Team); else AppearForAll(); }
/// <summary> /// /// </summary> /// <param name="spell"></param> /// <param name="spellId"></param> /// <param name="targetId"></param> public void Actualize(SpellLevel spell, int spellId, long targetId) { if (spell.Cooldown > 0) { if (!m_cooldowns.ContainsKey(spellId)) { m_cooldowns.Add(spellId, new SpellCooldown(spell.Cooldown)); } else { m_cooldowns[spellId].Cooldown = spell.Cooldown; } } if (spell.MaxLaunchPerTurn == 0 && spell.MaxLaunchPerTarget == 0) return; if (!m_targets.ContainsKey(spellId)) m_targets.Add(spellId, new List<SpellTarget>()); m_targets[spellId].Add(new SpellTarget(targetId)); }
/// <summary> /// /// </summary> /// <param name="spell"></param> /// <param name="spellId"></param> /// <param name="targetId"></param> /// <returns></returns> public bool CanLaunchSpell(SpellLevel spell, int spellId, long targetId) { if (spell.Cooldown > 0) { if (m_cooldowns.ContainsKey(spellId)) { if (m_cooldowns[spellId] != null) { if (m_cooldowns[spellId].Cooldown > 0) return false; } } } if (spell.MaxLaunchPerTurn == 0 && spell.MaxLaunchPerTarget == 0) return true; if (spell.MaxLaunchPerTurn > 0) { if (m_targets.ContainsKey(spellId)) { if (m_targets[spellId].Count >= spell.MaxLaunchPerTurn) return false; } } if (targetId == 0) return true; if (spell.MaxLaunchPerTarget > 0) { if (m_targets.ContainsKey(spellId)) { if (m_targets[spellId].Count(spellTarget => spellTarget.TargetId == targetId) >= spell.MaxLaunchPerTarget) return false; } } return true; }
/// <summary> /// /// </summary> /// <param name="fighter"></param> /// <param name="spellLevel"></param> /// <param name="spellId"></param> /// <param name="cellId"></param> /// <param name="castCell"></param> /// <returns></returns> public FightSpellLaunchResultEnum CanLaunchSpell(AbstractFighter fighter, SpellLevel spellLevel, int spellId, int cellId, int castCell) { if(LoopState != FightLoopStateEnum.STATE_WAIT_TURN && LoopState != FightLoopStateEnum.STATE_WAIT_AI) return FightSpellLaunchResultEnum.RESULT_ERROR; if (CurrentFighter != fighter) return FightSpellLaunchResultEnum.RESULT_ERROR; if (GetCell(castCell) == null) return FightSpellLaunchResultEnum.RESULT_ERROR; if (fighter.AP < spellLevel.APCost) return FightSpellLaunchResultEnum.RESULT_NO_AP; var distance = Pathfinding.GoalDistance(Map, cellId, castCell); var maxPo = spellLevel.AllowPOBoost ? spellLevel.MaxPO + fighter.Statistics.GetTotal(EffectEnum.AddPO) : spellLevel.MaxPO; if (maxPo < spellLevel.MinPO) maxPo = spellLevel.MinPO; if (distance > maxPo || distance < spellLevel.MinPO) return FightSpellLaunchResultEnum.RESULT_NEED_MOVE; if(spellLevel.EmptyCell && !GetCell(castCell).CanWalk) return FightSpellLaunchResultEnum.RESULT_WRONG_TARGET; if(spellLevel.InLine && !Pathfinding.InLine(Map, cellId, castCell)) return FightSpellLaunchResultEnum.RESULT_NEED_MOVE; if (spellLevel.EmptyCell && GetCell(castCell).HasObject(FightObstacleTypeEnum.TYPE_FIGHTER)) return FightSpellLaunchResultEnum.RESULT_NO_LOS; if (spellLevel.LOS && !Pathfinding.CheckView(this, cellId, castCell)) return FightSpellLaunchResultEnum.RESULT_NO_LOS; if (spellLevel.Effects != null) { if (spellLevel.Effects.Any(effect => effect.TypeEnum == EffectEnum.Invocation)) { var invocationCount = fighter.Team.AliveFighters.Count(f => f.Invocator == fighter && !f.StaticInvocation); if (invocationCount >= fighter.Statistics.GetTotal(EffectEnum.AddInvocationMax)) { fighter.Dispatch(WorldMessage.INFORMATION_MESSAGE(InformationTypeEnum.ERROR, InformationEnum.ERROR_MAX_INVOCATION_REACHED, fighter.Statistics.GetTotal(EffectEnum.AddInvocationMax))); return FightSpellLaunchResultEnum.RESULT_ERROR; } } } var target = GetFighterOnCell(castCell); long targetId = 0; if (target != null) targetId = target.Id; if (!fighter.SpellManager.CanLaunchSpell(spellLevel, spellId, targetId)) return FightSpellLaunchResultEnum.RESULT_WRONG_TARGET; return FightSpellLaunchResultEnum.RESULT_OK; }