public List <short> GetSpellRange(short characterCellId, SpellLevels spellLevel) { List <short> range = new List <short>(); foreach (var mp in SpellShapes.GetSpellRange(characterCellId, spellLevel, _account.Game.Character.Stats.Range.Total)) { if (mp == null || range.Contains(mp.CellId)) { continue; } if (spellLevel.NeedFreeCell && OccupiedCells.Contains(mp.CellId)) { continue; } if ((_account.Game.Map.Data.Cells[mp.CellId].l & 7) == 3) { range.Add(mp.CellId); } } if (spellLevel.CastTestLos) { for (int i = range.Count - 1; i >= 0; i--) { if (Dofus1Line.IsLineObstructed(_account.Game.Map.Data, characterCellId, range[i], OccupiedCells, spellLevel.CastInDiagonal)) { range.RemoveAt(i); } } } return(range); }
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); }
/// <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)) && 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); }
protected SpellInabilityReason CanLaunchSpellOn(int spellId, int characterCellId, int cellId, bool withMove = false) { if (!withMove) { var canLaunchSpell = CanLaunchSpell(spellId); if (canLaunchSpell != SpellInabilityReason.None) { return(canLaunchSpell); } } short spellLevel; try { spellLevel = Account.Character.Spells.First(s => s.SpellId == spellId).SpellLevel; } catch (Exception e) { Console.WriteLine(e); return(SpellInabilityReason.UnknownSpell); } var spell = ObjectDataManager.Instance.Get <API.Datacenter.Spell>(spellId); var id = Convert.ToInt32(spell.SpellLevels[spellLevel - 1]); var spellLevelsData = ObjectDataManager.Instance.Get <SpellLevel>(/*spellId */ id); if (spellLevelsData == null) { return(SpellInabilityReason.Unknown); } if (spellId == 0) { return(SpellInabilityReason.UnknownSpell); } var characterPoint = new MapPoint(characterCellId); var targetPoint = new MapPoint(cellId); var distanceToTarget = characterPoint.DistanceToCell(targetPoint); var minRange = spellLevelsData.MinRange; if (spellId != 0 && spellLevelsData.CastInDiagonal) { minRange = minRange * 2; } if (minRange < 0) { minRange = 0; } var maxRange = spellId != 0 ? spellLevelsData.Range + (spellLevelsData.RangeCanBeBoosted ? Account.Character.Stats.Range.ObjectsAndMountBonus : 0) : spellLevelsData.Range; if (spellId != 0 && spellLevelsData.CastInDiagonal) { maxRange = maxRange * 2; } if (maxRange < 0) { maxRange = 0; } if (distanceToTarget < minRange) { return(SpellInabilityReason.MinRange); } if (distanceToTarget > maxRange) { return(SpellInabilityReason.MaxRange); } if (spellId != 0 && spellLevelsData.CastInLine && characterPoint.X != targetPoint.X && characterPoint.Y != targetPoint.Y) { return(SpellInabilityReason.NotInLine); } if (spellId != 0 && spellLevelsData.CastInDiagonal) { var list = Dofus1Line.GetLine(characterPoint.X, characterPoint.Y, targetPoint.X, targetPoint.Y); var i = 0; while (i < list.Count - 1) { var actualPoint = (Dofus1Line.Point)list[i]; var nextPoint = (Dofus1Line.Point)list[i + 1]; i += 1; if (actualPoint.X == nextPoint.X + 1 && actualPoint.Y == nextPoint.Y + 1) { continue; } if (actualPoint.X == nextPoint.X - 1 && actualPoint.Y == nextPoint.Y - 1) { continue; } if (actualPoint.X == nextPoint.X + 1 && actualPoint.Y == nextPoint.Y - 1) { continue; } if (actualPoint.X == nextPoint.X - 1 && actualPoint.Y == nextPoint.Y + 1) { continue; } return(SpellInabilityReason.NotInDiagonal); } } if (spellId != 0 && spellLevelsData.CastTestLos && distanceToTarget > 1) { var list = Dofus1Line.GetLine(characterPoint.X, characterPoint.Y, targetPoint.X, targetPoint.Y); var i = 0; while (i < list.Count - 1) { var point3 = (Dofus1Line.Point)list[i]; var point4 = new MapPoint((int)Math.Round(Math.Floor(point3.X)), (int)Math.Round(Math.Floor(point3.Y))); if (!IsFreeCell(point4.CellId) || !Account.Character.Map.Data.IsLineOfSight(point4.CellId)) { return(SpellInabilityReason.LineOfSight); } i += 1; } } if (TotalLaunchByCellBySpell.ContainsKey(spellId) && TotalLaunchByCellBySpell[spellId].ContainsKey(targetPoint.CellId) && TotalLaunchByCellBySpell[spellId][targetPoint.CellId] >= spellLevelsData.MaxCastPerTarget && spellLevelsData.MaxCastPerTarget > 0) { return(SpellInabilityReason.TooManyLaunchOnCell); } if (IsFreeCell(cellId)) { if (spellLevelsData.NeedTakenCell) { return(SpellInabilityReason.NeedTakenCell); } } else if (spellLevelsData.NeedFreeCell) { return(SpellInabilityReason.NeedFreeCell); } return(SpellInabilityReason.None); }