public bool Move(Cell cell, ISimplePathFinder pathFinder = null, int minDistance = 0, bool cautious = false, bool cancelMove = true)
        {
            if (cell == null)
            {
                throw new ArgumentNullException("cell");
            }

            if (!CanMove())
            {
                return(false);
            }
            if (pathFinder == null)
            {
                pathFinder = new BiM.Behaviors.Game.World.Pathfinding.FFPathFinding.PathFinder(Map, false);
            }
            Path path = null;

            if (pathFinder is IAdvancedPathFinder)
            {
                path = (pathFinder as IAdvancedPathFinder).FindPath(Cell, cell, true, -1, minDistance, cautious);
            }
            else
            {
                path = pathFinder.FindPath(Cell, cell, true, -1);
            }

            return(Move(path, cell));
        }
        public bool ChangeMap(MapNeighbour neighbour, Predicate<CellInfo> cellSelector)
        {
            try
            {
                m_nextMap = null;
                PathFinder pathFinder = new PathFinder(Map, false);

                // Select a random cell in the set of all reachable cells that allow map change in the right direction. 
                Cell destCell = pathFinder.FindConnectedCells(Cell, false, true, cell => (cell.Cell.MapChangeData & Map.MapChangeDatas[neighbour]) != 0 && cellSelector(cell)).GetRandom();
                if (destCell == null) return false;
                neighbour = Map.GetDirectionOfTransitionCell(destCell);
                if (neighbour == MapNeighbour.None) return false;
                if (Move(destCell, pathFinder, 0, true))
                {
                    m_nextMap = GetNeighbourId(neighbour);
                    m_previousMap = Map.Id;
                    return true;
                }
                return false;
            }
            finally
            {
                if (m_nextMap == null)
                    SendMessage(String.Format("Can't find any linked map from {0}", this), Color.Red);
                else
                    SendMessage(String.Format("Moving at the {2} of map {0} to map {1}", this, m_nextMap, neighbour), Color.Pink);
            }
        }
        public MapNeighbour ChangeMap(MapNeighbour neighbour = MapNeighbour.Any)
        {
            m_nextMap = null;
            PathFinder pathFinder = new PathFinder(Map, false);

            // Select a random cell in the set of all reachable cells that allow map change in the right direction. 
            Cell destCell = pathFinder.FindConnectedCells(Cell, false, true, cell => (cell.Cell.MapChangeData & Map.MapChangeDatas[neighbour]) != 0).GetRandom();
            if (destCell == null) return MapNeighbour.None;
            neighbour = Map.GetDirectionOfTransitionCell(destCell);
            if (neighbour == MapNeighbour.None)
            {
                SendMessage(String.Format("Can't find any linked map from {0}", this), Color.Red);
                return MapNeighbour.None;
            }

            if (destCell.Id != Cell.Id)
            {
                if (Move(destCell, pathFinder, 0, true))
                {
                    m_nextMap = GetNeighbourId(neighbour);
                    SendMessage(String.Format("Moving at the {2} of map {0} to map {1}", this, m_nextMap, neighbour), Color.Pink);
                    return neighbour;
                }
                else
                    return MapNeighbour.None;
            }
            else
            {
                Bot.AddMessage(() => Bot.SendToServer(new ChangeMapMessage(GetNeighbourId(neighbour))));
                m_previousMap = Map.Id;
                SendMessage(String.Format("Moving at the {2} of map {0} to map {1} (direct)", this, m_nextMap, neighbour), Color.Pink);
            }
            return neighbour;

        }
        private void InternalChangeMap()
        {
            _changingMap = true;
            if (IsFighting())
            {
                SendWarning("InternalChangeMap : I'm fighting => stop it !");
                _changingMap = false;
                return;
            }
            if (_srcLeaderMap != Map.Id)
            {
                SendWarning("I'm not on the proper map to follow leader on the next map");
                _changingMap = false;
                return;
            }
            if (_pivotLeaderCell != Cell.Id)
            {
                PathFinder pathFinder = new PathFinder(Map, false);
                if (!Move(_pivotLeaderCell, pathFinder, 0, true))
                {
                    if (_nbTryLeft > 0)
                    {
                        SendWarning("InternalChangeMap : Can't join the leader yet, try later");
                        _nbTryLeft--;
                        Bot.CallDelayed(6000, InternalChangeMap);
                    }
                    else
                        if (_nbTryLeft > -6)
                        {
                            MapNeighbour neighbour = Map.GetDirectionOfTransitionCell(Map.Cells[_pivotLeaderCell]);
                            Cell destCell = pathFinder.FindConnectedCells(Cell, false, true, cell => (cell.Cell.MapChangeData & Map.MapChangeDatas[neighbour]) != 0).GetRandom();
                            if (destCell == null)
                                SendWarning("InternalChangeMap  : Can't join the leader, no try left. Can't even find any alternate path to go {0}", neighbour);
                            else
                            {
                                SendWarning("InternalChangeMap : Can't join the leader, no try left. Trying alternative path to go {0} : cell {1}", neighbour, destCell);
                                _pivotLeaderCell = destCell.Id;
                            }
                            _nbTryLeft--;
                            Bot.CallDelayed(2000, InternalChangeMap);
                        }
                        else
                        {
                            SendError("InternalChangeMap : Can't find any path to join the leader. Trying again later. ");
                            _changingMap = false;
                        }
                    return;
                }

                SendWarning("InternalChangeMap : Move from {0} to {1} succeeded. When move is complete, should go from map {2} to map {3}. ", Cell, Map.Cells[_pivotLeaderCell], Map.ToString(), new Map(_dstLeaderMap));
                _changingMap = false;
                m_nextMap = _dstLeaderMap;
                return;
            }
            SendError("I'm already on the good Cell, just try to jump to the other map.");

            Bot.CallDelayed(400, () => Bot.AddMessage(() => Bot.SendToServer(new ChangeMapMessage(_dstLeaderMap))));
            m_previousMap = Map.Id;
            _changingMap = false;
            return;
        }
        public bool Move(Cell cell, ISimplePathFinder pathFinder = null, int minDistance = 0, bool cautious = false, bool cancelMove = true)
        {
            if (cell == null) throw new ArgumentNullException("cell");

            if (!CanMove())
                return false;
            if (pathFinder == null)
                pathFinder = new BiM.Behaviors.Game.World.Pathfinding.FFPathFinding.PathFinder(Map, false);
            Path path = null;
            if (pathFinder is IAdvancedPathFinder)
                path = (pathFinder as IAdvancedPathFinder).FindPath(Cell, cell, true, -1, minDistance, cautious);
            else
                path = pathFinder.FindPath(Cell, cell, true, -1);

            return Move(path, cell);
        }
 /// <summary>
 /// Gives walkable cells where the character may walk within the turn.
 /// Note : it's now supposed to be reliable, using PathFinder
 /// </summary>
 /// <returns></returns>
 public IEnumerable<Cell> GetPossibleMoves(bool cautious, bool ForceIncludeStartingCell = true, PathFinder pathFinder = null)
 {
     if (pathFinder == null)
         pathFinder = new PathFinder(Fight, true);
     List<Cell> cells = pathFinder.FindConnectedCells(
         Cell, true, cautious,
         cell => cell.DistanceSteps <= Stats.CurrentMP, null, Stats.CurrentMP).ToList();
     if (ForceIncludeStartingCell && !cells.Contains(Cell))
         cells.Add(Cell);
     return cells;
 }
Esempio n. 7
0
        public SpellTarget FindBestUsage(PlayedFighter pc, Spell.SpellCategory category, bool withWeapon, IEnumerable<Cell> possiblePlacement = null)
        {
            SpellTarget spellTarget = new SpellTarget();
            if (pc.PCStats.CurrentAP <= 0) return spellTarget;
            Stopwatch timer = new Stopwatch();
            timer.Start();
            PathFinder pathFinder = new PathFinder(pc.Fight, true);
            IEnumerable<Cell> sourceCells = possiblePlacement == null ? pc.GetPossibleMoves(true, true, pathFinder) : possiblePlacement;
            IEnumerable<Fighter> actorsWithoutPC = pc.Fight.AliveActors.Where(actor => actor != pc);
            List<Spell> spells = m_spells.ToList();
            if (withWeapon && ((category & (Spell.SpellCategory.Damages | Spell.SpellCategory.Healing)) != 0))
                spells.Add(WeaponSpellLike());
            //logger.Debug("***FindBestUsage {0}, {1} spells in book. {2} PA. {3}/{4} HP ***", category, spells.Count, pc.PCStats.CurrentAP, pc.PCStats.Health, pc.PCStats.MaxHealth);
            Object thisLock = new Object();
            //foreach(Spell spell in spells)
            int NbSpellsChecked = 0;
            Parallel.ForEach(spells, spell =>
            {
                NbSpellsChecked++;
                if (spell != null && !IgnoredSpells.Contains(spell.Template.id))
                {
                    int spellId = spell.Template.id;
                    if (spell.IsAvailable(null) && ((spellId != 0 && pc.CanCastSpells) || (spellId == 0 && pc.CanFight)) && spell.LevelTemplate.apCost <= pc.Stats.CurrentAP && pc.CanCastSpell(spellId))
                    {
                        if ((spell.Categories & category) > 0)
                        {
                            SpellTarget lastSpellTarget = spell.FindBestTarget(pc, sourceCells, actorsWithoutPC, category);
                            if (lastSpellTarget != null && lastSpellTarget.Efficiency > spellTarget.Efficiency)
                                //lock (thisLock)
                                    spellTarget = lastSpellTarget;
                            //if (lastSpellTarget != null)
                            //    logger.Debug("efficiency {0} = {1} ({2})", lastSpellTarget.Spell, lastSpellTarget.Efficiency, lastSpellTarget.Comment);
                                //lock (thisLock)
//                                    logger.Debug("efficiency {0} = ???", spell); 
//                            else
                                //lock (thisLock)
 //                                  logger.Debug("efficiency {0} = {1} ({2})", lastSpellTarget.Spell, lastSpellTarget.Efficiency, lastSpellTarget.Comment);
                        }
                    }
                    else
                    {
  //                      lock (thisLock)
  //                          logger.Info("{0} skipped : available={1} ({6}), canUse={2}, ApCost={3}, CanCast({4})={5}", spell, spell.IsAvailable(null), ((spellId != 0 && pc.CanCastSpells) || (spellId == 0 && pc.CanFight)), spell.LevelTemplate.apCost <= pc.Stats.CurrentAP, spellId, pc.CanCastSpell(spellId), spell.AvailabilityExplainString(null));
                    }
                }
            }
            );
            //Debug.Assert(NbSpellsChecked == spells.Count);
            timer.Stop();
            spellTarget.TimeSpan = timer.Elapsed;
            //pc.Character.SendInformation("Spell {0} selected - efficientcy : {1} - comment = {2}", spellTarget.Spell, spellTarget.Efficiency, spellTarget.Comment);
            return spellTarget;
        }
Esempio n. 8
0
        /*public bool IsProperTarget(PlayedFighter caster, Fighter target, Spell spell)
        {
            // SpellTargetType
            if (target == null) return spell.LevelTemplate.needFreeCell && spell.IsAvailable(null, null);

            foreach (var spellEffect in spell.GetEffects())
                if (EffectBase.canAffectTarget(spellEffect, spell, caster, target)) return true;
            return false;
        }*/
        #endregion Availability management

        #region Spell selection
        /*public IEnumerable<Spell> GetOrderListOfSimpleBoostSpells(PlayedFighter caster, Fighter target, Spell.SpellCategory category)
        {
            return m_spells.Where(spell => (caster.Stats.CurrentAP >= spell.LevelTemplate.apCost) && spell.IsAvailable(caster.Id, category) && IsProperTarget(caster, target, spell)).OrderByDescending(spell => spell.Level).ThenByDescending(spell => spell.LevelTemplate.minPlayerLevel);
        }

        public IEnumerable<Spell> GetOrderedAttackSpells(PlayedFighter caster, Fighter target, Spell.SpellCategory category = Spell.SpellCategory.Damages)
        {
            Debug.Assert(((category & Spell.SpellCategory.Damages) > 0), "category do not include Damage effects");
            return m_spells.Where(spell =>
                (caster.Stats.CurrentAP >= spell.LevelTemplate.apCost) &&
                spell.IsAvailable(target.Id, category) &&
                IsProperTarget(caster, target, spell))
                .OrderByDescending(spell => (int)(spell.GetSpellDamages(caster, target, Spell.SpellCategory.Damages).Damage) * (caster.Stats.CurrentAP / (int)spell.LevelTemplate.apCost));
        }*/


        public SpellTarget FindBestUsage(PlayedFighter pc, List<int> spellIds, IEnumerable<Cell> possiblePlacement = null)
        {
            Stopwatch timer = new Stopwatch();
            timer.Start();
            PathFinder pathFinder = new PathFinder(pc.Fight, true);
            IEnumerable<Cell> sourceCells = possiblePlacement == null ? pc.GetPossibleMoves(true, true, pathFinder) : possiblePlacement;
            IEnumerable<Fighter> actorsWithoutPC = pc.Fight.AliveActors.Where(actor => actor != pc);
            SpellTarget spellTarget = new SpellTarget();
            foreach (int spellId in spellIds)
            {
                Spell spell = m_spells.FirstOrDefault(sp => sp.Template.id == spellId);
                if (spell == null && spellId == 0)
                    spell = WeaponSpellLike();
                if (spell != null)
                {

                    if (spell.IsAvailable(null) && ((spellId != 0 && pc.CanCastSpells) || (spellId == 0 && pc.CanFight)) && spell.LevelTemplate.apCost <= pc.Stats.CurrentAP && pc.CanCastSpell(spellId))

                        if (spell != null && spell.IsAvailable(null) && spell.LevelTemplate.apCost <= pc.Stats.CurrentAP)
                        {
                            SpellTarget lastSpellTarget = spell.FindBestTarget(pc, sourceCells, actorsWithoutPC, Spell.SpellCategory.All);
                            if (lastSpellTarget != null && lastSpellTarget.Efficiency > spellTarget.Efficiency)
                            {
                                spellTarget = lastSpellTarget;
                                break; // Stop on the first spell with positive efficiency
                            }
                        }
                }
            }
            timer.Stop();
            spellTarget.TimeSpan = timer.Elapsed;
            return spellTarget;
        }