using System; using System.Linq; using Superlazy; using Superlazy.UI; using UnityEngine; public class ZoneController : SLGameComponent { private static float startTime; private static int beforeFrame; private static Zone zone; private static ZoneView zoneView; private static SLCamera camera; public static event Action OnMessage; public override void Begin() { ZoneHandler.Init(); UnitHandler.Init(); startTime = Time.unscaledTime; zone = new Zone(SLGame.Session["Zone"], SLGame.Session["Player"]); zoneView = new GameObject("ZoneView").AddComponent(); zoneView.Init(zone.Entity, "ZoneView"); zone.OnMessage += OnZoneMessage; camera = UnityEngine.Object.FindFirstObjectByType(); } public static void InitCamera(int latitude, int dist, Vector3 center, Vector3 offset) { camera.InitCamera(latitude, dist, center, offset); } public static void AnchorBind(string anchorPosition, int stopDist, int moveDist, float zoomSpeed) { camera.AnchorBind(anchorPosition, stopDist, moveDist, zoomSpeed); } public static void PlayCameraOperation(SLEntity context) { if (context["Zoom"]) { var value = context["Zoom"]["Value"]; var duration = context["Zoom"]["Duration"]; var delay = context["Zoom"]["Delay"]; camera.Play(new CameraZoom(value, duration, delay)); } if (context["ZoomValue"]) { var value = context["ZoomValue"]["Value"]; var duration = context["ZoomValue"]["Duration"]; var delay = context["ZoomValue"]["Delay"]; camera.Play(new CameraZoom(value - SLGame.Session["CameraView"]["DestDistance"], duration, delay)); } if (context["Dest"]) { var dest = context["Dest"]["Value"].ToVector3(); var duration = context["Dest"]["Duration"]; var delay = context["Dest"]["Delay"]; var cameraDest = SLGame.Session["CameraView"]["Dest"].ToVector3(); camera.Play(new CameraMove(dest - cameraDest, duration, delay)); } if (context["Move"]) { var value = context["Move"]["Value"].ToVector3(); var duration = context["Move"]["Duration"]; var delay = context["Move"]["Delay"]; camera.Play(new CameraMove(value, duration, delay)); } if (context["Offset"]) { var value = context["Offset"]["Value"].ToVector3(); var duration = context["Offset"]["Duration"]; var delay = context["Offset"]["Delay"]; camera.Play(new CameraOffset(value, duration, delay)); } if (context["DestOffset"]) { var value = context["DestOffset"]["Value"].ToVector3(); var duration = context["DestOffset"]["Duration"]; var delay = context["DestOffset"]["Delay"]; var destOffset = SLGame.Session["CameraView"]["DestOffset"].ToVector3(); camera.Play(new CameraOffset(value - destOffset, duration, delay)); } if (context["Shake"]) { var value = context["Shake"]["Direction"].ToVector3().normalized; var power = context["Shake"]["Power"]; var count = context["Shake"]["Count"]; var duration = context["Shake"]["Duration"]; var delay = context["Shake"]["Delay"]; camera.Play(new CameraShake(value * power, count, duration, delay)); } if (context["Latitude"]) { var value = context["Latitude"]["Value"]; var duration = context["Latitude"]["Duration"]; var delay = context["Latitude"]["Delay"]; camera.Play(new CameraLatitude(value - SLGame.Session["CameraView"]["DestLatitude"], duration, delay)); } if (context["OffsetRotation"]) { var value = context["OffsetRotation"]["Value"]; var duration = context["OffsetRotation"]["Duration"]; var delay = context["OffsetRotation"]["Delay"]; camera.Play(new CameraRotation(value, duration, delay)); } } public static void ClearZone() { zone.Clear(); zoneView.Clear(); SLGame.ClearEvent(); SLUIEventList.Clear(); startTime = Time.time; beforeFrame = 0; } public static void ZoneMessage(string message, SLEntity context) { zone.Message(message, context); if (context["ForceUpdate"]) { zone.Update(); } } public override void Update() { SpeedUtil.Update(); var currTime = Time.time; var frame = Mathf.RoundToInt((currTime - startTime) * 60.0f); var deltaFrame = frame - beforeFrame; for (var i = 0; i < deltaFrame; ++i) { zone.Update(); } beforeFrame = frame; } public override void End() { zone.OnMessage -= OnZoneMessage; } public static void SetComponent(string component) { zone.AddComponent(component); } public static void UnsetComponent(string component) { zone.RemoveComponent(component); zone.Update(); // RemoveComponent 이후 한프레임동안 전체 컴포넌트 삭제처리등이 진행되지 않기때문에 이부분 강제 처리 추가 } // 이벤트관련 public void AddNPC(SLEntity context) { zone.Message("AddNPC", context); } public void AddParty(SLEntity context) { zone.Message("AddParty", context); } public void AddMonster(SLEntity context) { zone.Message("AddMonster", context); } public void MoveNPC(SLEntity context) { zone.Message("MoveNPC", context); } public void TileUnitAction(SLEntity context) { zone.Message("TileUnitAction", context); } public void OnZoneMessage(Unit unit, string message, SLEntity context) { OnMessage?.Invoke(unit, message, context); zoneView.Message(unit, message, context); } // TODO: 위치가 애매하긴 한데, 일단 카메라 바운더리가 편의상 여기까지밖에 안되지 않을까.. public static void SetCameraBound() { var roguelike = SLGame.Session["Roguelike"]; var minX = roguelike["Nodes"].Min(n => n["Position"]["X"]) - SLSystem.Data["Default"]["CameraBoundOffset"]; var minZ = roguelike["Nodes"].Min(n => n["Position"]["Z"]) - SLSystem.Data["Default"]["CameraBoundOffset"]; var maxX = roguelike["Nodes"].Max(n => n["Position"]["X"]) + SLSystem.Data["Default"]["CameraBoundOffset"]; var maxZ = roguelike["Nodes"].Max(n => n["Position"]["Z"]) + SLSystem.Data["Default"]["CameraBoundOffset"]; camera.SetBound(minX, minZ, maxX, maxZ); } public static void EndCameraBound() { camera.SetBound(float.MinValue, float.MinValue, float.MaxValue, float.MaxValue); } }