568 lines
21 KiB (Stored with Git LFS)
C#
568 lines
21 KiB (Stored with Git LFS)
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Superlazy;
|
|
using UnityEngine;
|
|
|
|
public static class UnitUtil
|
|
{
|
|
// Unit
|
|
public static SLEntity MakeUnitBase(string unitBind, string eventID, string unitType)
|
|
{
|
|
var unit = SLSystem.Data["Units"][unitBind].Override();
|
|
unit["EventID"] = eventID;
|
|
unit["UnitType"] = unitType;
|
|
|
|
unit.AddComponent("MoveController");
|
|
unit.AddComponent("ActionController");
|
|
|
|
return unit;
|
|
}
|
|
|
|
public static void AddComponent<T>(this SLEntity unitBase) where T : UnitComponent
|
|
{
|
|
AddComponent(unitBase, typeof(T).Name, typeof(T).Name, SLEntity.Empty);
|
|
}
|
|
|
|
public static void AddComponent<T>(this SLEntity unitBase, string key, SLEntity context) where T : UnitComponent
|
|
{
|
|
AddComponent(unitBase, key, typeof(T).Name, context);
|
|
}
|
|
|
|
public static void AddComponent(this SLEntity unitBase, string component)
|
|
{
|
|
AddComponent(unitBase, component, component, SLEntity.Empty);
|
|
}
|
|
|
|
public static void AddComponent(this SLEntity unitBase, string key, string component, SLEntity context)
|
|
{
|
|
unitBase["Components"][key] = context;
|
|
unitBase["Components"][key]["Component"] = component;
|
|
}
|
|
|
|
// Battle
|
|
|
|
public static void MakeBattleMessageContext(this SLEntity context, IUnit unit, SLEntity skill)
|
|
{
|
|
MakeBattleMessageContext(context, unit);
|
|
|
|
if (context["SkillType"] == false)
|
|
{
|
|
context["SkillType"] = skill["SkillType"];
|
|
}
|
|
|
|
if (context["UsingType"] == false)
|
|
{
|
|
context["UsingType"] = skill["UsingType"];
|
|
}
|
|
|
|
if (context["Target"] == false)
|
|
{
|
|
context["Target"] = skill["Target"];
|
|
}
|
|
|
|
if (skill["Damage"])
|
|
{
|
|
context["Damage"] = skill["Damage"];
|
|
context["Attack"] = unit.Entity["Attack"];
|
|
|
|
if (skill["SkillType"] == "NormalAttack")
|
|
{
|
|
context["Damage"] *= 1 + unit.Entity["NormalAttackDamage"];
|
|
}
|
|
else if (skill["SkillType"] == "Skill")
|
|
{
|
|
context["Damage"] *= 1 + unit.Entity["SkillDamage"];
|
|
}
|
|
|
|
if (skill["UsingType"] == "MultiAttack")
|
|
{
|
|
context["Damage"] *= 1 + unit.Entity["MultiAttackDamage"];
|
|
}
|
|
else if (skill["UsingType"] == "CounterAttack")
|
|
{
|
|
context["Damage"] *= 1 + unit.Entity["CounterAttackDamage"];
|
|
}
|
|
|
|
if (context["Projectile"]) //TODO: 가짜 프로젝타일 처리
|
|
{
|
|
context["Damage"] *= 1 + unit.Entity["ProjectileDamage"];
|
|
}
|
|
else
|
|
{
|
|
context["Damage"] *= 1 + unit.Entity["ImpactDamage"];
|
|
}
|
|
|
|
context["CriticalRatio"] = unit.Entity["CriticalRatio"];
|
|
context["CriticalDamage"] = unit.Entity["CriticalDamage"] + SLSystem.Data["Default"]["CriticalDamageBase"];
|
|
|
|
if (context["ActionStop"] == false)
|
|
{
|
|
context["ActionStop"] = 10;
|
|
}
|
|
|
|
if (context["HitStop"] == false)
|
|
{
|
|
context["HitStop"] = 10;
|
|
}
|
|
}
|
|
|
|
if (skill["Shield"])
|
|
{
|
|
context["Shield"] = Mathf.CeilToInt(skill["Shield"] * unit.Entity["MaxHP"]);
|
|
}
|
|
|
|
if (skill["Heal"])
|
|
{
|
|
context["Heal"] = Mathf.CeilToInt(skill["Heal"] * unit.Entity["Attack"] * (1 + unit.Entity["HealBoost"]));
|
|
}
|
|
|
|
if (skill["HPHeal"])
|
|
{
|
|
context["Heal"] += Mathf.CeilToInt(skill["HPHeal"] * unit.Entity["MaxHP"] * (1 + unit.Entity["HealBoost"]));
|
|
}
|
|
|
|
// 공통
|
|
if (skill["Buff"])
|
|
{
|
|
context["TargetBuffs"][skill["Buff"]].MakeBuffContext(skill["Buff"], unit, skill);
|
|
}
|
|
|
|
foreach (var hitIDBuff in skill["HitIDBuffs"])
|
|
{
|
|
if (hitIDBuff.ID != context["HitID"].ToString()) continue;
|
|
context["TargetBuffs"][hitIDBuff.ID].MakeBuffContext(hitIDBuff["Buff"], unit, hitIDBuff);
|
|
// TODO: 타겟버프 늘어나는 케이스 체크 AddedTargetBuffs 처럼
|
|
}
|
|
|
|
//foreach (var targetBuff in skill["AddedTargetBuffs"])
|
|
//{
|
|
// context["TargetBuffs"]["Added" + targetBuff.ID].MakeBuffContext(unit, targetBuff["Buff"], targetBuff);
|
|
//}
|
|
}
|
|
|
|
// Projectile등 컨텍스트만 업데이트
|
|
public static void MakeBattleMessageContext(this SLEntity context, IUnit unit)
|
|
{
|
|
// 공격하는 유닛이 죽을 경우를 대비해 Context에 나눠서 처리
|
|
if (context["Owner"] == false) // 최초대입때 Owner세팅
|
|
{
|
|
context["Owner"]["Handle"] = unit.Entity["Handle"];
|
|
context["Owner"]["Position"] = unit.Entity["Position"];
|
|
context["Owner"]["Forward"] = unit.Entity["Forward"];
|
|
context["Owner"]["UnitType"] = unit.Entity["UnitType"];
|
|
}
|
|
|
|
context["Sender"]["Handle"] = unit.Entity["Handle"];
|
|
context["Sender"]["Position"] = unit.Entity["Position"];
|
|
context["Sender"]["Forward"] = unit.Entity["Forward"];
|
|
context["Sender"]["UnitType"] = unit.Entity["UnitType"];
|
|
}
|
|
|
|
public static void SendBattleMessage(IZone zone, SLEntity targetContext, SLEntity context)
|
|
{
|
|
IUnit mainTarget = null;
|
|
|
|
if (targetContext["Handle"])
|
|
{
|
|
mainTarget = zone.GetUnit(targetContext["Handle"]);
|
|
}
|
|
|
|
var area = 0.3f; // TODO: 스플래시 등 처리
|
|
var targetPosition = targetContext["Position"].ToVector3();
|
|
// 범위 내에서 거리 이내에 있는
|
|
var targets = zone.Units.Where(u => CheckTarget(context["Owner"], context, u.Entity)
|
|
&& u.Entity["Radius"] + area >= Vector3.Distance(targetPosition, u.Entity["Position"].ToVector3()));
|
|
|
|
if (targets.Any())
|
|
{
|
|
var target = targets.MaxBy(u =>
|
|
(u.Entity["Handle"] == targetContext["Handle"] ? 100 : 0)
|
|
+ (50 - u.Entity["Radius"] - Vector3.Distance(targetPosition, u.Entity["Position"].ToVector3())));
|
|
|
|
target.Message(context["Message"], context);
|
|
}
|
|
}
|
|
|
|
public static bool CheckTarget(SLEntity currentUnit, SLEntity currentSkill, SLEntity targetUnit)
|
|
{
|
|
if (targetUnit["UnitType"] == false) return false; // 투사체? TODO
|
|
if (currentSkill["Target"] == "Self" && targetUnit["Handle"] != currentUnit["Handle"]) return false;
|
|
if (currentSkill["Target"] == "Enemy" && ((currentUnit["UnitType"] == "Ally" && targetUnit["UnitType"] == "Party") || (currentUnit["UnitType"] == "Party" && targetUnit["UnitType"] == "Ally"))) return false;
|
|
if (currentSkill["Target"] == "Enemy" && (targetUnit["UnitType"] == currentUnit["UnitType"] || targetUnit["CantTarget"] || targetUnit["CantTargetEnemy"] || (targetUnit["NoMove"] && targetUnit["MaxHP"] == false) /*|| targetUnit["HP"] == 0*/)) return false;
|
|
if (currentSkill["Target"] == "Ally" && (targetUnit["UnitType"] != currentUnit["UnitType"] || targetUnit["CantTarget"] || (targetUnit["NoMove"] && targetUnit["MaxHP"] == false) /*|| targetUnit["HP"] == 0*/)) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
public static int AddHP(this Unit unit, int addHP)
|
|
{
|
|
if (unit.Entity["MaxHP"] == false) return 0;
|
|
if (unit.Entity["HP"] == 0) return 0;
|
|
|
|
if (addHP < 0 && unit.Entity["Shield"] > 0)
|
|
{
|
|
unit.Entity["Shield"] += addHP;
|
|
if (unit.Entity["Shield"] < 0)
|
|
{
|
|
addHP = unit.Entity["Shield"];
|
|
unit.Entity["Shield"] = 0;
|
|
}
|
|
else
|
|
{
|
|
addHP = 0;
|
|
}
|
|
}
|
|
|
|
var originHP = unit.Entity["HP"];
|
|
unit.Entity["HP"] += addHP;
|
|
if (unit.Entity["HP"] > unit.Entity["MaxHP"])
|
|
{
|
|
unit.Entity["HP"] = unit.Entity["MaxHP"];
|
|
}
|
|
|
|
if (unit.Entity["HP"] <= 0)
|
|
{
|
|
unit.Entity["HP"] = 0;
|
|
}
|
|
|
|
var changedHP = unit.Entity["HP"] - originHP;
|
|
return changedHP;
|
|
}
|
|
|
|
public static void AddShield(this Unit unit, int addShield)
|
|
{
|
|
unit.Entity["Shield"] += addShield;
|
|
}
|
|
|
|
public static int BattleRandom(IZone zone, int min, int max)
|
|
{
|
|
var result = new System.Random(zone.Entity["BattleSeed"]).Next(min, max + 1);
|
|
zone.Entity["BattleSeed"] = new System.Random(zone.Entity["BattleSeed"]).Next();
|
|
return result;
|
|
}
|
|
|
|
public static double BattleRandom(IZone zone)
|
|
{
|
|
var result = new System.Random(zone.Entity["BattleSeed"]).NextDouble();
|
|
zone.Entity["BattleSeed"] = new System.Random(zone.Entity["BattleSeed"]).Next();
|
|
return result;
|
|
}
|
|
|
|
// Buff
|
|
|
|
public static void MakeBuffContext(this SLEntity context, string buff, IUnit unit, SLEntity skill)
|
|
{
|
|
var commonBuff = SLSystem.Data["Buffs"][buff];
|
|
if (commonBuff == false)
|
|
{
|
|
SLLog.Error($"[{buff}] 없음. Buffs 에서 만들어주세요");
|
|
return;
|
|
}
|
|
|
|
context["BuffKey"] = buff;
|
|
context["BuffEffect"] = buff;
|
|
context["Name"] = commonBuff["Name"];
|
|
context["Desc"] = commonBuff["Desc"];
|
|
if (commonBuff["Component"])
|
|
{
|
|
context["BuffName"] = commonBuff["Component"];
|
|
}
|
|
else
|
|
{
|
|
context["BuffName"] = "BattleBuff";
|
|
}
|
|
|
|
context["BuffType"] = commonBuff["BuffType"];
|
|
context["LookCaster"] = commonBuff["LookCaster"];
|
|
context["CantAction"] = commonBuff["CantAction"];
|
|
context["UseMove"] = commonBuff["UseMove"];
|
|
|
|
context["Owner"]["Handle"] = unit.Entity["Handle"];
|
|
context["Owner"]["UnitType"] = unit.Entity["UnitType"];
|
|
|
|
UnitHandler.MakeContext("MakeBuffContext", buff, context, unit, skill);
|
|
}
|
|
|
|
public static void BuffBegin(Unit unit, SLEntity buff)
|
|
{
|
|
if (buff["CantAction"])
|
|
{
|
|
unit.Entity["CantAction"][buff.ID] = true;
|
|
unit.Message("CancelSkill", SLEntity.Empty);
|
|
}
|
|
|
|
if (buff["LookCaster"])
|
|
{
|
|
var diff = buff["Position"].ToVector3() - unit.Entity["Position"].ToVector3();
|
|
unit.Entity["Forward"] = diff.ToEntity();
|
|
}
|
|
|
|
var statContext = SLEntity.Empty;
|
|
foreach (var stat in SLSystem.Data["Stats"])
|
|
{
|
|
if (buff[stat.ID] == false) continue; // End와 대칭맞추기용
|
|
statContext[stat.ID] = buff[stat.ID];
|
|
}
|
|
|
|
if (statContext)
|
|
{
|
|
unit.Message("AddStat", statContext);
|
|
}
|
|
}
|
|
|
|
public static void BuffUpdate(Unit unit, SLEntity buff)
|
|
{
|
|
if (buff["Duration"])
|
|
{
|
|
buff["Duration"] -= 1;
|
|
if (buff["Duration"] <= 0)
|
|
{
|
|
buff["End"] = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void BuffEnd(Unit unit, SLEntity buff)
|
|
{
|
|
if (buff["CantAction"])
|
|
{
|
|
unit.Entity["CantAction"][buff.ID] = false;
|
|
}
|
|
|
|
var statContext = SLEntity.Empty;
|
|
foreach (var stat in SLSystem.Data["Stats"])
|
|
{
|
|
if (buff[stat.ID] == false) continue; // End와 대칭맞추기용
|
|
statContext[stat.ID] = -buff[stat.ID];
|
|
}
|
|
|
|
if (statContext)
|
|
{
|
|
unit.Message("AddStat", statContext);
|
|
}
|
|
}
|
|
|
|
// action // 이건 액션컨트롤러 스태틱으로?
|
|
|
|
public static bool CanAction(this Unit unit)
|
|
{
|
|
if (unit.Entity["To"]) return false; // 이동, 넉백 등
|
|
if (unit.Entity["CantAction"]) return false; // 스턴, 사망 등
|
|
return true;
|
|
}
|
|
|
|
public static void SetActionIdle(this Unit unit)
|
|
{
|
|
if (unit.CheckActionEnd() && unit.Entity["Action"] == false)
|
|
{
|
|
unit.SetAction("Idle");
|
|
}
|
|
}
|
|
|
|
public static void SetAction(this Unit unit, string action)
|
|
{
|
|
unit.Entity["Action"] = action;
|
|
}
|
|
|
|
public static bool CheckActionEnd(this Unit unit, string frameType = null)
|
|
{
|
|
if (unit.Entity.HasChild("Action")) return false; // change Action
|
|
var currentAction = unit.Entity["CurrentAction"];
|
|
if (currentAction.HasChild("Frame") == false) return true;
|
|
if (currentAction.HasChild("Loop")) return true;
|
|
|
|
var actionEndFrame = currentAction["Frame"];
|
|
if (frameType != null && currentAction.HasChild(frameType))
|
|
{
|
|
actionEndFrame = currentAction[frameType];
|
|
}
|
|
|
|
return currentAction["CurrentFrame"] >= actionEndFrame;
|
|
}
|
|
|
|
public static SLEntity GetAction(this SLEntity unit, string action)
|
|
{
|
|
// 기본액션들이 있을 때
|
|
if (unit["Actions"][action]) return SLSystem.Data["Actions"][unit["Actions"][action]];
|
|
|
|
if (SLSystem.Data["AlternativeActions"][action])
|
|
{
|
|
// 일반액션 폴백 먼저하고 후속으로 커먼액션 폴백
|
|
foreach (var alternativeAction in SLSystem.Data["AlternativeActions"][action])
|
|
{
|
|
if (unit["Actions"][alternativeAction])
|
|
{
|
|
return SLSystem.Data["Actions"][unit["Actions"][alternativeAction]];
|
|
}
|
|
}
|
|
}
|
|
|
|
// 일반액션 폴백 먼저하고 후속으로 커먼액션 폴백
|
|
if (unit["CommonAction"])
|
|
{
|
|
if (SLSystem.Data["CommonActions"][action]) return SLSystem.Data["Actions"][SLSystem.Data["CommonActions"][action]];
|
|
}
|
|
|
|
if (SLSystem.Data["AlternativeActions"][action])
|
|
{
|
|
foreach (var alternativeAction in SLSystem.Data["AlternativeActions"][action])
|
|
{
|
|
if (unit["CommonAction"] && SLSystem.Data["CommonActions"][alternativeAction])
|
|
{
|
|
return SLSystem.Data["Actions"][SLSystem.Data["CommonActions"][alternativeAction]];
|
|
}
|
|
}
|
|
}
|
|
|
|
SLLog.Error($"[{unit["UnitType"]}] {action} 없음. Actions 에서 만들어주세요");
|
|
|
|
return SLEntity.Empty;
|
|
}
|
|
|
|
// Zone
|
|
|
|
public static IEnumerable<IUnit> GetEventTargets(this Zone zone, SLEntity targets)
|
|
{
|
|
var party = zone.Player["Party"]; // TODO: Party 체크 글로벌로 하거나 구조 동일하게 항상 유지가 불가능할것같아서 빼거나 등 필요
|
|
foreach (var target in targets)
|
|
{
|
|
if (target.ID == "NPC")
|
|
{
|
|
var id = SLGame.Session["LastTarget"]["EventID"]; // TODO: LastTarget도 애매하다
|
|
if (zone.Entity["EventIDs"][id] == false) continue;
|
|
yield return zone.GetUnit(zone.Entity["EventIDs"][id]);
|
|
}
|
|
else if (target.ID == "PartyAll")
|
|
{
|
|
var partyUnits = party.OrderBy(p => p);
|
|
|
|
foreach (var partyUnit in partyUnits)
|
|
{
|
|
if (zone.Entity["EventIDs"][partyUnit.ID] == false) continue;
|
|
if (targets.Any(t => t.ID == partyUnit.ID)) continue;
|
|
yield return zone.GetUnit(zone.Entity["EventIDs"][partyUnit.ID]);
|
|
}
|
|
}
|
|
else if (target.ID == "Party1")
|
|
{
|
|
if (party.Count() < 1) continue;
|
|
var id = party.OrderBy(p => p["Order"]).ElementAt(0).ID;
|
|
if (zone.Entity["EventIDs"][id] == false) continue;
|
|
if (targets.Any(t => t.ID == id)) continue;
|
|
yield return zone.GetUnit(zone.Entity["EventIDs"][id]);
|
|
}
|
|
else if (target.ID == "Party2")
|
|
{
|
|
if (party.Count() < 2) continue;
|
|
var id = party.OrderBy(p => p["Order"]).ElementAt(1).ID;
|
|
if (zone.Entity["EventIDs"][id] == false) continue;
|
|
if (targets.Any(t => t.ID == id)) continue;
|
|
yield return zone.GetUnit(zone.Entity["EventIDs"][id]);
|
|
}
|
|
else if (target.ID == "Party3")
|
|
{
|
|
if (party.Count() < 3) continue;
|
|
var id = party.OrderBy(p => p["Order"]).ElementAt(2).ID;
|
|
if (zone.Entity["EventIDs"][id] == false) continue;
|
|
if (targets.Any(t => t.ID == id)) continue;
|
|
yield return zone.GetUnit(zone.Entity["EventIDs"][id]);
|
|
}
|
|
else if (target.ID == "Party4")
|
|
{
|
|
if (party.Count() < 4) continue;
|
|
var id = party.OrderBy(p => p["Order"]).ElementAt(3).ID;
|
|
if (zone.Entity["EventIDs"][id] == false) continue;
|
|
if (targets.Any(t => t.ID == id)) continue;
|
|
yield return zone.GetUnit(zone.Entity["EventIDs"][id]);
|
|
}
|
|
else if (target.ID == "Party5")
|
|
{
|
|
if (party.Count() < 5) continue;
|
|
var id = party.OrderBy(p => p["Order"]).ElementAt(4).ID;
|
|
if (zone.Entity["EventIDs"][id] == false) continue;
|
|
if (targets.Any(t => t.ID == id)) continue;
|
|
yield return zone.GetUnit(zone.Entity["EventIDs"][id]);
|
|
}
|
|
else
|
|
{
|
|
if (zone.Entity["EventIDs"][target.ID] == false) continue;
|
|
yield return zone.GetUnit(zone.Entity["EventIDs"][target.ID]);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void MessageToTargets(this Zone zone, string message, SLEntity targets)
|
|
{
|
|
var party = zone.Player["Party"]; // TODO: Party 체크 글로벌로 하거나 구조 동일하게 항상 유지가 불가능할것같아서 빼거나 등 필요
|
|
foreach (var target in targets)
|
|
{
|
|
if (target.ID == "NPC")
|
|
{
|
|
var id = SLGame.Session["LastTarget"]["EventID"]; // TODO: LastTarget도 애매하다
|
|
if (zone.Entity["EventIDs"][id] == false) continue;
|
|
zone.GetUnit(zone.Entity["EventIDs"][id]).Message(message, target);
|
|
}
|
|
else if (target.ID == "PartyAll")
|
|
{
|
|
var partyUnits = party.Where(e => zone.Units.Any(u => u.Entity["UnitType"] == "Party" && u.Entity["EventID"] == e.ID)).OrderBy(p => SLSystem.Data["Characters"][p.ID]["Index"]);
|
|
|
|
foreach (var partyUnit in partyUnits)
|
|
{
|
|
if (zone.Entity["EventIDs"][partyUnit.ID] == false) continue;
|
|
if (targets.Any(t => t.ID == partyUnit.ID)) continue;
|
|
zone.GetUnit(zone.Entity["EventIDs"][partyUnit.ID]).Message(message, target);
|
|
}
|
|
}
|
|
else if (target.ID == "Party1")
|
|
{
|
|
var fieldParty = party.Where(e => zone.Units.Any(u => u.Entity["UnitType"] == "Party" && u.Entity["EventID"] == e.ID));
|
|
if (fieldParty.Count() < 1) continue;
|
|
var id = fieldParty.OrderBy(p => p["Order"]).ElementAt(0).ID;
|
|
if (zone.Entity["EventIDs"][id] == false) continue;
|
|
if (targets.Any(t => t.ID == id)) continue;
|
|
zone.GetUnit(zone.Entity["EventIDs"][id]).Message(message, target);
|
|
}
|
|
else if (target.ID == "Party2")
|
|
{
|
|
var fieldParty = party.Where(e => zone.Units.Any(u => u.Entity["UnitType"] == "Party" && u.Entity["EventID"] == e.ID));
|
|
if (fieldParty.Count() < 2) continue;
|
|
var id = fieldParty.OrderBy(p => p["Order"]).ElementAt(1).ID;
|
|
if (zone.Entity["EventIDs"][id] == false) continue;
|
|
if (targets.Any(t => t.ID == id)) continue;
|
|
zone.GetUnit(zone.Entity["EventIDs"][id]).Message(message, target);
|
|
}
|
|
else if (target.ID == "Party3")
|
|
{
|
|
var fieldParty = party.Where(e => zone.Units.Any(u => u.Entity["UnitType"] == "Party" && u.Entity["EventID"] == e.ID));
|
|
if (fieldParty.Count() < 3) continue;
|
|
var id = fieldParty.OrderBy(p => p["Order"]).ElementAt(2).ID;
|
|
if (zone.Entity["EventIDs"][id] == false) continue;
|
|
if (targets.Any(t => t.ID == id)) continue;
|
|
zone.GetUnit(zone.Entity["EventIDs"][id]).Message(message, target);
|
|
}
|
|
else if (target.ID == "Party4")
|
|
{
|
|
var fieldParty = party.Where(e => zone.Units.Any(u => u.Entity["UnitType"] == "Party" && u.Entity["EventID"] == e.ID));
|
|
if (fieldParty.Count() < 4) continue;
|
|
var id = fieldParty.OrderBy(p => p["Order"]).ElementAt(3).ID;
|
|
if (zone.Entity["EventIDs"][id] == false) continue;
|
|
if (targets.Any(t => t.ID == id)) continue;
|
|
zone.GetUnit(zone.Entity["EventIDs"][id]).Message(message, target);
|
|
}
|
|
else if (target.ID == "Party5")
|
|
{
|
|
var fieldParty = party.Where(e => zone.Units.Any(u => u.Entity["UnitType"] == "Party" && u.Entity["EventID"] == e.ID));
|
|
if (fieldParty.Count() < 5) continue;
|
|
var id = fieldParty.OrderBy(p => p["Order"]).ElementAt(4).ID;
|
|
if (zone.Entity["EventIDs"][id] == false) continue;
|
|
if (targets.Any(t => t.ID == id)) continue;
|
|
zone.GetUnit(zone.Entity["EventIDs"][id]).Message(message, target);
|
|
}
|
|
else
|
|
{
|
|
if (zone.Entity["EventIDs"][target.ID] == false) continue;
|
|
zone.GetUnit(zone.Entity["EventIDs"][target.ID]).Message(message, target);
|
|
}
|
|
}
|
|
}
|
|
} |