zz
This commit is contained in:
140
GlobalShared/OcTree/OcTreeHandler.cs
Normal file
140
GlobalShared/OcTree/OcTreeHandler.cs
Normal file
@@ -0,0 +1,140 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Global.Patches;
|
||||
using Global.Shared.API;
|
||||
using Global.Shared.Events;
|
||||
using Global.Shared.OcTree.Data;
|
||||
using Global.Shared.Plugin;
|
||||
using Sandbox.Game.Entities;
|
||||
using VRage.Game.Components;
|
||||
using VRage.Game.Entity;
|
||||
using VRage.Game.ModAPI;
|
||||
|
||||
namespace Global.Shared.OcTree
|
||||
{
|
||||
public class OcTreeHandler
|
||||
{
|
||||
public GenericOcTree<GridData> GridTree { get; private set; }
|
||||
|
||||
public GenericOcTree<ControllableEntityData> CharacterTree { get; private set; }
|
||||
|
||||
internal void Init()
|
||||
{
|
||||
var cfg = GlobalInstance.Config;
|
||||
var offset = cfg.CenterPosition;
|
||||
var x = cfg.Size;
|
||||
var y = cfg.Size;
|
||||
var z = cfg.Size;
|
||||
GridTree = new GenericOcTree<GridData>(offset.X - x, offset.Y - y, offset.Z - z, x * 2, y * 2, z * 2,
|
||||
cfg.Capacity, cfg.MaxDepth);
|
||||
CharacterTree =
|
||||
new GenericOcTree<ControllableEntityData>(offset.X - x, offset.Y - y, offset.Z - z, x * 2, y * 2, z * 2,
|
||||
cfg.Capacity, cfg.MaxDepth);
|
||||
|
||||
BlockEvents.OnPlayerControlAcquired += AddControllableEntity;
|
||||
BlockEvents.OnPlayerControlReleased += RemoveControllableEntity;
|
||||
}
|
||||
|
||||
public IGridData AddGrid(MyCubeGrid grid)
|
||||
{
|
||||
var bigOwner = grid.BigOwners.Count == 0 ? "No Owner!" : grid.BigOwners.First().ToString();
|
||||
// check if grid is new subgrid
|
||||
if (MyMechanicalConnectionBlockBasePatch.IsCreatingSubPart)
|
||||
{
|
||||
GlobalInstance.Log.Trace(
|
||||
$"Grid is subgrid, ignoring {grid.DisplayName} {grid.PositionComp.GetPosition()} {bigOwner}");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!GridTree.Contains(grid.EntityId))
|
||||
{
|
||||
var grids = grid.GetGridGroup(GridLinkTypeEnum.Mechanical).GetGrids(new List<IMyCubeGrid>());
|
||||
var largestGrid = grid;
|
||||
if (grids.Count > 1)
|
||||
foreach (var g in grids.Cast<MyCubeGrid>())
|
||||
if (g.BlocksCount > largestGrid.BlocksCount)
|
||||
largestGrid = g;
|
||||
|
||||
grid = largestGrid;
|
||||
//GlobalInstance.Log.Info(
|
||||
//$"Adding grid to OcTree: {grid.EntityId} {grid.DisplayName} {grid.PositionComp.GetPosition()}");
|
||||
|
||||
var data = new GridData(grid);
|
||||
grid.PositionComp.OnPositionChanged += Grid_OnPositionChanged;
|
||||
grid.OnMarkForClose += RemoveGrid;
|
||||
grid.OnTeleported += Grid_OnChanged;
|
||||
GridTree.Insert(data);
|
||||
grid.OnConnectionChanged += Grid_OnConnectionChanged;
|
||||
|
||||
GridEvents.GridCreated?.Invoke(grid);
|
||||
return data;
|
||||
}
|
||||
|
||||
GlobalInstance.Log.Debug(
|
||||
$"Attempted to add grid to OcTree that already exists, {grid.DisplayName} {grid.PositionComp.GetPosition()} {bigOwner}");
|
||||
|
||||
var existing = GridTree[grid.EntityId];
|
||||
|
||||
if (existing != null) return existing;
|
||||
|
||||
GridTree.Remove(grid.EntityId);
|
||||
return AddGrid(grid);
|
||||
}
|
||||
|
||||
public void AddControllableEntity(IMyControllableEntity entity)
|
||||
{
|
||||
if (entity.ControllerInfo?.Controller?.Player == null && !(entity is IMyCharacter))
|
||||
//GlobalInstance.Log.Info($"Entity is not controlled {entity.Entity.EntityId} {entity.Entity.DisplayName}");
|
||||
return;
|
||||
//GlobalInstance.Log.Debug($"AddControllableEntity {entity.Entity.EntityId} {entity.Entity.DisplayName}");
|
||||
entity.Entity.OnMarkForClose += RemoveControllableEntity;
|
||||
|
||||
var data = new ControllableEntityData(entity);
|
||||
|
||||
if (!CharacterTree.Contains(entity.Entity.EntityId)) CharacterTree.Insert(data);
|
||||
}
|
||||
|
||||
public void RemoveControllableEntity(IMyControllableEntity entity)
|
||||
{
|
||||
RemoveControllableEntity((MyEntity)entity);
|
||||
}
|
||||
|
||||
public void RemoveControllableEntity(MyEntity entity)
|
||||
{
|
||||
//GlobalInstance.Log.Debug("RemoveControllableEntity");
|
||||
CharacterTree.Remove(entity.EntityId);
|
||||
}
|
||||
|
||||
private void Grid_OnConnectionChanged(MyCubeGrid arg1, GridLinkTypeEnum arg2)
|
||||
{
|
||||
if (arg2 != GridLinkTypeEnum.Mechanical) return;
|
||||
|
||||
GridTree.Update(arg1.EntityId);
|
||||
}
|
||||
|
||||
internal void RemoveGrid(MyEntity grid)
|
||||
{
|
||||
GlobalInstance.Log.Debug($"Removing grid from OcTree: {grid.EntityId} {grid.DisplayName}");
|
||||
GridEvents.GridRemoved?.Invoke(grid as MyCubeGrid);
|
||||
|
||||
grid.PositionComp.OnPositionChanged -= Grid_OnPositionChanged;
|
||||
grid.OnMarkForClose -= RemoveGrid;
|
||||
grid.OnTeleported -= Grid_OnChanged;
|
||||
|
||||
GridTree.Remove(grid.EntityId);
|
||||
}
|
||||
|
||||
private void Grid_OnChanged(MyEntity obj)
|
||||
{
|
||||
GridTree.Update(obj.EntityId);
|
||||
}
|
||||
|
||||
private void Grid_OnPositionChanged(MyPositionComponentBase obj)
|
||||
{
|
||||
if (!(obj.Entity is MyCubeGrid grid)) return;
|
||||
if (grid.Closed || grid.MarkedForClose) return;
|
||||
|
||||
GridTree.Update(grid.EntityId);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user