using System.Collections.Generic; using Godot; public abstract class GameObject { public Sector CurrentSector { get; protected set; } public Vector3 LocalCoordinates { get; protected set; } public Vector3Dec GlobalCoordinates { get; protected set; } public Vector3 SectorOffset { get; set; } private bool reassigning = false; public GameObject(Sector sector, Vector3 localCoordinates) { CurrentSector = sector; LocalCoordinates = localCoordinates; GlobalCoordinates = new ( sector.GlobalCenterCoordinates.X + (decimal)localCoordinates.X, sector.GlobalCenterCoordinates.Y + (decimal)localCoordinates.Y, sector.GlobalCenterCoordinates.Z + (decimal)localCoordinates.Z ); } public GameObject(Sector sector, double localX, double localY, double localZ) { CurrentSector = sector; LocalCoordinates = new(localX, localY, localZ); GlobalCoordinates = new ( sector.GlobalStartCoordinates.X + (decimal)localX, sector.GlobalStartCoordinates.Y + (decimal)localY, sector.GlobalStartCoordinates.Z + (decimal)localZ ); } public GameObject(Vector3Dec coordinates) { GlobalCoordinates = coordinates; UpdateSector(); } public GameObject(decimal x, decimal y, decimal z) { GlobalCoordinates = new(x, y, z); UpdateSector(); } public bool IsInCurrentSector() { return Helpers.IsInsideArea(CurrentSector.Size / 2, LocalCoordinates); } public void UpdateSector() { List neighbours = CurrentSector.GetNeighbouringSectors(); foreach (Sector sector in neighbours) { if (sector.IsObjectInSector(this)) { sector.AssignObject(this); reassigning = true; return; } } foreach (Sector sector in GameManager.Singleton.GameUniverse.Sectors) { if (sector.IsObjectInSector(this)) { sector.AssignObject(this); reassigning = true; return; } } } public void AssignSector(Sector sector) { CurrentSector = sector; ResetLocalCoordinates(); SectorOffset = GetSectorOffset(GameManager.Singleton.GetCurrentSector()); if (this is Character) { GameManager.Singleton.ApplyOrigin(); } if (this is not Character) { List neighbours = GameManager.Singleton.GetCurrentSector().GetNeighbouringSectors(); if (neighbours.Contains(sector)) { GameManager.Singleton.Spawn(this); } else { GameManager.Singleton.Despawn(this); } } reassigning = false; } public Vector3 GetSectorOffset(Sector sector) { Vector3Dec relative = CurrentSector.GlobalCenterCoordinates - sector.GlobalCenterCoordinates; return relative.ToVector3(); } public virtual void UpdateSectorOffset(Sector sector) { SectorOffset = GetSectorOffset(sector); } public void SetCoordinatesFromGlobal(Vector3Dec globalCoordinates) { GlobalCoordinates = globalCoordinates; LocalCoordinates = (globalCoordinates - CurrentSector.GlobalCenterCoordinates).ToVector3(); UpdateNodePosition(); } public void SetCoordinatesFromLocal(Vector3 localCoordinates) { LocalCoordinates = localCoordinates; GlobalCoordinates = Vector3Dec.FromVector3(localCoordinates) + CurrentSector.GlobalCenterCoordinates; UpdateNodePosition(); } public void ResetLocalCoordinates() { SetCoordinatesFromGlobal(GlobalCoordinates); } public virtual void UpdateNodePosition() { } public virtual void Simulate(double delta) { if (!reassigning && !IsInCurrentSector()) { UpdateSector(); } } public virtual Node3D Instantiate(Sector sector) { PackedScene modulePrefab = ResourceLoader.Load("res://prefabs/gameObjects/node.tscn"); return modulePrefab.Instantiate(); } }