Skip to content

Commit

Permalink
Merge pull request #297 from InvalidArgument3/ringway
Browse files Browse the repository at this point in the history
stop double teleporting you nerd
  • Loading branch information
InvalidArgument3 authored Dec 16, 2024
2 parents 38e4ee4 + 64414ab commit edeb642
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 105 deletions.
122 changes: 73 additions & 49 deletions Ringway/Data/Scripts/TeleportGateway/TeleportCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,8 @@ public static void ServerProcessTeleportRequest(TeleportRequestMessage message)
}
}

public static void TeleportEntity(IMyEntity entity, IMyCollector sourceGateway, IMyCollector destGateway) {
MyLogger.Log($"TPCore: TeleportEntity: Teleporting entity {entity.EntityId}");

public static void TeleportEntity(IMyEntity entity, IMyCollector sourceGateway, IMyCollector destGateway)
{
var relativePosition = entity.GetPosition() - sourceGateway.GetPosition();
var localPosition = Vector3D.TransformNormal(relativePosition, MatrixD.Invert(sourceGateway.WorldMatrix));
var newPosition = Vector3D.TransformNormal(localPosition, destGateway.WorldMatrix) + destGateway.GetPosition();
Expand All @@ -188,91 +187,116 @@ public static void TeleportEntity(IMyEntity entity, IMyCollector sourceGateway,
var newOrientation = relativeOrientation * destGateway.WorldMatrix;

var character = entity as IMyCharacter;
if (character != null) {
if (character != null)
{
character.Teleport(newOrientation);
character.SetWorldMatrix(newOrientation);
}
else {
else
{
var grid = entity as IMyCubeGrid;
if (grid != null) {
if (grid != null)
{
TeleportGrid(grid, newOrientation, sourceGateway.WorldMatrix, destGateway.WorldMatrix);
}
}

MyLogger.Log($"TPCore: TeleportEntity: Entity {entity.EntityId} teleported to {newPosition}");
}

private static void TeleportGrid(IMyCubeGrid mainGrid, MatrixD newOrientation, MatrixD sourceGatewayMatrix, MatrixD destinationGatewayMatrix) {
var allGrids = new List<IMyCubeGrid>();
MyAPIGateway.GridGroups.GetGroup(mainGrid, GridLinkTypeEnum.Physical, allGrids);
private static void TeleportGrid(IMyCubeGrid mainGrid, MatrixD newOrientation, MatrixD sourceGatewayMatrix, MatrixD destinationGatewayMatrix)
{
MyLogger.Log($"TPGate: TeleportGrid: Starting teleport for main grid {mainGrid.DisplayName} (EntityId: {mainGrid.EntityId})");

// Get all physically connected grids (including mechanical connections like landing gear)
var allConnectedGrids = new HashSet<IMyCubeGrid>();
var physicalGroup = MyAPIGateway.GridGroups.GetGridGroup(GridLinkTypeEnum.Physical, mainGrid);
var mechanicalGroup = MyAPIGateway.GridGroups.GetGridGroup(GridLinkTypeEnum.Mechanical, mainGrid);

// Create a new list for subgrids, excluding the main grid
var subgrids = allGrids.Where(grid => grid != mainGrid).ToList();
if (physicalGroup != null)
{
MyAPIGateway.GridGroups.GetGroup(mainGrid, GridLinkTypeEnum.Physical, allConnectedGrids);
MyLogger.Log($"TPGate: TeleportGrid: Found {allConnectedGrids.Count} physically connected grids");
}

// Dictionary to store the local matrices of each subgrid relative to the main grid
Dictionary<IMyCubeGrid, MatrixD> relativeLocalMatrices = new Dictionary<IMyCubeGrid, MatrixD>();
if (mechanicalGroup != null)
{
MyAPIGateway.GridGroups.GetGroup(mainGrid, GridLinkTypeEnum.Mechanical, allConnectedGrids);
MyLogger.Log($"TPGate: TeleportGrid: Added mechanical connections, total grids: {allConnectedGrids.Count}");
}

// Calculate and store the relative local matrix for each subgrid
foreach (var subgrid in subgrids) {
MatrixD relativeMatrix = subgrid.WorldMatrix * MatrixD.Invert(mainGrid.WorldMatrix);
relativeLocalMatrices[subgrid] = relativeMatrix;
MyLogger.Log($"TPCore: TeleportGrid: Calculated relative matrix for subgrid {subgrid.DisplayName} (EntityId: {subgrid.EntityId}), Relative Matrix: {relativeMatrix}");
// Calculate relative positions before any teleporting
var relativeMatrices = new Dictionary<IMyCubeGrid, MatrixD>();
foreach (var grid in allConnectedGrids)
{
if (grid != mainGrid)
{
MatrixD relativeMatrix = grid.WorldMatrix * MatrixD.Invert(mainGrid.WorldMatrix);
relativeMatrices[grid] = relativeMatrix;
MyLogger.Log($"TPGate: TeleportGrid: Calculated relative matrix for grid {grid.DisplayName} (EntityId: {grid.EntityId})");
}
}

// Teleport the main grid using both Teleport and WorldMatrix setting
MyLogger.Log($"TPCore: TeleportGrid: Teleporting main grid {mainGrid.DisplayName} (EntityId: {mainGrid.EntityId}), New Orientation: {newOrientation}");
// First teleport the main grid
MyLogger.Log($"TPGate: TeleportGrid: Teleporting main grid to new position");
mainGrid.Teleport(newOrientation);
mainGrid.WorldMatrix = newOrientation; //double prevents most wiggle
mainGrid.WorldMatrix = newOrientation;

// Update physics for the main grid
// Update main grid physics
var mainPhysics = mainGrid.Physics;
if (mainPhysics != null) {
if (mainPhysics != null)
{
mainPhysics.LinearVelocity = Vector3D.Zero;
mainPhysics.AngularVelocity = Vector3D.Zero;

float naturalGravityInterference;
var naturalGravity = MyAPIGateway.Physics.CalculateNaturalGravityAt(mainGrid.PositionComp.WorldAABB.Center, out naturalGravityInterference);
mainPhysics.Gravity = naturalGravity;
MyLogger.Log($"TPCore: TeleportGrid: Updated physics for main grid {mainGrid.DisplayName} (EntityId: {mainGrid.EntityId}), Linear Velocity: {mainPhysics.LinearVelocity}, Angular Velocity: {mainPhysics.AngularVelocity}, Gravity: {mainPhysics.Gravity}");
MyLogger.Log($"TPGate: TeleportGrid: Updated main grid physics - Gravity: {naturalGravity}");
}

// HashSet to track processed subgrids
HashSet<long> processedSubgrids = new HashSet<long>();

// Transform and update all subgrids
foreach (var subgrid in subgrids) {
if (processedSubgrids.Contains(subgrid.EntityId)) {
MyLogger.Log($"TPCore: TeleportGrid: Skipping already processed subgrid {subgrid.DisplayName} (EntityId: {subgrid.EntityId})");
// Now teleport all connected grids
foreach (var grid in allConnectedGrids)
{
if (grid == mainGrid)
continue;
}

try {
MatrixD newGridWorldMatrix = relativeLocalMatrices[subgrid] * mainGrid.WorldMatrix;
MyLogger.Log($"TPCore: TeleportGrid: Calculating new WorldMatrix for subgrid {subgrid.DisplayName} (EntityId: {subgrid.EntityId}), New World Matrix: {newGridWorldMatrix}");
subgrid.WorldMatrix = newGridWorldMatrix;
MyLogger.Log($"TPCore: TeleportGrid: Updated WorldMatrix for subgrid {subgrid.DisplayName} (EntityId: {subgrid.EntityId}), New World Matrix: {newGridWorldMatrix}");
try
{
MatrixD newGridMatrix = relativeMatrices[grid] * mainGrid.WorldMatrix;
grid.WorldMatrix = newGridMatrix;

var physics = subgrid.Physics;
if (physics != null) {
var physics = grid.Physics;
if (physics != null)
{
physics.LinearVelocity = Vector3D.Zero;
physics.AngularVelocity = Vector3D.Zero;
physics.Gravity = mainPhysics?.Gravity ?? Vector3.Zero;
MyLogger.Log($"TPCore: TeleportGrid: Updated physics for subgrid {subgrid.DisplayName} (EntityId: {subgrid.EntityId}), Linear Velocity: {physics.LinearVelocity}, Angular Velocity: {physics.AngularVelocity}, Gravity: {physics.Gravity}");
}

// Mark this subgrid as processed
processedSubgrids.Add(subgrid.EntityId);
MyLogger.Log($"TPGate: TeleportGrid: Teleported connected grid {grid.DisplayName} (EntityId: {grid.EntityId})");
}
catch (Exception ex) {
MyLogger.Log($"TPCore: TeleportGrid: Exception occurred while handling subgrid {subgrid.DisplayName} (EntityId: {subgrid.EntityId}): {ex.Message}");
catch (Exception ex)
{
MyLogger.Log($"TPGate: TeleportGrid: Error teleporting grid {grid.DisplayName}: {ex.Message}");
}
}

// These last two get rid of connector based wiggle
mainGrid.Teleport(newOrientation);
mainGrid.WorldMatrix = newOrientation;
// Verify connections are maintained
var finalPhysicalGroup = MyAPIGateway.GridGroups.GetGridGroup(GridLinkTypeEnum.Physical, mainGrid);
var finalMechanicalGroup = MyAPIGateway.GridGroups.GetGridGroup(GridLinkTypeEnum.Mechanical, mainGrid);

if (finalPhysicalGroup != null && finalMechanicalGroup != null)
{
var finalConnectedGrids = new HashSet<IMyCubeGrid>();
MyAPIGateway.GridGroups.GetGroup(mainGrid, GridLinkTypeEnum.Physical, finalConnectedGrids);
MyAPIGateway.GridGroups.GetGroup(mainGrid, GridLinkTypeEnum.Mechanical, finalConnectedGrids);

MyLogger.Log($"TPCore: TeleportGrid: Teleportation complete for main grid {mainGrid.DisplayName} (EntityId: {mainGrid.EntityId}) and its {subgrids.Count} subgrids");
MyLogger.Log($"TPGate: TeleportGrid: Final connected grids count: {finalConnectedGrids.Count}");
if (finalConnectedGrids.Count != allConnectedGrids.Count)
{
MyLogger.Log($"TPGate: TeleportGrid: Warning - Grid connections may have been affected during teleport");
}
}
}

public static void ClientApplyTeleportResponse(TeleportResponseMessage message) {
Expand Down
Loading

0 comments on commit edeb642

Please sign in to comment.