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); }