internal SimpleCellInfo(MapData MapData, MapPoint OriginPoint, SimpleCellInfo class13_1, MapPoint mapPoint_2) { this.int_0 = 0; this.int_1 = 0; this.v_OriginPoint = OriginPoint; this.class13_0 = class13_1; this.int_1 = (mapPoint_2.DistanceToCell(OriginPoint) * 5); this.int_0 = (class13_1.int_0 + 10); if (((class13_1.class13_0 != null))) { int num2 = class13_1.class13_0.v_OriginPoint.OrientationTo(class13_1.v_OriginPoint); int num3 = class13_1.v_OriginPoint.OrientationTo(OriginPoint); int num = Math.Abs(Convert.ToInt32((num2 - num3))); if ((num != 0)) { this.int_0 = (this.int_0 + 5); if (((num != 1) && (num != 7))) { this.int_0 = (this.int_0 + 50); } } if ((MapData.Data.Cells[OriginPoint.CellId].Speed == 2)) { this.int_0 = (this.int_0 - 8); } } }
/// <summary> /// Returns the cells reachable by the player. /// </summary> private List<int> GetReachableCells() { // TODO : Manage challenge (zombie) List<int> listWalkableCells = new List<int>(); MapPoint point = new MapPoint(Fighter.CellId); int movementPoints = Fighter.MovementPoints; for (int i = 0; i < 600; i++) { if (IsCellWalkable(i)) { MapPoint cellPoint = new MapPoint(i); if (cellPoint.DistanceToCell(point) <= movementPoints) listWalkableCells.Add(i); } } if (listWalkableCells.Contains(point.CellId)) listWalkableCells.Add(point.CellId); return listWalkableCells; }
/// <summary> /// Returns if a spell is launchable on a specified spellId or not. /// </summary> /// <param name="spellId">ID du sort</param> /// <param name="characterCellId">CellId du personnage</param> /// <param name="cellId">CellId cible</param> /// <returns>SpellInabilityReasons: Unknown, ActionPoints, TooManyLaunch, Cooldown, TooManyInvocations, None </returns> private SpellInabilityReason CanLaunchSpellOn(int spellId, int characterCellId, int cellId, bool withMove = false) { if (!withMove) { SpellInabilityReason canLaunchSpell = CanLaunchSpell(spellId); if (canLaunchSpell != SpellInabilityReason.None) return canLaunchSpell; } Inventory.Item weapon = m_Account.Inventory.Weapon; DataClass weaponData = null; DataClass spellData = GameData.GetDataObject(D2oFileEnum.Spells, spellId); ArrayList ids = (ArrayList)spellData.Fields["spellLevels"]; int level = m_Account.Spells.FirstOrDefault(Spell => Spell.Id == spellId).Level; int id = Convert.ToInt32(ids[level - 1]); DataClass spellLevelsData = GameData.GetDataObject(D2oFileEnum.SpellLevels, id); if (spellLevelsData == null && spellId != -1) // spellId = -1 -> Use weapon. return SpellInabilityReason.Unknown; if (spellId == 0 && weapon != null) weaponData = GameData.GetDataObject(D2oFileEnum.Items, weapon.GID); MapPoint characterPoint = new MapPoint(characterCellId); MapPoint targetPoint = new MapPoint(cellId); int distanceToTarget = characterPoint.DistanceToCell(targetPoint); int minRange = (spellId != -1) ? (int)spellLevelsData.Fields["minRange"] : (int)weaponData.Fields["minRange"]; if ((spellId != 0 && (bool)spellLevelsData.Fields["castInDiagonal"]) || (weaponData != null && !(bool)weaponData.Fields["castInLine"])) minRange = (minRange * 2); if (minRange < 0) minRange = 0; int maxRange = (spellId != 0) ? (int)((int)spellLevelsData.Fields["range"] + ((bool)spellLevelsData.Fields["rangeCanBeBoosted"] ? (m_Account.CharacterStats.range.objectsAndMountBonus + m_Account.CharacterStats.range.contextModif) : 0)) : (int)spellLevelsData.Fields["range"]; if ((spellId != 0 && (bool)spellLevelsData.Fields["castInDiagonal"]) || (weaponData != null && !(bool)weaponData.Fields["castInLine"])) maxRange = (maxRange * 2); if (maxRange < 0) maxRange = 0; if (distanceToTarget < minRange && distanceToTarget > 0) return SpellInabilityReason.MinRange; if (distanceToTarget > maxRange) return SpellInabilityReason.MaxRange; if (((spellId != 0 && (bool)spellLevelsData.Fields["castInLine"]) || (weaponData != null && (bool)weaponData.Fields["castInLine"])) && characterPoint.X != targetPoint.X && characterPoint.Y != targetPoint.Y) return SpellInabilityReason.NotInLine; if ((spellId != 0 && (bool)spellLevelsData.Fields["castInDiagonal"]) || (weaponData != null && !(bool)weaponData.Fields["castInLine"])) { ArrayList list = Dofus1Line.GetLine(characterPoint.X, characterPoint.Y, targetPoint.X, targetPoint.Y); int i = 0; while (i < list.Count - 1) { Dofus1Line.Point actualPoint = (Dofus1Line.Point)list[i]; Dofus1Line.Point nextPoint = (Dofus1Line.Point)list[i + 1]; i += 1; if (actualPoint.X == nextPoint.X + 1 && actualPoint.Y == nextPoint.Y + 1) continue; else if (actualPoint.X == nextPoint.X - 1 && actualPoint.Y == nextPoint.Y - 1) continue; else if (actualPoint.X == nextPoint.X + 1 && actualPoint.Y == nextPoint.Y - 1) continue; else if (actualPoint.X == nextPoint.X - 1 && actualPoint.Y == nextPoint.Y + 1) continue; return SpellInabilityReason.NotInDiagonal; } } if (((spellId != 0 && (bool)spellLevelsData.Fields["castTestLos"] && distanceToTarget > 1)) || (weaponData != null && (bool)weaponData.Fields["castTestLos"]) && distanceToTarget > 1) { ArrayList list = Dofus1Line.GetLine(characterPoint.X, characterPoint.Y, targetPoint.X, targetPoint.Y); int i = 0; while (i < list.Count - 1) { Dofus1Line.Point point3 = (Dofus1Line.Point)list[i]; MapPoint point4 = new MapPoint((int)Math.Round(Math.Floor(point3.X)), (int)Math.Round(Math.Floor(point3.Y))); if (!(IsFreeCell(point4.CellId)) || !(m_Account.MapData.Data.IsLineOfSight(point4.CellId))) return SpellInabilityReason.LineOfSight; i += 1; } } if ((TotalLaunchByCellBySpell.ContainsKey(spellId) && TotalLaunchByCellBySpell[spellId].ContainsKey(targetPoint.CellId)) && this.TotalLaunchByCellBySpell[spellId][targetPoint.CellId] >= (int)spellLevelsData.Fields["maxCastPerTarget"] && (int)spellLevelsData.Fields["maxCastPerTarget"] > 0) return SpellInabilityReason.TooManyLaunchOnCell; if (IsFreeCell(cellId)) { if ((bool)spellLevelsData.Fields["needTakenCell"]) return SpellInabilityReason.NeedTakenCell; } else if ((bool)spellLevelsData.Fields["needFreeCell"]) return SpellInabilityReason.NeedFreeCell; return SpellInabilityReason.None; }
/// <summary> /// Returns the nearest monster from our player, in the specified list. /// </summary> public BFighter NearestMonster(List<BFighter> LFighters) { MapPoint CharacterPoint = new MapPoint(this.Fighter.CellId); BFighter Fighterr = null; int SavDistance = -1; foreach (BFighter TestFighter in LFighters) { if (TestFighter.TeamId == Fighter.TeamId || TestFighter.IsAlive == false) continue; MapPoint TestFighterPoint = new MapPoint(TestFighter.CellId); int dist = new SimplePathfinder(m_Account.MapData).FindPath(CharacterPoint.CellId, TestFighterPoint.CellId).Cells.Count(); dist += CharacterPoint.DistanceToCell(TestFighterPoint); if (((dist < SavDistance) || (SavDistance == -1)) && TestFighter != this.Fighter) { SavDistance = dist; Fighterr = TestFighter; } } if (Fighterr == null) { return null; } return Fighterr; }
/// <summary> /// Returns the nearest cell from the specified fighter. Default is the nearest monster. /// </summary> public int NearestCellFrom(BFighter fighter = null) { if (fighter == null) fighter = NearestMonster(); List<int> ReachableCells = GetReachableCells(); int CellId = -1; int SavDistance = -1; foreach (int ReachableCell in ReachableCells) { MapPoint ReachableCellPoint = new MapPoint(ReachableCell); int Distance = 0; Distance = (Distance + ReachableCellPoint.DistanceToCell(new MapPoint(fighter.CellId))); if (((SavDistance == -1) || (Distance < SavDistance))) { CellId = ReachableCell; SavDistance = Distance; } } return CellId; }
public bool CanUseSpell(BSpell spell, BFighter target) { // Principally AP if (CanLaunchSpell(spell.SpellId) != SpellInabilityReason.None) { return false; } // Use without move if (CanLaunchSpell(spell.SpellId, Fighter.CellId, target.CellId) == SpellInabilityReason.None) { //if (spell.IsHandToHand && !IsHandToHand()) //{ // MapPoint characterPoint = new MapPoint(Account.Game.Fight.Fighter.CellId); // int tempDistance = characterPoint.DistanceToCell(new MapPoint(NearestMonster().CellId)); // if (tempDistance - 1 > Account.Game.Fight.Fighter.MovementPoints) // { // return false; // } //} //else if (spell.IsHandToHand && IsHandToHand()) //{ // Account.Log("No need to move maggle", LogType.DEBUG); // return true; //} //else if (!spell.IsHandToHand) //{ m_Account.Log(new BotTextInformation("No need to move maggle"),5); return true; //} } // Try with move int moveCell = -1; int distance = -1; foreach (int cell in GetReachableCells()) { //if (spell.IsHandToHand) //{ // MapPoint characterPoint = new MapPoint(cell); // int tempDistance = characterPoint.DistanceToCell(new MapPoint(target.CellId)); // if (IsHandToHand(cell) && (tempDistance < distance || distance == -1)) // { // distance = tempDistance; // moveCell = cell; // } //} if (CanLaunchSpell(spell.SpellId, cell, target.CellId) == SpellInabilityReason.None) { MapPoint characterPoint = new MapPoint(cell); int tempDistance = characterPoint.DistanceToCell(new MapPoint(target.CellId)); if (tempDistance > distance || distance == -1) { distance = tempDistance; moveCell = cell; } } } if (moveCell != -1 && moveCell != Fighter.CellId) { MoveToCell(moveCell); m_Account.Log(new BotTextInformation("CanUseSpellWithMove!"),5); return true; } // Can't use m_Account.Log(new ErrorTextInformation("CantUseSpell"),5); return false; }
/// <summary> /// Place the character according to the AI positioning. /// </summary> public void PlaceCharacter(List<short> PlacementCells) { m_error = 0; m_Account.Log(new BotTextInformation("Placement du personnage."),5); try { PlacementEnum position = m_AI.GetPositioning(); int distance = -1; int cell = -1; Dictionary<int, int> cells = new Dictionary<int, int>(); foreach (short tempCell in PlacementCells) { int tempDistance = 0; MapPoint cellPoint = new MapPoint(Convert.ToInt32(tempCell)); foreach (BFighter fighter in m_Data.Fighters) { MapPoint fighterPoint = new MapPoint(fighter.CellId); tempDistance += cellPoint.DistanceToCell(fighterPoint); } switch (position) { case PlacementEnum.Eloigné: case PlacementEnum.Far: if (distance < tempDistance || distance == -1) { distance = tempDistance; cell = Convert.ToInt32(tempCell); } break; case PlacementEnum.Near: case PlacementEnum.Rapproché: if (distance > tempDistance || distance == -1 || tempDistance == 1) { distance = tempDistance; cell = Convert.ToInt32(tempCell); } break; } } if (cell != -1) { GameFightPlacementPositionRequestMessage msg = new GameFightPlacementPositionRequestMessage((short)cell); m_Account.SocketManager.Send(msg); } } catch (Exception ex) { m_Account.Log(new ErrorTextInformation(ex.Message),0); } }
public List<MapPoint> GetListPointAtGoodDistance(MapPoint characterPoint, MapPoint elementPoint, int weaponRange) { List<MapPoint> list = new List<MapPoint>(); int num = -1; int direction = 1; while (true) { int i = 0; while (i < weaponRange) { i += 1; MapPoint nearestCellInDirection = elementPoint.GetNearestCellInDirection(direction, i); if (nearestCellInDirection.IsInMap() && Data.IsWalkable(nearestCellInDirection.CellId)) { int dist = characterPoint.DistanceToCell(nearestCellInDirection); if ((num == -1) || (num >= dist)) { if (dist < num) list.Clear(); num = dist; list.Add(nearestCellInDirection); } break; } } direction = (direction + 2); if (direction > 7) return list; } }
/// <summary> /// CanUseSpell() vérifie si le sort peut être utilisé. /// </summary> /// <param name="spell">Sort à lancé</param> /// <param name="target">Cible</param> /// <returns>False si non, true si oui. </returns> public bool CanUseSpell(BSpell spell, BFighter target) { // Principally AP if (CanLaunchSpell(spell.SpellId) != SpellInabilityReason.None) { return false; } // Use without move if (CanLaunchSpell(spell.SpellId, Fighter.CellId, target.CellId) == SpellInabilityReason.None) { Account.Log(new BotTextInformation("No need to move maggle"), 5); return true; } // Try with move int moveCell = -1; int distance = -1; foreach (int cell in GetReachableCells()) { if (CanLaunchSpell(spell.SpellId, cell, target.CellId) == SpellInabilityReason.None) { MapPoint characterPoint = new MapPoint(cell); int tempDistance = characterPoint.DistanceToCell(new MapPoint(target.CellId)); if (tempDistance > distance || distance == -1) { distance = tempDistance; moveCell = cell; } } } if (moveCell != -1 && moveCell != Fighter.CellId) { MoveToCell(moveCell); Account.Log(new BotTextInformation("CanUseSpellWithMove!"), 5); return true; } // Can't use Account.Log(new ErrorTextInformation("CantUseSpell"), 5); return false; }
/// <summary> /// GetReachableCells() récupère les cellules que l'on peut atteindre. /// </summary> /// <returns>List INT contenant les cellIds que l'on peut atteindre</returns> private List<int> GetReachableCells() { // TODO : Generate Losange form Fighter Point List<int> listCellulesMarchables = new List<int>(); MapPoint point = new MapPoint(Fighter.CellId); int movementPoints = Fighter.MovementPoints; for (int i = 0; i < 600; i++) { if (IsCellWalkable(i)) { MapPoint cellPoint = new MapPoint(i); if (cellPoint.DistanceToCell(point) <= movementPoints) listCellulesMarchables.Add(i); } } if (listCellulesMarchables.Contains(point.CellId)) listCellulesMarchables.Add(point.CellId); return listCellulesMarchables; }
public void PlaceCharacter() { m_Account.Log(new BotTextInformation("Placement du personnage"),5); try { int distance = -1; int cell = -1; Dictionary<int, int> cells = new Dictionary<int, int>(); foreach (uint tempCell in PlacementCells) { int tempDistance = 0; MapPoint cellPoint = new MapPoint(Convert.ToInt32(tempCell)); foreach (BFighter fighter in Fighters) { MapPoint fighterPoint = new MapPoint(fighter.CellId); tempDistance += cellPoint.DistanceToCell(fighterPoint); } if (m_Conf.Placement == PlacementEnum.Eloigné) { if (distance < tempDistance || distance == -1) { distance = tempDistance; cell = Convert.ToInt32(tempCell); } } else if (m_Conf.Placement == PlacementEnum.Rapproché) { if (distance > tempDistance || distance == -1 || tempDistance == 1) { distance = tempDistance; cell = Convert.ToInt32(tempCell); } } } if (cell != -1) { GameFightPlacementPositionRequestMessage msg = new GameFightPlacementPositionRequestMessage((short)cell); m_Account.SocketManager.Send(msg); } } catch (Exception ex) { m_Account.Log(new ErrorTextInformation(ex.Message),0); } }
public int NearCell() { List<int> ReachableCells = GetReachableCells(); int CellId = -1; int SavDistance = -1; foreach (int ReachableCell in ReachableCells) { MapPoint ReachableCellPoint = new MapPoint(ReachableCell); int Distance = 0; Distance = (Distance + ReachableCellPoint.DistanceToCell(new MapPoint(NearMonster.CellId))); if (((SavDistance == -1) || (Distance < SavDistance))) { CellId = ReachableCell; SavDistance = Distance; } } return CellId; }
public bool MoveToCell(int cellId) { if (cellId != Fighter.CellId) { if (!(IsCellWalkable(cellId))) { int num = -1; int num2 = 5000; MapPoint point = new MapPoint(Fighter.CellId); MapPoint point2 = new MapPoint(cellId); int direction = 1; while (true) { MapPoint nearestCellInDirection = point2.GetNearestCellInDirection(direction, 1); if (IsCellWalkable(nearestCellInDirection.CellId)) { int num4 = point.DistanceToCell(nearestCellInDirection); if (num4 < num2) { num2 = num4; num = nearestCellInDirection.CellId; } } direction = (direction + 2); if (direction > 7) { if (num == -1) return false; cellId = num; break; } } } SimplePathfinder pathfinder = new SimplePathfinder((BlueSheep.Data.D2p.Map)m_Account.Map.Data); pathfinder.SetFight(Fighters, Fighter.MovementPoints); MovementPath path = pathfinder.FindPath(Fighter.CellId, cellId); if (path != null) { List<UInt32> serverMovement = MapMovementAdapter.GetServerMovement(path); //Account.Network.SendToServer(new GameMapMovementRequestMessage(serverMovement.ToList().Select<uint, short>(ui => (short)ui).ToArray(), Account.Game.Map.Id)); using (BigEndianWriter writer = new BigEndianWriter()) { GameMapMovementRequestMessage msg = new GameMapMovementRequestMessage(serverMovement.ToList().Select<uint, short>(ui => (short)ui).ToArray(), m_Account.Map.Id); msg.Serialize(writer); writer.Content = m_Account.HumanCheck.hash_function(writer.Content); MessagePackaging pack = new MessagePackaging(writer); pack.Pack((int)msg.ProtocolID); m_Account.SocketManager.Send(pack.Writer.Content); } return true; } } return false; }
public bool MoveToCellWithDistance(int cellId, int maxDistance, bool bool1) { m_Account.ModifBar(6, 0, 0, "Déplacement"); MovementPath path = null; int savDistance = -1; MapPoint characterPoint = new MapPoint(Character.CellId); MapPoint targetPoint = new MapPoint(cellId); foreach (MapPoint point in GetListPointAtGoodDistance(characterPoint, targetPoint, maxDistance)) { Pathfinder pathFinding = null; if ((targetPoint.DistanceToCell(point) > maxDistance) || ((targetPoint.X != point.X) && (targetPoint.Y != point.Y))) continue; int distance = characterPoint.DistanceTo(point); if ((savDistance != -1) && (distance >= savDistance)) continue; if (bool1) { if (Data.IsWalkable(point.CellId)) goto Label_00A8; continue; } if (!(NothingOnCell(point.CellId))) continue; Label_00A8: pathFinding = new Pathfinder(m_Account.Map.Data, m_Account.Map); MovementPath path2 = pathFinding.FindPath(Character.CellId, point.CellId); if (path2 != null) { path = path2; savDistance = distance; } } if (path == null) return false; //if (AutoTimeout) // m_Account.Game.Character.State.SetTimeout(StateEnum.Moving, false, TimeoutMin, TimeoutMax); List<UInt32> serverMovement = MapMovementAdapter.GetServerMovement(path); int timetowait; if (serverMovement.Count() < 3) timetowait = serverMovement.Count() * 500; else { timetowait = serverMovement.Count() * 300; } //m_Account.Network.SendToServer(new GameMapMovementRequestMessage(serverMovement.Select<uint, short>(ui => (short)ui).ToArray(), Id)); using (BigEndianWriter writer = new BigEndianWriter()) { GameMapMovementRequestMessage msg = new GameMapMovementRequestMessage(serverMovement.Select<uint, short>(ui => (short)ui).ToArray(), Id); msg.Serialize(writer); writer.Content = m_Account.HumanCheck.hash_function(writer.Content); MessagePackaging pack = new MessagePackaging(writer); pack.Pack((int)msg.ProtocolID); m_Account.SocketManager.Send(pack.Writer.Content); } m_Account.Wait(timetowait, timetowait + 100); using (BigEndianWriter writer = new BigEndianWriter()) { GameMapMovementConfirmMessage newmsg = new GameMapMovementConfirmMessage(); newmsg.Serialize(writer); MessagePackaging pack = new MessagePackaging(writer); pack.Pack((int)newmsg.ProtocolID); if (m_Account.Fight != null && m_Account.Fight.IsFollowingGroup()) { m_Account.SocketManager.Send(pack.Writer.Content); m_Account.Fight.LaunchFight(m_Account.Fight.followinggroup.m_contextualId); //m_Account.Wait(3000, 4000); //if (m_Account.StatusLb.Text != "Combat") //{ // m_Account.Fight.SearchFight(); //} } else if (m_Account.Gather.Id != -1) { m_Account.SocketManager.Send(pack.Writer.Content); UseElement(m_Account.Gather.Id, m_Account.Gather.SkillInstanceUid); } else { m_Account.SocketManager.Send(pack.Writer.Content); } m_Account.ModifBar(6, 0, 0, "Connecté"); } return true; }
/// <summary> /// Check if the target is targetable by the specified spell (with and without moving). /// </summary> /// <param name="spell">Spell to launch</param> /// <param name="target">Target</param> /// <returns>The cellId we need to move to. -1 if we can't use. 0 if we don't need to move.</returns> public int CanUseSpell(BSpell spell, BFighter target) { if (CanLaunchSpell(spell.SpellId) != SpellInabilityReason.None) { return -1; } // Use without move if (CanLaunchSpellOn(spell.SpellId, Fighter.CellId, target.CellId) == SpellInabilityReason.None) { return 0; } // Try with move int moveCell = -1; int distance = -1; foreach (int cell in GetReachableCells()) { if (CanLaunchSpellOn(spell.SpellId, cell, target.CellId, true) == SpellInabilityReason.None) { MapPoint characterPoint = new MapPoint(cell); int tempDistance = characterPoint.DistanceToCell(new MapPoint(target.CellId)); if (tempDistance > distance || distance == -1) { distance = tempDistance; moveCell = cell; } } } return moveCell; }
public bool MoveToCellWithDistance(int cellId, int maxDistance, bool bool1) { MovementPath path = null; int savDistance = -1; MapPoint characterPoint = new MapPoint(m_Account.MapData.Character.disposition.cellId); MapPoint targetPoint = new MapPoint(cellId); foreach (MapPoint point in m_Account.MapData.GetListPointAtGoodDistance(characterPoint, targetPoint, maxDistance)) { Pathfinder pathFinding = null; if ((targetPoint.DistanceToCell(point) > maxDistance) || ((targetPoint.X != point.X) && (targetPoint.Y != point.Y))) continue; int distance = characterPoint.DistanceTo(point); if ((savDistance != -1) && (distance >= savDistance)) continue; if (bool1) { if (m_Account.MapData.Data.IsWalkable(point.CellId)) goto Label_00A8; continue; } if (!(m_Account.MapData.NothingOnCell(point.CellId))) continue; Label_00A8: pathFinding = new Pathfinder(m_Account.MapData); MovementPath path2 = pathFinding.FindPath(m_Account.MapData.Character.disposition.cellId, point.CellId); if (path2 != null) { path = path2; savDistance = distance; } } if (path == null) return false; List<UInt32> serverMovement = MapMovementAdapter.GetServerMovement(path); if (serverMovement[serverMovement.Count - 1] == m_Account.MapData.Character.disposition.cellId) { Moving = false; ConfirmMove(); return true; } int timetowait; if (serverMovement.Count() < 3) timetowait = serverMovement.Count() * 514; else { timetowait = serverMovement.Count() * 320; } m_time = timetowait; using (BigEndianWriter writer = new BigEndianWriter()) { GameMapMovementRequestMessage msg = new GameMapMovementRequestMessage(serverMovement.Select<uint, short>(ui => (short)ui).ToArray(), m_Account.MapData.Id); msg.Serialize(writer); writer.Content = m_Account.HumanCheck.hash_function(writer.Content); MessagePackaging pack = new MessagePackaging(writer); pack.Pack((int)msg.ProtocolID); m_Account.SocketManager.Send(pack.Writer.Content); m_Account.SetStatus(Status.Moving); Moving = true; if (m_Account.DebugMode.Checked) m_Account.Log(new DebugTextInformation("[SND] 950 (GameMapMovementRequestMessage)"), 0); } return true; }
/// <summary> /// Returns the distance between our player and the specified fighter. Default is the nearest monster. /// </summary> public int DistanceFrom(BFighter fighter = null) { if (fighter == null) fighter = NearestMonster(); MapPoint CharacterPoint = new MapPoint(Fighter.CellId); MapPoint TestFighterPoint = new MapPoint(fighter.CellId); int dist = new SimplePathfinder(m_Account.MapData).FindPath(fighter.CellId, TestFighterPoint.CellId).Cells.Count(); dist += CharacterPoint.DistanceToCell(TestFighterPoint); return dist; }
public void ProcessPathfinding() { int actualX = 0; int actualY = 0; int speed = 0; int moveCost = 0; bool isDownRightEnd = false; bool isDownRightStart = false; bool isTopRightEnd = false; bool isTopRightStart = false; MapPoint actualPoint = null; int actualDistanceToEnd = 0; double heuristic = 0; uint square = 0; if (this.OpenList.Count > 0 && !(IsClosed(this.EndY, this.EndX))) { square = NearerSquare(); this.NowY = this.OpenList[(int)square].Y; this.NowX = this.OpenList[(int)square].X; this.PreviousCellId = (new MapPoint(this.NowX, this.NowY)).CellId; CloseSquare(this.NowY, this.NowX); for (actualY = this.NowY - 1; actualY <= this.NowY + 1; actualY++) { for (actualX = this.NowX - 1; actualX <= this.NowX + 1; actualX++) { if ((new MapPoint(actualX, actualY)).IsInMap()) { if (actualY >= this.MinY && actualY < this.MaxY && actualX >= this.MinX && actualX < this.MaxX && !(actualY == this.NowY && actualX == this.NowX) && ((this.AllowDiag) || actualY == this.NowY || actualX == this.NowX && ((AllowDiagCornering) || actualY == this.NowY || actualX == this.NowX || (PointMov(this.NowX, this.NowY, this.PreviousCellId, this.AllowTroughEntity)) || (PointMov(actualX, this.NowY, this.PreviousCellId, this.AllowTroughEntity))))) { if (!(!(PointMov(this.NowX, actualY, this.PreviousCellId, this.AllowTroughEntity)) && !(PointMov(actualX, this.NowY, this.PreviousCellId, this.AllowTroughEntity)) && !this.IsFighting && (this.AllowDiag))) { if (PointMov(actualX, actualY, this.PreviousCellId, this.AllowTroughEntity)) { if (!(IsClosed(actualY, actualX))) { if (actualX == this.EndX && actualY == this.EndY) { speed = 1; } else { speed = (int)GetCellSpeed((new MapPoint(actualX, actualY)).CellId, AllowTroughEntity); } moveCost = this.GetCellInfo(this.NowY, this.NowX).MovementCost + ((actualY == this.NowY || actualX == this.NowX) ? this.HVCost : this.DCost) * speed; if (AllowTroughEntity) { isDownRightEnd = actualX + actualY == this.EndX + this.EndY; isDownRightStart = actualX + actualY == this.StartX + this.StartY; isTopRightEnd = actualX - actualY == this.EndX - this.EndY; isTopRightStart = actualX - actualY == this.StartX - this.StartY; actualPoint = new MapPoint(actualX, actualY); if (!isDownRightEnd && !isTopRightEnd || !isDownRightStart && !isTopRightStart) { moveCost = moveCost + actualPoint.DistanceToCell(this.EndPoint); moveCost = moveCost + actualPoint.DistanceToCell(this.StartPoint); } if (actualX == this.EndX || actualY == this.EndY) { moveCost = moveCost - 3; } if ((isDownRightEnd) || (isTopRightEnd) || actualX + actualY == this.NowX + this.NowY || actualX - actualY == this.NowX - this.NowY) { moveCost = moveCost - 2; } if (actualX == this.StartX || actualY == this.StartY) { moveCost = moveCost - 3; } if ((isDownRightStart) || (isTopRightStart)) { moveCost = moveCost - 2; } actualDistanceToEnd = actualPoint.DistanceToCell(this.EndPoint); if (actualDistanceToEnd < this.DistanceToEnd) { if (actualX == this.EndX || actualY == this.EndY || actualX + actualY == this.EndX + this.EndY || actualX - actualY == this.EndX - this.EndY) { this.AuxEndPoint = actualPoint; this.AuxEndX = actualX; this.AuxEndY = actualY; this.DistanceToEnd = actualDistanceToEnd; } } } if (IsOpened(actualY, actualX)) { if (moveCost < this.GetCellInfo(actualY, actualX).MovementCost) { this.OpenSquare(actualY, actualX, new[] { this.NowY, this.NowX }, moveCost, 0, true); } } else { heuristic = Convert.ToDouble(this.HeuristicCost) * Math.Sqrt((this.EndY - actualY) * (this.EndY - actualY) + (this.EndX - actualX) * (this.EndX - actualX)); OpenSquare(actualY, actualX, new[] { this.NowY, this.NowX }, moveCost, heuristic, false); } } } } } } } } ProcessPathfinding(); } else { EndPathfinding(); } }
/// <summary> /// Returns if we are currently hand to hand with the nearest monster or not. /// </summary> public bool IsHandToHand(int cell = 0) { if (cell == 0) cell = Fighter.CellId; MapPoint characterPoint = new MapPoint(cell); MapPoint targetPoint = new MapPoint(NearestMonster().CellId); if (characterPoint.DistanceToCell(targetPoint) <= 1) return true; return false; }
/// <summary> /// Move to the specified cell (Fight). /// </summary> private bool MoveToCell(int cellId) { if (cellId != m_Data.Fighter.CellId) { if (!(m_Data.IsCellWalkable(cellId))) { int num = -1; int num2 = 5000; MapPoint point = new MapPoint(m_Data.Fighter.CellId); MapPoint point2 = new MapPoint(cellId); int direction = 1; while (true) { MapPoint nearestCellInDirection = point2.GetNearestCellInDirection(direction, 1); if (m_Data.IsCellWalkable(nearestCellInDirection.CellId)) { int num4 = point.DistanceToCell(nearestCellInDirection); if (num4 < num2) { num2 = num4; num = nearestCellInDirection.CellId; } } direction = (direction + 2); if (direction > 7) { if (num == -1) return false; cellId = num; break; } } } SimplePathfinder pathfinder = new SimplePathfinder(m_Account.MapData); pathfinder.SetFight(m_Data.Fighters, m_Data.Fighter.MovementPoints); MovementPath path = pathfinder.FindPath(m_Data.Fighter.CellId, cellId); if (path != null) { List<UInt32> serverMovement = MapMovementAdapter.GetServerMovement(path); using (BigEndianWriter writer = new BigEndianWriter()) { GameMapMovementRequestMessage msg = new GameMapMovementRequestMessage(serverMovement.ToList().Select<uint, short>(ui => (short)ui).ToArray(), m_Account.MapData.Id); msg.Serialize(writer); writer.Content = m_Account.HumanCheck.hash_function(writer.Content); MessagePackaging pack = new MessagePackaging(writer); pack.Pack((int)msg.ProtocolID); flag = 0; m_Account.SocketManager.Send(pack.Writer.Content); if (m_Account.DebugMode.Checked) m_Account.Log(new DebugTextInformation("[SND] 950 (GameMapMovementRequestMessage)"), 0); } return true; } } return false; }
public SpellInabilityReason CanLaunchSpell(int spellId, int characterCellId, int cellId) { //IItem weapon = Account.Game.Character.Inventory.Items.FirstOrDefault(i => (InventoryPositionEnum)i.Position == InventoryPositionEnum.Weapon); //Weapon weaponData = null; //SpellLevel spellLevelsData = (SpellLevel)m_Account.GameDataFileAccessor.GetObject("SpellLevels", spellId); DataClass spellData = GameData.GetDataObject(D2oFileEnum.Spells, spellId); ArrayList ids = (ArrayList)spellData.Fields["spellLevels"]; int level = m_Account.Spells.FirstOrDefault(Spell => Spell.Id == spellId).Level; int id = Convert.ToInt32(ids[level - 1]); DataClass spellLevelsData = GameData.GetDataObject(D2oFileEnum.SpellLevels, id); if (spellLevelsData == null) return SpellInabilityReason.Unknown; //if (spellId == 0 && weapon != null) // weaponData = ObjectDataManager.Instance.Get<Weapon>(weapon.GID); MapPoint characterPoint = new MapPoint(characterCellId); MapPoint targetPoint = new MapPoint(cellId); int distanceToTarget = characterPoint.DistanceToCell(targetPoint); int minRange = (spellId != 0) ? (int)spellLevelsData.Fields["minRange"] : 0; //weaponData.minRange; if ((spellId != 0 && (bool)spellLevelsData.Fields["castInDiagonal"]))// || (weaponData != null && weaponData.castInDiagonal)) minRange = (minRange * 2); if (minRange < 0) minRange = 0; int maxRange = (spellId != 0) ? (int)((int)spellLevelsData.Fields["range"] + ((bool)spellLevelsData.Fields["rangeCanBeBoosted"] ? m_Account.CharacterStats.range.objectsAndMountBonus : 0)) : (int)spellLevelsData.Fields["range"]; if ((spellId != 0 && (bool)spellLevelsData.Fields["castInDiagonal"]))// || (weaponData != null && weaponData.castInDiagonal)) maxRange = (maxRange * 2); if (maxRange < 0) maxRange = 0; if (distanceToTarget < minRange && distanceToTarget > 0) return SpellInabilityReason.MinRange; if (distanceToTarget > maxRange) return SpellInabilityReason.MaxRange; if (((spellId != 0 && (bool)spellLevelsData.Fields["castInLine"]))// || (weaponData != null && weaponData.castInDiagonal)) && && characterPoint.X != targetPoint.X && characterPoint.Y != targetPoint.Y) return SpellInabilityReason.NotInLine; if ((spellId != 0 && (bool)spellLevelsData.Fields["castInDiagonal"]))// || (weaponData != null && weaponData.castInDiagonal)) { ArrayList list = Dofus1Line.GetLine(characterPoint.X, characterPoint.Y, targetPoint.X, targetPoint.Y); int i = 0; while (i < list.Count - 1) { Dofus1Line.Point actualPoint = (Dofus1Line.Point)list[i]; Dofus1Line.Point nextPoint = (Dofus1Line.Point)list[i + 1]; i += 1; if (actualPoint.X == nextPoint.X + 1 && actualPoint.Y == nextPoint.Y + 1) continue; else if (actualPoint.X == nextPoint.X - 1 && actualPoint.Y == nextPoint.Y - 1) continue; else if (actualPoint.X == nextPoint.X + 1 && actualPoint.Y == nextPoint.Y - 1) continue; else if (actualPoint.X == nextPoint.X - 1 && actualPoint.Y == nextPoint.Y + 1) continue; return SpellInabilityReason.NotInDiagonal; } } if (((spellId != 0 && (bool)spellLevelsData.Fields["castTestLos"] && distanceToTarget > 1)))// || (weaponData != null && weaponData.castTestLos)) && distanceToTarget > 1) { ArrayList list = Dofus1Line.GetLine(characterPoint.X, characterPoint.Y, targetPoint.X, targetPoint.Y); int i = 0; while (i < list.Count - 1) { Dofus1Line.Point point3 = (Dofus1Line.Point)list[i]; MapPoint point4 = new MapPoint((int)Math.Round(Math.Floor(point3.X)), (int)Math.Round(Math.Floor(point3.Y))); if (!(IsFreeCell(point4.CellId)) || !(m_Account.Map.Data.IsLineOfSight(point4.CellId))) return SpellInabilityReason.LineOfSight; i += 1; } } if ((TotalLaunchByCellBySpell.ContainsKey(spellId) && TotalLaunchByCellBySpell[spellId].ContainsKey(targetPoint.CellId)) && this.TotalLaunchByCellBySpell[spellId][targetPoint.CellId] >= (int)spellLevelsData.Fields["maxCastPerTarget"] && (int)spellLevelsData.Fields["maxCastPerTarget"] > 0) return SpellInabilityReason.TooManyLaunchOnCell; if (IsFreeCell(cellId)) { if ((bool)spellLevelsData.Fields["needTakenCell"]) return SpellInabilityReason.NeedTakenCell; } else if ((bool)spellLevelsData.Fields["needFreeCell"]) return SpellInabilityReason.NeedFreeCell; return SpellInabilityReason.None; }