public FighterEntry GetNearestAlly(Func <FighterEntry, bool> filter = null) { MapPoint charMp = MapPoint.FromCellId(PlayedFighter.CellId), allyMp; int distance = -1, tempDistance; FighterEntry ally = null; foreach (var allyEntry in filter == null ? Allies : Allies.Where(f => filter(f))) { if (!allyEntry.Alive) { continue; } allyMp = MapPoint.FromCellId(allyEntry.CellId); tempDistance = charMp.DistanceToCell(allyMp); if (distance == -1 || tempDistance < distance) { distance = tempDistance; ally = allyEntry; } } return(ally); }
public FighterEntry GetNearestEnnemy(short cellId = -1, Func <FighterEntry, bool> filter = null) { MapPoint charMp = MapPoint.FromCellId(cellId == -1 ? PlayedFighter.CellId : cellId), ennemyMp; int distance = -1, tempDistance; FighterEntry ennemy = null; foreach (var ennemyEntry in filter == null ? Ennemies : Ennemies.Where(f => filter(f))) { if (!ennemyEntry.Alive) { continue; } ennemyMp = MapPoint.FromCellId(ennemyEntry.CellId); tempDistance = charMp.DistanceToCell(ennemyMp); if (distance == -1 || tempDistance < distance) { distance = tempDistance; ennemy = ennemyEntry; } } return(ennemy); }
private Dictionary <InteractiveElementEntry, short> GetUsableElements(List <int> ressourcesIds) { Dictionary <InteractiveElementEntry, short> usableElements = new Dictionary <InteractiveElementEntry, short>(); try { bool hasFishingRod = _account.Game.Character.Inventory.HasFishingRod; int weaponRange = _account.Game.Character.Inventory.GetWeaponRange(); foreach (var interactive in _account.Game.Map.Interactives) { // The element must be usable if (!interactive.Usable) { continue; } // Check if the element is blacklisted if (_blackListedElements.Contains(interactive.Id)) { continue; } // Check if this interactive is something we want if (!ressourcesIds.Contains(interactive.ElementTypeId)) { continue; } var statedElement = _account.Game.Map.GetStatedElement((int)interactive.Id); var elementMp = MapPoint.FromCellId(statedElement.CellId); var path = _pathfinder.GetPath(_account.Game.Map.PlayedCharacter.CellId, statedElement.CellId, _account.Game.Map.OccupiedCells, true, true); // If the path is invalid if (path.Count == 0) { continue; } // Check the distance between where we will be and the element we're intressted in // If we have a fishing rod, we need to compare it with the rod's range, otherwise we'll compare it to 1 if (hasFishingRod && MapPoint.FromCellId(path.Last()).DistanceToCell(elementMp) <= weaponRange || !hasFishingRod && MapPoint.FromCellId(path.Last()).DistanceTo(elementMp) == 1) { // Check if this path ends with a group of monsters if (_account.Game.Map.MonstersGroups.FirstOrDefault(mg => mg.CellId == path.Last()) != null) { continue; } usableElements.Add(interactive, statedElement.CellId); } } } catch { } return(usableElements); }
private async Task EndTurn() { if (!_account.Game.Fight.IsOurTurn) { return; } Console.WriteLine("EndTurn"); if (Configuration.Tactic == FightTactics.PASSIVE) { await FinishTurn(400); return; } // If we're h2h then just avoid this if (_account.Game.Fight.IsHandToHandWithAnEnnemy() && Configuration.Tactic == FightTactics.AGRESSIVE) { await FinishTurn(400); return; } if (_account.Game.Fight.PlayedFighter.MovementPoints > 0 && _account.Game.Fight.Ennemies.Any()) { // If no spell was casted, approach even if the tactic is fugitive // Also if distance to the nearest ennemy is >= MaxCells bool nearest = Configuration.Tactic == FightTactics.AGRESSIVE || (Configuration.ApproachWhenNoSpellWasCasted || _account.Extensions.CharacterCreation.IsDoingTutorial) && !_spellCasted || MapPoint.FromCellId(_account.Game.Fight.GetNearestEnnemy().CellId).DistanceToCell(MapPoint.FromCellId(_account.Game.Fight.PlayedFighter.CellId)) >= Configuration.MaxCells; var node = _utility.GetNearestOrFarthestEndMoveNode(nearest, (Configuration.Tactic == FightTactics.FUGITIVE || Configuration.BaseApproachOnAllMonsters)); if (node != null) { _endTurn = true; _account.Logger.LogDebug(LanguageManager.Translate("472"), LanguageManager.Translate("56", node.Value.Key)); await _account.Game.Managers.Movements.MoveToCellInFight(node); return; } } await FinishTurn(400); }
private bool IsDistanceGood(Spell spell) { // This option is ignored when the value is 0 if (spell.DistanceToClosestMonster == 0) { return(true); } var nearestEnnemy = _account.Game.Fight.GetNearestEnnemy(); if (nearestEnnemy == null) { return(false); } MapPoint mp = MapPoint.FromCellId(nearestEnnemy.CellId); return(MapPoint.FromCellId(_account.Game.Fight.PlayedFighter.CellId).DistanceToCell(mp) <= spell.DistanceToClosestMonster); }
public KeyValuePair <short, MoveNode>?GetNearestOrFarthestEndMoveNode(bool nearest, bool basedOnAllMonsters = true) { KeyValuePair <short, MoveNode>?node = null; int totalDistances = -1; int distance = -1; // Include our current cell totalDistances = basedOnAllMonsters ? GetTotalDistancesFromEnnemies(_account.Game.Fight.PlayedFighter.CellId) : MapPoint.FromCellId(_account.Game.Fight.PlayedFighter.CellId).DistanceToCell(MapPoint.FromCellId(_account.Game.Fight.GetNearestEnnemy().CellId)); foreach (var kvp in FightsPathfinder.GetReachableZone(_account.Game.Fight, _account.Game.Map.Data, _account.Game.Fight.PlayedFighter.CellId)) { if (!kvp.Value.Reachable) { continue; } int tempTotalDistances = basedOnAllMonsters ? GetTotalDistancesFromEnnemies(kvp.Key) : MapPoint.FromCellId(kvp.Key).DistanceToCell(MapPoint.FromCellId(_account.Game.Fight.GetNearestEnnemy().CellId)); if ((nearest && tempTotalDistances <= totalDistances) || (!nearest && tempTotalDistances >= totalDistances)) { if (nearest) { node = kvp; totalDistances = tempTotalDistances; } // If we need to give the farthest cell, we might aswell give the one that uses the most available MP else if (kvp.Value.Path.Reachable.Count >= distance) { node = kvp; totalDistances = tempTotalDistances; distance = kvp.Value.Path.Reachable.Count; } } } return(node); }
private async Task <bool> TryApproachingMonster(List <uint> possiblePlacements) { if (Configuration.MonsterToApproach == -1) { return(false); } FightMonsterEntry monster = _account.Game.Fight.Monsters.FirstOrDefault(f => f.CreatureGenericId == Configuration.MonsterToApproach); if (monster == null) { _account.Logger.LogDebug(LanguageManager.Translate("472"), LanguageManager.Translate("60")); return(false); } // The monster to approach is in the fight ! else { short cellId = -1; int distance = -1; foreach (short cell in possiblePlacements) { if (cellId == -1 || (MapPoint.FromCellId(monster.CellId).DistanceToCell(MapPoint.FromCellId(cell)) < distance)) { cellId = cell; distance = MapPoint.FromCellId(monster.CellId).DistanceToCell(MapPoint.FromCellId(cell)); } } // If we're not already close if (cellId != _account.Game.Fight.PlayedFighter.CellId) { _account.Logger.LogDebug(LanguageManager.Translate("472"), LanguageManager.Translate("61", cellId)); await _account.Network.SendMessageAsync(new GameFightPlacementPositionRequestMessage((uint)cellId)); } return(true); } }
private async Task <SpellCastingResults> CastSpellOnEmptyCell(Spell spell) { if (_account.Game.Fight.CanLaunchSpell(spell.SpellId) != SpellInabilityReasons.NONE) { return(SpellCastingResults.NOT_CASTED); } // In case we need to cast the spell on an empty case next to the character but all of them are taken if (spell.Target == SpellTargets.EMPTY_CELL && _account.Game.Fight.GetHandToHandEnnemies().Count() == 4) { return(SpellCastingResults.NOT_CASTED); } var spellEntry = _account.Game.Character.GetSpell(spell.SpellId); Spells spellData = DataManager.Get <Spells>(spell.SpellId); SpellLevels spellLevel = DataManager.Get <SpellLevels>(spellData.SpellLevels[spellEntry.Level - 1]); var range = _account.Game.Fight.GetSpellRange(_account.Game.Fight.PlayedFighter.CellId, spellLevel); for (int i = 0; i < range.Count; i++) { if (_account.Game.Fight.CanLaunchSpell(spell.SpellId, _account.Game.Fight.PlayedFighter.CellId, range[i]) == SpellInabilityReasons.NONE) { if (spell.HandToHand && MapPoint.FromCellId(range[i]).DistanceToCell(MapPoint.FromCellId(_account.Game.Fight.PlayedFighter.CellId)) != 1) { continue; } _account.Logger.LogDebug(LanguageManager.Translate("52"), LanguageManager.Translate("64", spell.SpellName, range[i])); await _account.Game.Fight.LaunchSpell(spell.SpellId, range[i]); return(SpellCastingResults.CASTED); } } // We need to move return(await MoveToCastSpellOnEmptyCell(spell, spellLevel)); }
public static IEnumerable <MapPoint> GetSpellRange(short sourceCellId, SpellLevels spellLevel, int additionalRange = 0) { var mp = MapPoint.FromCellId(sourceCellId); int range = spellLevel.Range + (spellLevel.RangeCanBeBoosted ? additionalRange : 0); if (spellLevel.CastInLine && spellLevel.CastInDiagonal) { return(Shaper.ShapeCross(mp.X, mp.Y, spellLevel.MinRange, range) .Union(Shaper.ShapeStar(mp.X, mp.Y, spellLevel.MinRange, range))); } else if (spellLevel.CastInDiagonal) { return(Shaper.ShapeStar(mp.X, mp.Y, spellLevel.MinRange, range)); } else if (spellLevel.CastInLine) { return(Shaper.ShapeCross(mp.X, mp.Y, spellLevel.MinRange, range)); } else { return(Shaper.ShapeRing(mp.X, mp.Y, spellLevel.MinRange, range)); } }
public static List <MapPoint> GetSpellEffectZone(Map map, SpellLevels spellLevel, short casterCellId, short targetCellId) { List <MapPoint> zone = new List <MapPoint>(); Zone effect = GetZoneEffect(spellLevel); var shaper = Shaper.ShaperMap[effect.ZoneShape]; if (shaper == null) { zone.Add(MapPoint.FromCellId(targetCellId)); return(zone); } var targetCoords = MapPoint.FromCellId(targetCellId); int dirX = 0, dirY = 0; if (shaper.HasDirection) { var casterCoords = MapPoint.FromCellId(casterCellId); dirX = targetCoords.X == casterCoords.X ? 0 : targetCoords.X > casterCoords.X ? 1 : -1; dirY = targetCoords.Y == casterCoords.Y ? 0 : targetCoords.Y > casterCoords.Y ? 1 : -1; } var radiusMin = shaper.WithoutCenter ? (effect.ZoneMinSize == 0 ? 1 : effect.ZoneMinSize): effect.ZoneMinSize; var rangeCoords = shaper.Fn(targetCoords.X, targetCoords.Y, radiusMin, effect.ZoneSize, dirX, dirY); foreach (var mp in rangeCoords) { if (map.Cells[mp.CellId].IsWalkable(true)) { zone.Add(mp); } } return(zone); }
public int GetTotalDistancesFromEnnemies(short fromCellId) { return(_account.Game.Fight.Ennemies.Sum(e => (MapPoint.FromCellId(fromCellId).DistanceToCell(MapPoint.FromCellId(e.CellId)) - 1))); }
public IEnumerable <FighterEntry> GetHandToHandAllies(short cellId = -1) { MapPoint charMp = MapPoint.FromCellId(cellId == -1 ? PlayedFighter.CellId : cellId); return(Allies.Where(a => a.Alive && charMp.DistanceToCell(MapPoint.FromCellId(a.CellId)) == 1)); }