private void OnPositionChanged(Object p_sender, EventArgs p_args) { if (p_sender is Party) { m_decision = EMonsterStrategyDecision.CALCULATE_STRATEGY; m_targetSlot = null; } if (p_sender is Monster) { m_decision = EMonsterStrategyDecision.CALCULATE_STRATEGY; } }
public virtual void DoTurn(Grid p_grid, Party p_party) { CalculatesRanged = false; if (m_owner.State == Monster.EState.SPAWNING) { return; } m_owner.AbilityHandler.ExecuteAttack(null, null, false, EExecutionPhase.BEGIN_OF_MONSTERS_TURN); m_owner.AbilityHandler.FlushActionLog(EExecutionPhase.BEGIN_OF_MONSTERS_TURN); if (PartyIsCaged(p_grid, p_party)) { m_owner.SkipMovement.Trigger(); return; } GridSlot slot = p_grid.GetSlot(m_owner.Position); Boolean p_isMelee = true; m_owner.BuffHandler.ModifyMonsterValues(); m_owner.CombatHandler.MeleeStrikes += m_owner.CombatHandler.MeleeStrikesRoundBonus; m_owner.CombatHandler.MeleeStrikesRoundBonus = 0; if (m_owner.CombatHandler.IsFleeing) { m_decision = EMonsterStrategyDecision.FLEEING; } else if (m_decision == EMonsterStrategyDecision.FLEEING) { m_decision = EMonsterStrategyDecision.CALCULATE_STRATEGY; } CheckAIEvents(); if (m_owner.State != Monster.EState.ACTION_FINISHED) { Boolean flag = DoCastSpell(); CalculatesRanged = true; DoRanged(flag, p_party, p_grid, slot, out p_isMelee); CalculatesRanged = false; if (flag) { p_isMelee = false; m_owner.RangedAttack = false; m_owner.CombatHandler.Attack(); return; } if (m_decision == EMonsterStrategyDecision.MELEE || m_decision == EMonsterStrategyDecision.CALCULATE_STRATEGY) { DoMelee(p_isMelee, p_party, p_grid, slot); } else if (m_decision == EMonsterStrategyDecision.FLEEING) { DoFlee(p_party, p_grid, slot); } } m_owner.SkipMovement.Trigger(); }
protected virtual void DoMelee(Boolean p_isMelee, Party p_party, Grid p_grid, GridSlot p_startSlot) { if (p_isMelee) { m_decision = EMonsterStrategyDecision.MELEE; if (m_owner.DistanceToParty <= 1f) { EDirection direction = EDirectionFunctions.GetDirection(m_owner.Position, p_party.Position); if (p_startSlot.GetTransition(direction).TransitionType == EGridTransitionType.CLOSED) { if (m_canOpenDoors) { TryOpenDoor(p_startSlot, direction); } return; } m_owner.RangedAttack = false; m_owner.CombatHandler.Attack(); return; } else { if (m_owner.DistanceToParty <= 1.6f) { return; } List <GridSlot> meleeTargets = GetMeleeTargets(p_grid, p_party); meleeTargets.Sort(new Comparison <GridSlot>(DistSortAsc)); if (meleeTargets.Count > 0) { if (TryMove(meleeTargets, p_grid, p_startSlot, p_party)) { return; } } else { Party party = LegacyLogic.Instance.WorldManager.Party; GridSlot slot = LegacyLogic.Instance.MapLoader.Grid.GetSlot(party.Position + new Position(1, 1)); if (slot != null && slot.IsPassable(m_owner, false)) { meleeTargets.Add(slot); } GridSlot slot2 = LegacyLogic.Instance.MapLoader.Grid.GetSlot(party.Position + new Position(-1, -1)); if (slot2 != null && slot2.IsPassable(m_owner, false)) { meleeTargets.Add(slot2); } GridSlot slot3 = LegacyLogic.Instance.MapLoader.Grid.GetSlot(party.Position + new Position(-1, 1)); if (slot3 != null && slot3.IsPassable(m_owner, false)) { meleeTargets.Add(slot3); } GridSlot slot4 = LegacyLogic.Instance.MapLoader.Grid.GetSlot(party.Position + new Position(1, -1)); if (slot4 != null && slot4.IsPassable(m_owner, false)) { meleeTargets.Add(slot4); } slot = LegacyLogic.Instance.MapLoader.Grid.GetSlot(party.Position + new Position(0, 2)); if (slot != null && slot.IsPassable(m_owner, false)) { meleeTargets.Add(slot); } slot2 = LegacyLogic.Instance.MapLoader.Grid.GetSlot(party.Position + new Position(2, 0)); if (slot2 != null && slot2.IsPassable(m_owner, false)) { meleeTargets.Add(slot2); } slot3 = LegacyLogic.Instance.MapLoader.Grid.GetSlot(party.Position + new Position(-2, 0)); if (slot3 != null && slot3.IsPassable(m_owner, false)) { meleeTargets.Add(slot3); } slot4 = LegacyLogic.Instance.MapLoader.Grid.GetSlot(party.Position + new Position(0, -2)); if (slot4 != null && slot4.IsPassable(m_owner, false)) { meleeTargets.Add(slot4); } meleeTargets.RemoveAll((GridSlot t) => t.Position == m_owner.Position); if (meleeTargets.Count > 0 && TryMove(meleeTargets, p_grid, p_startSlot, p_party)) { return; } } } } }
protected virtual void DoRanged(Boolean p_isMagic, Party p_party, Grid p_grid, GridSlot p_startSlot, out Boolean p_isMelee) { p_isMelee = true; if (m_decision == EMonsterStrategyDecision.RANGED || m_decision == EMonsterStrategyDecision.CALCULATE_STRATEGY) { if (m_owner.DistanceToParty <= 1.6f) { m_decision = EMonsterStrategyDecision.MELEE; p_isMelee = true; } if (!p_isMagic && m_owner.StaticData.SpellRanges > m_owner.CombatHandler.AttackRange && m_owner.DistanceToParty > 1.6f) { if (m_targetSlot == null) { List <GridSlot> rangedTargets = GetRangedTargets(p_grid, p_party, m_owner.StaticData.SpellRanges); if (rangedTargets.Count > 0) { rangedTargets.Sort(new Comparison <GridSlot>(DistSortAsc)); if (TryMove(rangedTargets, p_grid, p_startSlot, p_party)) { p_isMelee = false; return; } p_isMelee = true; m_decision = EMonsterStrategyDecision.MELEE; } else { p_isMelee = true; m_decision = EMonsterStrategyDecision.MELEE; } } } else { m_decision = EMonsterStrategyDecision.MELEE; p_isMelee = true; } if (!p_isMagic && m_owner.CombatHandler.AttackRange > 1f && m_owner.DistanceToParty > 1.6f) { p_isMelee = false; m_decision = EMonsterStrategyDecision.RANGED; if (p_grid.LineOfSight(m_owner.Position, p_party.Position, true) && Position.Distance(m_owner.Position, p_party.Position) <= m_owner.CombatHandler.AttackRange && m_owner.DistanceToParty >= 2f) { m_owner.CombatHandler.AttackRanged(); return; } if (m_targetSlot == null && (m_owner.Position.X == p_party.Position.X || m_owner.Position.Y == p_party.Position.Y)) { EDirection direction = EDirectionFunctions.GetDirection(p_party.Position, m_owner.Position); GridSlot gridSlot = p_grid.GetSlot(p_party.Position); for (Int32 i = 0; i < m_owner.StaticData.AttackRange; i++) { GridSlot neighborSlot = gridSlot.GetNeighborSlot(p_grid, direction); if (neighborSlot == null) { break; } gridSlot = neighborSlot; } if (gridSlot != null) { m_targetSlot = gridSlot; } } if (m_targetSlot == null) { List <GridSlot> rangedTargets2 = GetRangedTargets(p_grid, p_party); if (rangedTargets2.Count > 0) { rangedTargets2.Sort(new Comparison <GridSlot>(DistSortAsc)); if (TryMove(rangedTargets2, p_grid, p_startSlot, p_party)) { return; } p_isMelee = true; m_decision = EMonsterStrategyDecision.MELEE; } else { p_isMelee = true; m_decision = EMonsterStrategyDecision.MELEE; } } else { if (!(m_owner.Position != m_targetSlot.Position)) { p_isMelee = true; m_decision = EMonsterStrategyDecision.MELEE; return; } if (TryMove(new List <GridSlot> { m_targetSlot }, p_grid, p_startSlot, p_party)) { return; } p_isMelee = true; m_targetSlot = null; m_decision = EMonsterStrategyDecision.CALCULATE_STRATEGY; } } } }