Random offset for DefaultGrid every round (#4411)

* Random offset for DefaultGrid every round

This is useful to make coders aware of entitycoordinates and mapcoordinates being different and to help spot problems early. It also puts the onus of fixing positioning bugs back onto the original coder rather than someone else if they happen to spot it.

* Fix clickable test

* Fix entitysystemextensions
This commit is contained in:
metalgearsloth 2021-08-03 18:49:25 +10:00 committed by GitHub
parent 3d2f05e3e4
commit af05332b36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 31 additions and 9 deletions

View File

@ -1,11 +1,14 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Content.Client.Clickable; using Content.Client.Clickable;
using Content.Server.GameTicking;
using NUnit.Framework; using NUnit.Framework;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Timing;
namespace Content.IntegrationTests.Tests namespace Content.IntegrationTests.Tests
{ {
@ -57,12 +60,19 @@ namespace Content.IntegrationTests.Tests
[TestCase("ClickTestRotatingCornerInvisibleNoRot", 0.25f, 0.25f, DirSouthEastJustShy, 1, ExpectedResult = true)] [TestCase("ClickTestRotatingCornerInvisibleNoRot", 0.25f, 0.25f, DirSouthEastJustShy, 1, ExpectedResult = true)]
public async Task<bool> Test(string prototype, float clickPosX, float clickPosY, double angle, float scale) public async Task<bool> Test(string prototype, float clickPosX, float clickPosY, double angle, float scale)
{ {
Vector2? worldPos = null;
EntityUid entity = default; EntityUid entity = default;
var clientEntManager = _client.ResolveDependency<IEntityManager>();
var serverEntManager = _server.ResolveDependency<IEntityManager>();
var mapManager = _server.ResolveDependency<IMapManager>();
var gameTicker = _server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<GameTicker>();
await _server.WaitPost(() => await _server.WaitPost(() =>
{ {
var entMgr = IoCManager.Resolve<IEntityManager>(); var gridEnt = mapManager.GetGrid(gameTicker.DefaultGridId).GridEntityId;
var ent = entMgr.SpawnEntity(prototype, new MapCoordinates(0, 0, new MapId(1))); worldPos = serverEntManager.GetEntity(gridEnt).Transform.WorldPosition;
var ent = serverEntManager.SpawnEntity(prototype, new EntityCoordinates(gridEnt, 0f, 0f));
ent.Transform.LocalRotation = angle; ent.Transform.LocalRotation = angle;
ent.GetComponent<SpriteComponent>().Scale = (scale, scale); ent.GetComponent<SpriteComponent>().Scale = (scale, scale);
entity = ent.Uid; entity = ent.Uid;
@ -75,17 +85,15 @@ namespace Content.IntegrationTests.Tests
await _client.WaitPost(() => await _client.WaitPost(() =>
{ {
var entMgr = IoCManager.Resolve<IEntityManager>(); var ent = clientEntManager.GetEntity(entity);
var ent = entMgr.GetEntity(entity);
var clickable = ent.GetComponent<ClickableComponent>(); var clickable = ent.GetComponent<ClickableComponent>();
hit = clickable.CheckClick((clickPosX, clickPosY), out _, out _); hit = clickable.CheckClick((clickPosX, clickPosY) + worldPos!.Value, out _, out _);
}); });
await _server.WaitPost(() => await _server.WaitPost(() =>
{ {
var entMgr = IoCManager.Resolve<IEntityManager>(); serverEntManager.DeleteEntity(entity);
entMgr.DeleteEntity(entity);
}); });
return hit; return hit;

View File

@ -48,6 +48,8 @@ namespace Content.IntegrationTests.Tests.Utility
var mapId = new MapId(1); var mapId = new MapId(1);
var grid = sMapManager.GetGrid(new GridId(1)); var grid = sMapManager.GetGrid(new GridId(1));
grid.SetTile(new Vector2i(0, 0), new Tile(1)); grid.SetTile(new Vector2i(0, 0), new Tile(1));
var gridEnt = sEntityManager.GetEntity(grid.GridEntityId);
var gridPos = gridEnt.Transform.WorldPosition;
var entityCoordinates = new EntityCoordinates(grid.GridEntityId, 0, 0); var entityCoordinates = new EntityCoordinates(grid.GridEntityId, 0, 0);
// Nothing blocking it, only entity is the grid // Nothing blocking it, only entity is the grid
@ -55,7 +57,7 @@ namespace Content.IntegrationTests.Tests.Utility
Assert.True(sEntityManager.TrySpawnIfUnobstructed(null, entityCoordinates, CollisionGroup.Impassable, out var entity)); Assert.True(sEntityManager.TrySpawnIfUnobstructed(null, entityCoordinates, CollisionGroup.Impassable, out var entity));
Assert.NotNull(entity); Assert.NotNull(entity);
var mapCoordinates = new MapCoordinates(0, 0, mapId); var mapCoordinates = new MapCoordinates(gridPos.X, gridPos.Y, mapId);
// Nothing blocking it, only entity is the grid // Nothing blocking it, only entity is the grid
Assert.NotNull(sEntityManager.SpawnIfUnobstructed(null, mapCoordinates, CollisionGroup.Impassable)); Assert.NotNull(sEntityManager.SpawnIfUnobstructed(null, mapCoordinates, CollisionGroup.Impassable));

View File

@ -11,6 +11,7 @@ using Robust.Server.Player;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.Localization; using Robust.Shared.Localization;
using Robust.Shared.Log; using Robust.Shared.Log;
using Robust.Shared.Maths;
using Robust.Shared.Player; using Robust.Shared.Player;
using Robust.Shared.Random; using Robust.Shared.Random;
using Robust.Shared.Timing; using Robust.Shared.Timing;
@ -62,6 +63,11 @@ namespace Content.Server.GameTicking
throw new InvalidOperationException($"No grid found for map {map}"); throw new InvalidOperationException($"No grid found for map {map}");
} }
var maxStationOffset = _configurationManager.GetCVar(CCVars.MaxStationOffset);
var x = _robustRandom.NextFloat() * maxStationOffset * 2 - maxStationOffset;
var y = _robustRandom.NextFloat() * maxStationOffset * 2 - maxStationOffset;
_entityManager.GetEntity(grid.GridEntityId).Transform.LocalPosition = new Vector2(x, y);
DefaultGridId = grid.Index; DefaultGridId = grid.Index;
_spawnPoint = grid.ToCoordinates(); _spawnPoint = grid.ToCoordinates();

View File

@ -55,6 +55,12 @@ namespace Content.Shared.CCVar
public static readonly CVarDef<string> public static readonly CVarDef<string>
GameMap = CVarDef.Create("game.map", "Maps/saltern.yml", CVar.SERVERONLY); GameMap = CVarDef.Create("game.map", "Maps/saltern.yml", CVar.SERVERONLY);
/// <summary>
/// When the default blueprint is loaded what is the maximum amount it can be offset from 0,0.
/// </summary>
public static readonly CVarDef<float> MaxStationOffset =
CVarDef.Create("game.maxstationoffset", 1000.0f);
/// <summary> /// <summary>
/// When enabled, guests will be assigned permanent UIDs and will have their preferences stored. /// When enabled, guests will be assigned permanent UIDs and will have their preferences stored.
/// </summary> /// </summary>

View File

@ -32,7 +32,7 @@ namespace Content.Shared.Spawning
in Box2? box = null, in Box2? box = null,
SharedBroadphaseSystem? collision = null) SharedBroadphaseSystem? collision = null)
{ {
var boxOrDefault = box.GetValueOrDefault(Box2.UnitCentered); var boxOrDefault = box.GetValueOrDefault(Box2.UnitCentered).Translated(coordinates.Position);
collision ??= EntitySystem.Get<SharedBroadphaseSystem>(); collision ??= EntitySystem.Get<SharedBroadphaseSystem>();
foreach (var body in collision.GetCollidingEntities(coordinates.MapId, in boxOrDefault)) foreach (var body in collision.GetCollidingEntities(coordinates.MapId, in boxOrDefault))