private bool IsRCDStillValid(RCDComponent rcd, AfterInteractEvent eventArgs, IMapGrid mapGrid, TileRef tile, RcdMode startingMode) { //Less expensive checks first. Failing those ones, we need to check that the tile isn't obstructed. if (rcd.CurrentAmmo <= 0) { _popup.PopupEntity(Loc.GetString("rcd-component-no-ammo-message"), rcd.Owner, Filter.Entities(eventArgs.User)); return(false); } if (rcd.Mode != startingMode) { return(false); } var unobstructed = eventArgs.Target == null ? _interactionSystem.InRangeUnobstructed(eventArgs.User, mapGrid.GridTileToWorld(tile.GridIndices), popup : true) : _interactionSystem.InRangeUnobstructed(eventArgs.User, eventArgs.Target.Value, popup: true); if (!unobstructed) { return(false); } switch (rcd.Mode) { //Floor mode just needs the tile to be a space tile (subFloor) case RcdMode.Floors: if (!tile.Tile.IsEmpty) { _popup.PopupEntity(Loc.GetString("rcd-component-cannot-build-floor-tile-not-empty-message"), rcd.Owner, Filter.Entities(eventArgs.User)); return(false); } return(true); //We don't want to place a space tile on something that's already a space tile. Let's do the inverse of the last check. case RcdMode.Deconstruct: if (tile.Tile.IsEmpty) { return(false); } //They tried to decon a turf but the turf is blocked if (eventArgs.Target == null && tile.IsBlockedTurf(true)) { _popup.PopupEntity(Loc.GetString("rcd-component-tile-obstructed-message"), rcd.Owner, Filter.Entities(eventArgs.User)); return(false); } //They tried to decon a non-turf but it's not in the whitelist if (eventArgs.Target != null && !_tagSystem.HasTag(eventArgs.Target.Value, "RCDDeconstructWhitelist")) { _popup.PopupEntity(Loc.GetString("rcd-component-deconstruct-target-not-on-whitelist-message"), rcd.Owner, Filter.Entities(eventArgs.User)); return(false); } return(true); //Walls are a special behaviour, and require us to build a new object with a transform rather than setting a grid tile, thus we early return to avoid the tile set code. case RcdMode.Walls: if (tile.Tile.IsEmpty) { _popup.PopupEntity(Loc.GetString("rcd-component-cannot-build-wall-tile-not-empty-message"), rcd.Owner, Filter.Entities(eventArgs.User)); return(false); } if (tile.IsBlockedTurf(true)) { _popup.PopupEntity(Loc.GetString("rcd-component-tile-obstructed-message"), rcd.Owner, Filter.Entities(eventArgs.User)); return(false); } return(true); case RcdMode.Airlock: if (tile.Tile.IsEmpty) { _popup.PopupEntity(Loc.GetString("rcd-component-cannot-build-airlock-tile-not-empty-message"), rcd.Owner, Filter.Entities(eventArgs.User)); return(false); } if (tile.IsBlockedTurf(true)) { _popup.PopupEntity(Loc.GetString("rcd-component-tile-obstructed-message"), rcd.Owner, Filter.Entities(eventArgs.User)); return(false); } return(true); default: return(false); //I don't know why this would happen, but sure I guess. Get out of here invalid state! } }