Fix RCD light spam, bypass of indestructible tiles and some plating fixes (#42432)
* No more light spam, and some plating fixes * fixed test
This commit is contained in:
parent
693e29c0f2
commit
83b2bae724
|
|
@ -38,9 +38,9 @@ public sealed class RCDTest : InteractionTest
|
||||||
pEast = Transform.WithEntityId(pEast, MapData.Grid);
|
pEast = Transform.WithEntityId(pEast, MapData.Grid);
|
||||||
pWest = Transform.WithEntityId(pWest, MapData.Grid);
|
pWest = Transform.WithEntityId(pWest, MapData.Grid);
|
||||||
|
|
||||||
await SetTile(Plating, SEntMan.GetNetCoordinates(pNorth), MapData.Grid);
|
await SetTile(PlatingRCD, SEntMan.GetNetCoordinates(pNorth), MapData.Grid);
|
||||||
await SetTile(Plating, SEntMan.GetNetCoordinates(pSouth), MapData.Grid);
|
await SetTile(PlatingRCD, SEntMan.GetNetCoordinates(pSouth), MapData.Grid);
|
||||||
await SetTile(Plating, SEntMan.GetNetCoordinates(pEast), MapData.Grid);
|
await SetTile(PlatingRCD, SEntMan.GetNetCoordinates(pEast), MapData.Grid);
|
||||||
await SetTile(Lattice, SEntMan.GetNetCoordinates(pWest), MapData.Grid);
|
await SetTile(Lattice, SEntMan.GetNetCoordinates(pWest), MapData.Grid);
|
||||||
|
|
||||||
Assert.That(ProtoMan.TryIndex(RCDSettingWall, out var settingWall), $"RCDPrototype not found: {RCDSettingWall}.");
|
Assert.That(ProtoMan.TryIndex(RCDSettingWall, out var settingWall), $"RCDPrototype not found: {RCDSettingWall}.");
|
||||||
|
|
@ -194,7 +194,7 @@ public sealed class RCDTest : InteractionTest
|
||||||
// Deconstruct the steel tile.
|
// Deconstruct the steel tile.
|
||||||
await Interact(null, pEast);
|
await Interact(null, pEast);
|
||||||
await RunSeconds(settingDeconstructTile.Delay + 1); // wait for the deconstruction to finish
|
await RunSeconds(settingDeconstructTile.Delay + 1); // wait for the deconstruction to finish
|
||||||
await AssertTile(Plating, FromServer(pEast));
|
await AssertTile(PlatingRCD, FromServer(pEast));
|
||||||
|
|
||||||
// Check that the cost of the deconstruction was subtracted from the current charges.
|
// Check that the cost of the deconstruction was subtracted from the current charges.
|
||||||
newCharges = sCharges.GetCurrentCharges(ToServer(rcd));
|
newCharges = sCharges.GetCurrentCharges(ToServer(rcd));
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ public abstract partial class InteractionTest
|
||||||
protected const string Floor = "FloorSteel";
|
protected const string Floor = "FloorSteel";
|
||||||
protected const string FloorItem = "FloorTileItemSteel";
|
protected const string FloorItem = "FloorTileItemSteel";
|
||||||
protected const string Plating = "Plating";
|
protected const string Plating = "Plating";
|
||||||
|
protected const string PlatingRCD = "PlatingRCD";
|
||||||
protected const string Lattice = "Lattice";
|
protected const string Lattice = "Lattice";
|
||||||
protected const string PlatingBrass = "PlatingBrass";
|
protected const string PlatingBrass = "PlatingBrass";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,12 @@ public sealed partial class RCDPrototype : IPrototype
|
||||||
[DataField, ViewVariables(VVAccess.ReadOnly)]
|
[DataField, ViewVariables(VVAccess.ReadOnly)]
|
||||||
public string? Prototype { get; private set; }
|
public string? Prototype { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If true, allows placing the entity once per direction (North, West, South and East)
|
||||||
|
/// </summary>
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadOnly)]
|
||||||
|
public bool AllowMultiDirection { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Number of charges consumed when the operation is completed
|
/// Number of charges consumed when the operation is completed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ public sealed class RCDSystem : EntitySystem
|
||||||
var tile = _mapSystem.GetTileRef(gridUid.Value, mapGrid, location);
|
var tile = _mapSystem.GetTileRef(gridUid.Value, mapGrid, location);
|
||||||
var position = _mapSystem.TileIndicesFor(gridUid.Value, mapGrid, location);
|
var position = _mapSystem.TileIndicesFor(gridUid.Value, mapGrid, location);
|
||||||
|
|
||||||
if (!IsRCDOperationStillValid(uid, component, gridUid.Value, mapGrid, tile, position, args.Target, args.User))
|
if (!IsRCDOperationStillValid(uid, component, gridUid.Value, mapGrid, tile, position, component.ConstructionDirection, args.Target, args.User))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!_net.IsServer)
|
if (!_net.IsServer)
|
||||||
|
|
@ -254,7 +254,7 @@ public sealed class RCDSystem : EntitySystem
|
||||||
var tile = _mapSystem.GetTileRef(gridUid.Value, mapGrid, location);
|
var tile = _mapSystem.GetTileRef(gridUid.Value, mapGrid, location);
|
||||||
var position = _mapSystem.TileIndicesFor(gridUid.Value, mapGrid, location);
|
var position = _mapSystem.TileIndicesFor(gridUid.Value, mapGrid, location);
|
||||||
|
|
||||||
if (!IsRCDOperationStillValid(uid, component, gridUid.Value, mapGrid, tile, position, args.Event.Target, args.Event.User))
|
if (!IsRCDOperationStillValid(uid, component, gridUid.Value, mapGrid, tile, position, args.Event.Direction, args.Event.Target, args.Event.User))
|
||||||
args.Cancel();
|
args.Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -284,7 +284,7 @@ public sealed class RCDSystem : EntitySystem
|
||||||
var position = _mapSystem.TileIndicesFor(gridUid.Value, mapGrid, location);
|
var position = _mapSystem.TileIndicesFor(gridUid.Value, mapGrid, location);
|
||||||
|
|
||||||
// Ensure the RCD operation is still valid
|
// Ensure the RCD operation is still valid
|
||||||
if (!IsRCDOperationStillValid(uid, component, gridUid.Value, mapGrid, tile, position, args.Target, args.User))
|
if (!IsRCDOperationStillValid(uid, component, gridUid.Value, mapGrid, tile, position, args.Direction, args.Target, args.User))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Finalize the operation (this should handle prediction properly)
|
// Finalize the operation (this should handle prediction properly)
|
||||||
|
|
@ -319,6 +319,11 @@ public sealed class RCDSystem : EntitySystem
|
||||||
#region Entity construction/deconstruction rule checks
|
#region Entity construction/deconstruction rule checks
|
||||||
|
|
||||||
public bool IsRCDOperationStillValid(EntityUid uid, RCDComponent component, EntityUid gridUid, MapGridComponent mapGrid, TileRef tile, Vector2i position, EntityUid? target, EntityUid user, bool popMsgs = true)
|
public bool IsRCDOperationStillValid(EntityUid uid, RCDComponent component, EntityUid gridUid, MapGridComponent mapGrid, TileRef tile, Vector2i position, EntityUid? target, EntityUid user, bool popMsgs = true)
|
||||||
|
{
|
||||||
|
return IsRCDOperationStillValid(uid, component, gridUid, mapGrid, tile, position, component.ConstructionDirection, target, user, popMsgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsRCDOperationStillValid(EntityUid uid, RCDComponent component, EntityUid gridUid, MapGridComponent mapGrid, TileRef tile, Vector2i position, Direction direction, EntityUid? target, EntityUid user, bool popMsgs = true)
|
||||||
{
|
{
|
||||||
var prototype = _protoManager.Index(component.ProtoId);
|
var prototype = _protoManager.Index(component.ProtoId);
|
||||||
|
|
||||||
|
|
@ -355,7 +360,7 @@ public sealed class RCDSystem : EntitySystem
|
||||||
{
|
{
|
||||||
case RcdMode.ConstructTile:
|
case RcdMode.ConstructTile:
|
||||||
case RcdMode.ConstructObject:
|
case RcdMode.ConstructObject:
|
||||||
return IsConstructionLocationValid(uid, component, gridUid, mapGrid, tile, position, user, popMsgs);
|
return IsConstructionLocationValid(uid, component, gridUid, mapGrid, tile, position, direction, user, popMsgs);
|
||||||
case RcdMode.Deconstruct:
|
case RcdMode.Deconstruct:
|
||||||
return IsDeconstructionStillValid(uid, tile, target, user, popMsgs);
|
return IsDeconstructionStillValid(uid, tile, target, user, popMsgs);
|
||||||
}
|
}
|
||||||
|
|
@ -363,7 +368,7 @@ public sealed class RCDSystem : EntitySystem
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsConstructionLocationValid(EntityUid uid, RCDComponent component, EntityUid gridUid, MapGridComponent mapGrid, TileRef tile, Vector2i position, EntityUid user, bool popMsgs = true)
|
private bool IsConstructionLocationValid(EntityUid uid, RCDComponent component, EntityUid gridUid, MapGridComponent mapGrid, TileRef tile, Vector2i position, Direction direction, EntityUid user, bool popMsgs = true)
|
||||||
{
|
{
|
||||||
var prototype = _protoManager.Index(component.ProtoId);
|
var prototype = _protoManager.Index(component.ProtoId);
|
||||||
|
|
||||||
|
|
@ -406,8 +411,24 @@ public sealed class RCDSystem : EntitySystem
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var tileDef = _turf.GetContentTileDefinition(tile);
|
||||||
|
|
||||||
|
// Check rule: Respect baseTurf and baseWhitelist
|
||||||
|
if (prototype.Prototype != null && _tileDefMan.TryGetDefinition(prototype.Prototype, out var replacementDef))
|
||||||
|
{
|
||||||
|
var replacementContentDef = (ContentTileDefinition) replacementDef;
|
||||||
|
|
||||||
|
if (replacementContentDef.BaseTurf != tileDef.ID && !replacementContentDef.BaseWhitelist.Contains(tileDef.ID))
|
||||||
|
{
|
||||||
|
if (popMsgs)
|
||||||
|
_popup.PopupClient(Loc.GetString("rcd-component-cannot-build-on-empty-tile-message"), uid, user);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check rule: Tiles can't be identical
|
// Check rule: Tiles can't be identical
|
||||||
if (_turf.GetContentTileDefinition(tile).ID == prototype.Prototype)
|
if (tileDef.ID == prototype.Prototype)
|
||||||
{
|
{
|
||||||
if (popMsgs)
|
if (popMsgs)
|
||||||
_popup.PopupClient(Loc.GetString("rcd-component-cannot-build-identical-tile"), uid, user);
|
_popup.PopupClient(Loc.GetString("rcd-component-cannot-build-identical-tile"), uid, user);
|
||||||
|
|
@ -430,6 +451,28 @@ public sealed class RCDSystem : EntitySystem
|
||||||
|
|
||||||
foreach (var ent in _intersectingEntities)
|
foreach (var ent in _intersectingEntities)
|
||||||
{
|
{
|
||||||
|
// If the entity is the exact same prototype as what we are trying to build, then block it.
|
||||||
|
// This is to prevent spamming objects on the same tile (e.g. lights)
|
||||||
|
if (prototype.Prototype != null && MetaData(ent).EntityPrototype?.ID == prototype.Prototype)
|
||||||
|
{
|
||||||
|
var isIdentical = true;
|
||||||
|
|
||||||
|
if (prototype.AllowMultiDirection)
|
||||||
|
{
|
||||||
|
var entDirection = Transform(ent).LocalRotation.GetCardinalDir();
|
||||||
|
if (entDirection != direction)
|
||||||
|
isIdentical = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isIdentical)
|
||||||
|
{
|
||||||
|
if (popMsgs)
|
||||||
|
_popup.PopupClient(Loc.GetString("rcd-component-cannot-build-identical-entity"), uid, user);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isWindow && HasComp<SharedCanBuildWindowOnTopComponent>(ent))
|
if (isWindow && HasComp<SharedCanBuildWindowOnTopComponent>(ent))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -534,7 +577,10 @@ public sealed class RCDSystem : EntitySystem
|
||||||
switch (prototype.Mode)
|
switch (prototype.Mode)
|
||||||
{
|
{
|
||||||
case RcdMode.ConstructTile:
|
case RcdMode.ConstructTile:
|
||||||
_mapSystem.SetTile(gridUid, mapGrid, position, new Tile(_tileDefMan[prototype.Prototype].TileId));
|
if (!_tileDefMan.TryGetDefinition(prototype.Prototype, out var tileDef))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_tile.ReplaceTile(tile, (ContentTileDefinition) tileDef, gridUid, mapGrid);
|
||||||
_adminLogger.Add(LogType.RCD, LogImpact.High, $"{ToPrettyString(user):user} used RCD to set grid: {gridUid} {position} to {prototype.Prototype}");
|
_adminLogger.Add(LogType.RCD, LogImpact.High, $"{ToPrettyString(user):user} used RCD to set grid: {gridUid} {position} to {prototype.Prototype}");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ rcd-component-must-build-on-subfloor-message = You can only build that on expose
|
||||||
rcd-component-cannot-build-on-subfloor-message = You can't build that on exposed subfloor!
|
rcd-component-cannot-build-on-subfloor-message = You can't build that on exposed subfloor!
|
||||||
rcd-component-cannot-build-on-occupied-tile-message = You can't build here, the space is already occupied!
|
rcd-component-cannot-build-on-occupied-tile-message = You can't build here, the space is already occupied!
|
||||||
rcd-component-cannot-build-identical-tile = That tile already exists there!
|
rcd-component-cannot-build-identical-tile = That tile already exists there!
|
||||||
|
rcd-component-cannot-build-identical-entity = That already exists there!
|
||||||
|
|
||||||
|
|
||||||
### Category names
|
### Category names
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
category: WallsAndFlooring
|
category: WallsAndFlooring
|
||||||
sprite: /Textures/Interface/Radial/RCD/plating.png
|
sprite: /Textures/Interface/Radial/RCD/plating.png
|
||||||
mode: ConstructTile
|
mode: ConstructTile
|
||||||
prototype: Plating
|
prototype: PlatingRCD
|
||||||
cost: 1
|
cost: 1
|
||||||
delay: 1
|
delay: 1
|
||||||
collisionMask: InteractImpassable
|
collisionMask: InteractImpassable
|
||||||
|
|
@ -128,6 +128,7 @@
|
||||||
- IsWindow
|
- IsWindow
|
||||||
rotation: User
|
rotation: User
|
||||||
fx: EffectRCDConstruct1
|
fx: EffectRCDConstruct1
|
||||||
|
allowMultiDirection: true
|
||||||
|
|
||||||
- type: rcd
|
- type: rcd
|
||||||
id: ReinforcedWindow
|
id: ReinforcedWindow
|
||||||
|
|
@ -157,6 +158,7 @@
|
||||||
- IsWindow
|
- IsWindow
|
||||||
rotation: User
|
rotation: User
|
||||||
fx: EffectRCDConstruct2
|
fx: EffectRCDConstruct2
|
||||||
|
allowMultiDirection: true
|
||||||
|
|
||||||
# Airlocks
|
# Airlocks
|
||||||
- type: rcd
|
- type: rcd
|
||||||
|
|
@ -208,6 +210,7 @@
|
||||||
collisionBounds: "-0.23,-0.49,0.23,-0.36"
|
collisionBounds: "-0.23,-0.49,0.23,-0.36"
|
||||||
rotation: User
|
rotation: User
|
||||||
fx: EffectRCDConstruct1
|
fx: EffectRCDConstruct1
|
||||||
|
allowMultiDirection: true
|
||||||
|
|
||||||
- type: rcd
|
- type: rcd
|
||||||
id: BulbLight
|
id: BulbLight
|
||||||
|
|
@ -221,6 +224,7 @@
|
||||||
collisionBounds: "-0.23,-0.49,0.23,-0.36"
|
collisionBounds: "-0.23,-0.49,0.23,-0.36"
|
||||||
rotation: User
|
rotation: User
|
||||||
fx: EffectRCDConstruct1
|
fx: EffectRCDConstruct1
|
||||||
|
allowMultiDirection: true
|
||||||
|
|
||||||
# Electrical
|
# Electrical
|
||||||
- type: rcd
|
- type: rcd
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@
|
||||||
- FloorPlanetGrass
|
- FloorPlanetGrass
|
||||||
- FloorSnow
|
- FloorSnow
|
||||||
- FloorDirt
|
- FloorDirt
|
||||||
|
- PlatingRCD
|
||||||
|
- FloorHullReinforced
|
||||||
|
|
||||||
- type: tile
|
- type: tile
|
||||||
id: FloorSteel
|
id: FloorSteel
|
||||||
|
|
@ -1607,17 +1609,6 @@
|
||||||
collection: FootstepHull
|
collection: FootstepHull
|
||||||
itemDrop: FloorTileItemSteel #probably should not be normally obtainable, but the game shits itself and dies when you try to put null here
|
itemDrop: FloorTileItemSteel #probably should not be normally obtainable, but the game shits itself and dies when you try to put null here
|
||||||
|
|
||||||
- type: tile
|
|
||||||
id: FloorHullReinforced
|
|
||||||
parent: BaseStationTile
|
|
||||||
name: tiles-hull-reinforced
|
|
||||||
sprite: /Textures/Tiles/hull_reinforced.png
|
|
||||||
footstepSounds:
|
|
||||||
collection: FootstepHull
|
|
||||||
itemDrop: FloorTileItemSteel
|
|
||||||
heatCapacity: 100000 #/tg/ has this set as "INFINITY." I don't know if that exists here so I've just added an extra 0
|
|
||||||
indestructible: true
|
|
||||||
|
|
||||||
- type: tile
|
- type: tile
|
||||||
id: FloorReinforcedHardened
|
id: FloorReinforcedHardened
|
||||||
parent: BaseStationTile
|
parent: BaseStationTile
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,34 @@
|
||||||
name: tiles-plating
|
name: tiles-plating
|
||||||
sprite: /Textures/_DV/Tiles/plating.png #Delta V - Resprite Tile
|
sprite: /Textures/_DV/Tiles/plating.png #Delta V - Resprite Tile
|
||||||
|
|
||||||
|
- type: tile
|
||||||
|
id: PlatingRCD
|
||||||
|
parent: Plating
|
||||||
|
baseWhitelist:
|
||||||
|
- TrainLattice
|
||||||
|
- FloorPlanetDirt
|
||||||
|
- FloorDesert
|
||||||
|
- FloorLowDesert
|
||||||
|
- FloorPlanetGrass
|
||||||
|
- FloorSnow
|
||||||
|
- FloorDirt
|
||||||
|
- FloorAsteroidIronsand
|
||||||
|
- FloorAsteroidSand
|
||||||
|
- FloorAsteroidSandBorderless
|
||||||
|
- FloorAsteroidIronsandBorderless
|
||||||
|
- FloorAsteroidSandRedBorderless
|
||||||
|
|
||||||
|
- type: tile
|
||||||
|
id: FloorHullReinforced
|
||||||
|
parent: BasePlating
|
||||||
|
name: tiles-hull-reinforced
|
||||||
|
sprite: /Textures/Tiles/hull_reinforced.png
|
||||||
|
footstepSounds:
|
||||||
|
collection: FootstepHull
|
||||||
|
itemDrop: FloorTileItemSteel
|
||||||
|
heatCapacity: 100000 #/tg/ has this set as "INFINITY." I don't know if that exists here so I've just added an extra 0
|
||||||
|
indestructible: true
|
||||||
|
|
||||||
- type: tile
|
- type: tile
|
||||||
id: PlatingDamaged
|
id: PlatingDamaged
|
||||||
parent: BasePlating
|
parent: BasePlating
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue