/// <summary> /// 玩家点击场景后,根据点击的位置和技能配置得到最终目标表 /// </summary> /// <param name="position"></param> /// <param name="skill"></param> /// <returns></returns> public static List <TeamDisplay> FindSkillTarget(Vector3 position, ClientSkill skill) { List <TeamDisplay> result = new List <TeamDisplay>(); if (skill.Prop.shape_type != Def.ShapeType.Circle) { return(result); } Dictionary <int, TeamDisplay> playerList = BattleSceneDisplayManager.Instance.GetTeamDisplayList(true); Dictionary <int, TeamDisplay> enemyList = BattleSceneDisplayManager.Instance.GetTeamDisplayList(false); int castTargetType = skill.Prop.cast_target_type; switch (castTargetType) { // 范围攻击,不应该只包含自己 case Def.CastTargetType.Self: break; case Def.CastTargetType.BothSides: result.AddRange(GetInAttackRangeAllShip(position, skill, playerList)); result.AddRange(GetInAttackRangeAllShip(position, skill, enemyList)); break; case Def.CastTargetType.Friend: result.AddRange(GetInAttackRangeAllShip(position, skill, playerList)); break; case Def.CastTargetType.Enemy: result.AddRange(GetInAttackRangeAllShip(position, skill, enemyList)); break; } return(result); }
// 距离最近的敌人 private static void GetClosestDefaultEnemy(ShipEntity caster, ClientSkill skill, ref List <ShipEntity> targetList) { float distSeq = float.MaxValue; int targetIndex = -1; for (int i = 0; i < EntityManager.Instance.DefenderUnitList.Count; ++i) { ShipEntity targetShip = EntityManager.Instance.DefenderUnitList[i] as ShipEntity; int seqDistance = (skill.Prop.cast_range + targetShip.Ship.Reference.vol) * (skill.Prop.cast_range + targetShip.Ship.Reference.vol); if (!IsInCricularSector2(skill.ControlPart, targetShip, seqDistance, skill.Prop.cast_angle)) { continue; } float targetDistSeq = GetDistanceSq(caster.Ship, targetShip.Ship); if (targetDistSeq < distSeq) { distSeq = targetDistSeq; targetIndex = i; } } if (targetIndex != -1) { targetList.Add(EntityManager.Instance.DefenderUnitList[targetIndex] as ShipEntity); } }
/// <summary> /// 执行技能 /// </summary> /// <param name="skill"></param> /// <param name="targetID"></param> private void DoSkill(ClientSkill skill, int targetID, Vector3 position) { proto.UseSkill useSkill = new proto.UseSkill(); useSkill.skillid = skill.ID; useSkill.unitid = this.ID; useSkill.partid = skill.ControlPart.Id; useSkill.skillstage = Def.SkillStage.Casting; useSkill.posx = (int)(position.x * 10000); useSkill.posy = (int)(position.y * 10000); useSkill.posz = (int)(position.z * 10000); FightMessageCache.Instance.AddMessage(useSkill); var targetList = TargetSelector.FindSkillTarget(this, skill, targetID, position); for (int i = 0; i < targetList.Count; ++i) { ShipEntity target = targetList[i]; proto.PartFireInfo fireInfo = new proto.PartFireInfo(); fireInfo.targetid = target.ID; fireInfo.delayframe = skill.Prop.continued_time; if (skill.Prop.missle_vel > 0) { float distance = Vector3.Distance(this.Ship.Position, target.Ship.Position); fireInfo.delayframe = Mathf.CeilToInt(distance / (skill.Prop.missle_vel * FightServiceDef.SPEED_SCALAR)); } useSkill.add_fireinfolist(fireInfo); // 给目标发一条被技能打击的消息 MessageDispatcher.Instance.DispatchMessage(TelegramType.UnderSkillAttack, this.ID, target.ID, fireInfo.delayframe, skill.Prop.effect_val, skill.Prop.skill_effect_type); } }
private IEnumerator ShowAOE(List <BulletTarget> targetList, Vector3 position, ClientSkill skill) { if (skill.Prop.skill_select_type != Def.SkillSelectType.PlayerSelect) { StartCoroutine(UpdatePosition()); CoroutineJoin join = new CoroutineJoin(AssetLoader.Instance); for (int i = 0; i < targetList.Count; i++) { BulletTarget bulletTarget = targetList[i]; TeamDisplay target = bulletTarget.Target; if (target == null) { continue; } join.StartSubtask(ShowHurtEffect(target, bulletTarget.delayFrame)); } yield return(join.WaitForAll()); } else { Global.ShowHurtEffect(null, HurtEffect_, position); } yield return(null); StartCoroutine(WaitAndDestroy(true, 2f)); }
private void InitSkillBtnList() { SkillList_ = new List <BattleSkillButton>(); SkillListRoot_ = transform.FindChild("Root/SkillList/Content"); for (int i = 0; i < SkillBtnCount; i++) { GameObject go = Global.CreateUI("BattleSkillButton", SkillListRoot_.gameObject); go.name = i.ToString(); BattleSkillButton script = go.AddComponent <BattleSkillButton>(); SkillList_.Add(script); ClientSkill skill = CommandShip_.GetSkillByIndex(i); if (skill == null) //为空的时候理解为未解锁,现在没这个状态,以后再加 //进入未解锁状态 { } else { script.SkillID = skill.ID; bool isAble = true;//是否激活,待取 script.ConfigIcon(skill.Prop.disableicon, skill.Prop.enableicon); script.EnableSkill(isAble); BattleSceneDisplayManager.EventOnSkillSing += script.ForbidFireSkill; BattleSceneDisplayManager.EventOnSkillTrigger += script.CoolDownSkill; } script.SelectedSkillCallback += SetSelectSkill; script.FireSkillCallback += FireSkill; } }
public override void Import(ClientEffect importObject, IEnumerable <FieldInfo> getters) { base.Import(importObject, getters); // count is always equals 1 for summonservant effect and // differs for summon homing bool isSummonHoming = importObject.reserved[4] != null; if (isSummonHoming) { this.npc_count = Int32.Parse(importObject.reserved[4].Trim()); this.attack_count = Int32.Parse(importObject.reserved[3].Trim()); } else { this.time = Int32.Parse(importObject.reserved[3].Trim()); } //this.time = importObject.reserved[5] != null ? Int32.Parse(importObject.reserved[5].Trim()) : 0; string skillName = importObject.reserved[8].Trim(); this.npc_id = Utility.ClientNpcIndex[skillName]; string[] nameParts = skillName.Split('_'); if (nameParts[nameParts.Length - 1] == "NPC" || nameParts[nameParts.Length - 1] == "N") { //if (nameParts.Contains("Slave")) // skillName = String.Format("{0}_{1}_{2}_{3}_{4}", // nameParts[nameParts.Length - 6], // nameParts[nameParts.Length - 5], // nameParts[nameParts.Length - 4], // nameParts[nameParts.Length - 3], // nameParts[nameParts.Length - 2]); //else skillName = String.Format("{0}_{1}", nameParts[nameParts.Length - 3], nameParts[nameParts.Length - 2]); } else { skillName = String.Format("{0}_{1}", nameParts[nameParts.Length - 2], nameParts[nameParts.Length - 1]); } ClientSkill skill = Utility.SkillIndex[skillName]; if (skill == null) { string origName = isSummonHoming ? "summonhoming" : "summonservant"; Debug.Print("Unknown skill for the {0}: {1} (skillId={2})", origName, skillName, importObject.Skill.id); } else { skill_id = skill.id; } }
public static List <ShipEntity> FindSkillTarget(ShipEntity caster, ClientSkill skill, int targetID, Vector3 position) { List <ShipEntity> targetList = new List <ShipEntity>(); if (skill.Prop.cast_target_type == Def.CastTargetType.Self) { // 针对自身 targetList.Add(caster); } else if (skill.Prop.skill_select_type == Def.SkillSelectType.CastScope) { FilterSkillTargetByCastTargetType(caster, skill, ref targetList); if (skill.Prop.shape_type == Def.ShapeType.Circle && targetList.Count == 1) { // Shape为Circle的时候,为溅射伤害 ShipEntity centerTarget = targetList[0]; FilterAllInCircleSkillTarget(skill, centerTarget.Ship.Position, EntityManager.Instance.DefenderUnitList, ref targetList); } } else if (skill.Prop.skill_select_type == Def.SkillSelectType.PlayerSelect) { if (skill.Prop.shape_type == Def.ShapeType.Default) { // 选定一个目标来攻击 ShipEntity targetEntity = EntityManager.Instance.GetEntityByID(targetID) as ShipEntity; if (targetEntity != null) { targetList.Add(targetEntity); } } else if (skill.Prop.shape_type == Def.ShapeType.Circle) { int castTargetType = skill.Prop.cast_target_type; switch (castTargetType) { case Def.CastTargetType.BothSides: FilterAllInCircleSkillTarget(skill, position, EntityManager.Instance.AttackUnitList, ref targetList); FilterAllInCircleSkillTarget(skill, position, EntityManager.Instance.DefenderUnitList, ref targetList); break; case Def.CastTargetType.Friend: FilterAllInCircleSkillTarget(skill, position, EntityManager.Instance.AttackUnitList, ref targetList); break; case Def.CastTargetType.Enemy: FilterAllInCircleSkillTarget(skill, position, EntityManager.Instance.DefenderUnitList, ref targetList); break; } } } else if (skill.Prop.skill_select_type == Def.SkillSelectType.NoSelection) { FilterSkillTargetByCastTargetType(caster, skill, ref targetList); } return(targetList); }
/// <summary> /// 播放子弹 /// </summary> /// <param name="part"></param> /// <param name="target"></param> /// <param name="delayFrame"></param> private void ShowBullet(ClientParts clientPart, List <BulletTarget> targetList, SpellType spellType, string attackPoint, string bulletPath, Effect hurtEffect, Vector3 position, ClientSkill skill = null) { Transform attackTransRoot = GetTransformByName(attackPoint); foreach (Transform attackTrans in attackTransRoot) { BulletDisplay.ShowBullet(attackTrans.position.x, attackTrans, targetList, clientPart, spellType, bulletPath, hurtEffect, position, skill); } }
private static void FilterAllInCircleSkillTarget(ClientSkill skill, Vector3 position, List <Entity> entityList, ref List <ShipEntity> targetList) { for (int i = 0; i < entityList.Count; ++i) { ShipEntity targetShip = entityList[i] as ShipEntity; if (IsInCircle(targetShip, skill.Prop.aoe_range + targetShip.Ship.Reference.vol, position.x, position.y, position.z)) { targetList.Add(targetShip); } } }
public override void Import(ClientEffect importObject, IEnumerable <FieldInfo> getters) { base.Import(importObject, getters); ClientSkill skill = Utility.SkillIndex[importObject.reserved[5].Trim()]; if (skill != null) { this.skill_id = skill.id; } }
/// <summary> /// 激活指挥技能(这个代码可能就是服务于Demo的) /// </summary> public void ActivateCommanderSkill(ClientParts part) { ClientSkill skill = ClientSkill.CreateSkillByID(part.Reference.skill_attach); if (skill == null) { return; } skill.ControlPart = part; this.SkillDic.Add(skill.ID, skill); }
/// <summary> /// 技能触发 /// </summary> /// <param name="msg"></param> private void OnSkillTrigger(Telegram msg) { ClientSkill skill = this.Ship.SkillDic[msg.Val1]; int targetID = msg.Val2; Vector3 vPosition; vPosition.x = msg.Val3; vPosition.y = msg.Val4; vPosition.z = msg.Val5; this.DoSkill(skill, targetID, vPosition); }
// 攻击范围的全体友方 // InAttackRangeAllFriend类型的特殊实现 private static void GetInAttackRangeAllFriend(ShipEntity caster, ClientSkill skill, ref List <ShipEntity> targetList) { int seqDist = skill.Prop.cast_range * skill.Prop.cast_range; for (int i = 0; i < EntityManager.Instance.AttackUnitList.Count; ++i) { ShipEntity targetEntity = EntityManager.Instance.AttackUnitList[i] as ShipEntity; if (IsInCricularSector2(skill.ControlPart, targetEntity, seqDist, skill.Prop.cast_angle)) { targetList.Add(targetEntity); } } }
/// <summary> /// ship是否在pos为圆心的范围内 /// </summary> /// <param name="pos"></param> /// <param name="ship"></param> /// <param name="skill"></param> /// <returns></returns> private static bool IsInSkillRange(Vector3 pos, TeamDisplay ship, ClientSkill skill) { proto.SkillReference reference = skill.Prop; int shapType = reference.shape_type; if (shapType != Def.ShapeType.Circle) { return(false); } int angle = 360; int range = reference.aoe_range; int vol = ship.GetShip().Reference.vol; return(IsInSector(pos, ship.GetTeamGo().transform, angle, range, vol)); }
static string getRequiredWeapons(ClientSkill sk) { string required = ""; if (sk.required_2hsword) { required += "SWORD_2H" + " "; } if (sk.required_book) { required += "BOOK_2H" + " "; } if (sk.required_bow) { required += "BOW" + " "; } if (sk.required_dagger) { required += "DAGGER_1H" + " "; } if (sk.required_mace) { required += "MACE_1H" + " "; } if (sk.required_orb) { required += "ORB_2H" + " "; } if (sk.required_polearm) { required += "POLEARM_2H" + " "; } if (sk.required_staff) { required += "STAFF_2H" + " "; } if (sk.required_sword) { required += "SWORD_1H" + " "; } if (required == "") { return(null); } return(required.Trim()); }
/// <summary> /// 根据技能配置,距离,角度得到最终的目标表 /// </summary> /// <param name="shipTrans"></param> /// <param name="skill"></param> /// <returns></returns> public static List <TeamDisplay> FindSkillTarget(TeamDisplay ship, ClientSkill skill) { // 目标表 List <TeamDisplay> result = new List <TeamDisplay>(); if (skill.Prop.cast_target_type != Def.CastTargetType.Self) { Dictionary <int, TeamDisplay> playerList = BattleSceneDisplayManager.Instance.GetTeamDisplayList(true); Dictionary <int, TeamDisplay> enemyList = BattleSceneDisplayManager.Instance.GetTeamDisplayList(false); result.AddRange(FindSkillTarget(ship.GetTeamGo().transform, skill, playerList, enemyList)); } else { result.Add(ship); } return(result); }
/// <summary> /// 释放当前选中的技能, by lxl /// </summary> private void FireSkill(int currentClickIndex) { // 旗舰 ClientShip commandShip = BattleSys.GetCommanderShip(); if (commandShip == null) { return; } bool isSelectedSkillTarget = BattleSceneDisplayManager.IsSelectedSkillTarget; // 玩家还没选择目标,给提示 if (!isSelectedSkillTarget) { // 提示玩家选择目标 ShowSelecteTargetNotice(); return; } // 得到选中的技能 ClientSkill skill = BattleSceneDisplayManager.SelectedSkill; Vector3 pos = Vector3.zero; int fightID = -1; // 如果是玩家选择的技能 if (skill.Prop.skill_select_type == Def.SkillSelectType.PlayerSelect) { // 得到玩家选择的位置或目标 if (skill.Prop.shape_type == Def.ShapeType.Default) { TeamDisplay display = (TeamDisplay)BattleSceneDisplayManager.Instance.SkillSelectParam; fightID = display.GetShip().InFightID; } else if (skill.Prop.shape_type == Def.ShapeType.Circle) { pos = (Vector3)BattleSceneDisplayManager.Instance.SkillSelectParam; } } // 使用技能 FightService.Instance.UseCommanderSkill(commandShip.InFightID, skill.ID, fightID, pos); // 技能释放完毕后要重设选择状态 BattleSceneDisplayManager.CastSkillComplete(); BattleSceneDisplayManager.CheckCommanderAttackRange(); }
/// <summary> /// 技能引导 /// </summary> /// <param name="msg"></param> private void OnSkillLead(Telegram msg) { ClientSkill skill = this.Ship.SkillDic[msg.Val1]; skill.StartCoolDown(); proto.UseSkill useSkill = new proto.UseSkill(); useSkill.unitid = this.ID; useSkill.skillid = skill.ID; useSkill.partid = skill.ControlPart.Id; useSkill.skillstage = Def.SkillStage.Sing; useSkill.posx = (int)(msg.Val3 * 10000); useSkill.posy = (int)(msg.Val4 * 10000); useSkill.posz = (int)(msg.Val5 * 10000); FightMessageCache.Instance.AddMessage(useSkill); // 再给自己发一条技能触发的延时消息 MessageDispatcher.Instance.DispatchMessage(TelegramType.SkillTrigger, this.ID, this.ID, skill.Prop.skill_lead_time, msg.Val1, msg.Val2, msg.Val3, msg.Val4, msg.Val5); }
private void ShowSelecteTargetNotice() { ClientSkill skill = BattleSceneDisplayManager.SelectedSkill; if (skill == null) { return; } // 如果是默认,提示玩家选择一个目标舰船 if (skill.Prop.shape_type == Def.ShapeType.Default) { SampleNotePopWindow.Instance.ShowMessage(1006); } // 如果是范围攻击,提示玩家选择一个目标点 else if (skill.Prop.shape_type == Def.ShapeType.Circle) { SampleNotePopWindow.Instance.ShowMessage(1007); } }
// 临时接口 public static ClientSkill CreateSkillByID(int Id) { var prop = GlobalConfig.GetSkillReference(Id); if (prop == null) { return(null); } ClientSkill skill = new ClientSkill(); skill.Prop = prop; skill.Level = 1; skill.Ammo = skill.Prop.ammo_num; skill.ID = Id; skill.CoolDownTime = skill.Prop.cd; return(skill); }
public void CheckCommanderShipSkillTarget() { // 停止之前的技能目标锁定 StopCoroutine("DelayCheckCommanderShipSkillTarget"); // 清除所有的目标框 ClearArrowGroupList(); TeamDisplay display = GetCommanderShipTeam(); if (display == null) { return; } ClientSkill skill = SelectedSkill; if (skill == null) { return; } // 开始新的技能目标锁定 StartCoroutine("DelayCheckCommanderShipSkillTarget"); }
public override void Import(ClientEffect importObject, IEnumerable <FieldInfo> getters) { base.Import(importObject, getters); this.signet = "SYSTEM_SKILL_SIGNET" + importObject.reserved[12].Trim(); this.signetlvl = Int32.Parse(importObject.reserved[13]); string signetName = String.Format("Signet1_{0}", this.signetlvl); ClientSkill skill = Utility.SkillIndex[signetName]; if (skill == null) { Debug.Print("Missing signet skill '{0}' for skillId {1}", signetName, importObject.Skill.id); } else { signetid = skill.id; } if (importObject.reserved[3] != null) { this.value = Int32.Parse(importObject.reserved[3]); this.delta = Int32.Parse(importObject.reserved[2]); } else if (importObject.reserved[1] != null) { this.value = Int32.Parse(importObject.reserved[1]); this.delta = Int32.Parse(importObject.reserved[0]); } if (importObject.reserved[6] != null) { string subName = "NormalAttack_" + importObject.reserved[6].Trim(); this.subeffect = new SubEffect(); this.subeffect.skill_id = Utility.SkillIndex[subName].id; } this.probability = Int32.Parse(importObject.reserved[15]); }
public int signetlvl; // %e1.SignetBurst.SignetGrade public override void Import(ClientEffect importObject, IEnumerable <FieldInfo> getters) { base.Import(importObject, getters); this.signet = "SYSTEM_SKILL_SIGNET" + importObject.reserved[6].Trim(); this.signetlvl = Int32.Parse(importObject.reserved[7]); this.value = Int32.Parse(importObject.reserved[1]); this.delta = Int32.Parse(importObject.reserved[0]); int[] exceptions = { 823, 824, 853, 11573 }; bool isException = exceptions.Contains(importObject.Skill.id); if (isException) { this.subeffect = new SubEffect(); string skillName = importObject.reserved[12].Trim(); ClientSkill skill = Utility.SkillIndex[skillName]; if (skill == null) { skill = Utility.SkillIndex[String.Format("NormalAttack_{0}", skillName)]; } this.subeffect.skill_id = skill.id; return; } if (importObject.reserved[14] != null) { this.subeffect = new SubEffect(); this.subeffect.skill_id = Utility.SkillIndex[importObject.reserved[14].Trim()].id; } if (importObject.reserved[12] != null) { base.AddModifiers(importObject.reserved[12].Trim().ToLower(), importObject, 5, 4); } }
/// <summary> /// 选中对应index的技能, by lxl /// </summary> /// <param name="index"></param> void SetSelectSkill(int index) { if (index != BattleSceneDisplayManager.SelectedSkillIndex) { for (int i = 0; i < SkillList_.Count; i++) { if (i != index) { //如果处于冷却状态,不应该被打断 if (!SkillList_[i].IsCooling) { SkillList_[i].EnableSkill(true); } } } } // 一般技能不需要选择目标 BattleSceneDisplayManager.IsSelectedSkillTarget = true; // 缓存技能index BattleSceneDisplayManager.SelectedSkillIndex = index; // 缓存选中技能 BattleSceneDisplayManager.SelectedSkill = CommandShip_.GetSkillByIndex(index); ClientSkill skill = BattleSceneDisplayManager.SelectedSkill; // 如果是需要玩家选择目标的技能 if (skill.Prop.skill_select_type == Def.SkillSelectType.PlayerSelect) { // 需要选择目标 BattleSceneDisplayManager.IsSelectedSkillTarget = false; // 提示玩家选择目标 ShowSelecteTargetNotice(); } // 相机设置为技能选择模式 CameraManager.Instance.SetCameraType(CameraManager.CameraStatusType.SkillSelect); // 开始显示技能范围和目标选择 BattleSceneDisplayManager.ShowCommanderShipSkillRange(); }
// 根据Shape过滤目标,提供给6~8种CastTargetType使用 private static void FilterSkillTargetByShape(ShipEntity caster, ClientSkill skill, List <Entity> entityList, ref List <ShipEntity> targetList) { for (int i = 0; i < entityList.Count; ++i) { ShipEntity targetShip = entityList[i] as ShipEntity; if (skill.Prop.shape_type == Def.ShapeType.Circle) { if (!IsInCircle(targetShip, skill.Prop.aoe_range + targetShip.Ship.Reference.vol, caster.Ship.Position.x, caster.Ship.Position.y, caster.Ship.Position.z)) { continue; } } else if (skill.Prop.shape_type == Def.ShapeType.Rectangle) { if (!IsInRectangle1(caster, targetShip, skill.Prop.radiate_len, skill.Prop.radiate_wid)) { continue; } } targetList.Add(targetShip); } }
// 攻击范围内最近的友方 // InAttackRangeClosestFriend类型的特殊实现 private static void GetInAttackRangeClosestFriend(ShipEntity caster, ClientSkill skill, ref List <ShipEntity> targetList) { int seqDist = skill.Prop.cast_range * skill.Prop.cast_range; int targetIndex = 0; float dist = float.MaxValue; for (int i = 0; i < EntityManager.Instance.AttackUnitList.Count; ++i) { ShipEntity targetEntity = EntityManager.Instance.AttackUnitList[i] as ShipEntity; if (IsInCricularSector2(skill.ControlPart, targetEntity, seqDist, skill.Prop.cast_angle)) { float distSeq = GetDistanceSq(caster.Ship, targetEntity.Ship); if (distSeq < dist) { dist = distSeq; targetIndex = i; } } } targetList.Add(EntityManager.Instance.AttackUnitList[targetIndex] as ShipEntity); }
/// <summary> /// 得到攻击范围内所有 /// </summary> /// <param name="pos"></param> /// <param name="skill"></param> /// <param name="list"></param> /// <returns></returns> private static List <TeamDisplay> GetInAttackRangeAllShip(Vector3 pos, ClientSkill skill, Dictionary <int, TeamDisplay> list) { List <TeamDisplay> result = new List <TeamDisplay>(); foreach (var iter in list) { if (iter.Value == null) { continue; } if (iter.Value.IsDead) { continue; } // 需要在范围内 if (!IsInSkillRange(pos, iter.Value, skill)) { continue; } TeamDisplay tempTrans = iter.Value; result.Add(tempTrans); } return(result); }
static void Main(string[] args) { Utility.WriteExeDetails(); Utility.LoadStrings(root); Utility.LoadClientNpcs(root); Utility.LoadItems(root); Utility.LoadSkills(root); Utility.LoadSkillLearns(root); Utility.LoadUltraSkills(root); string outputPath = Path.Combine(root, @".\output"); if (!Directory.Exists(outputPath)) { Directory.CreateDirectory(outputPath); } var outputFile = new SkillData(); var settings = new XmlWriterSettings() { CheckCharacters = false, CloseOutput = false, Indent = true, IndentChars = "\t", NewLineChars = "\n", Encoding = new UTF8Encoding(false) }; #region Pet UltraSkill parsing PetSkillTemplates petTemplates = new PetSkillTemplates(); List <PetSkill> ultraSkills = new List <PetSkill>(); foreach (var ultra in Utility.UltraSkillIndex.UltraSkillList) { PetSkill petSkill = new PetSkill(); petSkill.skill_id = Utility.SkillIndex[ultra.ultra_skill].id; if (String.Compare("Light_Summon_MagmaElemental_G1", ultra.pet_name) == 0) { ultra.pet_name = "Dark_Summon_MagmaElemental_G1"; } else if (String.Compare("Dark_Summon_TempestElemental_G1", ultra.pet_name) == 0) { ultra.pet_name = "Light_Summon_TempestElemental_G1"; } petSkill.pet_id = Utility.ClientNpcIndex[ultra.pet_name]; if (petSkill.pet_id == -1) { petSkill.missing_pet_id = ultra.pet_name; petSkill.pet_id = 0; } ClientSkill skill = Utility.SkillIndex[ultra.order_skill]; if (skill != null) { petSkill.order_skill = Utility.SkillIndex[ultra.order_skill].id; } //else // petSkill.missing_order_skill = ultra.order_skill; ultraSkills.Add(petSkill); } petTemplates.SkillList = ultraSkills.OrderBy(s => s.skill_id).ToList(); try { using (var fs = new FileStream(Path.Combine(outputPath, "pet_skills.xml"), FileMode.Create, FileAccess.Write)) using (var writer = XmlWriter.Create(fs, settings)) { XmlSerializer ser = new XmlSerializer(typeof(PetSkillTemplates)); ser.Serialize(writer, petTemplates); } } catch (Exception ex) { Debug.Print(ex.ToString()); } #endregion /* Old * var skillsetEx = new Dictionary<int, int>() { * { 1566, 1564 }, { 1586, 1564 }, { 2210, 1564 }, { 1574, 1564 }, { 1575, 1564 }, { 1576, 1564 }, * { 1596, 1564 }, { 1564, 1564 }, { 1565, 1564 }, { 1590, 1564 }, * { 1554, 1554 }, { 1588, 1554 }, * { 969, 969 }, { 970, 969 }, { 971, 969 }, { 989, 969 }, { 2181, 969 }, { 1220, 969 }, * { 1221, 969 }, { 1222, 969 }, { 1267, 969 }, { 1318, 969 }, { 1319, 969 }, { 1342, 969 }, * { 2183, 969 }, * { 1105, 1105 }, { 1107, 1105 }, { 1108, 1105 }, { 1187, 1105 }, { 1112, 1105 }, { 1186, 1105 } * }; */ // skillset_exception == client_skills.delay_id (All client skills have delay id but skills on same cooldown/exception list have the same delay id) var skillsetEx2 = new Dictionary <int, int>() { { 1564, 2 }, { 1565, 2 }, { 1566, 2 }, { 1574, 2 }, { 1575, 2 }, { 1586, 2 }, { 1590, 2 }, { 1596, 2 }, { 2210, 2 }, { 1105, 4 }, { 1107, 4 }, { 1108, 4 }, { 1112, 4 }, { 1186, 4 }, { 1187, 4 }, { 969, 5 }, { 970, 5 }, { 971, 5 }, { 989, 5 }, { 1220, 5 }, { 1221, 5 }, { 1222, 5 }, { 1267, 5 }, { 1318, 5 }, { 1319, 5 }, { 1342, 5 }, { 2181, 5 }, { 2183, 5 }, { 540, 6 }, { 1636, 6 }, { 1637, 6 }, { 1685, 6 }, { 1708, 6 }, { 1781, 6 }, { 1782, 6 }, { 1935, 6 }, { 2008, 6 }, { 2062, 6 }, { 2231, 6 }, { 2232, 6 }, { 8345, 6 }, { 173, 7 }, { 524, 7 }, { 1554, 8 }, { 1555, 8 }, { 1556, 8 }, { 1587, 8 }, { 1588, 8 }, { 955, 9 }, { 956, 9 }, { 957, 9 }, { 986, 9 }, { 1230, 9 }, { 2159, 9 }, { 2165, 9 }, { 2178, 9 }, { 559, 175 }, { 582, 175 }, { 851, 175 }, { 858, 175 }, { 948, 175 }, { 646, 2005 }, { 684, 2005 }, { 693, 2005 }, { 694, 2005 }, { 776, 2005 }, { 777, 2005 }, { 786, 2005 }, { 2075, 2005 } }; // Limit skills with same delay_id to a max # of occurances var skillset_maxoccurs = new Dictionary <int, int>() { { 646, 2 }, { 684, 2 }, { 693, 2 }, { 776, 2 }, { 777, 2 }, { 786, 2 }, { 2075, 2 } }; var delayIdOverrides = new Dictionary <int, int>() { { 11885, 11885 }, { 11886, 11885 }, { 11887, 11885 }, { 11888, 11885 }, { 11889, 11885 }, { 11890, 11890 }, { 11891, 11890 }, { 11892, 11890 }, { 11893, 11890 }, { 11894, 11890 } }; // skills which have 0 cast time or cooldown is smaller and which exclude each other var delayIdsForSkills = new Dictionary <int, int>() { { 1178, 1178 }, { 2148, 1178 }, { 1177, 1178 }, { 2147, 1178 } }; #region Finding the chainDelayIdsInclude //Dictionary<int, int> diffDelays = Utility.SkillIndex.SkillList.ToDictionary(s => s.id, s => s.delay_id); //Dictionary<int, bool> diffCount = diffDelays.Values.GroupBy(x => x).ToDictionary(x => x.Key, g => g.Count() > 1); /* * //test lookups * int skill_id = 2075; //known to have listed exception * int delay_id = 2005; //delay id associated with client skill * * if (diffCount.ContainsKey(delay_id) && diffCount[delay_id]) { * int skill_exception_test = diffDelays[skill_id]; * } */ /* * var diffDelays = Utility.SkillIndex.SkillList.Where(s => s.delay_id > 0 && * s.sub_type == SkillSubType.buff && * s.chain_category_level > 0) * .ToLookup(s => s.delay_id, s => s); * var chainCategories = new Dictionary<string, List<ClientSkill>>(); * * foreach (var group in diffDelays) { * var skills = diffDelays[group.Key]; * string[] chains = skills.Select(s => s.chain_category_priority).Distinct().ToArray(); * string categoryName = chains.Where(s => s != null).FirstOrDefault(); * if (categoryName == null) { * chains = skills.Select(s => s.prechain_skillname).Distinct().ToArray(); * categoryName = chains.Where(s => s != null).FirstOrDefault(); * } * * if (categoryName == null) * continue; * * if (chainCategories.ContainsKey(categoryName)) { * Debug.Print("Different delay id for chain: {0}", categoryName); * chainCategories[categoryName].AddRange(skills.ToList()); * } else { * chainCategories.Add(categoryName, skills.ToList()); * } * } * * chainCategories = chainCategories.Where(pair => pair.Value.Count > 1) * .OrderBy(p => p.Value.First().delay_id) * .ToDictionary(pair => pair.Key, pair => pair.Value); * * // StringBuilder sb = new StringBuilder(); * foreach (var pair in chainCategories) { * // sb.AppendFormat("SkillSet by delay: {0}\r\n", pair.Key); * foreach (var skill in pair.Value) { * // string desc = Utility.StringIndex.GetString(skill.desc); * if (skill.casting_delay == 0) { * int dur = 0; * if (skill.effect1_reserved_cond1 == null || * skill.effect1_reserved_cond1_prob2 == 100 && * skill.effect1_reserved_cond1 == "EveryHit") * dur = Math.Max(dur, skill.effect1_remain2); * if (skill.effect2_reserved_cond1 == null || * skill.effect2_reserved_cond1_prob2 == 100 && * skill.effect2_reserved_cond1 == "EveryHit") * dur = Math.Max(dur, skill.effect2_remain2); * if (skill.effect3_reserved_cond1 == null || * skill.effect3_reserved_cond1_prob2 == 100 && * skill.effect3_reserved_cond1 == "EveryHit") * dur = Math.Max(dur, skill.effect3_remain2); * if (skill.effect4_reserved_cond1 == null || * skill.effect4_reserved_cond1_prob2 == 100 && * skill.effect4_reserved_cond1 == "EveryHit") * dur = Math.Max(dur, skill.effect4_remain2); * skill.casting_delay = dur; * } * * if (skill.casting_delay == 0 || skill.casting_delay / 1000 > skill.delay_time / 100) { * sb.AppendFormat("\tSkill: id={0}; name={1}; delayId={2}; r10={3}/{4}/{5}/{6}; delay={7}; cooldown={8}\r\n", * skill.id, desc, * skill.delay_id, skill.effect1_reserved10, skill.effect2_reserved10, * skill.effect3_reserved10, skill.effect4_reserved10, * skill.casting_delay, skill.delay_time / 100); * } * } * } */ #endregion Dictionary <ClientSkill, List <ClientEffect> > list = new Dictionary <ClientSkill, List <ClientEffect> >(); Dictionary <string, HashSet <string> > statData = new Dictionary <string, HashSet <string> >(); const EffectType filterEffect = EffectType.None; const Stat filterStat = Stat.None; StringBuilder sb = new StringBuilder(); //for (var filterEffect = EffectType.None + 1; // filterEffect <= EffectType.XPBoost; filterEffect++) { foreach (var sk in Utility.SkillIndex.SkillList) { var template = new SkillTemplate(); template.skill_id = sk.id; template.name = sk.desc; // Check Skill Strings for Name ID template.nameId = Utility.StringIndex[sk.desc.ToUpper()] * 2 + 1; // SKill Name ID is Not in Skill Strings, Check Item Stings if (template.nameId == -1) { template.nameId = Utility.StringIndex[sk.desc.ToUpper()] * 2 + 1; } // SKill Name ID is Not in Item Strings, Check Main Strings if (template.nameId == -1) { template.nameId = Utility.StringIndex[sk.desc.ToUpper()] * 2 + 1; } // SKill Name ID is Not in General Strings, Check UI Strings if (template.nameId == -1) { template.nameId = Utility.StringIndex[sk.desc.ToUpper()] * 2 + 1; } string stack; int level = -1; if (level == -1) { level = Utility.GetSkillLevelFromName(sk.name, out stack); } //if (level == -1 && !String.IsNullOrEmpty(sk.skillicon_name)) // level = Utility.GetSkillLevelFromName(sk.skillicon_name, out stack); if (level == -1) { level = 1; } template.lvl = level; level = Utility.GetSkillLevelFromName(sk.desc, out stack); template.stack = stack.ToUpper(); // some overides for stack. if (sk.id == 251 || sk.id == 258 || sk.id == 385) { template.stack = "SKILL_GL_251_258_385"; } template.skilltype = (skillType)sk.type; template.skillsubtype = (skillSubType)sk.sub_type; template.tslot = (TargetSlot)sk.target_slot; template.tslot_level = sk.target_slot_level; template.activation = (activationAttribute)sk.activation_attribute; template.cooldown = sk.delay_time / 100; template.cancel_rate = sk.cancel_rate; if (sk.casting_delay > 0) { template.duration = sk.casting_delay; } template.pvp_duration = sk.pvp_remain_time_ratio; template.chain_skill_prob = sk.chain_skill_prob1 == 0 && sk.chain_skill_prob2 != 0 ? sk.chain_skill_prob2 : 0; //template.dispel_category = sk.dispel_category.ToString().ToUpper(); template.dispel_category = sk.getDispellCategory(); //template.dispel_level = sk.required_dispel_level; //template.delay_id = sk.delay_id; if (!String.IsNullOrEmpty(sk.penalty_skill_succ)) { var penaltySkill = Utility.SkillIndex[sk.penalty_skill_succ]; if (penaltySkill == null) { Debug.Print("Missing penalty skill: {0}", sk.penalty_skill_succ); } else { template.penalty_skill_id = penaltySkill.id; } } if (sk.change_stance != Stance.none) { template.stance = true; } template.pvp_damage = sk.pvp_damage_ratio; if (sk.first_target != FirstTarget.None) { //template.setproperties = new Properties(); var properties = new Properties(); properties.firsttarget = new FirstTargetProperty(); properties.firsttarget.value = (FirstTargetAttribute)sk.first_target; if (sk.first_target_valid_distance > 0) { properties.firsttargetrange = new FirstTargetRangeProperty(); properties.firsttargetrange.value = sk.first_target_valid_distance; properties.firsttargetrange.valueSpecified = true; } //else if (sk.first_target == FirstTarget.Target) // properties.firsttargetrange = new FirstTargetRangeProperty(); if (sk.target_range != TargetRange.None) { properties.target_range = new TargetRangeProperty(); if (sk.target_range_opt1 != 0) { properties.target_range.distance = sk.target_range_opt1; properties.target_range.distanceSpecified = true; } if (sk.target_maxcount != 0) { properties.target_range.maxcount = sk.target_maxcount; properties.target_range.maxcountSpecified = true; } if (sk.target_range != TargetRange.None) { properties.target_range.value = (TargetRangeAttribute)sk.target_range; } } if (sk.target_relation_restriction != RelationRestriction.None) { properties.targetrelation = new TargetRelationProperty(); properties.targetrelation.value = (TargetRelationAttribute)sk.target_relation_restriction; } if (sk.target_species_restriction != SpeciesRestriction.None) { properties.targetspecies = new TargetSpeciesProperty(); properties.targetspecies.value = (TargetSpeciesAttribute)sk.target_species_restriction; } var importUtil = Utility <ClientSkill> .Instance; List <string> states = new List <string>(); importUtil.Export <string>(sk, "target_valid_status", states); TargetState state = 0; foreach (string s in states) { try { TargetState s1 = (TargetState)Enum.Parse(typeof(TargetState), s, true); state |= s1; } catch (Exception e) { } } //if (state != TargetState.NONE) //{ // states = states.ConvertAll(s => s.ToUpper()); // List<TargetStatusProperty> statusProperties = states.ConvertAll(s => { TargetStatusProperty t = new TargetStatusProperty(); t.value = s; return t; }); // properties.targetstatus = statusProperties; //} if (sk.add_wpn_range) { template.initproperties = new Properties(); template.initproperties.addweaponrange = new AddWeaponRangeProperty(); } template.setproperties = properties; } template.useconditions = new Conditions(); template.startconditions = new Conditions(); template.actions = new Actions(); List <Condition> useList = new List <Condition>(); List <Condition> useEquipmentConditionsList = new List <Condition>(); List <Condition> startList = new List <Condition>(); List <Action> actionList = new List <Action>(); //TargetFlyingCondition targetflyingcondition = null; TargetCondition targetcondition = null; /* * if (sk.target_species_restriction != SpeciesRestriction.None && sk.target_species_restriction != SpeciesRestriction.All) * { * targetcondition = new TargetCondition((FlyingRestriction)sk.target_species_restriction); * startList.Add(targetcondition); * }*/ /* * if (sk.required_leftweapon != LeftWeapon.None) * { * useEquipmentConditionsList.Add(new ArmorCondition(sk.required_leftweapon.ToString().ToUpper())); * } */ // Periodic Actions if (sk.cost_checktime > 0 || sk.cost_toggle > 0) { PeriodicAction periodicAction = new PeriodicAction(); CostType parameter = sk.cost_checktime_parameter; if (parameter == CostType.NONE) { parameter = sk.cost_parameter; } if (parameter == CostType.MP || parameter == CostType.MP_RATIO) { var mpUseAction = new MpUseAction(); periodicAction.checktime = sk.cost_time; mpUseAction.percent = parameter == CostType.MP_RATIO; if (sk.cost_checktime_lv > 0 || sk.cost_checktime > 0) { mpUseAction.value = sk.cost_checktime; mpUseAction.delta = sk.cost_checktime_lv; } else if (sk.cost_toggle_lv > 0 || sk.cost_toggle > 0) { mpUseAction.value = sk.cost_toggle; mpUseAction.delta = sk.cost_toggle_lv; } periodicAction.mpuse = mpUseAction; } else if (parameter == CostType.HP || parameter == CostType.HP_RATIO) { var hpUseAction = new HpUseAction(); periodicAction.checktime = sk.cost_time; hpUseAction.percent = parameter == CostType.HP_RATIO; if (sk.cost_checktime_lv > 0 || sk.cost_checktime > 0) { hpUseAction.value = sk.cost_checktime; hpUseAction.delta = sk.cost_checktime_lv; } else if (sk.cost_toggle_lv > 0 || sk.cost_toggle > 0) { hpUseAction.value = sk.cost_toggle; hpUseAction.delta = sk.cost_toggle_lv; } periodicAction.hpuse = hpUseAction; } //template.periodicactions = periodicAction; } else { // Non Periodic Actions if (sk.cost_parameter != CostType.NONE && sk.cost_checktime == 0) { CostType parameter = sk.cost_checktime_parameter; if (parameter == CostType.NONE) { parameter = sk.cost_parameter; } if (parameter == CostType.MP || parameter == CostType.MP_RATIO) { var mpUseAction = new MpUseAction(); mpUseAction.percent = parameter == CostType.MP_RATIO; if (sk.cost_end > 0 || sk.cost_end_lv > 0) { mpUseAction.value = sk.cost_end; mpUseAction.delta = sk.cost_end_lv; actionList.Add(mpUseAction); } else if (sk.cost_toggle_lv > 0 || sk.cost_toggle > 0) { mpUseAction.value = sk.cost_toggle; mpUseAction.delta = sk.cost_toggle_lv; actionList.Add(mpUseAction); } } else if (parameter == CostType.HP || parameter == CostType.HP_RATIO) { var hpUseAction = new HpUseAction(); hpUseAction.percent = parameter == CostType.HP_RATIO; if (sk.cost_end > 0 || sk.cost_end_lv > 0) { hpUseAction.value = sk.cost_end; hpUseAction.delta = sk.cost_end_lv; actionList.Add(hpUseAction); } else if (sk.cost_toggle_lv > 0 || sk.cost_toggle > 0) { hpUseAction.value = sk.cost_toggle; hpUseAction.delta = sk.cost_toggle_lv; actionList.Add(hpUseAction); } } } } if (sk.cost_end != 0) { startList.Add(new MpCondition(sk.cost_end, sk.cost_end_lv)); } /* * if (sk.required_leftweapon != LeftWeapon.None) * { * startList.Add(new ArmorCondition(sk.required_leftweapon.ToString().ToUpper())); * }*/ if (sk.use_arrow != null && sk.use_arrow != "0") { // 3 arena skills have FX_pow, FX_HIT and weaponbody startList.Add(new ArrowCheckCondition()); } else { if (sk.use_arrow_count != 0) { startList.Add(new ArrowCheckCondition()); } } if (sk.cost_dp > 0) { startList.Add(new DpCondition(sk.cost_dp)); actionList.Add(new DpUseAction(sk.cost_dp, sk.cost_dp_lv)); } /* * string required_weapons = getRequiredWeapons(sk); * if (required_weapons != null) * { * startList.Add(new WeaponCondition(required_weapons)); * } * * // Target Flying Start Condition * FlyRestriction restriction = (FlyRestriction)sk.target_flying_restriction; * if (restriction != FlyRestriction.NONE) * { * if (targetflyingcondition == null) * startList.Add(new TargetFlyingCondition(restriction)); * else * targetflyingcondition.restriction = restriction; * } * * if (sk.chain_category_name != null) * { * ChainCondition chain = new ChainCondition(); * chain.category = sk.chain_category_name.ToUpper(); * * if (sk.prechain_category_name != null) chain.precategory = sk.prechain_category_name.ToUpper(); * if (sk.chain_time != null) chain.time = Int32.Parse(sk.chain_time); * * startList.Add(chain); * } */ // Self Flying Start Condition /* * restriction = (FlyRestriction)sk.self_flying_restriction; * if (restriction != FlyRestriction.NONE) * startList.Add(new SelfCondition(restriction)); * * if (sk.nouse_combat_state == 1) * { * startList.Add(new CombatCheckCondition()); * } */ if (sk.component != null) { Item item = Utility.ItemIndex.GetItem(sk.component); if (item == null) { Debug.Print("Missing item for skill {0}", sk.id); } else { actionList.Add(new ItemUseAction(item.id, sk.component_count)); } } if (!sk.move_casting) { useList.Add(new PlayerMovedCondition(false)); } #region Fill conditions and actions // Use Conditions if (useList.Count == 0) { template.useconditions = null; } else { template.useconditions.ConditionList = useList; } // Start Conditions if (startList.Count == 0) { template.startconditions = null; } else { template.startconditions.ConditionList = startList; } // Skill Actions if (actionList.Count == 0) { template.actions = null; } else { template.actions.ActionList = actionList; } #endregion if (skillsetEx2.ContainsKey(sk.id)) { template.skillset_exception = skillsetEx2[sk.id]; } /* * if (sk.delay_id != 0) * template.skillset_exception = diffCount.ContainsKey(sk.delay_id) && diffCount[sk.delay_id] == true ? diffDelays[sk.id] : 0; */ //if (delayIdsForSkills.ContainsKey(sk.id)) //{ // template.delay_id = delayIdsForSkills[sk.id]; //} //else if (delayIdOverrides.ContainsKey(sk.id)) //{ // template.delay_id = delayIdOverrides[sk.id]; //} string descrStr = sk.desc_long == null ? sk.desc : sk.desc_long; var desc = Utility.StringIndex.GetStringDescription(descrStr); string desc_2nd; if (!String.IsNullOrEmpty(sk.desc_long_2nd)) { desc_2nd = Utility.StringIndex.GetStringDescription(sk.desc_long_2nd).body; } if (sk.motion_name != ClientMotion.None) { Motion motion = new Motion(); motion.name = sk.motion_name != ClientMotion.None ? sk.motion_name.ToString().ToLower() : null; motion.instant_skill = sk.instant_skill != null && sk.instant_skill == "1" ? true : false; motion.speed = sk.motion_play_speed != 0 && sk.motion_play_speed != 100 ? sk.motion_play_speed : 0; template.motion = motion; } #region Effect processing var utility = Utility <ClientSkill> .Instance; List <ClientEffect> effects = new List <ClientEffect>(); utility.Export(sk, "effect", effects); var validEffects = effects.Where(e => e.type != EffectType.None).ToArray(); bool save = validEffects.Where(e => e.type == filterEffect).Any(); // var validEffects = effects.Where(e => e.changeStat != Stat.None).ToArray(); // bool save = validEffects.Where(e => e.changeStat == filterStat).Any(); string text = desc == null ? String.Empty : desc.body; int idx = 0; var vars = (from v in Utility.GetVarStrings(text) let parts = v.Split('.') let parsed = Int32.TryParse(parts[0].Remove(0, 1), out idx) let name = parsed ? parts[1] : v let var = parsed ? parts[2] : String.Empty select new { Id = idx, Data = new StatData(name, var) }) .ToLookup(a => a.Id, a => a); if (save) { sb.Append("\r\n"); sb.AppendFormat("---Skill Id = {0}, Name = '{1}' ---\r\n", sk.id, Utility.StringIndex.GetString(sk.desc)); if (desc == null) { sb.AppendFormat("NO DESCRIPTION\r\n"); } else { sb.AppendFormat("{0}: {1}\r\n", desc.name, desc.body); } if (sk.desc_abnormal != null) { sb.AppendFormat("ABNORMAL: {0}\r\n", Utility.StringIndex.GetString(sk.desc_abnormal)); } } foreach (var eff in validEffects) { EffectClass @class = (EffectClass)eff.type; #region Overrides #endregion Type type = effectsAssembly.GetType(String.Format("{0}.{1}", typeof(Effect).Namespace, @class.ToString())); Effect ourEffect = null; if (save) { sb.AppendFormat("Data for {0}:\r\n", @class); } if (vars.Any()) { if (vars.Contains(idx + 1)) { foreach (var v in vars[idx + 1]) { if (!statData.ContainsKey(v.Data.Name)) { statData.Add(v.Data.Name, new HashSet <string>()); } statData[v.Data.Name].Add(v.Data.Var); if (save) { sb.AppendFormat("\tEffect = {0}, Var = {1}\r\n", v.Data.Name, v.Data.Var); } } } } if (save) { sb.AppendFormat("\tE{0} Reserved: ", eff.e); using (TextWriter wr = new StringWriter(sb)) { ObjectDumper.Write(eff.reserved, wr); sb.Append("\r\n"); if (!String.IsNullOrEmpty(eff.reserved_cond1)) { sb.AppendFormat("\tCondition = {0}, Prob. = ", eff.reserved_cond1); ObjectDumper.Write(eff.reserved_cond1_prob, wr); sb.Append("\r\n"); } if (!String.IsNullOrEmpty(eff.reserved_cond2)) { sb.AppendFormat("\tCondition = {0}, Prob. = ", eff.reserved_cond2); ObjectDumper.Write(eff.reserved_cond2_prob, wr); sb.Append("\r\n"); } } } if (type == null) { string skillName = Utility.StringIndex.GetString(sk.desc); Debug.Print("Effect {0} not handled (skillId={1}; name='{2}')", @class, sk.id, skillName); continue; } else { ourEffect = (Effect)Activator.CreateInstance(type); } if (template.effects == null) { template.effects = new Effects();/* * if (sk.skillicon_name != null) * template.effects.food = sk.skillicon_name.EndsWith("_food"); */ } eff.Skill = sk; eff.Template = template; ourEffect.Import(eff, null); template.effects.EffectList.Add(ourEffect); } #endregion //if (template.effects != null && template.effects.EffectList != null) { // if (template.effects.EffectList.Count == 0) // template.effects.EffectList = null; // else if (template.activation != activationAttribute.PASSIVE) { // foreach (var eff in template.effects.EffectList) { // if (eff is DeformEffect || eff is PolymorphEffect || eff is ShapeChangeEffect || // eff is WeaponDualEffect) { // } else // eff.basiclvl = 0; // not used for active skills // } // } //} if (template.effects != null && template.effects.EffectList == null) { template.effects = null; } outputFile.SkillList.Add(template); if (filterEffect != EffectType.None) { string fileName = /*"stat_" + filterStat*/ filterEffect.ToString() + ".txt"; using (var fs = new FileStream(Path.Combine(outputPath, fileName), FileMode.Create, FileAccess.Write)) { using (TextWriter wr = new StreamWriter(fs)) { wr.Write(sb.ToString()); } } } sb.Length = 0; } try { using (var fs = new FileStream(Path.Combine(outputPath, "skill_templates.xml"), FileMode.Create, FileAccess.Write)) using (var writer = XmlWriter.Create(fs, settings)) { XmlSerializer ser = new XmlSerializer(typeof(SkillData)); ser.UnknownAttribute += new XmlAttributeEventHandler(OnUnknownAttribute); ser.UnknownElement += new XmlElementEventHandler(OnUnknownElement); ser.Serialize(writer, outputFile); } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } Console.WriteLine("Process completed"); Console.Read(); }
private static bool IsInSkillRange(Transform trans1, TeamDisplay ship2, ClientSkill skill) { return(IsInSkillRange(trans1, ship2, skill.Prop)); }
/// <summary> /// 得到技能目标表 /// </summary> /// <param name="shipTrans"></param> /// <param name="skill"></param> /// <param name="playerList"></param> /// <param name="enemyList"></param> /// <returns></returns> private static List <TeamDisplay> FindSkillTarget(Transform shipTrans, ClientSkill skill, Dictionary <int, TeamDisplay> playerList, Dictionary <int, TeamDisplay> enemyList) { List <TeamDisplay> result = new List <TeamDisplay>(); int castTargetType = skill.Prop.cast_target_type; switch (castTargetType) { case Def.CastTargetType.Default: // 攻击范围内最近敌方 result.AddRange(GetInAttackRangeClosestShip(shipTrans, skill, enemyList)); break; case Def.CastTargetType.InAttackRangeAllEnemy: // 攻击范围内的所有敌方 result.AddRange(GetInAttackRangeAllShip(shipTrans, skill, enemyList)); break; case Def.CastTargetType.InAttackRangeClosestFriend: // 攻击范围内的最近友方 result.AddRange(GetInAttackRangeAllShip(shipTrans, skill, playerList)); break; case Def.CastTargetType.InAttackRangeAllFriend: // 攻击范围内的所有友方 result.AddRange(GetInAttackRangeAllShip(shipTrans, skill, playerList)); break; case Def.CastTargetType.Self: // 自身特殊处理,避免重复入表 break; case Def.CastTargetType.BothSides: // 敌友双方 if (skill.Prop.skill_select_type == Def.SkillSelectType.PlayerSelect) { // 如果是需要玩家选择的,那么则把所有舰船入表,作预先显示 result.AddRange(GetAllShip(playerList)); result.AddRange(GetAllShip(enemyList)); } else if (skill.Prop.skill_select_type == Def.SkillSelectType.NoSelection) { // 不可选择的,那么把所有在攻击范围内的舰船入表 result.AddRange(GetInAttackRangeAllShip(shipTrans, skill, playerList)); result.AddRange(GetInAttackRangeAllShip(shipTrans, skill, enemyList)); } break; case Def.CastTargetType.Friend: // 友方 if (skill.Prop.skill_select_type == Def.SkillSelectType.PlayerSelect) { // 如果是需要玩家选择的,那么则把所有舰船入表,作预先显示 result.AddRange(GetAllShip(playerList)); } else if (skill.Prop.skill_select_type == Def.SkillSelectType.NoSelection) { // 不可选择的,那么把所有在攻击范围内的舰船入表 result.AddRange(GetInAttackRangeAllShip(shipTrans, skill, playerList)); } break; case Def.CastTargetType.Enemy: // 敌方 if (skill.Prop.skill_select_type == Def.SkillSelectType.PlayerSelect) { // 如果是需要玩家选择的,那么则把所有舰船入表,作预先显示 result.AddRange(GetAllShip(enemyList)); } else if (skill.Prop.skill_select_type == Def.SkillSelectType.NoSelection) { // 不可选择的,那么把所有在攻击范围内的舰船入表 result.AddRange(GetInAttackRangeAllShip(shipTrans, skill, enemyList)); } break; case Def.CastTargetType.ClosestFriend: // 最近友方 result.AddRange(GetClosestShip(shipTrans, GetAllShip(playerList))); break; case Def.CastTargetType.FarthestFriend: // 最远友方 result.AddRange(GetFarthestShip(shipTrans, GetAllShip(playerList))); break; case Def.CastTargetType.DurabilityLowestFriend: // 耐久最低友方 result.AddRange(GetDurabilityLowestShip(GetAllShipData(playerList))); break; case Def.CastTargetType.ArmorLowestFriend: // 装甲值最低友方 result.AddRange(GetArmorLowestShip(GetAllShipData(playerList))); break; case Def.CastTargetType.EnergyLowestFriend: // 能量值最低友方 result.AddRange(GetEnergyLowestShip(GetAllShipData(playerList))); break; case Def.CastTargetType.AllFriendBuilding: // 所有友方建筑 result.AddRange(GetAllBuilding(GetAllShipData(playerList))); break; case Def.CastTargetType.ClosestFriendBuilding: // 最近友方建筑 result.AddRange(GetClosestBuilding(shipTrans, GetAllShipData(playerList))); break; case Def.CastTargetType.AllFriend: // 全体友方 result.AddRange(GetAllShip(playerList)); break; case Def.CastTargetType.ClosestEnemy: // 最近敌方 result.AddRange(GetClosestShip(shipTrans, GetAllShip(enemyList))); break; case Def.CastTargetType.FarthestEnemy: // 最远敌方 result.AddRange(GetFarthestShip(shipTrans, GetAllShip(enemyList))); break; case Def.CastTargetType.DurabilityLowestEnemy: // 耐久值最低敌方 result.AddRange(GetDurabilityLowestShip(GetAllShipData(enemyList))); break; case Def.CastTargetType.ArmorLowestEnemy: // 装甲值最低敌方 result.AddRange(GetArmorLowestShip(GetAllShipData(enemyList))); break; case Def.CastTargetType.EnergyLowestEnemy: // 能量值最低敌方 result.AddRange(GetEnergyLowestShip(GetAllShipData(enemyList))); break; case Def.CastTargetType.AllEnemyBuilding: // 所有敌方建筑 result.AddRange(GetAllBuilding(GetAllShipData(enemyList))); break; case Def.CastTargetType.ClosestEnemyBuilding: // 最近敌方建筑 result.AddRange(GetClosestBuilding(shipTrans, GetAllShipData(enemyList))); break; case Def.CastTargetType.AllEnemy: // 全体敌方 result.AddRange(GetAllShip(enemyList)); break; case Def.CastTargetType.All: // 全体 result.AddRange(GetAllShip(playerList)); result.AddRange(GetAllShip(enemyList)); break; } return(result); }