2025-07-08 10:46:31 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
|
|
|
|
namespace Superlazy
|
|
|
|
|
{
|
|
|
|
|
public interface IZone
|
|
|
|
|
{
|
|
|
|
|
IEnumerable<IUnit> Units { get; }
|
|
|
|
|
SLEntity Entity { get; }
|
|
|
|
|
SLEntity Player { get; }
|
|
|
|
|
|
|
|
|
|
IUnit AddUnit(SLEntity unitEntity);
|
|
|
|
|
|
|
|
|
|
IUnit GetUnit(int handle);
|
|
|
|
|
|
|
|
|
|
SLEntity Message(string message, SLEntity context);
|
|
|
|
|
|
|
|
|
|
void Event(Unit unit, string message, SLEntity context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class Zone : IZone
|
|
|
|
|
{
|
|
|
|
|
public IEnumerable<Unit> Units => units;
|
|
|
|
|
IEnumerable<IUnit> IZone.Units => units; // 인터페이스에서는 IUnit만 적용
|
|
|
|
|
|
|
|
|
|
public SLEntity Entity { get; }
|
|
|
|
|
|
|
|
|
|
public SLEntity Player { get; }
|
|
|
|
|
|
|
|
|
|
public event Action<Unit, string, SLEntity> OnMessage;
|
|
|
|
|
|
|
|
|
|
private int handleIndex = 0;
|
|
|
|
|
private readonly Dictionary<int, Unit> unitHandles = new Dictionary<int, Unit>();
|
|
|
|
|
private readonly List<Unit> units = new List<Unit>();
|
|
|
|
|
private readonly List<Unit> addUnits = new List<Unit>();
|
|
|
|
|
private readonly List<int> removeHandles = new List<int>();
|
|
|
|
|
private bool useDelayUnit;
|
|
|
|
|
|
|
|
|
|
internal List<SLEntity> startComponents;
|
|
|
|
|
internal SortedList<int, List<SLEntity>> components;
|
|
|
|
|
internal Dictionary<string, SortedList<int, List<SLEntity>>> componentMessages;
|
|
|
|
|
|
|
|
|
|
public Zone(SLEntity session, SLEntity player)
|
|
|
|
|
{
|
|
|
|
|
Entity = session;
|
|
|
|
|
Player = player;
|
|
|
|
|
|
|
|
|
|
ZoneHandler.Begin(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IUnit AddUnit(SLEntity unitEntity)
|
|
|
|
|
{
|
|
|
|
|
var unit = new Unit(unitEntity, this);
|
|
|
|
|
|
|
|
|
|
if (useDelayUnit)
|
|
|
|
|
{
|
|
|
|
|
addUnits.Add(unit);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
AddUnit(unit);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return unit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void AddUnit(Unit unit)
|
|
|
|
|
{
|
|
|
|
|
if (unit == null)
|
|
|
|
|
{
|
|
|
|
|
SLLog.Error("Unit is null");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
handleIndex += 1;
|
|
|
|
|
|
|
|
|
|
unit.Entity["Handle"] = handleIndex;
|
|
|
|
|
|
|
|
|
|
Entity["Units"][handleIndex] = unit.Entity;
|
|
|
|
|
if (unit.Entity["UnitType"])
|
|
|
|
|
{
|
|
|
|
|
Entity["UnitTypes"][unit.Entity["UnitType"]][unit.Entity["EventID"]] = handleIndex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (unit.Entity["EventID"])
|
|
|
|
|
{
|
|
|
|
|
Entity["EventIDs"][unit.Entity["EventID"]] = handleIndex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
units.Add(unit);
|
|
|
|
|
unitHandles[handleIndex] = unit;
|
|
|
|
|
|
|
|
|
|
Event(unit, "AddUnit", unit.Entity);
|
|
|
|
|
UnitHandler.Begin(unit);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RemoveUnit(Unit unit)
|
|
|
|
|
{
|
|
|
|
|
Event(unit, "RemoveUnit", unit.Entity);
|
|
|
|
|
UnitHandler.End(unit);
|
|
|
|
|
|
|
|
|
|
if (unit.Entity["UnitType"])
|
|
|
|
|
{
|
|
|
|
|
Entity["UnitTypes"][unit.Entity["UnitType"]][unit.Entity["EventID"]] = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (unit.Entity["EventID"])
|
|
|
|
|
{
|
|
|
|
|
Entity["EventIDs"][unit.Entity["EventID"]] = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Entity["Units"][unit.Entity["Handle"]] = false;
|
|
|
|
|
|
|
|
|
|
unitHandles.Remove(unit.Entity["Handle"]);
|
|
|
|
|
units.Remove(unit);
|
|
|
|
|
|
|
|
|
|
unit.Entity["Handle"] = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IUnit GetUnit(int handle)
|
|
|
|
|
{
|
|
|
|
|
if (unitHandles.ContainsKey(handle))
|
|
|
|
|
{
|
|
|
|
|
return unitHandles[handle];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Update()
|
|
|
|
|
{
|
|
|
|
|
ZoneHandler.Update(this);
|
|
|
|
|
|
|
|
|
|
useDelayUnit = true;
|
|
|
|
|
foreach (var unit in units)
|
|
|
|
|
{
|
|
|
|
|
UnitHandler.Update(unit);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var unit in units)
|
|
|
|
|
{
|
|
|
|
|
unit.Message("OnEndUpdate", Entity);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
useDelayUnit = false;
|
|
|
|
|
|
|
|
|
|
foreach (var unit in addUnits)
|
|
|
|
|
{
|
|
|
|
|
AddUnit(unit);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
addUnits.Clear();
|
|
|
|
|
removeHandles.Clear();
|
|
|
|
|
foreach (var unit in units)
|
|
|
|
|
{
|
|
|
|
|
if (unit.Entity.HasChild("End"))
|
|
|
|
|
{
|
|
|
|
|
removeHandles.Add(unit.Entity["Handle"]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var handle in removeHandles)
|
|
|
|
|
{
|
|
|
|
|
RemoveUnit(unitHandles[handle]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SLEntity Message(string message, SLEntity context)
|
|
|
|
|
{
|
|
|
|
|
if (context)
|
|
|
|
|
{
|
|
|
|
|
context = context.Override();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
context = SLEntity.Empty; // TODO: 전달할때 빈거 전달한게 메모리가 아깝다면 최적화가 필요
|
|
|
|
|
}
|
|
|
|
|
ZoneHandler.Message(message, this, context);
|
|
|
|
|
return context;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Event(Unit unit, string message, SLEntity context)
|
|
|
|
|
{
|
|
|
|
|
OnMessage?.Invoke(unit, message, context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddComponent<T>() where T : ZoneComponent
|
|
|
|
|
{
|
|
|
|
|
ZoneHandler.AddComponent(this, typeof(T).Name, typeof(T).Name, SLEntity.Empty); // Start의 경우 이후 즉시 호출하는 케이스들 대응용으로 즉시 실행한다
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddComponent<T>(SLEntity context) where T : ZoneComponent
|
|
|
|
|
{
|
|
|
|
|
ZoneHandler.AddComponent(this, typeof(T).Name, typeof(T).Name, context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddComponent<T>(string key, SLEntity context) where T : ZoneComponent
|
|
|
|
|
{
|
|
|
|
|
ZoneHandler.AddComponent(this, key, typeof(T).Name, context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddComponent(string component)
|
|
|
|
|
{
|
|
|
|
|
ZoneHandler.AddComponent(this, component, component, SLEntity.Empty); // Start의 경우 이후 즉시 호출하는 케이스들 대응용으로 즉시 실행한다
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddComponent(string component, SLEntity context)
|
|
|
|
|
{
|
|
|
|
|
ZoneHandler.AddComponent(this, component, component, context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddComponent(string key, string component, SLEntity context)
|
|
|
|
|
{
|
|
|
|
|
ZoneHandler.AddComponent(this, key, component, context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RemoveComponent<T>() where T : ZoneComponent
|
|
|
|
|
{
|
|
|
|
|
RemoveComponent(typeof(T).Name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RemoveComponent(string component)
|
|
|
|
|
{
|
|
|
|
|
if (Entity["Components"][component] == false) return;
|
|
|
|
|
|
|
|
|
|
Entity["Components"][component]["End"] = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Clear()
|
|
|
|
|
{
|
|
|
|
|
foreach (var unit in Units)
|
|
|
|
|
{
|
|
|
|
|
unit.Entity["End"] = true;
|
|
|
|
|
unit.Entity["Force"] = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EffectView.ClearEffect();
|
|
|
|
|
|
|
|
|
|
Update();
|
|
|
|
|
handleIndex = 0;
|
|
|
|
|
ZoneHandler.End(this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|