using System; using System.Linq; using Superlazy; using UnityEngine; [ComponentOrder(2000)] public class ActionController : UnitComponent { public override void Begin(Unit unit, SLEntity component) { foreach (var e in unit.Entity["Actions"]) { var actionTag = e.ID; var action = SLSystem.Data["Actions"][e]; if (action == false) { SLLog.Error($"Action Not Found: {e.ID}:{e}"); continue; } component["Actions"][actionTag] = action.Override(); component["Actions"][actionTag]["Tag"] = actionTag; component["Actions"][actionTag]["ActionID"] = e; } if (unit.Entity["CommonAction"]) { foreach (var e in SLSystem.Data["CommonActions"]) { var actionTag = e.ID; if (component["Actions"][actionTag]) continue; var action = SLSystem.Data["Actions"][e]; if (action == false) { SLLog.Error($"Action Not Found: {e.ID}:{e}"); continue; } component["Actions"][actionTag] = action.Override(); component["Actions"][actionTag]["Tag"] = actionTag; component["Actions"][actionTag]["ActionID"] = e; } } foreach (var alternativeActions in SLSystem.Data["AlternativeActions"]) { if (unit.Entity["Actions"][alternativeActions.ID] == false) { if (alternativeActions.Any(a => unit.Entity["Actions"][a])) { var tag = alternativeActions.FirstOrDefault(a => unit.Entity["Actions"][a]); var actionID = component["Actions"][tag]["ActionID"]; component["Actions"][alternativeActions.ID] = SLSystem.Data["Actions"][actionID].Override(); component["Actions"][alternativeActions.ID]["Tag"] = alternativeActions.ID; component["Actions"][alternativeActions.ID]["ActionID"] = actionID; } else if (alternativeActions.Any(a => unit.Entity["CommonAction"] && SLSystem.Data["CommonActions"][a])) { var tag = alternativeActions.FirstOrDefault(a => SLSystem.Data["CommonActions"][a]); var actionID = component["Actions"][tag]["ActionID"]; component["Actions"][alternativeActions.ID] = SLSystem.Data["Actions"][actionID].Override(); component["Actions"][alternativeActions.ID]["Tag"] = alternativeActions.ID; component["Actions"][alternativeActions.ID]["ActionID"] = actionID; } } } UpdateAction(unit, component); } public override void End(Unit unit, SLEntity component) { foreach (var actionComponent in unit.Entity["ActionComponents"]) { actionComponent["End"] = true; } component["Actions"] = false; unit.Entity["CurrentAction"] = false; unit.Entity["Action"] = false; unit.Entity["ActionStop"] = false; } public override void Update(Unit unit, SLEntity component) { UpdateAction(unit, component); if (unit.Entity.HasChild("CurrentAction") == false) return; if (unit.Entity.HasChild("ActionStop")) { unit.Entity["ActionStop"] -= 1; if (unit.Entity["ActionStop"] <= 0) unit.Entity["ActionStop"] = false; return; } UpdateActionFrame(unit); UpdateActionMessage(unit); } public void OnEndUpdate(Unit unit, SLEntity component, SLEntity context) { UpdateAction(unit, component); } private void UpdateAction(Unit unit, SLEntity component) { if (unit.Entity.HasChild("Action")) { } else if (unit.Entity.HasChild("CurrentAction")) // 현재 액션의 원래 태그와 실제 태그가 바뀌면 액션 교체 - CustomAction Update { var currentTag = unit.Entity["CurrentAction"]["Tag"]; var newTag = unit.Entity["CurrentAction"]["OriginTag"]; if (unit.Entity.HasChild("CustomAction") && unit.Entity["CustomAction"].HasChild(newTag)) { newTag = unit.Entity["CustomAction"][currentTag]; } if (currentTag != newTag) // 태그가 변경되면 액션도 변경 { unit.Entity["Action"] = unit.Entity["CurrentAction"]["OriginTag"]; // 오리지널 태그를 오버로드 } } if (unit.Entity.HasChild("Action") == false) return; var action = unit.Entity["Action"]; var originAction = action; if (unit.Entity.HasChild("CustomAction") && unit.Entity["CustomAction"].HasChild(action)) { action = unit.Entity["CustomAction"][action]; } if (component["Actions"].HasChild(action) == false) { unit.Entity["Action"] = false; return; } if (unit.Entity.HasChild("CurrentAction")) { if (unit.Entity["CurrentAction"].HasChild("Loop") && unit.Entity["CurrentAction"]["Tag"] == action) { unit.Entity["Action"] = false; return; } } if (unit.Entity.HasChild("ActionComponents")) { foreach (var actionComponent in unit.Entity["ActionComponents"]) { actionComponent["End"] = true; } } unit.Entity["CurrentAction"] = component["Actions"][action].Override(); unit.Entity["Action"] = false; unit.Entity["CurrentAction"]["MessageIndex"] = 1; unit.Entity["CurrentAction"]["CurrentFrame"] = 0; unit.Entity["CurrentAction"]["OldFrame"] = 0; unit.Entity["CurrentAction"]["OriginTag"] = originAction; } private void UpdateActionFrame(Unit unit) { var currentAction = unit.Entity["CurrentAction"]; var delta = 1.0f; if (currentAction.HasChild("MoveSpeedBind") && unit.Entity.HasChild("MoveSpeed")) { delta *= unit.Entity["MoveSpeed"] / currentAction["MoveSpeedBind"]; } if (unit.Entity.HasChild("ActionSpeed")) { delta *= unit.Entity["ActionSpeed"]; } var newFrameDelta = delta + currentAction["CurrentFrameTime"]; var frameDelta = Mathf.FloorToInt(newFrameDelta); currentAction["CurrentFrameTime"] = newFrameDelta - frameDelta; if (frameDelta > 0) { currentAction["CurrentFrame"] += frameDelta; } } private void UpdateActionMessage(Unit unit) { var currentAction = unit.Entity["CurrentAction"]; int oldFrame = currentAction["OldFrame"]; if (currentAction.HasChild("Messages") == false) { int frame = currentAction["CurrentFrame"]; while (currentAction.HasChild("Loop") && currentAction.HasChild("Frame") && frame > currentAction["Frame"]) { int actionFrame = currentAction["Frame"]; currentAction["MessageIndex"] = 1; currentAction["OldFrame"] -= actionFrame; currentAction["CurrentFrame"] -= actionFrame; frame -= actionFrame; oldFrame -= actionFrame; } return; } var frameDiff = currentAction["CurrentFrame"] - oldFrame; for (var i = 1; i <= frameDiff; i++) { var frame = i + oldFrame; if (currentAction.HasChild("Loop") && currentAction.HasChild("Frame") && frame > currentAction["Frame"]) { int actionFrame = currentAction["Frame"]; currentAction["MessageIndex"] = 1; currentAction["OldFrame"] -= actionFrame; currentAction["CurrentFrame"] -= actionFrame; frame -= actionFrame; oldFrame -= actionFrame; } while (currentAction["Messages"].HasChild(currentAction["MessageIndex"]) && currentAction["Messages"][currentAction["MessageIndex"]]["Frame"] == frame) { var messageContext = currentAction["Messages"][currentAction["MessageIndex"]]; unit.Message(messageContext["Message"], messageContext); currentAction["MessageIndex"] += 1; } } currentAction["OldFrame"] = currentAction["CurrentFrame"]; } public void ActionCommand(Unit unit, SLEntity component, SLEntity context) { unit.AddComponent(context["Type"], context["Type"], context); unit.Entity["ActionComponents"][context["Type"]] = unit.Entity["Components"][context["Type"]].Link(); } }