Demiplane exploration map (#1251)
* dehardcode nodeTreeControl part 1 * finish * demiplane map system setup * link map entity with station data! * random demiplane map generation * redesign demiplane map node tree * center * map generate v2 * location generation * modifier generation * missing location icons * ui polish * data refactor * fix line color * ejectabling * split demiplane component into two * blocker attempt * revoking * fix frontier calculation * dimensit * demiplane core room spawning * demiplane cool destruction * Update round_end.yml * progression works now! * Update CP14NodeTree.cs * Update CP14NodeTree.cs * documentation pass * fix abusing, some balance pass * demiplane naming fix * см * location names * delete old keys * Update buy.yml * Update migration.yml * fix guidebook * Update misc.yml * Update misc.yml
@@ -0,0 +1,7 @@
|
||||
using Content.Shared._CP14.DemiplaneTraveling;
|
||||
|
||||
namespace Content.Client._CP14.DemiplaneTraveling;
|
||||
|
||||
public sealed partial class CP14ClientStationDemiplaneMapSystem : CP14SharedStationDemiplaneMapSystem
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using Content.Shared._CP14.DemiplaneTraveling;
|
||||
using Robust.Client.UserInterface;
|
||||
|
||||
namespace Content.Client._CP14.DemiplaneTraveling;
|
||||
|
||||
public sealed class CP14DemiplaneMapBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
private CP14DemiplaneMapWindow? _window;
|
||||
|
||||
public CP14DemiplaneMapBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_window = this.CreateWindow<CP14DemiplaneMapWindow>();
|
||||
|
||||
_window.OnEject += pos => SendMessage(new CP14DemiplaneMapEjectMessage(pos));
|
||||
_window.OnRevoke += pos => SendMessage(new CP14DemiplaneMapRevokeMessage(pos));
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
if (_window == null || state is not CP14DemiplaneMapUiState mapState)
|
||||
return;
|
||||
|
||||
_window?.UpdateState(mapState);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<demiplaneTraveling:CP14DemiplaneMapWindow
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:graphics="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
||||
xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"
|
||||
xmlns:parallax="clr-namespace:Content.Client.Parallax"
|
||||
xmlns:nodeTree="clr-namespace:Content.Client._CP14.UserInterface.Systems.NodeTree"
|
||||
xmlns:demiplaneTraveling="clr-namespace:Content.Client._CP14.DemiplaneTraveling"
|
||||
Title="{Loc 'cp14-demiplane-map-title'}"
|
||||
MinSize="1200 850"
|
||||
SetSize="1200 850">
|
||||
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" VerticalExpand="True">
|
||||
|
||||
<!-- Selected Location -->
|
||||
<BoxContainer Margin="10 10 10 10" MaxWidth="240" SetWidth="240" Orientation="Vertical"
|
||||
HorizontalExpand="False" VerticalExpand="True">
|
||||
<!-- Location View -->
|
||||
<PanelContainer Name="BackPanel" HorizontalAlignment="Center">
|
||||
<PanelContainer.PanelOverride>
|
||||
<graphics:StyleBoxTexture Modulate="#1B1B1E" PatchMarginBottom="10" PatchMarginLeft="10"
|
||||
PatchMarginRight="10" PatchMarginTop="10" />
|
||||
</PanelContainer.PanelOverride>
|
||||
<BoxContainer HorizontalExpand="True" VerticalExpand="True" >
|
||||
<TextureRect Stretch="Scale" Name="LocationView" SetSize="64 64" HorizontalAlignment="Center" VerticalAlignment="Center" MinSize="64 64"
|
||||
HorizontalExpand="True" VerticalExpand="True" Access="Public"/>
|
||||
</BoxContainer>
|
||||
</PanelContainer>
|
||||
<customControls:HSeparator StyleClasses="HighDivider" Margin="0 15 0 10" />
|
||||
<!-- Location Data -->
|
||||
<BoxContainer Name="NodeViewContainer" Orientation="Vertical" VerticalExpand="True">
|
||||
<ScrollContainer HScrollEnabled="False" HorizontalExpand="True" VerticalExpand="True">
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="False" VerticalExpand="True">
|
||||
<BoxContainer Name="InfoContainer" Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True">
|
||||
<BoxContainer HorizontalExpand="True">
|
||||
<Label Name="Name" Access="Public" StyleClasses="LabelHeadingBigger" VAlign="Center"
|
||||
HorizontalExpand="True" HorizontalAlignment="Center" />
|
||||
</BoxContainer>
|
||||
<!-- Description -->
|
||||
<BoxContainer HorizontalExpand="True">
|
||||
<RichTextLabel Name="Description" HorizontalExpand="True" Access="Public"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</ScrollContainer>
|
||||
<Control MinHeight="5"/>
|
||||
<!-- Buttons -->
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<Button Name="EjectButton" Text="{Loc 'cp14-demiplane-map-eject'}" ToolTip="{Loc 'cp14-demiplane-map-eject-tooltip'}" StyleClasses="OpenRight" HorizontalExpand="True" MinHeight="35" Access="Public"/>
|
||||
</BoxContainer>
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<Button Name="RevokeButton" Text="{Loc 'cp14-demiplane-map-revoke'}" ToolTip="{Loc 'cp14-demiplane-map-revoke-tooltip'}" StyleClasses="OpenRight" HorizontalExpand="True" MinHeight="35" Access="Public"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
|
||||
<customControls:VSeparator StyleClasses="LowDivider" />
|
||||
|
||||
<!-- Demiplane map Tree -->
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True">
|
||||
<BoxContainer HorizontalExpand="True">
|
||||
<Label Name="TreeName" Access="Public" StyleClasses="LabelHeadingBigger" VAlign="Center"
|
||||
HorizontalExpand="True" HorizontalAlignment="Center" />
|
||||
</BoxContainer>
|
||||
<PanelContainer Margin="10 10 10 10" HorizontalExpand="True" VerticalExpand="True" RectClipContent="True">
|
||||
<parallax:ParallaxControl Name="ParallaxBackground" ScaleX="4" ScaleY="4" ParallaxPrototype="CP14Astral" Access="Public" SpeedX="10" SpeedY="5"/>
|
||||
<BoxContainer Margin="10 10 10 10" Orientation="Horizontal" HorizontalExpand="True" VerticalExpand="True">
|
||||
<nodeTree:CP14NodeTreeGraphControl Name="GraphControl" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Access="Public"/>
|
||||
</BoxContainer>
|
||||
</PanelContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</demiplaneTraveling:CP14DemiplaneMapWindow>
|
||||
@@ -0,0 +1,246 @@
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using Content.Client._CP14.UserInterface.Systems.NodeTree;
|
||||
using Content.Shared._CP14.DemiplaneTraveling;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client._CP14.DemiplaneTraveling;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class CP14DemiplaneMapWindow : DefaultWindow
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
[Dependency] private readonly ILogManager _log = default!;
|
||||
|
||||
private CP14DemiplaneMapUiState? _cachedState;
|
||||
private CP14DemiplaneMapNode? _selectedNode;
|
||||
|
||||
public event Action<Vector2i>? OnEject;
|
||||
public event Action<Vector2i>? OnRevoke;
|
||||
private ISawmill Sawmill { get; init; }
|
||||
|
||||
public CP14DemiplaneMapWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
Sawmill = _log.GetSawmill("cp14_demiplane_map_window");
|
||||
|
||||
EjectButton.OnPressed += EjectPressed;
|
||||
RevokeButton.OnPressed += RevokePressed;
|
||||
GraphControl.OnOffsetChanged += offset =>
|
||||
{
|
||||
ParallaxBackground.Offset = -offset * 0.25f + new Vector2(1000, 1000); //hardcoding is bad
|
||||
};
|
||||
GraphControl.OnNodeSelected += SelectNode;
|
||||
}
|
||||
|
||||
private void RevokePressed(BaseButton.ButtonEventArgs obj)
|
||||
{
|
||||
if (_selectedNode == null)
|
||||
return;
|
||||
|
||||
if (_cachedState == null)
|
||||
return;
|
||||
|
||||
foreach (var node in _cachedState.Nodes)
|
||||
{
|
||||
if (node.Value != _selectedNode)
|
||||
continue;
|
||||
|
||||
OnRevoke?.Invoke(node.Key);
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void EjectPressed(BaseButton.ButtonEventArgs obj)
|
||||
{
|
||||
if (_selectedNode == null)
|
||||
return;
|
||||
|
||||
if (_cachedState == null)
|
||||
return;
|
||||
|
||||
foreach (var node in _cachedState.Nodes)
|
||||
{
|
||||
if (node.Value != _selectedNode)
|
||||
continue;
|
||||
|
||||
OnEject?.Invoke(node.Key);
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateState(CP14DemiplaneMapUiState state)
|
||||
{
|
||||
_cachedState = state;
|
||||
|
||||
HashSet<CP14NodeTreeElement> nodeTreeElements = new();
|
||||
foreach (var node in state.Nodes)
|
||||
{
|
||||
if (node.Value.Start)
|
||||
{
|
||||
var startElement = new CP14NodeTreeElement(
|
||||
nodeKey: node.Key.ToString(),
|
||||
gained: true,
|
||||
active: false,
|
||||
node.Value.UiPosition * 100,
|
||||
icon: new SpriteSpecifier.Rsi(new ResPath("_CP14/Interface/NodeTree/demiplane_map.rsi"), "center"));
|
||||
nodeTreeElements.Add(startElement);
|
||||
}
|
||||
else
|
||||
{
|
||||
_prototype.TryIndex(node.Value.LocationConfig, out var location);
|
||||
|
||||
var treeElement = new CP14NodeTreeElement(
|
||||
nodeKey: node.Key.ToString(),
|
||||
gained: node.Value.Scanned,
|
||||
active: node.Value.InFrontierZone || node.Value.Scanned,
|
||||
node.Value.UiPosition * 100,
|
||||
icon: location?.Icon);
|
||||
nodeTreeElements.Add(treeElement);
|
||||
}
|
||||
}
|
||||
|
||||
var edges = new HashSet<(string, string)>();
|
||||
foreach (var edge in state.Edges)
|
||||
{
|
||||
edges.Add((edge.Item1.ToString(), edge.Item2.ToString()));
|
||||
}
|
||||
GraphControl.UpdateState(
|
||||
new CP14NodeTreeUiState(
|
||||
nodeTreeElements,
|
||||
edges: edges,
|
||||
frameIcon: new SpriteSpecifier.Rsi(new ResPath("/Textures/_CP14/Interface/NodeTree/demiplane_map.rsi"),
|
||||
"frame"),
|
||||
hoveredIcon: new SpriteSpecifier.Rsi(
|
||||
new ResPath("/Textures/_CP14/Interface/NodeTree/demiplane_map.rsi"),
|
||||
"hovered"),
|
||||
selectedIcon: new SpriteSpecifier.Rsi(
|
||||
new ResPath("/Textures/_CP14/Interface/NodeTree/demiplane_map.rsi"),
|
||||
"selected"),
|
||||
learnedIcon: new SpriteSpecifier.Rsi(
|
||||
new ResPath("/Textures/_CP14/Interface/NodeTree/demiplane_map.rsi"),
|
||||
"learned"),
|
||||
activeLineColor: new Color(172, 102, 190),
|
||||
lineColor: new Color(83, 40, 121)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private void SelectNode(CP14NodeTreeElement? node)
|
||||
{
|
||||
if (node == null)
|
||||
{
|
||||
DeselectNode();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_cachedState == null)
|
||||
{
|
||||
Sawmill.Error("Tried to select node without a cached state.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.NodeKey.Trim('(', ')').Split(',') is { Length: 2 } parts
|
||||
&& int.TryParse(parts[0], out var x)
|
||||
&& int.TryParse(parts[1], out var y)
|
||||
&& _cachedState.Nodes.TryGetValue(new Vector2i(x, y), out var mapNode))
|
||||
{
|
||||
SelectNode(mapNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
Sawmill.Error($"Tried to select node {node.NodeKey} that doesn't exist in the map.");
|
||||
DeselectNode();
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectNode(CP14DemiplaneMapNode? node)
|
||||
{
|
||||
_selectedNode = node;
|
||||
if (node == null)
|
||||
{
|
||||
DeselectNode();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_cachedState == null)
|
||||
{
|
||||
Sawmill.Error("Tried to select node without a cached state.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.LocationConfig != null && _prototype.TryIndex(node.LocationConfig, out var location))
|
||||
{
|
||||
if (location.Name is not null)
|
||||
Name.Text = Loc.GetString(location.Name);
|
||||
|
||||
//Generate description
|
||||
HashSet<LocId> modifierNames = new();
|
||||
foreach (var modifier in node.Modifiers)
|
||||
{
|
||||
if (!_prototype.TryIndex(modifier, out var indexedModifier))
|
||||
continue;
|
||||
|
||||
if (indexedModifier.Name is null)
|
||||
continue;
|
||||
|
||||
modifierNames.Add(indexedModifier.Name.Value);
|
||||
}
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (var name in modifierNames)
|
||||
{
|
||||
sb.Append("- " + Loc.GetString(name) + "\n");
|
||||
}
|
||||
|
||||
sb.Append("\n");
|
||||
if (!node.InFrontierZone && !node.Scanned)
|
||||
sb.Append(Loc.GetString("cp14-demiplane-map-status-blocked"));
|
||||
else if (node.InFrontierZone && !node.InUsing)
|
||||
sb.Append(Loc.GetString("cp14-demiplane-map-status-allowed"));
|
||||
else if (node.InUsing)
|
||||
sb.Append(Loc.GetString("cp14-demiplane-map-status-used"));
|
||||
else if (node.Scanned)
|
||||
sb.Append(Loc.GetString("cp14-demiplane-map-status-scanned"));
|
||||
|
||||
sb.Append("\n \n");
|
||||
|
||||
if (node.AdditionalLevel > 0 && !node.Scanned)
|
||||
{
|
||||
sb.Append(Loc.GetString("cp14-demiplane-map-add-level", ("count", node.AdditionalLevel))+"\n");
|
||||
sb.Append(Loc.GetString("cp14-demiplane-map-add-level-tooltip")+"\n");
|
||||
}
|
||||
|
||||
Description.Text = sb.ToString();
|
||||
LocationView.Texture = location.Icon?.Frame0();
|
||||
}
|
||||
else
|
||||
{
|
||||
Name.Text = string.Empty;
|
||||
Description.Text = string.Empty;
|
||||
LocationView.Texture = null;
|
||||
}
|
||||
|
||||
EjectButton.Disabled = !node.InFrontierZone || node.InUsing;
|
||||
RevokeButton.Disabled = !node.InUsing;
|
||||
}
|
||||
|
||||
private void DeselectNode()
|
||||
{
|
||||
Name.Text = string.Empty;
|
||||
Description.Text = string.Empty;
|
||||
LocationView.Texture = null;
|
||||
EjectButton.Disabled = true;
|
||||
RevokeButton.Disabled = true;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
<ui:CP14SkillTreeGraphControl
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:controls="clr-namespace:Content.Client._CP14.Skill.Ui"
|
||||
xmlns:ui="clr-namespace:Content.Client._CP14.Skill.Ui"
|
||||
HorizontalExpand="True"
|
||||
VerticalExpand="True"
|
||||
MouseFilter="Stop"/>
|
||||
@@ -1,227 +0,0 @@
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Shared._CP14.Skill;
|
||||
using Content.Shared._CP14.Skill.Components;
|
||||
using Content.Shared._CP14.Skill.Prototypes;
|
||||
using Content.Shared._CP14.Skill.Restrictions;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client._CP14.Skill.Ui;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class CP14SkillTreeGraphControl : BoxContainer
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
private readonly CP14SharedSkillSystem _skillSystem;
|
||||
|
||||
private Entity<CP14SkillStorageComponent>? _player;
|
||||
|
||||
private IEnumerable<CP14SkillPrototype> _allSkills;
|
||||
|
||||
private CP14SkillPrototype? _hoveredNode;
|
||||
private CP14SkillPrototype? _selectedNode;
|
||||
public CP14SkillTreePrototype? Tree;
|
||||
|
||||
private bool dragging = false;
|
||||
private Vector2 _previousMousePosition = Vector2.Zero;
|
||||
private Vector2 _globalOffset = new (60,60);
|
||||
|
||||
private const float GridSize = 25f;
|
||||
|
||||
public event Action<CP14SkillPrototype?>? OnNodeSelected;
|
||||
public event Action<Vector2>? OnOffsetChanged;
|
||||
|
||||
public CP14SkillTreeGraphControl()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
_skillSystem = _entManager.System<CP14SharedSkillSystem>();
|
||||
|
||||
_allSkills = _proto.EnumeratePrototypes<CP14SkillPrototype>();
|
||||
_proto.PrototypesReloaded += _ => _allSkills = _proto.EnumeratePrototypes<CP14SkillPrototype>().OrderBy(skill => _skillSystem.GetSkillName(skill)).ToList();
|
||||
OnOffsetChanged?.Invoke(_globalOffset);
|
||||
}
|
||||
|
||||
public void UpdateState(Entity<CP14SkillStorageComponent>? player)
|
||||
{
|
||||
_player = player;
|
||||
OnOffsetChanged?.Invoke(_globalOffset);
|
||||
}
|
||||
|
||||
protected override void KeyBindDown(GUIBoundKeyEventArgs args)
|
||||
{
|
||||
base.KeyBindDown(args);
|
||||
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (args.Function == EngineKeyFunctions.UIClick)
|
||||
{
|
||||
dragging = true;
|
||||
|
||||
if (_hoveredNode == null)
|
||||
return;
|
||||
|
||||
OnNodeSelected?.Invoke(_hoveredNode);
|
||||
UserInterfaceManager.ClickSound();
|
||||
_selectedNode = _hoveredNode;
|
||||
}
|
||||
|
||||
if (args.Function == EngineKeyFunctions.UIRightClick)
|
||||
{
|
||||
_globalOffset = new Vector2(60, 60); // Reset offset on right click
|
||||
OnOffsetChanged?.Invoke(_globalOffset);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void KeyBindUp(GUIBoundKeyEventArgs args)
|
||||
{
|
||||
base.KeyBindUp(args);
|
||||
|
||||
if (args.Handled || args.Function != EngineKeyFunctions.UIClick)
|
||||
return;
|
||||
|
||||
dragging = false;
|
||||
}
|
||||
|
||||
protected override void ExitedTree()
|
||||
{
|
||||
base.ExitedTree();
|
||||
|
||||
OnNodeSelected?.Invoke(null);
|
||||
}
|
||||
|
||||
protected override void Draw(DrawingHandleScreen handle)
|
||||
{
|
||||
base.Draw(handle);
|
||||
|
||||
_hoveredNode = null;
|
||||
if (_player == null || Tree == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var cursor = (UserInterfaceManager.MousePositionScaled.Position * UIScale) - GlobalPixelPosition;
|
||||
|
||||
if (dragging)
|
||||
{
|
||||
var delta = cursor - _previousMousePosition;
|
||||
_globalOffset += delta;
|
||||
OnOffsetChanged?.Invoke(_globalOffset);
|
||||
}
|
||||
|
||||
_previousMousePosition = cursor;
|
||||
|
||||
var playerSkills = _player.Value.Comp.LearnedSkills;
|
||||
|
||||
//Draw connection lines
|
||||
foreach (var skill in _allSkills)
|
||||
{
|
||||
if (skill.Tree != Tree)
|
||||
continue;
|
||||
|
||||
var fromPos = skill.SkillUiPosition * GridSize * UIScale + _globalOffset;
|
||||
|
||||
foreach (var req in skill.Restrictions)
|
||||
{
|
||||
switch (req)
|
||||
{
|
||||
case NeedPrerequisite prerequisite:
|
||||
if (!_proto.TryIndex(prerequisite.Prerequisite, out var prerequisiteSkill))
|
||||
continue;
|
||||
|
||||
if (prerequisiteSkill.Tree != Tree)
|
||||
continue;
|
||||
|
||||
var learned = playerSkills.Contains(skill.ID);
|
||||
|
||||
var toPos = prerequisiteSkill.SkillUiPosition * GridSize * UIScale + _globalOffset;
|
||||
var color = learned ? Color.White : Color.FromSrgb(new Color(0.7f, 0.7f, 0.7f));
|
||||
handle.DrawLine(fromPos, toPos, color);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Draw skill icons over lines
|
||||
foreach (var skill in _allSkills)
|
||||
{
|
||||
if (skill.Tree != Tree)
|
||||
continue;
|
||||
|
||||
//TODO: Not optimized, recalculates every frame. Needs to be calculated on state update and cached.
|
||||
var canBeLearned = _skillSystem.CanLearnSkill(_player.Value, skill, _player.Value.Comp);
|
||||
var pos = skill.SkillUiPosition * GridSize * UIScale + _globalOffset;
|
||||
|
||||
// Base skill icon
|
||||
var baseTexture = skill.Icon.Frame0();
|
||||
var baseSize = new Vector2(baseTexture.Width, baseTexture.Height) * 1.5f * UIScale;
|
||||
var baseQuad = new UIBox2(pos - baseSize / 2, pos + baseSize / 2);
|
||||
|
||||
var hovered = (cursor - pos).LengthSquared() <= (baseSize.X / 2) * (baseSize.X / 2);
|
||||
|
||||
// Frame
|
||||
var frameTexture = Tree.FrameIcon.Frame0();
|
||||
var frameSize = new Vector2(frameTexture.Width, frameTexture.Height) * 1.5f * UIScale;
|
||||
var frameQuad = new UIBox2(pos - frameSize / 2, pos + frameSize / 2);
|
||||
handle.DrawTextureRect(frameTexture, frameQuad, canBeLearned ? Color.White : Color.FromSrgb(new Color(0.7f, 0.7f, 0.7f)));
|
||||
|
||||
// Selected Skill
|
||||
if (_selectedNode == skill)
|
||||
{
|
||||
var selectedTexture = Tree.SelectedIcon.Frame0();
|
||||
var selectedSize = new Vector2(selectedTexture.Width, selectedTexture.Height) * 1.5f * UIScale;
|
||||
var selectedQuad = new UIBox2(pos - selectedSize / 2, pos + selectedSize / 2);
|
||||
handle.DrawTextureRect(selectedTexture, selectedQuad, Color.White);
|
||||
}
|
||||
|
||||
// Hovered Skill
|
||||
if (hovered)
|
||||
{
|
||||
_hoveredNode = skill;
|
||||
var hoveredTexture = Tree.HoveredIcon.Frame0();
|
||||
var hoveredSize = new Vector2(hoveredTexture.Width, hoveredTexture.Height) * 1.5f * UIScale;
|
||||
var hoveredQuad = new UIBox2(pos - hoveredSize / 2, pos + hoveredSize / 2);
|
||||
handle.DrawTextureRect(hoveredTexture, hoveredQuad, Color.White);
|
||||
}
|
||||
|
||||
var learned = playerSkills.Contains(skill.ID);
|
||||
var allowedToLearn = _skillSystem.AllowedToLearn(_player.Value, skill, _player.Value.Comp);
|
||||
|
||||
// Learned Skill
|
||||
if (learned)
|
||||
{
|
||||
var learnedTexture = Tree.LearnedIcon.Frame0();
|
||||
var learnedSize = new Vector2(learnedTexture.Width, learnedTexture.Height) * 1.5f * UIScale;
|
||||
var learnedQuad = new UIBox2(pos - learnedSize / 2, pos + learnedSize / 2);
|
||||
handle.DrawTextureRect(learnedTexture, learnedQuad, Color.White);
|
||||
}
|
||||
else if (canBeLearned)
|
||||
{
|
||||
var availableTexture = Tree.AvailableIcon.Frame0();
|
||||
var availableSize = new Vector2(availableTexture.Width, availableTexture.Height) * 1.5f * UIScale;
|
||||
var availableQuad = new UIBox2(pos - availableSize / 2, pos + availableSize / 2);
|
||||
handle.DrawTextureRect(availableTexture, availableQuad, Color.White);
|
||||
}
|
||||
|
||||
var iconColor = allowedToLearn switch
|
||||
{
|
||||
true when !learned => Color.FromSrgb(new Color(0.7f, 0.7f, 0.7f)),
|
||||
false when !learned => Color.FromSrgb(new Color(0f, 0f, 0f)),
|
||||
_ => Color.White
|
||||
};
|
||||
|
||||
handle.DrawTextureRect(baseTexture, baseQuad, iconColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using System.Numerics;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client._CP14.UserInterface.Systems.NodeTree;
|
||||
|
||||
public sealed class CP14NodeTreeElement(string nodeKey, bool gained ,bool active, Vector2 uiPosition, SpriteSpecifier? icon = null)
|
||||
{
|
||||
public string NodeKey = nodeKey;
|
||||
public bool Gained = gained;
|
||||
public bool Active = active;
|
||||
|
||||
public Vector2 UiPosition = uiPosition;
|
||||
public SpriteSpecifier? Icon = icon;
|
||||
}
|
||||
|
||||
public sealed class CP14NodeTreeUiState(
|
||||
HashSet<CP14NodeTreeElement> nodes,
|
||||
HashSet<(string, string)>? edges = null,
|
||||
SpriteSpecifier? frameIcon = null,
|
||||
SpriteSpecifier? hoveredIcon = null,
|
||||
SpriteSpecifier? selectedIcon = null,
|
||||
SpriteSpecifier? learnedIcon = null,
|
||||
Color? lineColor = null,
|
||||
Color? activeLineColor = null
|
||||
) : BoundUserInterfaceState
|
||||
{
|
||||
public HashSet<CP14NodeTreeElement> Nodes = nodes;
|
||||
public HashSet<(string, string)> Edges = edges ?? new HashSet<(string, string)>();
|
||||
|
||||
public SpriteSpecifier FrameIcon = frameIcon ?? new SpriteSpecifier.Rsi(new ResPath("/Textures/_CP14/Interface/NodeTree/default.rsi"), "frame");
|
||||
public SpriteSpecifier HoveredIcon = hoveredIcon ?? new SpriteSpecifier.Rsi(new ResPath("/Textures/_CP14/Interface/NodeTree/default.rsi"), "hovered");
|
||||
public SpriteSpecifier SelectedIcon = selectedIcon?? new SpriteSpecifier.Rsi(new ResPath("/Textures/_CP14/Interface/NodeTree/default.rsi"), "selected");
|
||||
public SpriteSpecifier LearnedIcon = learnedIcon?? new SpriteSpecifier.Rsi(new ResPath("/Textures/_CP14/Interface/NodeTree/default.rsi"), "learned");
|
||||
|
||||
public Color LineColor = lineColor ?? Color.Gray;
|
||||
public Color ActiveLineColor = activeLineColor ?? Color.White;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<ui:CP14NodeTreeGraphControl
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:ui="clr-namespace:Content.Client._CP14.UserInterface.Systems.NodeTree"
|
||||
HorizontalExpand="True"
|
||||
VerticalExpand="True"
|
||||
MouseFilter="Stop"/>
|
||||
@@ -0,0 +1,179 @@
|
||||
using System.Numerics;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Input;
|
||||
using Serilog;
|
||||
|
||||
namespace Content.Client._CP14.UserInterface.Systems.NodeTree;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class CP14NodeTreeGraphControl : BoxContainer
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||
|
||||
private CP14NodeTreeUiState? _state;
|
||||
|
||||
private CP14NodeTreeElement? _hoveredNode;
|
||||
private CP14NodeTreeElement? _selectedNode;
|
||||
|
||||
private Dictionary<string, CP14NodeTreeElement> _nodeDict = new();
|
||||
|
||||
private bool _dragging = false;
|
||||
private Vector2 _previousMousePosition = Vector2.Zero;
|
||||
private Vector2 _globalOffset = new (60,60);
|
||||
|
||||
public event Action<CP14NodeTreeElement?>? OnNodeSelected;
|
||||
public event Action<Vector2>? OnOffsetChanged;
|
||||
|
||||
public CP14NodeTreeGraphControl()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
OnOffsetChanged?.Invoke(_globalOffset);
|
||||
}
|
||||
|
||||
public void UpdateState(CP14NodeTreeUiState state)
|
||||
{
|
||||
_state = state;
|
||||
|
||||
_nodeDict.Clear();
|
||||
foreach (var node in state.Nodes)
|
||||
{
|
||||
_nodeDict[node.NodeKey] = node;
|
||||
}
|
||||
|
||||
OnOffsetChanged?.Invoke(_globalOffset);
|
||||
}
|
||||
|
||||
protected override void KeyBindDown(GUIBoundKeyEventArgs args)
|
||||
{
|
||||
base.KeyBindDown(args);
|
||||
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (args.Function == EngineKeyFunctions.UIClick)
|
||||
{
|
||||
_dragging = true;
|
||||
|
||||
if (_hoveredNode == null)
|
||||
return;
|
||||
|
||||
OnNodeSelected?.Invoke(_hoveredNode);
|
||||
UserInterfaceManager.ClickSound();
|
||||
_selectedNode = _hoveredNode;
|
||||
}
|
||||
|
||||
if (args.Function == EngineKeyFunctions.UIRightClick)
|
||||
{
|
||||
_globalOffset = new Vector2(60, 60); // Reset offset on right click
|
||||
OnOffsetChanged?.Invoke(_globalOffset);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void KeyBindUp(GUIBoundKeyEventArgs args)
|
||||
{
|
||||
base.KeyBindUp(args);
|
||||
|
||||
if (args.Handled || args.Function != EngineKeyFunctions.UIClick)
|
||||
return;
|
||||
|
||||
_dragging = false;
|
||||
}
|
||||
|
||||
protected override void ExitedTree()
|
||||
{
|
||||
base.ExitedTree();
|
||||
|
||||
OnNodeSelected?.Invoke(null);
|
||||
}
|
||||
|
||||
protected override void Draw(DrawingHandleScreen handle)
|
||||
{
|
||||
base.Draw(handle);
|
||||
|
||||
if (_state is null)
|
||||
return;
|
||||
|
||||
_hoveredNode = null;
|
||||
|
||||
var cursor = (UserInterfaceManager.MousePositionScaled.Position * UIScale) - GlobalPixelPosition;
|
||||
|
||||
if (_dragging)
|
||||
{
|
||||
var delta = cursor - _previousMousePosition;
|
||||
_globalOffset += delta;
|
||||
OnOffsetChanged?.Invoke(_globalOffset);
|
||||
}
|
||||
|
||||
_previousMousePosition = cursor;
|
||||
|
||||
//Draw connection lines
|
||||
foreach (var edge in _state.Edges)
|
||||
{
|
||||
var node1 = _nodeDict[edge.Item1];
|
||||
var node2 = _nodeDict[edge.Item2];
|
||||
var fromPos = node1.UiPosition * UIScale + _globalOffset;
|
||||
var toPos = node2.UiPosition * UIScale + _globalOffset;
|
||||
|
||||
var lineColor = node1.Gained || node2.Gained ? _state.ActiveLineColor : _state.LineColor;
|
||||
handle.DrawLine(fromPos, toPos, lineColor);
|
||||
}
|
||||
|
||||
//Draw Node icons over lines
|
||||
foreach (var node in _state.Nodes)
|
||||
{
|
||||
var pos = node.UiPosition * UIScale + _globalOffset;
|
||||
|
||||
// Frame
|
||||
var frameTexture = _state.FrameIcon.Frame0();
|
||||
var frameSize = new Vector2(frameTexture.Width, frameTexture.Height) * 1.5f * UIScale;
|
||||
var frameQuad = new UIBox2(pos - frameSize / 2, pos + frameSize / 2);
|
||||
handle.DrawTextureRect(frameTexture, frameQuad);
|
||||
|
||||
// Selected Node
|
||||
if (_selectedNode == node)
|
||||
{
|
||||
var selectedTexture = _state.SelectedIcon.Frame0();
|
||||
var selectedSize = new Vector2(selectedTexture.Width, selectedTexture.Height) * 1.5f * UIScale;
|
||||
var selectedQuad = new UIBox2(pos - selectedSize / 2, pos + selectedSize / 2);
|
||||
handle.DrawTextureRect(selectedTexture, selectedQuad);
|
||||
}
|
||||
|
||||
// Hovered Node
|
||||
var hovered = (cursor - pos).LengthSquared() <= (frameSize.X / 2) * (frameSize.X / 2);
|
||||
if (hovered)
|
||||
{
|
||||
_hoveredNode = node;
|
||||
var hoveredTexture = _state.HoveredIcon.Frame0();
|
||||
var hoveredSize = new Vector2(hoveredTexture.Width, hoveredTexture.Height) * 1.5f * UIScale;
|
||||
var hoveredQuad = new UIBox2(pos - hoveredSize / 2, pos + hoveredSize / 2);
|
||||
handle.DrawTextureRect(hoveredTexture, hoveredQuad);
|
||||
}
|
||||
|
||||
// Learned Node
|
||||
if (node.Gained)
|
||||
{
|
||||
var learnedTexture = _state.LearnedIcon.Frame0();
|
||||
var learnedSize = new Vector2(learnedTexture.Width, learnedTexture.Height) * 1.5f * UIScale;
|
||||
var learnedQuad = new UIBox2(pos - learnedSize / 2, pos + learnedSize / 2);
|
||||
handle.DrawTextureRect(learnedTexture, learnedQuad);
|
||||
}
|
||||
|
||||
// Base Node icon
|
||||
if (node.Icon is not null)
|
||||
{
|
||||
var baseTexture = node.Icon.Frame0();
|
||||
var baseSize = new Vector2(baseTexture.Width, baseTexture.Height) * 1.5f * UIScale;
|
||||
var baseQuad = new UIBox2(pos - baseSize / 2, pos + baseSize / 2);
|
||||
var tint = node.Gained || node.Active ? Color.White : Color.FromSrgb(new Color(0.6f, 0.6f, 0.6f));
|
||||
handle.DrawTextureRect(baseTexture, baseQuad, tint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,11 +3,13 @@ using System.Numerics;
|
||||
using System.Text;
|
||||
using Content.Client._CP14.Skill;
|
||||
using Content.Client._CP14.Skill.Ui;
|
||||
using Content.Client._CP14.UserInterface.Systems.NodeTree;
|
||||
using Content.Client._CP14.UserInterface.Systems.Skill.Window;
|
||||
using Content.Client.Gameplay;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared._CP14.Skill.Components;
|
||||
using Content.Shared._CP14.Skill.Prototypes;
|
||||
using Content.Shared._CP14.Skill.Restrictions;
|
||||
using Content.Shared.Input;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.Player;
|
||||
@@ -25,15 +27,22 @@ namespace Content.Client._CP14.UserInterface.Systems.Skill;
|
||||
public sealed class CP14SkillUIController : UIController, IOnStateEntered<GameplayState>, IOnStateExited<GameplayState>,
|
||||
IOnSystemChanged<CP14ClientSkillSystem>
|
||||
{
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||
[UISystemDependency] private readonly CP14ClientSkillSystem _skill = default!;
|
||||
|
||||
private CP14SkillWindow? _window;
|
||||
private CP14SkillPrototype? _selectedSkill;
|
||||
private EntityUid? _targetPlayer;
|
||||
|
||||
private MenuButton? SkillButton => UIManager.GetActiveUIWidgetOrNull<Client.UserInterface.Systems.MenuBar.Widgets.GameTopMenuBar>()?.CP14SkillButton;
|
||||
private IEnumerable<CP14SkillPrototype> _allSkills = [];
|
||||
|
||||
private CP14SkillPrototype? _selectedSkill;
|
||||
private CP14SkillTreePrototype? _selectedSkillTree;
|
||||
|
||||
private MenuButton? SkillButton => UIManager
|
||||
.GetActiveUIWidgetOrNull<Client.UserInterface.Systems.MenuBar.Widgets.GameTopMenuBar>()
|
||||
?.CP14SkillButton;
|
||||
|
||||
public void OnStateEntered(GameplayState state)
|
||||
{
|
||||
@@ -47,14 +56,22 @@ public sealed class CP14SkillUIController : UIController, IOnStateEntered<Gamepl
|
||||
InputCmdHandler.FromDelegate(_ => ToggleWindow()))
|
||||
.Register<CP14SkillUIController>();
|
||||
|
||||
_window.LearnButton.OnPressed += _ => _skill.RequestLearnSkill(_player.LocalEntity, _selectedSkill);
|
||||
CacheSkillProto();
|
||||
_proto.PrototypesReloaded += _ => CacheSkillProto();
|
||||
|
||||
_window.LearnButton.OnPressed += _ => _skill.RequestLearnSkill(_playerManager.LocalEntity, _selectedSkill);
|
||||
_window.GraphControl.OnNodeSelected += SelectNode;
|
||||
_window.GraphControl.OnOffsetChanged += offset =>
|
||||
{
|
||||
_window.ParallaxBackground.Offset = -offset * 0.25f + new Vector2(1000,1000); //hardcoding is bad
|
||||
_window.ParallaxBackground.Offset = -offset * 0.25f + new Vector2(1000, 1000); //hardcoding is bad
|
||||
};
|
||||
}
|
||||
|
||||
private void CacheSkillProto()
|
||||
{
|
||||
_allSkills = _proto.EnumeratePrototypes<CP14SkillPrototype>();
|
||||
}
|
||||
|
||||
|
||||
public void OnStateExited(GameplayState state)
|
||||
{
|
||||
@@ -72,13 +89,13 @@ public sealed class CP14SkillUIController : UIController, IOnStateEntered<Gamepl
|
||||
public void OnSystemLoaded(CP14ClientSkillSystem system)
|
||||
{
|
||||
system.OnSkillUpdate += UpdateState;
|
||||
_player.LocalPlayerDetached += CharacterDetached;
|
||||
_playerManager.LocalPlayerDetached += CharacterDetached;
|
||||
}
|
||||
|
||||
public void OnSystemUnloaded(CP14ClientSkillSystem system)
|
||||
{
|
||||
system.OnSkillUpdate -= UpdateState;
|
||||
_player.LocalPlayerDetached -= CharacterDetached;
|
||||
_playerManager.LocalPlayerDetached -= CharacterDetached;
|
||||
}
|
||||
|
||||
public void UnloadButton()
|
||||
@@ -113,38 +130,71 @@ public sealed class CP14SkillUIController : UIController, IOnStateEntered<Gamepl
|
||||
SkillButton!.Pressed = true;
|
||||
}
|
||||
|
||||
private void SelectNode(CP14NodeTreeElement? node)
|
||||
{
|
||||
if (_window is null)
|
||||
return;
|
||||
|
||||
if (_playerManager.LocalEntity == null)
|
||||
return;
|
||||
|
||||
if (node == null)
|
||||
{
|
||||
DeselectNode();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_proto.TryIndex<CP14SkillPrototype>(node.NodeKey, out var skill))
|
||||
{
|
||||
DeselectNode();
|
||||
return;
|
||||
}
|
||||
|
||||
SelectNode(skill);
|
||||
}
|
||||
|
||||
private void SelectNode(CP14SkillPrototype? skill)
|
||||
{
|
||||
if (_window is null)
|
||||
return;
|
||||
|
||||
if (_player.LocalEntity == null)
|
||||
if (_playerManager.LocalEntity == null)
|
||||
return;
|
||||
|
||||
_selectedSkill = skill;
|
||||
|
||||
if (skill == null)
|
||||
{
|
||||
_window.SkillName.Text = string.Empty;
|
||||
_window.SkillDescription.Text = string.Empty;
|
||||
_window.SkillView.Texture = null;
|
||||
_window.LearnButton.Disabled = true;
|
||||
DeselectNode();
|
||||
}
|
||||
else
|
||||
{
|
||||
_window.SkillName.Text = _skill.GetSkillName(skill);
|
||||
_window.SkillDescription.SetMessage(GetSkillDescription(skill));
|
||||
_window.SkillView.Texture = skill.Icon.Frame0();
|
||||
_window.LearnButton.Disabled = !_skill.CanLearnSkill(_player.LocalEntity.Value, skill);
|
||||
_window.LearnButton.Disabled = !_skill.CanLearnSkill(_playerManager.LocalEntity.Value, skill);
|
||||
_window.SkillCost.Text = skill.LearnCost.ToString();
|
||||
}
|
||||
|
||||
UpdateGraphControl();
|
||||
}
|
||||
|
||||
private void DeselectNode()
|
||||
{
|
||||
if (_window is null)
|
||||
return;
|
||||
|
||||
_window.SkillName.Text = string.Empty;
|
||||
_window.SkillDescription.Text = string.Empty;
|
||||
_window.SkillView.Texture = null;
|
||||
_window.LearnButton.Disabled = true;
|
||||
}
|
||||
|
||||
private FormattedMessage GetSkillDescription(CP14SkillPrototype skill)
|
||||
{
|
||||
var msg = new FormattedMessage();
|
||||
|
||||
if (_player.LocalEntity == null)
|
||||
if (_playerManager.LocalEntity == null)
|
||||
return msg;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
@@ -155,7 +205,7 @@ public sealed class CP14SkillUIController : UIController, IOnStateEntered<Gamepl
|
||||
//Restrictions
|
||||
foreach (var req in skill.Restrictions)
|
||||
{
|
||||
var color = req.Check(_entManager, _player.LocalEntity.Value) ? "green" : "red";
|
||||
var color = req.Check(_entManager, _playerManager.LocalEntity.Value) ? "green" : "red";
|
||||
|
||||
sb.Append($"- [color={color}]{req.GetDescription(_entManager, _proto)}[/color]\n");
|
||||
}
|
||||
@@ -165,21 +215,76 @@ public sealed class CP14SkillUIController : UIController, IOnStateEntered<Gamepl
|
||||
return msg;
|
||||
}
|
||||
|
||||
private void UpdateState(EntityUid player)
|
||||
private void UpdateGraphControl()
|
||||
{
|
||||
if (_window is null)
|
||||
return;
|
||||
|
||||
if (!EntityManager.TryGetComponent<CP14SkillStorageComponent>(player, out var storage))
|
||||
if (_selectedSkillTree == null)
|
||||
return;
|
||||
|
||||
_window.GraphControl.UpdateState((player, storage));
|
||||
if (!EntityManager.TryGetComponent<CP14SkillStorageComponent>(_targetPlayer, out var storage))
|
||||
return;
|
||||
|
||||
// Reselect for update state
|
||||
SelectNode(_selectedSkill);
|
||||
HashSet<CP14NodeTreeElement> nodeTreeElements = new();
|
||||
|
||||
HashSet<(string, string)> nodeTreeEdges = new();
|
||||
|
||||
var learned = storage.LearnedSkills;
|
||||
foreach (var skill in _allSkills)
|
||||
{
|
||||
if (skill.Tree != _selectedSkillTree)
|
||||
continue;
|
||||
|
||||
foreach (var req in skill.Restrictions)
|
||||
{
|
||||
switch (req)
|
||||
{
|
||||
case NeedPrerequisite prerequisite:
|
||||
if (!_proto.TryIndex(prerequisite.Prerequisite, out var prerequisiteSkill))
|
||||
continue;
|
||||
|
||||
if (prerequisiteSkill.Tree != _selectedSkillTree)
|
||||
continue;
|
||||
|
||||
nodeTreeEdges.Add((skill.ID, prerequisiteSkill.ID));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var nodeTreeElement = new CP14NodeTreeElement(
|
||||
skill.ID,
|
||||
gained: learned.Contains(skill),
|
||||
active: _skill.CanLearnSkill(_targetPlayer.Value, skill),
|
||||
skill.SkillUiPosition * 25f,
|
||||
skill.Icon);
|
||||
nodeTreeElements.Add(nodeTreeElement);
|
||||
}
|
||||
|
||||
_window.GraphControl.UpdateState(
|
||||
new CP14NodeTreeUiState(
|
||||
nodes: nodeTreeElements,
|
||||
edges: nodeTreeEdges,
|
||||
frameIcon: _selectedSkillTree.FrameIcon,
|
||||
hoveredIcon: _selectedSkillTree.HoveredIcon,
|
||||
selectedIcon: _selectedSkillTree.SelectedIcon,
|
||||
learnedIcon: _selectedSkillTree.LearnedIcon
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private void UpdateState(EntityUid player)
|
||||
{
|
||||
_targetPlayer = player;
|
||||
|
||||
if (_window is null)
|
||||
return;
|
||||
|
||||
if (!EntityManager.TryGetComponent<CP14SkillStorageComponent>(_targetPlayer, out var storage))
|
||||
return;
|
||||
|
||||
//If tree not selected, select the first one
|
||||
if (_window.GraphControl.Tree == null && storage.Progress.Count > 0)
|
||||
if (_selectedSkillTree == null && storage.Progress.Count > 0)
|
||||
{
|
||||
var firstTree = storage.Progress.First().Key;
|
||||
|
||||
@@ -189,17 +294,24 @@ public sealed class CP14SkillUIController : UIController, IOnStateEntered<Gamepl
|
||||
}
|
||||
}
|
||||
|
||||
if (_selectedSkillTree == null)
|
||||
return;
|
||||
|
||||
// Reselect for update state
|
||||
SelectNode(_selectedSkill);
|
||||
UpdateGraphControl();
|
||||
|
||||
// Update the experience points for the selected tree
|
||||
var playerProgress = storage.Progress;
|
||||
if (_window.GraphControl.Tree is not null && playerProgress.TryGetValue(_window.GraphControl.Tree, out var skillpoint))
|
||||
if (playerProgress.TryGetValue(_selectedSkillTree, out var skillPoint))
|
||||
{
|
||||
_window.ExpPointLabel.Text = skillpoint.ToString();
|
||||
_window.ExpPointLabel.Text = skillPoint.ToString();
|
||||
}
|
||||
|
||||
_window.LevelLabel.Text = $"{storage.SkillsSumExperience}/{storage.ExperienceMaxCap}";
|
||||
|
||||
_window.TreeTabsContainer.RemoveAllChildren();
|
||||
foreach (var (tree, progress) in storage.Progress)
|
||||
foreach (var (tree, _) in storage.Progress)
|
||||
{
|
||||
if (!_proto.TryIndex(tree, out var indexedTree))
|
||||
continue;
|
||||
@@ -220,12 +332,14 @@ public sealed class CP14SkillUIController : UIController, IOnStateEntered<Gamepl
|
||||
if (_window == null)
|
||||
return;
|
||||
|
||||
_window.GraphControl.Tree = tree;
|
||||
_selectedSkillTree = tree;
|
||||
_window.ParallaxBackground.ParallaxPrototype = tree.Parallax;
|
||||
_window.TreeName.Text = Loc.GetString(tree.Name);
|
||||
|
||||
var playerProgress = storage.Progress;
|
||||
_window.ExpPointLabel.Text = playerProgress.TryGetValue(tree, out var skillpoint) ? skillpoint.ToString() : "0";
|
||||
|
||||
UpdateGraphControl();
|
||||
}
|
||||
|
||||
private void CharacterDetached(EntityUid uid)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"
|
||||
xmlns:parallax="clr-namespace:Content.Client.Parallax"
|
||||
xmlns:ui1="clr-namespace:Content.Client._CP14.Skill.Ui"
|
||||
xmlns:nodeTree="clr-namespace:Content.Client._CP14.UserInterface.Systems.NodeTree"
|
||||
Title="{Loc 'cp14-skill-info-title'}"
|
||||
MinSize="700 350"
|
||||
SetSize="980 550">
|
||||
@@ -38,7 +39,7 @@
|
||||
<!-- Skill Cost -->
|
||||
<BoxContainer HorizontalExpand="True">
|
||||
<RichTextLabel HorizontalExpand="True" Access="Public" Text="{Loc 'cp14-skill-menu-learncost'}" Margin="0 10 0 10" />
|
||||
<TextureRect VerticalAlignment="Center" HorizontalAlignment="Left" TextureScale="2, 2" TexturePath="/Textures/_CP14/Interface/Skills/skillpoint.png"/>
|
||||
<TextureRect VerticalAlignment="Center" HorizontalAlignment="Left" TextureScale="2, 2" TexturePath="/Textures/_CP14/Interface/Misc/skillpoint.png"/>
|
||||
<RichTextLabel Name="SkillCost" Access="Public" Text="0"/>
|
||||
</BoxContainer>
|
||||
<!-- Skill Description -->
|
||||
@@ -67,7 +68,7 @@
|
||||
<PanelContainer Margin="10 10 10 10" HorizontalExpand="True" VerticalExpand="True" RectClipContent="True">
|
||||
<parallax:ParallaxControl Name="ParallaxBackground" ScaleX="4" ScaleY="4" Access="Public" SpeedX="10" SpeedY="5"/>
|
||||
<BoxContainer Margin="10 10 10 10" Orientation="Horizontal" HorizontalExpand="True" VerticalExpand="True">
|
||||
<ui1:CP14SkillTreeGraphControl Name="GraphControl" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Access="Public"/>
|
||||
<nodeTree:CP14NodeTreeGraphControl Name="GraphControl" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Access="Public"/>
|
||||
</BoxContainer>
|
||||
<!-- Tree Tabs -->
|
||||
<BoxContainer Margin="10 10 10 10" VerticalAlignment="Top" HorizontalAlignment="Right" Orientation="Vertical" VerticalExpand="True">
|
||||
@@ -76,11 +77,11 @@
|
||||
<!-- Experience Data -->
|
||||
<BoxContainer Margin="10 10 10 10" VerticalAlignment="Bottom" HorizontalAlignment="Center" Orientation="Horizontal" VerticalExpand="True">
|
||||
<RichTextLabel VerticalAlignment="Center" HorizontalAlignment="Left" Text="{Loc 'cp14-skill-menu-skillpoints'}" StyleClasses="LabelKeyText"/>
|
||||
<TextureRect VerticalAlignment="Center" HorizontalAlignment="Center" TextureScale="2, 2" TexturePath="/Textures/_CP14/Interface/Skills/skillpoint.png"/>
|
||||
<TextureRect VerticalAlignment="Center" HorizontalAlignment="Center" TextureScale="2, 2" TexturePath="/Textures/_CP14/Interface/Misc/skillpoint.png"/>
|
||||
<RichTextLabel Margin="0 0 20 0" Name="ExpPointLabel" VerticalAlignment="Center" HorizontalAlignment="Left" Text="0" StyleClasses="LabelKeyText" Access="Public"/>
|
||||
|
||||
<RichTextLabel VerticalAlignment="Center" HorizontalAlignment="Left" Text="{Loc 'cp14-skill-menu-level'}" StyleClasses="LabelKeyText"/>
|
||||
<TextureRect VerticalAlignment="Center" HorizontalAlignment="Center" TextureScale="2, 2" TexturePath="/Textures/_CP14/Interface/Skills/skillpoint.png"/>
|
||||
<TextureRect VerticalAlignment="Center" HorizontalAlignment="Center" TextureScale="2, 2" TexturePath="/Textures/_CP14/Interface/Misc/skillpoint.png"/>
|
||||
<RichTextLabel Margin="0 0 0 0" Name="LevelLabel" VerticalAlignment="Center" HorizontalAlignment="Left" Text="0" StyleClasses="LabelKeyText" Access="Public"/>
|
||||
</BoxContainer>
|
||||
</PanelContainer>
|
||||
|
||||
@@ -41,7 +41,7 @@ public sealed partial class CP14DemiplaneSystem
|
||||
return;
|
||||
|
||||
RemoveDemiplaneRandomEntryPoint((rift.Comp.Demiplane.Value, riftDemiplane), rift);
|
||||
RemoveDemiplanRandomExitPoint((rift.Comp.Demiplane.Value, riftDemiplane), rift);
|
||||
RemoveDemiplaneRandomExitPoint((rift.Comp.Demiplane.Value, riftDemiplane), rift);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -57,7 +57,7 @@ public sealed partial class CP14DemiplaneSystem
|
||||
/// <summary>
|
||||
/// Removing the demiplane exit point, one of which the player can exit to
|
||||
/// </summary>
|
||||
private void RemoveDemiplanRandomExitPoint(Entity<CP14DemiplaneComponent>? demiplane,
|
||||
private void RemoveDemiplaneRandomExitPoint(Entity<CP14DemiplaneComponent>? demiplane,
|
||||
EntityUid exitPoint)
|
||||
{
|
||||
if (!TryComp<CP14DemiplaneRiftComponent>(exitPoint, out var riftComp))
|
||||
@@ -69,7 +69,7 @@ public sealed partial class CP14DemiplaneSystem
|
||||
riftComp.Demiplane = null;
|
||||
}
|
||||
|
||||
if (riftComp.DeleteAfterDisconnect)
|
||||
if (riftComp.DeleteAfterDisconnect && exitPoint.Valid)
|
||||
QueueDel(exitPoint);
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ public sealed partial class CP14DemiplaneSystem
|
||||
riftComp.Demiplane = null;
|
||||
}
|
||||
|
||||
if (riftComp.DeleteAfterDisconnect)
|
||||
if (riftComp.DeleteAfterDisconnect && entryPoint.Valid)
|
||||
QueueDel(entryPoint);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,42 @@
|
||||
using Content.Server._CP14.WeatherControl;
|
||||
using Content.Server.Weather;
|
||||
using Content.Shared._CP14.Demiplane.Components;
|
||||
using Content.Shared.Weather;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._CP14.Demiplane;
|
||||
|
||||
public sealed partial class CP14DemiplaneSystem
|
||||
{
|
||||
[Dependency] private readonly WeatherSystem _weather = default!;
|
||||
private void InitDestruction()
|
||||
{
|
||||
SubscribeLocalEvent<CP14DemiplaneTimedDestructionComponent, ComponentAdd>(OnDestructionStarted);
|
||||
}
|
||||
|
||||
public void StartDestructDemiplane(Entity<CP14DemiplaneComponent> demiplane)
|
||||
{
|
||||
if (!TryComp<MapComponent>(demiplane, out var map))
|
||||
return;
|
||||
|
||||
if (HasComp<CP14DemiplaneTimedDestructionComponent>(demiplane))
|
||||
return;
|
||||
|
||||
EnsureComp<CP14DemiplaneTimedDestructionComponent>(demiplane);
|
||||
|
||||
if (HasComp<CP14WeatherControllerComponent>(demiplane))
|
||||
{
|
||||
RemCompDeferred<CP14WeatherControllerComponent>(demiplane);
|
||||
}
|
||||
|
||||
if (!_proto.TryIndex<WeatherPrototype>("CP14DemiplaneDestructionStorm", out var indexedWeather))
|
||||
return;
|
||||
|
||||
_weather.SetWeather(map.MapId, indexedWeather, null);
|
||||
}
|
||||
|
||||
private void OnDestructionStarted(Entity<CP14DemiplaneTimedDestructionComponent> ent, ref ComponentAdd args)
|
||||
{
|
||||
ent.Comp.EndTime = _timing.CurTime + ent.Comp.TimeToDestruction;
|
||||
|
||||
@@ -30,13 +30,115 @@ public sealed partial class CP14DemiplaneSystem
|
||||
|
||||
private void InitGeneration()
|
||||
{
|
||||
SubscribeLocalEvent<CP14DemiplaneGeneratorDataComponent, MapInitEvent>(GeneratorMapInit);
|
||||
SubscribeLocalEvent<CP14DemiplaneRandomGeneratorComponent, MapInitEvent>(GeneratorMapInit);
|
||||
SubscribeLocalEvent<CP14DemiplaneUsingOpenComponent, UseInHandEvent>(GeneratorUsedInHand);
|
||||
|
||||
SubscribeLocalEvent<CP14DemiplaneGeneratorDataComponent, GetVerbsEvent<ExamineVerb>>(OnVerbExamine);
|
||||
SubscribeLocalEvent<CP14DemiplaneDataComponent, GetVerbsEvent<ExamineVerb>>(OnVerbExamine);
|
||||
}
|
||||
|
||||
private void OnVerbExamine(Entity<CP14DemiplaneGeneratorDataComponent> ent, ref GetVerbsEvent<ExamineVerb> args)
|
||||
private void GeneratorMapInit(Entity<CP14DemiplaneRandomGeneratorComponent> generator, ref MapInitEvent args)
|
||||
{
|
||||
if (!TryComp<CP14DemiplaneDataComponent>(generator, out var data))
|
||||
return;
|
||||
|
||||
CP14DemiplaneLocationPrototype? selectedConfig = null;
|
||||
//Location generation
|
||||
if (data.Location is null || generator.Comp.OverrideLocation)
|
||||
{
|
||||
selectedConfig = GenerateDemiplaneLocation(generator.Comp.Level);
|
||||
data.Location = selectedConfig;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_proto.TryIndex(data.Location, out selectedConfig))
|
||||
return;
|
||||
}
|
||||
|
||||
//Modifier generation
|
||||
var newModifiers = GenerateDemiplaneModifiers(
|
||||
generator.Comp.Level,
|
||||
selectedConfig,
|
||||
generator.Comp.Limits);
|
||||
|
||||
foreach (var mod in newModifiers)
|
||||
{
|
||||
data.SelectedModifiers.Add(mod);
|
||||
}
|
||||
}
|
||||
|
||||
private void GeneratorUsedInHand(Entity<CP14DemiplaneUsingOpenComponent> ent, ref UseInHandEvent args)
|
||||
{
|
||||
if (!TryComp<CP14DemiplaneDataComponent>(ent, out var generator))
|
||||
return;
|
||||
|
||||
UseGenerator((ent, generator), args.User);
|
||||
}
|
||||
//Ed: I hate this function.
|
||||
private void UseGenerator(Entity<CP14DemiplaneDataComponent> generator, EntityUid? user = null)
|
||||
{
|
||||
//block the opening of demiplanes after the end of a round
|
||||
if (_gameTicker.RunLevel != GameRunLevel.InRound)
|
||||
{
|
||||
if (user is not null)
|
||||
_popup.PopupEntity(Loc.GetString("cp14-demiplan-cannot-open-end-round"), generator, user.Value);
|
||||
return;
|
||||
}
|
||||
//We cant open demiplane in another demiplane or if parent is not Map
|
||||
if (_demiplaneQuery.HasComp(Transform(generator).MapUid))
|
||||
{
|
||||
if (user is not null)
|
||||
_popup.PopupEntity(Loc.GetString("cp14-demiplan-cannot-open", ("name", MetaData(generator).EntityName)), generator, user.Value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (generator.Comp.Location is null)
|
||||
return;
|
||||
|
||||
//an attempt to open demiplanes can be intercepted by other systems that substitute a map instead of generating the planned demiplane.
|
||||
Entity<CP14DemiplaneComponent>? demiplane = null;
|
||||
var ev = new CP14DemiplaneGenerationCatchAttemptEvent();
|
||||
RaiseLocalEvent(ev);
|
||||
|
||||
if (ev.Demiplane is null)
|
||||
{
|
||||
SpawnRandomDemiplane(generator.Comp.Location.Value, generator.Comp.SelectedModifiers, out demiplane, out var mapId);
|
||||
if (demiplane is not null && TryComp<CP14DemiplaneMapNodeBlockerComponent>(generator, out var blocker))
|
||||
{
|
||||
EnsureComp<CP14DemiplaneMapNodeBlockerComponent>(demiplane.Value, out var blockerMap);
|
||||
blockerMap.Position = blocker.Position;
|
||||
blockerMap.Station = blocker.Station;
|
||||
blockerMap.IncreaseNodeDifficulty = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
demiplane = ev.Demiplane;
|
||||
}
|
||||
|
||||
_statistic.TrackAdd(generator.Comp.Statistic, 1);
|
||||
|
||||
if (demiplane is null)
|
||||
return;
|
||||
|
||||
//Admin log needed
|
||||
EnsureComp<CP14DemiplaneDestroyWithoutStabilizationComponent>(demiplane.Value);
|
||||
|
||||
//Rifts spawning
|
||||
foreach (var rift in generator.Comp.AutoRifts)
|
||||
{
|
||||
var spawnedRift = EntityManager.Spawn(rift);
|
||||
_transform.SetCoordinates(spawnedRift, Transform(generator).Coordinates);
|
||||
_transform.AttachToGridOrMap(spawnedRift);
|
||||
var connection = EnsureComp<CP14DemiplaneRiftComponent>(spawnedRift);
|
||||
AddDemiplaneRandomExitPoint(demiplane.Value, (spawnedRift, connection));
|
||||
}
|
||||
|
||||
#if !DEBUG
|
||||
QueueDel(generator); //wtf its crash debug build!
|
||||
#endif
|
||||
}
|
||||
|
||||
private void OnVerbExamine(Entity<CP14DemiplaneDataComponent> ent, ref GetVerbsEvent<ExamineVerb> args)
|
||||
{
|
||||
if (!args.CanInteract || !args.CanAccess)
|
||||
return;
|
||||
@@ -50,7 +152,7 @@ public sealed partial class CP14DemiplaneSystem
|
||||
"/Textures/Interface/VerbIcons/dot.svg.192dpi.png"); //TODO custom icon
|
||||
}
|
||||
|
||||
private FormattedMessage GetDemiplanExamine(CP14DemiplaneGeneratorDataComponent comp)
|
||||
private FormattedMessage GetDemiplanExamine(CP14DemiplaneDataComponent comp)
|
||||
{
|
||||
var msg = new FormattedMessage();
|
||||
|
||||
@@ -136,114 +238,52 @@ public sealed partial class CP14DemiplaneSystem
|
||||
_expeditionQueue.EnqueueJob(job);
|
||||
}
|
||||
|
||||
private void UseGenerator(Entity<CP14DemiplaneGeneratorDataComponent> generator, EntityUid? user = null)
|
||||
{
|
||||
//block the opening of demiplanes after the end of a round
|
||||
if (_gameTicker.RunLevel != GameRunLevel.InRound)
|
||||
{
|
||||
if (user is not null)
|
||||
_popup.PopupEntity(Loc.GetString("cp14-demiplan-cannot-open-end-round"), generator, user.Value);
|
||||
return;
|
||||
}
|
||||
//We cant open demiplane in another demiplane or if parent is not Map
|
||||
if (_demiplaneQuery.HasComp(Transform(generator).MapUid))
|
||||
{
|
||||
if (user is not null)
|
||||
_popup.PopupEntity(Loc.GetString("cp14-demiplan-cannot-open", ("name", MetaData(generator).EntityName)), generator, user.Value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (generator.Comp.Location is null)
|
||||
return;
|
||||
|
||||
//an attempt to open demiplanes can be intercepted by other systems that substitute a map instead of generating the planned demiplane.
|
||||
Entity<CP14DemiplaneComponent>? demiplane = null;
|
||||
var ev = new CP14DemiplaneGenerationCatchAttemptEvent();
|
||||
RaiseLocalEvent(ev);
|
||||
|
||||
if (ev.Demiplane is null)
|
||||
{
|
||||
SpawnRandomDemiplane(generator.Comp.Location.Value, generator.Comp.SelectedModifiers, out demiplane, out var mapId);
|
||||
}
|
||||
else
|
||||
{
|
||||
demiplane = ev.Demiplane;
|
||||
}
|
||||
|
||||
_statistic.TrackAdd(generator.Comp.Statistic, 1);
|
||||
|
||||
if (demiplane is null)
|
||||
return;
|
||||
|
||||
//Admin log needed
|
||||
EnsureComp<CP14DemiplaneDestroyWithoutStabilizationComponent>(demiplane.Value);
|
||||
|
||||
//Rifts spawning
|
||||
foreach (var rift in generator.Comp.AutoRifts)
|
||||
{
|
||||
var spawnedRift = EntityManager.Spawn(rift);
|
||||
_transform.SetCoordinates(spawnedRift, Transform(generator).Coordinates);
|
||||
_transform.AttachToGridOrMap(spawnedRift);
|
||||
var connection = EnsureComp<CP14DemiplaneRiftComponent>(spawnedRift);
|
||||
AddDemiplaneRandomExitPoint(demiplane.Value, (spawnedRift, connection));
|
||||
}
|
||||
|
||||
#if !DEBUG
|
||||
QueueDel(generator); //wtf its crash debug build!
|
||||
#endif
|
||||
}
|
||||
|
||||
private void GeneratorUsedInHand(Entity<CP14DemiplaneUsingOpenComponent> ent, ref UseInHandEvent args)
|
||||
{
|
||||
if (!TryComp<CP14DemiplaneGeneratorDataComponent>(ent, out var generator))
|
||||
return;
|
||||
|
||||
UseGenerator((ent, generator), args.User);
|
||||
}
|
||||
|
||||
private void GeneratorMapInit(Entity<CP14DemiplaneGeneratorDataComponent> generator, ref MapInitEvent args)
|
||||
/// <summary>
|
||||
/// Returns a suitable demiplane location for the specified difficulty level.
|
||||
/// </summary>
|
||||
public CP14DemiplaneLocationPrototype GenerateDemiplaneLocation(int level)
|
||||
{
|
||||
CP14DemiplaneLocationPrototype? selectedConfig = null;
|
||||
//Location generation
|
||||
if (generator.Comp.Location is null)
|
||||
|
||||
HashSet<CP14DemiplaneLocationPrototype> suitableConfigs = new();
|
||||
foreach (var locationConfig in _proto.EnumeratePrototypes<CP14DemiplaneLocationPrototype>())
|
||||
{
|
||||
HashSet<CP14DemiplaneLocationPrototype> suitableConfigs = new();
|
||||
foreach (var locationConfig in _proto.EnumeratePrototypes<CP14DemiplaneLocationPrototype>())
|
||||
{
|
||||
suitableConfigs.Add(locationConfig);
|
||||
}
|
||||
|
||||
while (suitableConfigs.Count > 0)
|
||||
{
|
||||
var randomConfig = _random.Pick(suitableConfigs);
|
||||
|
||||
//LevelRange filter
|
||||
if (generator.Comp.Level < randomConfig.Levels.Min || generator.Comp.Level > randomConfig.Levels.Max)
|
||||
{
|
||||
suitableConfigs.Remove(randomConfig);
|
||||
continue;
|
||||
}
|
||||
|
||||
selectedConfig = randomConfig;
|
||||
break;
|
||||
}
|
||||
|
||||
if (selectedConfig is null)
|
||||
{
|
||||
// We dont should be here
|
||||
|
||||
Log.Warning("Expedition mission generation failed: No suitable location configs.");
|
||||
QueueDel(generator);
|
||||
return;
|
||||
}
|
||||
generator.Comp.Location = selectedConfig;
|
||||
suitableConfigs.Add(locationConfig);
|
||||
}
|
||||
else
|
||||
|
||||
while (suitableConfigs.Count > 0)
|
||||
{
|
||||
if (!_proto.TryIndex(generator.Comp.Location, out selectedConfig))
|
||||
return;
|
||||
var randomConfig = _random.Pick(suitableConfigs);
|
||||
|
||||
//LevelRange filter
|
||||
if (level < randomConfig.Levels.Min || level > randomConfig.Levels.Max)
|
||||
{
|
||||
suitableConfigs.Remove(randomConfig);
|
||||
continue;
|
||||
}
|
||||
|
||||
selectedConfig = randomConfig;
|
||||
break;
|
||||
}
|
||||
|
||||
if (selectedConfig is null)
|
||||
throw new Exception($"No suitable demiplane location config found for level {level}!");
|
||||
|
||||
return selectedConfig;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a set of modifiers under the specified difficulty level that are appropriate for the specified demiplane location
|
||||
/// </summary>
|
||||
public List<CP14DemiplaneModifierPrototype> GenerateDemiplaneModifiers(
|
||||
int level,
|
||||
CP14DemiplaneLocationPrototype location,
|
||||
Dictionary<ProtoId<CP14DemiplaneModifierCategoryPrototype>,float> modifierLimits)
|
||||
{
|
||||
List<CP14DemiplaneModifierPrototype> selectedModifiers = new();
|
||||
|
||||
//Modifier generation
|
||||
Dictionary<CP14DemiplaneModifierPrototype, float> suitableModifiersWeights = new();
|
||||
foreach (var modifier in _proto.EnumeratePrototypes<CP14DemiplaneModifierPrototype>())
|
||||
@@ -262,14 +302,14 @@ public sealed partial class CP14DemiplaneSystem
|
||||
//Levels filter
|
||||
if (passed)
|
||||
{
|
||||
if (generator.Comp.Level < modifier.Levels.Min || generator.Comp.Level > modifier.Levels.Max)
|
||||
if (level < modifier.Levels.Min || level > modifier.Levels.Max)
|
||||
{
|
||||
passed = false;
|
||||
}
|
||||
}
|
||||
|
||||
//Tag blacklist filter
|
||||
foreach (var configTag in selectedConfig.Tags)
|
||||
foreach (var configTag in location.Tags)
|
||||
{
|
||||
if (modifier.BlacklistTags.Count != 0 && modifier.BlacklistTags.Contains(configTag))
|
||||
{
|
||||
@@ -283,7 +323,7 @@ public sealed partial class CP14DemiplaneSystem
|
||||
{
|
||||
foreach (var reqTag in modifier.RequiredTags)
|
||||
{
|
||||
if (!selectedConfig.Tags.Contains(reqTag))
|
||||
if (!location.Tags.Contains(reqTag))
|
||||
{
|
||||
passed = false;
|
||||
break;
|
||||
@@ -298,11 +338,12 @@ public sealed partial class CP14DemiplaneSystem
|
||||
|
||||
//Limits calculation
|
||||
Dictionary<ProtoId<CP14DemiplaneModifierCategoryPrototype>, float> limits = new();
|
||||
foreach (var limit in generator.Comp.Limits)
|
||||
foreach (var limit in modifierLimits)
|
||||
{
|
||||
limits.Add(limit.Key, limit.Value);
|
||||
}
|
||||
|
||||
|
||||
while (suitableModifiersWeights.Count > 0)
|
||||
{
|
||||
var selectedModifier = ModifierPick(suitableModifiersWeights, _random);
|
||||
@@ -329,7 +370,7 @@ public sealed partial class CP14DemiplaneSystem
|
||||
if (!passed)
|
||||
continue;
|
||||
|
||||
generator.Comp.SelectedModifiers.Add(selectedModifier);
|
||||
selectedModifiers.Add(selectedModifier);
|
||||
|
||||
foreach (var category in selectedModifier.Categories)
|
||||
{
|
||||
@@ -340,15 +381,9 @@ public sealed partial class CP14DemiplaneSystem
|
||||
suitableModifiersWeights.Remove(selectedModifier);
|
||||
}
|
||||
|
||||
//Scenario generation
|
||||
|
||||
//ETC generation
|
||||
|
||||
if (HasComp<CP14DemiplaneAutoOpenComponent>(generator))
|
||||
UseGenerator(generator);
|
||||
return selectedModifiers;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Optimization moment: avoid re-indexing for weight selection
|
||||
/// </summary>
|
||||
|
||||
@@ -75,7 +75,7 @@ public sealed partial class CP14DemiplaneSystem
|
||||
}
|
||||
}
|
||||
|
||||
private void DeleteDemiplane(Entity<CP14DemiplaneComponent> demiplane, bool safe = false)
|
||||
public void DeleteDemiplane(Entity<CP14DemiplaneComponent> demiplane, bool safe = false)
|
||||
{
|
||||
var query = EntityQueryEnumerator<CP14DemiplaneStabilizerComponent, TransformComponent>();
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ public sealed partial class CP14DemiplaneSystem : CP14SharedDemiplaneSystem
|
||||
|
||||
foreach (var exit in demiplane.Comp.ExitPoints)
|
||||
{
|
||||
RemoveDemiplanRandomExitPoint(demiplane, exit);
|
||||
RemoveDemiplaneRandomExitPoint(demiplane, exit);
|
||||
}
|
||||
|
||||
foreach (var entry in demiplane.Comp.EntryPoints)
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace Content.Server._CP14.Demiplane.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Open demiplane automatically on MapInit
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14DemiplaneSystem))]
|
||||
public sealed partial class CP14DemiplaneAutoOpenComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Content.Server._CP14.DemiplaneTraveling;
|
||||
|
||||
namespace Content.Server._CP14.Demiplane.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Demiplane Core - stores a position on the demiplane map to mark it as “passed” when all conditions are met
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14DemiplaneSystem), typeof(CP14StationDemiplaneMapSystem))]
|
||||
public sealed partial class CP14DemiplaneCoreComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public EntityUid? Demiplane;
|
||||
|
||||
[DataField]
|
||||
public EntityUid? Station;
|
||||
|
||||
[DataField]
|
||||
public Vector2i Position;
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using Content.Server._CP14.DemiplaneTraveling;
|
||||
using Content.Shared._CP14.Demiplane.Prototypes;
|
||||
using Content.Shared._CP14.RoundStatistic;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -5,10 +6,10 @@ using Robust.Shared.Prototypes;
|
||||
namespace Content.Server._CP14.Demiplane.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Stores the data needed to generate a new demiplane
|
||||
/// Stores all the information needed to generate a new demiplane
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14DemiplaneSystem))]
|
||||
public sealed partial class CP14DemiplaneGeneratorDataComponent : Component
|
||||
[RegisterComponent, Access(typeof(CP14DemiplaneSystem), typeof(CP14StationDemiplaneMapSystem))]
|
||||
public sealed partial class CP14DemiplaneDataComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public ProtoId<CP14DemiplaneLocationPrototype>? Location;
|
||||
@@ -16,15 +17,6 @@ public sealed partial class CP14DemiplaneGeneratorDataComponent : Component
|
||||
[DataField]
|
||||
public List<ProtoId<CP14DemiplaneModifierPrototype>> SelectedModifiers = new();
|
||||
|
||||
/// <summary>
|
||||
/// Demiplane Difficulty Level. By design, the plan so far is for a framework of 1 to 10, but technically could support more.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public int Level = 1;
|
||||
|
||||
[DataField(required: true)]
|
||||
public Dictionary<ProtoId<CP14DemiplaneModifierCategoryPrototype>, float> Limits = new();
|
||||
|
||||
[DataField]
|
||||
public ProtoId<CP14RoundStatTrackerPrototype> Statistic = "DemiplaneOpen";
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
using Content.Server._CP14.DemiplaneTraveling;
|
||||
|
||||
namespace Content.Server._CP14.Demiplane.Components;
|
||||
|
||||
/// <summary>
|
||||
/// The existence of an entity with this component will block the discovery of a particular coordinate in the demiplane navigation map.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14StationDemiplaneMapSystem), typeof(CP14DemiplaneSystem))]
|
||||
public sealed partial class CP14DemiplaneMapNodeBlockerComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public EntityUid? Station = null;
|
||||
|
||||
[DataField]
|
||||
public Vector2i Position = new (0,0);
|
||||
|
||||
[DataField]
|
||||
public int IncreaseNodeDifficulty = 0;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using Content.Shared._CP14.Demiplane.Prototypes;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._CP14.Demiplane.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Fills the DemiplaneDataComponent with random modifiers and location
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CP14DemiplaneSystem))]
|
||||
public sealed partial class CP14DemiplaneRandomGeneratorComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public bool OverrideLocation = false;
|
||||
|
||||
/// <summary>
|
||||
/// Demiplane Difficulty Level. By design, the plan so far is for a framework of 1 to 10, but technically could support more.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public int Level = 1;
|
||||
|
||||
[DataField(required: true)]
|
||||
public Dictionary<ProtoId<CP14DemiplaneModifierCategoryPrototype>, float> Limits = new();
|
||||
}
|
||||
@@ -34,7 +34,7 @@ public sealed partial class CP14DemiplaneTravelingSystem : EntitySystem
|
||||
}
|
||||
|
||||
// !!!SHITCODE WARNING!!!
|
||||
// This whole module is saturated with shieldcode, code duplication and other delights. Why? Because.
|
||||
// This whole module is saturated with shitcode, code duplication and other delights. Why? Because.
|
||||
//TODO: Refactor this shitcode
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,350 @@
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Server._CP14.Demiplane;
|
||||
using Content.Server._CP14.Demiplane.Components;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared._CP14.Demiplane.Components;
|
||||
using Content.Shared._CP14.Demiplane.Prototypes;
|
||||
using Content.Shared._CP14.DemiplaneTraveling;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Destructible;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Pulling.Events;
|
||||
using Content.Shared.UserInterface;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server._CP14.DemiplaneTraveling;
|
||||
|
||||
public sealed partial class CP14StationDemiplaneMapSystem : CP14SharedStationDemiplaneMapSystem
|
||||
{
|
||||
[Dependency] private readonly UserInterfaceSystem _userInterface = default!;
|
||||
[Dependency] private readonly StationSystem _station = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly CP14DemiplaneSystem _demiplane = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<CP14StationDemiplaneMapComponent, MapInitEvent>(OnMapInit);
|
||||
|
||||
SubscribeLocalEvent<CP14DemiplaneNavigationMapComponent, CP14DemiplaneMapEjectMessage>(DemiplaneEjectAttempt);
|
||||
SubscribeLocalEvent<CP14DemiplaneNavigationMapComponent, CP14DemiplaneMapRevokeMessage>(DemiplaneRevokeAttempt);
|
||||
|
||||
SubscribeLocalEvent<CP14DemiplaneNavigationMapComponent, BeforeActivatableUIOpenEvent>(OnBeforeActivatableUiOpen);
|
||||
SubscribeLocalEvent<CP14DemiplaneMapNodeBlockerComponent, ComponentShutdown>(OnNodeBlockerShutdown);
|
||||
|
||||
SubscribeLocalEvent<CP14DemiplaneCoreComponent, MapInitEvent>(OnCoreInit);
|
||||
SubscribeLocalEvent<CP14DemiplaneCoreComponent, DestructionEventArgs>(OnCoreDestroyed);
|
||||
}
|
||||
|
||||
private void OnCoreDestroyed(Entity<CP14DemiplaneCoreComponent> ent, ref DestructionEventArgs args)
|
||||
{
|
||||
if (TryComp<CP14DemiplaneComponent>(ent.Comp.Demiplane, out var demiplane))
|
||||
{
|
||||
_demiplane.StartDestructDemiplane((ent.Comp.Demiplane.Value, demiplane));
|
||||
}
|
||||
|
||||
var station = _station.GetOwningStation(ent, Transform(ent));
|
||||
|
||||
if (TryComp<CP14StationDemiplaneMapComponent>(station, out var stationMap) &&
|
||||
stationMap.Nodes.TryGetValue(ent.Comp.Position, out var node) && ent.Comp.Station == station)
|
||||
{
|
||||
node.Scanned = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCoreInit(Entity<CP14DemiplaneCoreComponent> core, ref MapInitEvent args)
|
||||
{
|
||||
core.Comp.Demiplane = Transform(core).MapUid;
|
||||
if (!TryComp<CP14DemiplaneMapNodeBlockerComponent>(core.Comp.Demiplane, out var demiBlocker))
|
||||
return;
|
||||
|
||||
core.Comp.Station = demiBlocker.Station;
|
||||
core.Comp.Position = demiBlocker.Position;
|
||||
|
||||
EnsureComp<CP14DemiplaneMapNodeBlockerComponent>(core, out var coreBlocker);
|
||||
|
||||
coreBlocker.Position = core.Comp.Position;
|
||||
coreBlocker.Station = core.Comp.Station;
|
||||
coreBlocker.IncreaseNodeDifficulty = 0;
|
||||
}
|
||||
|
||||
private void OnNodeBlockerShutdown(Entity<CP14DemiplaneMapNodeBlockerComponent> ent, ref ComponentShutdown args)
|
||||
{
|
||||
if (!TryComp<CP14StationDemiplaneMapComponent>(ent.Comp.Station, out var stationMap))
|
||||
return;
|
||||
|
||||
if (!stationMap.Nodes.TryGetValue(ent.Comp.Position, out var node))
|
||||
return;
|
||||
|
||||
if (ent.Comp.IncreaseNodeDifficulty == 0)
|
||||
return;
|
||||
|
||||
node.AdditionalLevel += ent.Comp.IncreaseNodeDifficulty;
|
||||
GenerateNodeData(node, clearOldModifiers: true);
|
||||
}
|
||||
|
||||
private void DemiplaneEjectAttempt(Entity<CP14DemiplaneNavigationMapComponent> ent, ref CP14DemiplaneMapEjectMessage args)
|
||||
{
|
||||
var station = _station.GetOwningStation(ent, Transform(ent));
|
||||
|
||||
if (!TryComp<CP14StationDemiplaneMapComponent>(station, out var stationMap))
|
||||
return;
|
||||
|
||||
if (!stationMap.Nodes.TryGetValue(args.Position, out var node))
|
||||
return;
|
||||
|
||||
if (!node.InFrontierZone)
|
||||
return;
|
||||
|
||||
//Eject!
|
||||
var key = SpawnAttachedTo(ent.Comp.KeyProto, Transform(ent).Coordinates);
|
||||
_audio.PlayPvs(ent.Comp.EjectSound, Transform(key).Coordinates);
|
||||
|
||||
if (TryComp<CP14DemiplaneDataComponent>(key, out var demiData))
|
||||
{
|
||||
demiData.Location = node.LocationConfig;
|
||||
demiData.SelectedModifiers.AddRange(node.Modifiers);
|
||||
}
|
||||
|
||||
EnsureComp<CP14DemiplaneMapNodeBlockerComponent>(key, out var blockerComp);
|
||||
blockerComp.Position = args.Position;
|
||||
blockerComp.Station = station;
|
||||
}
|
||||
|
||||
private void DemiplaneRevokeAttempt(Entity<CP14DemiplaneNavigationMapComponent> ent, ref CP14DemiplaneMapRevokeMessage args)
|
||||
{
|
||||
var station = _station.GetOwningStation(ent, Transform(ent));
|
||||
|
||||
var query = EntityQueryEnumerator<CP14DemiplaneMapNodeBlockerComponent>();
|
||||
while (query.MoveNext(out var uid, out var blocker))
|
||||
{
|
||||
if (blocker.Station != station)
|
||||
continue;
|
||||
|
||||
if (blocker.Position != args.Position)
|
||||
continue;
|
||||
|
||||
if (!TryComp<CP14StationDemiplaneMapComponent>(station, out var demiStation))
|
||||
continue;
|
||||
|
||||
if (!demiStation.Nodes.TryGetValue(args.Position, out var node))
|
||||
continue;
|
||||
|
||||
SpawnAttachedTo("CP14ImpactEffectMagicSplitting", Transform(ent).Coordinates);
|
||||
|
||||
//If it's a demiplane, initiate closure. If not, just delete it.
|
||||
if (TryComp<CP14DemiplaneComponent>(uid, out var demiplane))
|
||||
{
|
||||
_demiplane.StartDestructDemiplane((uid, demiplane));
|
||||
_popup.PopupEntity(Loc.GetString("cp14-demiplane-revoke-map"), ent);
|
||||
}
|
||||
else
|
||||
{
|
||||
SpawnAttachedTo("CP14ImpactEffectMagicSplitting", Transform(uid).Coordinates);
|
||||
_popup.PopupEntity(Loc.GetString("cp14-demiplane-revoke-item"), ent);
|
||||
_popup.PopupEntity(Loc.GetString("cp14-demiplane-revoke-item"), uid);
|
||||
QueueDel(uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnBeforeActivatableUiOpen(Entity<CP14DemiplaneNavigationMapComponent> ent,
|
||||
ref BeforeActivatableUIOpenEvent args)
|
||||
{
|
||||
var station = _station.GetOwningStation(ent, Transform(ent));
|
||||
|
||||
if (!TryComp<CP14StationDemiplaneMapComponent>(station, out var stationMap))
|
||||
return;
|
||||
|
||||
UpdateNodesStatus((station.Value, stationMap));
|
||||
|
||||
_userInterface.SetUiState(ent.Owner,
|
||||
CP14DemiplaneMapUiKey.Key,
|
||||
new CP14DemiplaneMapUiState(stationMap.Nodes, stationMap.Edges));
|
||||
}
|
||||
|
||||
private void OnMapInit(Entity<CP14StationDemiplaneMapComponent> ent, ref MapInitEvent args)
|
||||
{
|
||||
GenerateDemiplaneMap(ent);
|
||||
}
|
||||
|
||||
private void GenerateDemiplaneMap(Entity<CP14StationDemiplaneMapComponent> ent)
|
||||
{
|
||||
ent.Comp.Nodes.Clear();
|
||||
ent.Comp.Edges.Clear();
|
||||
|
||||
var allSpecials = _proto.EnumeratePrototypes<CP14SpecialDemiplanePrototype>().ToList();
|
||||
_random.Shuffle(allSpecials);
|
||||
|
||||
var grid = new Dictionary<Vector2i, CP14DemiplaneMapNode>();
|
||||
|
||||
//Spawn start room at 0 0
|
||||
var startPos = new Vector2i(0, 0);
|
||||
var startNode = new CP14DemiplaneMapNode(0, startPos, true);
|
||||
grid[startPos] = startNode;
|
||||
|
||||
//Spawn special rooms
|
||||
var specialCount = _random.Next(ent.Comp.Specials.Min, ent.Comp.Specials.Max + 1);
|
||||
var placedSpecials = 0;
|
||||
var specialPositions = new List<Vector2i>();
|
||||
|
||||
foreach (var special in allSpecials)
|
||||
{
|
||||
if (placedSpecials >= specialCount)
|
||||
break;
|
||||
|
||||
var specialLevel = special.Levels.Next(_random);
|
||||
|
||||
var possiblePositions = new List<Vector2i>();
|
||||
for (var x = -specialLevel; x <= specialLevel; x++)
|
||||
{
|
||||
var y = specialLevel - Math.Abs(x);
|
||||
if (y != 0)
|
||||
possiblePositions.Add(new Vector2i(x, y));
|
||||
possiblePositions.Add(new Vector2i(x, -y));
|
||||
}
|
||||
|
||||
_random.Shuffle(possiblePositions);
|
||||
|
||||
var specialPos = new Vector2i(0, 0);
|
||||
foreach (var pos in possiblePositions)
|
||||
{
|
||||
if (!grid.ContainsKey(pos))
|
||||
{
|
||||
specialPos = pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (grid.ContainsKey(specialPos))
|
||||
continue;
|
||||
|
||||
var specialNode = new CP14DemiplaneMapNode(
|
||||
specialLevel,
|
||||
new Vector2(specialPos.X, specialPos.Y),
|
||||
false,
|
||||
locationConfig: special.Location,
|
||||
modifiers: special.Modifiers
|
||||
);
|
||||
grid[specialPos] = specialNode;
|
||||
specialPositions.Add(specialPos);
|
||||
placedSpecials++;
|
||||
}
|
||||
|
||||
// Build meandering paths to each special room and add edges
|
||||
foreach (var specialPos in specialPositions)
|
||||
{
|
||||
var current = startPos;
|
||||
|
||||
while (current != specialPos)
|
||||
{
|
||||
var delta = specialPos - current;
|
||||
var options = new List<Vector2i>();
|
||||
|
||||
if (delta.X != 0)
|
||||
options.Add(new Vector2i(Math.Sign(delta.X), 0));
|
||||
if (delta.Y != 0)
|
||||
options.Add(new Vector2i(0, Math.Sign(delta.Y)));
|
||||
|
||||
// Add the possibility of a "mistaken" step to the side
|
||||
if (_random.Prob(0.3f)) // 30% chance to take a side step
|
||||
{
|
||||
if (delta.X != 0 && delta.Y != 0)
|
||||
{
|
||||
options.Add(new Vector2i(0, Math.Sign(delta.Y)) * -1);
|
||||
options.Add(new Vector2i(Math.Sign(delta.X), 0) * -1);
|
||||
}
|
||||
}
|
||||
|
||||
_random.Shuffle(options);
|
||||
var step = options[0];
|
||||
var next = current + step;
|
||||
|
||||
if (!grid.TryGetValue(next, out var nextNode))
|
||||
{
|
||||
nextNode = new CP14DemiplaneMapNode(Math.Abs(next.X) + Math.Abs(next.Y),
|
||||
new Vector2(next.X, next.Y),
|
||||
false);
|
||||
grid[next] = nextNode;
|
||||
}
|
||||
|
||||
ent.Comp.Edges.Add((current, next));
|
||||
|
||||
current = next;
|
||||
}
|
||||
}
|
||||
|
||||
//Fill nodes with random data
|
||||
foreach (var node in grid.Values)
|
||||
{
|
||||
GenerateNodeData(node);
|
||||
}
|
||||
|
||||
// Random visual offset
|
||||
foreach (var node in grid.Values)
|
||||
{
|
||||
var x = node.UiPosition.X + _random.NextFloat(-0.2f, 0.2f);
|
||||
var y = node.UiPosition.Y + _random.NextFloat(-0.2f, 0.2f);
|
||||
node.UiPosition = new Vector2(x, y);
|
||||
}
|
||||
|
||||
//Add all rooms into component
|
||||
ent.Comp.Nodes = grid;
|
||||
}
|
||||
|
||||
private void GenerateNodeData(CP14DemiplaneMapNode node, bool clearOldModifiers = false)
|
||||
{
|
||||
if (node.Level == 0)
|
||||
return;
|
||||
|
||||
var location = _demiplane.GenerateDemiplaneLocation(node.Level);
|
||||
node.LocationConfig ??= location;
|
||||
|
||||
var limits = new Dictionary<ProtoId<CP14DemiplaneModifierCategoryPrototype>, float>
|
||||
{
|
||||
{ "Danger", (node.Level + node.AdditionalLevel) * 0.2f },
|
||||
{ "GhostRoleDanger", node.Level * 0.2f },
|
||||
{ "Reward", Math.Max(node.Level * 0.2f, 0.5f) },
|
||||
{ "Fun", 1f },
|
||||
{ "Weather", 1f },
|
||||
{ "MapLight", 1f },
|
||||
};
|
||||
var mods = _demiplane.GenerateDemiplaneModifiers(node.Level, location, limits);
|
||||
|
||||
if (clearOldModifiers)
|
||||
node.Modifiers.Clear();
|
||||
foreach (var mod in mods)
|
||||
{
|
||||
node.Modifiers.Add(mod);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateNodesStatus(Entity<CP14StationDemiplaneMapComponent> ent)
|
||||
{
|
||||
foreach (var node in ent.Comp.Nodes)
|
||||
{
|
||||
node.Value.InFrontierZone = NodeInFronrierZone(ent.Comp.Nodes, ent.Comp.Edges, node.Key);
|
||||
node.Value.InUsing = false;
|
||||
}
|
||||
|
||||
var query = EntityQueryEnumerator<CP14DemiplaneMapNodeBlockerComponent>();
|
||||
while (query.MoveNext(out var uid, out var blocker))
|
||||
{
|
||||
if (!TryComp<CP14StationDemiplaneMapComponent>(blocker.Station, out var stationMap))
|
||||
continue;
|
||||
|
||||
if (!stationMap.Nodes.TryGetValue(blocker.Position, out var node))
|
||||
continue;
|
||||
|
||||
node.InUsing = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,9 @@ public sealed class CP14WeatherControllerSystem : EntitySystem
|
||||
|
||||
var weatherData = PickWeatherDataByWeight(uid, weather.Entries);
|
||||
|
||||
if (weatherData is null)
|
||||
continue;
|
||||
|
||||
if (!_proto.TryIndex(weatherData.Visuals, out var weatherVisualsIndexed))
|
||||
{
|
||||
var weatherDuration = TimeSpan.FromSeconds(weatherData.Duration.Next(_random));
|
||||
@@ -45,7 +48,7 @@ public sealed class CP14WeatherControllerSystem : EntitySystem
|
||||
}
|
||||
}
|
||||
|
||||
private CP14WeatherData PickWeatherDataByWeight(EntityUid map, HashSet<CP14WeatherData> entries)
|
||||
private CP14WeatherData? PickWeatherDataByWeight(EntityUid map, HashSet<CP14WeatherData> entries)
|
||||
{
|
||||
var filteredEntries = new HashSet<CP14WeatherData>(entries);
|
||||
|
||||
@@ -60,6 +63,9 @@ public sealed class CP14WeatherControllerSystem : EntitySystem
|
||||
}
|
||||
}
|
||||
|
||||
if (filteredEntries.Count == 0)
|
||||
return null;
|
||||
|
||||
var totalWeight = filteredEntries.Sum(entry => entry.Weight);
|
||||
var randomWeight = _random.NextFloat() * totalWeight;
|
||||
var currentWeight = 0f;
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Content.Shared._CP14.Demiplane.Components;
|
||||
public sealed partial class CP14DemiplaneTimedDestructionComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public TimeSpan TimeToDestruction = TimeSpan.FromSeconds(150f);
|
||||
public TimeSpan TimeToDestruction = TimeSpan.FromSeconds(130f);
|
||||
|
||||
[DataField, AutoPausedField]
|
||||
public TimeSpan EndTime = TimeSpan.Zero;
|
||||
|
||||
@@ -2,6 +2,7 @@ using Content.Shared.Destructible.Thresholds;
|
||||
using Content.Shared.Procedural;
|
||||
using Content.Shared.Tag;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared._CP14.Demiplane.Prototypes;
|
||||
|
||||
@@ -39,4 +40,7 @@ public sealed partial class CP14DemiplaneLocationPrototype : IPrototype
|
||||
|
||||
[DataField]
|
||||
public float ExamineProb = 0.75f;
|
||||
|
||||
[DataField]
|
||||
public SpriteSpecifier? Icon = null;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
using Content.Shared.Destructible.Thresholds;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Demiplane.Prototypes;
|
||||
|
||||
/// <summary>
|
||||
/// A prototype “Special Demiplane” that can appear on the demiplane map as the final room of a chain of demiplanes.
|
||||
/// It is supposed to be used as a special demiplane with special modifiers, and mining resources and
|
||||
/// equipment from here is the main task of adventurers
|
||||
/// </summary>
|
||||
[Prototype("cp14SpecialDemiplane")]
|
||||
public sealed partial class CP14SpecialDemiplanePrototype : IPrototype
|
||||
{
|
||||
[IdDataField] public string ID { get; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The difficulty levels at which this location can be generated.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public MinMax Levels = new(1, 10);
|
||||
|
||||
/// <summary>
|
||||
/// The location config that will be used to generate the demiplane. May be null, and if so, the location will be generated using the default way.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public ProtoId<CP14DemiplaneLocationPrototype>? Location;
|
||||
|
||||
/// <summary>
|
||||
/// Modifiers that will be automatically added to the demiplane when it is generated.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public List<ProtoId<CP14DemiplaneModifierPrototype>>? Modifiers = new();
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
using System.Numerics;
|
||||
using Content.Shared._CP14.Demiplane.Prototypes;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._CP14.DemiplaneTraveling;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum CP14DemiplaneMapUiKey
|
||||
{
|
||||
Key,
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CP14DemiplaneMapUiState(Dictionary<Vector2i, CP14DemiplaneMapNode> nodes, HashSet<(Vector2i, Vector2i)>? edges = null) : BoundUserInterfaceState
|
||||
{
|
||||
public Dictionary<Vector2i, CP14DemiplaneMapNode> Nodes = nodes;
|
||||
public HashSet<(Vector2i, Vector2i)> Edges = edges ?? new();
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CP14DemiplaneMapNode(int level, Vector2 uiPosition, bool start, ProtoId<CP14DemiplaneLocationPrototype>? locationConfig = null, List<ProtoId<CP14DemiplaneModifierPrototype>>? modifiers = null)
|
||||
{
|
||||
public int Level = level;
|
||||
public int AdditionalLevel = 0;
|
||||
public Vector2 UiPosition = uiPosition;
|
||||
public bool Start = start;
|
||||
|
||||
public bool InFrontierZone = false;
|
||||
public bool InUsing = false;
|
||||
public bool Scanned = start;
|
||||
|
||||
public ProtoId<CP14DemiplaneLocationPrototype>? LocationConfig = locationConfig;
|
||||
public List<ProtoId<CP14DemiplaneModifierPrototype>> Modifiers = modifiers ?? new();
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.DemiplaneTraveling;
|
||||
|
||||
/// <summary>
|
||||
/// Component for opening demiplane map UI and interacting with StationDemiplaneMapComponent
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class CP14DemiplaneNavigationMapComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Extracting coordinates from the demiplane node will create this entity and synchronize its modifiers, location and other parameters.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntProtoId KeyProto = "CP14BaseDemiplaneKey";
|
||||
|
||||
[DataField]
|
||||
public SoundSpecifier EjectSound = new SoundPathSpecifier("/Audio/Magic/ethereal_exit.ogg");
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._CP14.DemiplaneTraveling;
|
||||
|
||||
public abstract partial class CP14SharedStationDemiplaneMapSystem : EntitySystem
|
||||
{
|
||||
public static bool NodeInFronrierZone(Dictionary<Vector2i,CP14DemiplaneMapNode> nodes, HashSet<(Vector2i, Vector2i)> edges, Vector2i key)
|
||||
{
|
||||
if (!nodes.TryGetValue(key, out var node))
|
||||
return false;
|
||||
|
||||
if (node.Scanned || node.Start)
|
||||
return false;
|
||||
|
||||
//return false if no finished or start nodes near
|
||||
var near = new List<Vector2i>();
|
||||
foreach (var edge in edges)
|
||||
{
|
||||
var node1 = nodes[edge.Item1];
|
||||
var node2 = nodes[edge.Item2];
|
||||
|
||||
if (node1 != node && node2 != node)
|
||||
continue;
|
||||
|
||||
if (node1.Scanned || node1.Start || node2.Scanned || node2.Start)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CP14DemiplaneMapEjectMessage(Vector2i position) : BoundUserInterfaceMessage
|
||||
{
|
||||
public readonly Vector2i Position = position;
|
||||
}
|
||||
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CP14DemiplaneMapRevokeMessage(Vector2i position) : BoundUserInterfaceMessage
|
||||
{
|
||||
public readonly Vector2i Position = position;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
using Content.Shared.Destructible.Thresholds;
|
||||
|
||||
namespace Content.Shared._CP14.DemiplaneTraveling;
|
||||
|
||||
/// <summary>
|
||||
/// A station component that stores information about the current map of demiplanes, their research status and relationships.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class CP14StationDemiplaneMapComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public Dictionary<Vector2i, CP14DemiplaneMapNode> Nodes = new();
|
||||
|
||||
[DataField]
|
||||
public HashSet<(Vector2i, Vector2i)> Edges = new();
|
||||
|
||||
/// <summary>
|
||||
/// Count of special rooms that can be generated in the demiplane map.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public MinMax Specials = new(30, 30);
|
||||
}
|
||||
@@ -16,19 +16,19 @@ public sealed partial class CP14SkillTreePrototype : IPrototype
|
||||
public LocId Name;
|
||||
|
||||
[DataField]
|
||||
public SpriteSpecifier FrameIcon = new SpriteSpecifier.Rsi(new ResPath("/Textures/_CP14/Interface/Skills/default.rsi"), "frame");
|
||||
public SpriteSpecifier? FrameIcon;
|
||||
|
||||
[DataField]
|
||||
public SpriteSpecifier HoveredIcon = new SpriteSpecifier.Rsi(new ResPath("/Textures/_CP14/Interface/Skills/default.rsi"), "hovered");
|
||||
public SpriteSpecifier? HoveredIcon;
|
||||
|
||||
[DataField]
|
||||
public SpriteSpecifier SelectedIcon = new SpriteSpecifier.Rsi(new ResPath("/Textures/_CP14/Interface/Skills/default.rsi"), "selected");
|
||||
public SpriteSpecifier? SelectedIcon;
|
||||
|
||||
[DataField]
|
||||
public SpriteSpecifier LearnedIcon = new SpriteSpecifier.Rsi(new ResPath("/Textures/_CP14/Interface/Skills/default.rsi"), "learned");
|
||||
public SpriteSpecifier? LearnedIcon;
|
||||
|
||||
[DataField]
|
||||
public SpriteSpecifier AvailableIcon = new SpriteSpecifier.Rsi(new ResPath("/Textures/_CP14/Interface/Skills/default.rsi"), "available");
|
||||
public SpriteSpecifier? AvailableIcon;
|
||||
|
||||
[DataField]
|
||||
public string Parallax = "AspidParallax";
|
||||
|
||||
@@ -11,4 +11,7 @@ cp14-round-end = The demiplane link crystal was completely discharged. The conne
|
||||
|
||||
cp14-demiplane-echoes = Echoes of voices
|
||||
|
||||
cp14-demiplane-countdown = The Demiplane is beginning to collapse! You have {$duration} minutes to escape!
|
||||
cp14-demiplane-countdown = The Demiplane is beginning to collapse! You have {$duration} minutes to escape!
|
||||
|
||||
cp14-demiplane-revoke-item = The bound key has been destroyed!
|
||||
cp14-demiplane-revoke-map = The process of destroying the bound demiplane has been initiated!
|
||||
@@ -1,4 +1,4 @@
|
||||
cp14-demiplane-location-cave = Dark caves
|
||||
cp14-demiplane-location-cave = Caves
|
||||
cp14-demiplane-location-cave-grass = Overgrown caves
|
||||
cp14-demiplane-location-cave-magma = Flaming caves
|
||||
cp14-demiplane-location-grassland-island = Green Island
|
||||
|
||||
15
Resources/Locale/en-US/_CP14/demiplane/map_ui.ftl
Normal file
@@ -0,0 +1,15 @@
|
||||
cp14-demiplane-map-title = Demiplane navigation map
|
||||
|
||||
cp14-demiplane-map-eject = Extract coordinates
|
||||
cp14-demiplane-map-eject-tooltip = Extract the coordinates of the demiplane into physical form, allowing you to open a passageway into it at any time.
|
||||
|
||||
cp14-demiplane-map-revoke = Cut the link
|
||||
cp14-demiplane-map-revoke-tooltip = You cut the connection to the selected demiplane. This either instantly removes the demiplane key or starts a 2-minute process to destroy the demiplane.
|
||||
|
||||
cp14-demiplane-map-add-level = [color=red]Difficulty +{$count}[/color]
|
||||
cp14-demiplane-map-add-level-tooltip = This demiplane has been opened several times already, and this point in space is becoming more difficult and unstable.
|
||||
|
||||
cp14-demiplane-map-status-blocked = [color=red]This demiplane cannot be opened: You must explore any nearby demiplane to unlock the coordinates.[/color]
|
||||
cp14-demiplane-map-status-allowed = [color=green]The demiplane is available for exploration.[/color]
|
||||
cp14-demiplane-map-status-used = [color=yellow]The coordinates of this demiplane are already in use. It is not possible to create a copy.[/color]
|
||||
cp14-demiplane-map-status-scanned = [color=purple]The demiplane core has been destroyed and successfully scanned. Demiplane reopening is impossible, coordinates of neighboring demiplanes are available for research.[/color]
|
||||
@@ -10,11 +10,10 @@ cp14-modifier-wild-sage = wild Sage
|
||||
cp14-modifier-lumisroom = lumishrooms
|
||||
cp14-modifier-explosive = explosive mines
|
||||
cp14-modifier-ruins = ancient ruins
|
||||
cp14-modifier-xeno = xenomorphs
|
||||
cp14-modifier-zombie = swarms of undead
|
||||
cp14-modifier-zombie = zombies
|
||||
cp14-modifier-slime = slimes
|
||||
cp14-modifier-skeleton = sentient skeletons
|
||||
cp14-modifier-dyno = prehistoric fauna
|
||||
cp14-modifier-dyno = dynos
|
||||
cp14-modifier-mole = predatory moles
|
||||
cp14-modifier-watcher = watchers
|
||||
cp14-modifier-rabbits = rabbits
|
||||
@@ -23,7 +22,6 @@ cp14-modifier-invisible-whistler = invisible whistlers
|
||||
cp14-modifier-sheeps = sheeps
|
||||
cp14-modifier-chasm = bottomless chasms
|
||||
cp14-modifier-air-lily = air lilies
|
||||
cp14-modifier-time-limit-10 = temporary disintegration (10 minutes)
|
||||
cp14-modifier-shadow-kudzu = spreading astral haze
|
||||
cp14-modifier-night = darkness
|
||||
|
||||
|
||||
@@ -11,4 +11,7 @@ cp14-round-end = Кристалл связи с демипланами окон
|
||||
|
||||
cp14-demiplane-echoes = Эхо голосов
|
||||
|
||||
cp14-demiplane-countdown = Демиплан начинает коллапсировать! У вас {$duration} минут, чтобы покинуть его!
|
||||
cp14-demiplane-countdown = Демиплан начинает коллапсировать! У вас {$duration} минут, чтобы покинуть его!
|
||||
|
||||
cp14-demiplane-revoke-item = Связанный ключ уничтожен!
|
||||
cp14-demiplane-revoke-map = Запущен процесс уничтожения связанного демиплана!
|
||||
@@ -1,6 +1,6 @@
|
||||
cp14-demiplane-location-cave = Темные пещеры
|
||||
cp14-demiplane-location-cave = Пещеры
|
||||
cp14-demiplane-location-cave-grass = Заросшие пещеры
|
||||
cp14-demiplane-location-cave-magma = Раскаленные пещеры
|
||||
cp14-demiplane-location-cave-magma = Раскаленные недра
|
||||
cp14-demiplane-location-grassland-island = Зеленый остров
|
||||
cp14-demiplane-location-ice-cave = Ледяные пещеры
|
||||
cp14-demiplane-location-snow-island = Заснеженный остров
|
||||
|
||||
15
Resources/Locale/ru-RU/_CP14/demiplane/map_ui.ftl
Normal file
@@ -0,0 +1,15 @@
|
||||
cp14-demiplane-map-title = Карта навигации демипланов
|
||||
|
||||
cp14-demiplane-map-eject = Извлечь координаты
|
||||
cp14-demiplane-map-eject-tooltip = Извлечь координаты демиплана в физическую форму, что позволит открыть в него проход в любое время.
|
||||
|
||||
cp14-demiplane-map-revoke = Оборвать связь
|
||||
cp14-demiplane-map-revoke-tooltip = Вы обрываете связь с выбранным демипланом. Это либо мгновенно удаляет ключ демиплана, либо запускает 2-минутный процесс уничтожения демиплана.
|
||||
|
||||
cp14-demiplane-map-add-level = [color=red]Сложность +{$count}[/color]
|
||||
cp14-demiplane-map-add-level-tooltip = Этот демиплан открывался уже несколько раз, и данная точка пространства становится сложнее и нестабильнее.
|
||||
|
||||
cp14-demiplane-map-status-blocked = [color=red]Открыть этот демиплан невозможно: Необходимо исследовать любой ближайший демиплан, для разблокировки координат.[/color]
|
||||
cp14-demiplane-map-status-allowed = [color=green]Демиплан доступен для изучения.[/color]
|
||||
cp14-demiplane-map-status-used = [color=yellow]Координаты этого демиплана уже используются. Невозможно создать копию.[/color]
|
||||
cp14-demiplane-map-status-scanned = [color=purple]Ядро демиплана уничтожено и успешно просканировано. Повторное открытие демиплана невозможно, координаты соседних демипланов доступны для исследования.[/color]
|
||||
@@ -1,34 +1,32 @@
|
||||
cp14-modifier-gold-ore = золотой руды
|
||||
cp14-modifier-iron-ore = железной руды
|
||||
cp14-modifier-copper-ore = медной руды
|
||||
cp14-modifier-mithril-ore = мифриловой руды
|
||||
cp14-modifier-dayflin = днецветов
|
||||
cp14-modifier-fly-agaric = мухоморов
|
||||
cp14-modifier-blue-amanita = лазурной аманиты
|
||||
cp14-modifier-blood-flower = кровоцветов
|
||||
cp14-modifier-wild-sage = дикого Шалфея
|
||||
cp14-modifier-lumisroom = люмигрибов
|
||||
cp14-modifier-explosive = взрывных мин
|
||||
cp14-modifier-ruins = древних руин
|
||||
cp14-modifier-xeno = ксеноморфов
|
||||
cp14-modifier-zombie = толп нежити
|
||||
cp14-modifier-slime = слаймов
|
||||
cp14-modifier-gold-ore = золотая руда
|
||||
cp14-modifier-iron-ore = железная руда
|
||||
cp14-modifier-copper-ore = медная руда
|
||||
cp14-modifier-mithril-ore = мифриловая руда
|
||||
cp14-modifier-dayflin = днецветы
|
||||
cp14-modifier-fly-agaric = мухоморы
|
||||
cp14-modifier-blue-amanita = лазурная аманита
|
||||
cp14-modifier-blood-flower = кровоцветы
|
||||
cp14-modifier-wild-sage = дикий шалфей
|
||||
cp14-modifier-lumisroom = люмигрибы
|
||||
cp14-modifier-explosive = взрывные мины
|
||||
cp14-modifier-ruins = древние руины
|
||||
cp14-modifier-zombie = зомби
|
||||
cp14-modifier-slime = слаймы
|
||||
cp14-modifier-skeleton = разумные скелеты
|
||||
cp14-modifier-dyno = доисторической фауны
|
||||
cp14-modifier-mole = хищных кротов
|
||||
cp14-modifier-watcher = наблюдателей
|
||||
cp14-modifier-rabbits = кроликов
|
||||
cp14-modifier-boars = диких кабанов
|
||||
cp14-modifier-sheeps = овец
|
||||
cp14-modifier-invisible-whistler = невидимых свистунов
|
||||
cp14-modifier-chasm = бездонных пропастей
|
||||
cp14-modifier-air-lily = воздушных лилий
|
||||
cp14-modifier-time-limit-10 = временного распада (10 минут)
|
||||
cp14-modifier-shadow-kudzu = распространяющгося астрального мрака
|
||||
cp14-modifier-night = темноты
|
||||
cp14-modifier-dyno = динозавры
|
||||
cp14-modifier-mole = хищные кроты
|
||||
cp14-modifier-watcher = наблюдатели
|
||||
cp14-modifier-rabbits = кролики
|
||||
cp14-modifier-boars = дикие кабаны
|
||||
cp14-modifier-sheeps = овцы
|
||||
cp14-modifier-invisible-whistler = невидимые свистуны
|
||||
cp14-modifier-chasm = бездонные пропасти
|
||||
cp14-modifier-air-lily = воздушные лилии
|
||||
cp14-modifier-shadow-kudzu = поглощающий астральный мрак
|
||||
cp14-modifier-night = темнота
|
||||
|
||||
cp14-modifier-storm = грозы
|
||||
cp14-modifier-storm = гроза
|
||||
cp14-modifier-fire-storm = огненный шторм
|
||||
cp14-modifier-snow-storm = снежный шторм
|
||||
cp14-modifier-mana-mist = магического тумана
|
||||
cp14-modifier-anti-mana-mist = антимагического тумана
|
||||
cp14-modifier-mana-mist = магический туман
|
||||
cp14-modifier-anti-mana-mist = антимагический туман
|
||||
|
||||
648
Resources/Maps/_CP14/Dungeon/demiplane_core.yml
Normal file
@@ -0,0 +1,648 @@
|
||||
meta:
|
||||
format: 7
|
||||
category: Map
|
||||
engineVersion: 255.0.0
|
||||
forkId: ""
|
||||
forkVersion: ""
|
||||
time: 05/03/2025 21:59:43
|
||||
entityCount: 104
|
||||
maps:
|
||||
- 1
|
||||
grids:
|
||||
- 1
|
||||
orphans: []
|
||||
nullspace: []
|
||||
tilemap:
|
||||
0: Space
|
||||
20: CP14FloorBase
|
||||
9: CP14FloorFoundation
|
||||
13: CP14FloorGrass
|
||||
14: CP14FloorGrassLight
|
||||
15: CP14FloorGrassTall
|
||||
10: CP14FloorOakWoodPlanksBig
|
||||
12: CP14FloorOakWoodPlanksBroken
|
||||
11: CP14FloorOakWoodPlanksCruciform
|
||||
17: CP14FloorStonebricks
|
||||
16: CP14FloorStonebricksSmallCarved1
|
||||
19: CP14FloorStonebricksSmallCarved2
|
||||
18: CP14FloorStonebricksSquareCarved
|
||||
2: FloorAsteroidSand
|
||||
6: FloorAsteroidSandUnvariantized
|
||||
5: FloorAsteroidTile
|
||||
8: FloorBrokenWood
|
||||
82: FloorShuttleOrange
|
||||
1: FloorShuttlePurple
|
||||
89: FloorSteel
|
||||
7: FloorWood
|
||||
3: Plating
|
||||
4: PlatingAsteroid
|
||||
entities:
|
||||
- proto: ""
|
||||
entities:
|
||||
- uid: 1
|
||||
components:
|
||||
- type: MetaData
|
||||
- type: Transform
|
||||
- type: Map
|
||||
mapPaused: True
|
||||
- type: PhysicsMap
|
||||
- type: GridTree
|
||||
- type: MovedGrids
|
||||
- type: Broadphase
|
||||
- type: OccluderTree
|
||||
- type: MapGrid
|
||||
chunks:
|
||||
-1,-1:
|
||||
ind: -1,-1
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAA
|
||||
version: 6
|
||||
0,0:
|
||||
ind: 0,0
|
||||
tiles: FAAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAA
|
||||
version: 6
|
||||
0,1:
|
||||
ind: 0,1
|
||||
tiles: AQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAA
|
||||
version: 6
|
||||
0,-1:
|
||||
ind: 0,-1
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAA
|
||||
version: 6
|
||||
-1,0:
|
||||
ind: -1,0
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAA
|
||||
version: 6
|
||||
-1,1:
|
||||
ind: -1,1
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAA
|
||||
version: 6
|
||||
1,-1:
|
||||
ind: 1,-1
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAA
|
||||
version: 6
|
||||
1,0:
|
||||
ind: 1,0
|
||||
tiles: AQAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAFAAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAFAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAA
|
||||
version: 6
|
||||
1,1:
|
||||
ind: 1,1
|
||||
tiles: AQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAA
|
||||
version: 6
|
||||
-1,2:
|
||||
ind: -1,2
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
version: 6
|
||||
0,2:
|
||||
ind: 0,2
|
||||
tiles: AQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
version: 6
|
||||
1,2:
|
||||
ind: 1,2
|
||||
tiles: AQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
version: 6
|
||||
2,-1:
|
||||
ind: 2,-1
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
version: 6
|
||||
2,0:
|
||||
ind: 2,0
|
||||
tiles: AQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
version: 6
|
||||
2,1:
|
||||
ind: 2,1
|
||||
tiles: AQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
version: 6
|
||||
2,2:
|
||||
ind: 2,2
|
||||
tiles: AQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
version: 6
|
||||
- type: Gravity
|
||||
gravityShakeSound: !type:SoundPathSpecifier
|
||||
path: /Audio/Effects/alert.ogg
|
||||
- type: DecalGrid
|
||||
chunkCollection:
|
||||
version: 2
|
||||
nodes: []
|
||||
- type: SpreaderGrid
|
||||
- type: GridPathfinding
|
||||
- type: RadiationGridResistance
|
||||
- proto: CP14DemiplaneCore
|
||||
entities:
|
||||
- uid: 14
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 11.5,2.5
|
||||
parent: 1
|
||||
- uid: 24
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 19.5,3.5
|
||||
parent: 1
|
||||
- uid: 25
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 27.5,3.5
|
||||
parent: 1
|
||||
- uid: 71
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 3.5,3.5
|
||||
parent: 1
|
||||
- proto: CP14WallDimensit
|
||||
entities:
|
||||
- uid: 2
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 20.5,0.5
|
||||
parent: 1
|
||||
- uid: 3
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 10.5,1.5
|
||||
parent: 1
|
||||
- uid: 4
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 14.5,0.5
|
||||
parent: 1
|
||||
- uid: 5
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 4.5,1.5
|
||||
parent: 1
|
||||
- uid: 6
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 4.5,5.5
|
||||
parent: 1
|
||||
- uid: 7
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5,0.5
|
||||
parent: 1
|
||||
- uid: 8
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 3.5,4.5
|
||||
parent: 1
|
||||
- uid: 9
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 4.5,4.5
|
||||
parent: 1
|
||||
- uid: 10
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 4.5,2.5
|
||||
parent: 1
|
||||
- uid: 11
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 28.5,1.5
|
||||
parent: 1
|
||||
- uid: 12
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 20.5,5.5
|
||||
parent: 1
|
||||
- uid: 13
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 20.5,4.5
|
||||
parent: 1
|
||||
- uid: 15
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 20.5,1.5
|
||||
parent: 1
|
||||
- uid: 16
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 20.5,2.5
|
||||
parent: 1
|
||||
- uid: 17
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 19.5,4.5
|
||||
parent: 1
|
||||
- uid: 18
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 19.5,5.5
|
||||
parent: 1
|
||||
- uid: 19
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 20.5,3.5
|
||||
parent: 1
|
||||
- uid: 20
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 28.5,2.5
|
||||
parent: 1
|
||||
- uid: 21
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 29.5,2.5
|
||||
parent: 1
|
||||
- uid: 22
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 22.5,1.5
|
||||
parent: 1
|
||||
- uid: 23
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 24.5,5.5
|
||||
parent: 1
|
||||
- uid: 26
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 22.5,2.5
|
||||
parent: 1
|
||||
- uid: 27
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 27.5,0.5
|
||||
parent: 1
|
||||
- uid: 28
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 29.5,5.5
|
||||
parent: 1
|
||||
- uid: 29
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 27.5,1.5
|
||||
parent: 1
|
||||
- uid: 30
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 21.5,1.5
|
||||
parent: 1
|
||||
- uid: 31
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 21.5,0.5
|
||||
parent: 1
|
||||
- uid: 32
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 21.5,2.5
|
||||
parent: 1
|
||||
- uid: 33
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 21.5,3.5
|
||||
parent: 1
|
||||
- uid: 34
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 21.5,4.5
|
||||
parent: 1
|
||||
- uid: 35
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 25.5,4.5
|
||||
parent: 1
|
||||
- uid: 36
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 18.5,0.5
|
||||
parent: 1
|
||||
- uid: 37
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 18.5,1.5
|
||||
parent: 1
|
||||
- uid: 38
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 18.5,2.5
|
||||
parent: 1
|
||||
- uid: 39
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 16.5,4.5
|
||||
parent: 1
|
||||
- uid: 40
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 25.5,3.5
|
||||
parent: 1
|
||||
- uid: 41
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 9.5,5.5
|
||||
parent: 1
|
||||
- uid: 42
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 24.5,4.5
|
||||
parent: 1
|
||||
- uid: 43
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 27.5,5.5
|
||||
parent: 1
|
||||
- uid: 44
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 17.5,2.5
|
||||
parent: 1
|
||||
- uid: 45
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 13.5,6.5
|
||||
parent: 1
|
||||
- uid: 46
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 17.5,5.5
|
||||
parent: 1
|
||||
- uid: 47
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 17.5,1.5
|
||||
parent: 1
|
||||
- uid: 48
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 17.5,3.5
|
||||
parent: 1
|
||||
- uid: 49
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 13.5,5.5
|
||||
parent: 1
|
||||
- uid: 50
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 9.5,4.5
|
||||
parent: 1
|
||||
- uid: 51
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 19.5,2.5
|
||||
parent: 1
|
||||
- uid: 52
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 18.5,5.5
|
||||
parent: 1
|
||||
- uid: 53
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 18.5,3.5
|
||||
parent: 1
|
||||
- uid: 54
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 19.5,0.5
|
||||
parent: 1
|
||||
- uid: 55
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 19.5,1.5
|
||||
parent: 1
|
||||
- uid: 56
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 18.5,4.5
|
||||
parent: 1
|
||||
- uid: 57
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 8.5,5.5
|
||||
parent: 1
|
||||
- uid: 58
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 8.5,6.5
|
||||
parent: 1
|
||||
- uid: 59
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 16.5,2.5
|
||||
parent: 1
|
||||
- uid: 60
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 16.5,3.5
|
||||
parent: 1
|
||||
- uid: 61
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 14.5,5.5
|
||||
parent: 1
|
||||
- uid: 62
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 12.5,3.5
|
||||
parent: 1
|
||||
- uid: 63
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 12.5,1.5
|
||||
parent: 1
|
||||
- uid: 64
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 10.5,4.5
|
||||
parent: 1
|
||||
- uid: 65
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 8.5,2.5
|
||||
parent: 1
|
||||
- uid: 66
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 11.5,5.5
|
||||
parent: 1
|
||||
- uid: 67
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 25.5,1.5
|
||||
parent: 1
|
||||
- uid: 68
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 12.5,2.5
|
||||
parent: 1
|
||||
- uid: 69
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 10.5,3.5
|
||||
parent: 1
|
||||
- uid: 70
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 8.5,1.5
|
||||
parent: 1
|
||||
- uid: 72
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5,2.5
|
||||
parent: 1
|
||||
- uid: 73
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 5.5,2.5
|
||||
parent: 1
|
||||
- uid: 74
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 11.5,0.5
|
||||
parent: 1
|
||||
- uid: 75
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 10.5,5.5
|
||||
parent: 1
|
||||
- uid: 76
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,1.5
|
||||
parent: 1
|
||||
- uid: 77
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5,3.5
|
||||
parent: 1
|
||||
- uid: 78
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 0.5,0.5
|
||||
parent: 1
|
||||
- uid: 79
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 6.5,6.5
|
||||
parent: 1
|
||||
- uid: 80
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 6.5,4.5
|
||||
parent: 1
|
||||
- uid: 81
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 11.5,1.5
|
||||
parent: 1
|
||||
- uid: 82
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 11.5,3.5
|
||||
parent: 1
|
||||
- uid: 83
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 0.5,1.5
|
||||
parent: 1
|
||||
- uid: 84
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 6.5,5.5
|
||||
parent: 1
|
||||
- uid: 85
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 5.5,3.5
|
||||
parent: 1
|
||||
- uid: 86
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 12.5,4.5
|
||||
parent: 1
|
||||
- uid: 87
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 14.5,4.5
|
||||
parent: 1
|
||||
- uid: 88
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 5.5,4.5
|
||||
parent: 1
|
||||
- uid: 89
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 5.5,5.5
|
||||
parent: 1
|
||||
- uid: 90
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 4.5,3.5
|
||||
parent: 1
|
||||
- uid: 91
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5,1.5
|
||||
parent: 1
|
||||
- uid: 92
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,0.5
|
||||
parent: 1
|
||||
- uid: 93
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 3.5,2.5
|
||||
parent: 1
|
||||
- uid: 94
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,4.5
|
||||
parent: 1
|
||||
- uid: 95
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,2.5
|
||||
parent: 1
|
||||
- uid: 96
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,3.5
|
||||
parent: 1
|
||||
- uid: 97
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 3.5,1.5
|
||||
parent: 1
|
||||
- uid: 98
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 18.5,6.5
|
||||
parent: 1
|
||||
- uid: 99
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 21.5,5.5
|
||||
parent: 1
|
||||
- uid: 100
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 22.5,3.5
|
||||
parent: 1
|
||||
- uid: 101
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 9.5,6.5
|
||||
parent: 1
|
||||
- uid: 102
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 17.5,4.5
|
||||
parent: 1
|
||||
- uid: 103
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 10.5,2.5
|
||||
parent: 1
|
||||
- uid: 104
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 11.5,4.5
|
||||
parent: 1
|
||||
...
|
||||
@@ -116,27 +116,6 @@
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14GoldBar10
|
||||
|
||||
|
||||
- type: storePositionBuy
|
||||
id: Demiplane
|
||||
code: DEMIPLANE_1
|
||||
price: 100
|
||||
factions:
|
||||
- SpiceStream
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14DemiplaneKeyT1
|
||||
count: 5
|
||||
|
||||
- type: storePositionBuy
|
||||
id: Demiplane2
|
||||
code: DEMIPLANE_2
|
||||
price: 200
|
||||
factions:
|
||||
- SpiceStream
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14DemiplaneKeyT2
|
||||
count: 5
|
||||
|
||||
- type: storePositionBuy
|
||||
id: Bureaucracy
|
||||
code: PAPER
|
||||
|
||||
@@ -71,6 +71,14 @@
|
||||
- state: electrified
|
||||
color: "#601fc2"
|
||||
shader: unshaded
|
||||
- type: PointLight
|
||||
color: "#601fc2"
|
||||
enabled: true
|
||||
radius: 2
|
||||
energy: 2
|
||||
netsync: false
|
||||
- type: LightFade
|
||||
duration: 1
|
||||
|
||||
- type: entity
|
||||
parent: CP14BaseSpellScrollMeta
|
||||
|
||||
@@ -56,4 +56,42 @@
|
||||
farSound:
|
||||
collection: CP14LightningFar
|
||||
params:
|
||||
variation: 0.2
|
||||
variation: 0.2
|
||||
|
||||
- type: entity
|
||||
id: CP14SkyLightningPurple
|
||||
parent: CP14SkyLightning
|
||||
suffix: Purple
|
||||
components:
|
||||
- type: PointLight
|
||||
color: "#8f42ff"
|
||||
- type: Sprite
|
||||
color: "#8f42ff"
|
||||
- type: CP14AreaEntityEffect
|
||||
range: 1
|
||||
effects:
|
||||
- !type:CP14SpellApplyEntityEffect
|
||||
effects:
|
||||
- !type:Electrocute
|
||||
electrocuteTime: 3
|
||||
- !type:HealthChange
|
||||
damage:
|
||||
types:
|
||||
Shock: 15
|
||||
- !type:FlammableReaction
|
||||
multiplier: 1.5
|
||||
- !type:AdjustTemperature
|
||||
amount: 15000
|
||||
- !type:Ignite
|
||||
- type: CP14FarSound
|
||||
closeSound:
|
||||
path: /Audio/_CP14/Ambience/Lightning/lightning_close1.ogg
|
||||
params:
|
||||
variation: 0.2
|
||||
maxDistance: 20
|
||||
volume: 10
|
||||
farSound:
|
||||
collection: CP14LightningFar
|
||||
params:
|
||||
variation: 0.2
|
||||
volume: -5
|
||||
@@ -1,7 +1,6 @@
|
||||
- type: entity
|
||||
parent: BaseItem
|
||||
id: CP14BaseSubdimensionalKey
|
||||
abstract: true
|
||||
id: CP14BaseDemiplaneKey
|
||||
categories: [ ForkFiltered ]
|
||||
name: demiplane key
|
||||
description: The core that connects the real world to the demiplane. Use it to open a temporary passage to the other world.
|
||||
@@ -17,43 +16,43 @@
|
||||
- CP14_RU_Demiplanes
|
||||
- CP14_EN_Demiplanes
|
||||
- type: CP14DemiplaneUsingOpen
|
||||
|
||||
- type: entity
|
||||
id: CP14DemiplaneKeyT1
|
||||
parent: CP14BaseSubdimensionalKey
|
||||
suffix: Level 3
|
||||
components:
|
||||
- type: CP14DemiplaneGeneratorData
|
||||
level: 3
|
||||
limits:
|
||||
Reward: 1
|
||||
Danger: 1
|
||||
GhostRoleDanger: 1
|
||||
Fun: 1
|
||||
Weather: 1
|
||||
MapLight: 1
|
||||
- type: CP14DemiplaneData
|
||||
selectedModifiers:
|
||||
- DemiplaneDecor
|
||||
- Core
|
||||
- EntryRoom
|
||||
- Exit
|
||||
|
||||
- type: entity
|
||||
id: CP14DemiplaneKeyT2
|
||||
parent: CP14BaseSubdimensionalKey
|
||||
suffix: Level 6
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: core
|
||||
color: red
|
||||
- type: CP14DemiplaneGeneratorData
|
||||
level: 6
|
||||
limits:
|
||||
Reward: 1
|
||||
Danger: 1.5
|
||||
GhostRoleDanger: 1
|
||||
Fun: 1
|
||||
Weather: 1
|
||||
MapLight: 1
|
||||
selectedModifiers:
|
||||
- EntryRoom
|
||||
- Exit
|
||||
#- type: entity
|
||||
# id: CP14DemiplaneKeyT1
|
||||
# parent: CP14BaseDemiplaneKey
|
||||
# suffix: Level 3
|
||||
# components:
|
||||
# - type: CP14DemiplaneRandomGenerator
|
||||
# level: 3
|
||||
# limits:
|
||||
# Reward: 1
|
||||
# Danger: 1
|
||||
# GhostRoleDanger: 1
|
||||
# Fun: 1
|
||||
# Weather: 1
|
||||
# MapLight: 1
|
||||
#
|
||||
#- type: entity
|
||||
# id: CP14DemiplaneKeyT2
|
||||
# parent: CP14BaseDemiplaneKey
|
||||
# suffix: Level 6
|
||||
# components:
|
||||
# - type: Sprite
|
||||
# layers:
|
||||
# - state: core
|
||||
# color: red
|
||||
# - type: CP14DemiplaneRandomGenerator
|
||||
# level: 6
|
||||
# limits:
|
||||
# Reward: 1
|
||||
# Danger: 1.5
|
||||
# GhostRoleDanger: 1
|
||||
# Fun: 1
|
||||
# Weather: 1
|
||||
# MapLight: 1
|
||||
@@ -9,6 +9,7 @@
|
||||
- BaseStationRecords # Required for lobby manifest + cryo leave
|
||||
- CP14BaseStationCommonObjectives
|
||||
- CP14BaseStationSalary
|
||||
- CP14BaseStationDemiplaneMap
|
||||
|
||||
- type: entity
|
||||
id: CP14BaseStationCommonObjectives
|
||||
@@ -23,4 +24,10 @@
|
||||
- type: CP14StationSalary
|
||||
#frequency: every 20 minutes
|
||||
salary:
|
||||
CP14Guard: 550
|
||||
CP14Guard: 550
|
||||
|
||||
- type: entity
|
||||
id: CP14BaseStationDemiplaneMap
|
||||
abstract: true
|
||||
components:
|
||||
- type: CP14StationDemiplaneMap
|
||||
@@ -52,6 +52,14 @@
|
||||
range: 10
|
||||
sound:
|
||||
path: /Audio/_CP14/Effects/demiplane_heartbeat.ogg
|
||||
- type: ActivatableUI
|
||||
key: enum.CP14DemiplaneMapUiKey.Key
|
||||
requiresComplex: true
|
||||
- type: CP14DemiplaneNavigationMap
|
||||
- type: UserInterface
|
||||
interfaces:
|
||||
enum.CP14DemiplaneMapUiKey.Key:
|
||||
type: CP14DemiplaneMapBoundUserInterface
|
||||
|
||||
- type: entity
|
||||
id: CP14PortalFrameCrystal
|
||||
@@ -92,4 +100,86 @@
|
||||
maxEnergy: 100
|
||||
energy: 100
|
||||
- type: CP14MagicEnergyExaminable
|
||||
- type: CP14MagicEnergyPortRelay
|
||||
- type: CP14MagicEnergyPortRelay
|
||||
|
||||
- type: entity
|
||||
id: CP14DemiplaneCore
|
||||
categories: [ ForkFiltered ]
|
||||
parent: BaseStructureDynamic
|
||||
name: demiplane core
|
||||
description: The heart of the demiplane. Your task is to take it out of the demiplane safe and sound and hand it over to the guildmaster.
|
||||
components:
|
||||
- type: CP14DemiplaneCore
|
||||
- type: Transform
|
||||
anchored: false
|
||||
- type: Pullable
|
||||
- type: Clickable
|
||||
- type: Physics
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
fix1:
|
||||
shape:
|
||||
!type:PhysShapeAabb
|
||||
bounds: "-0.25,-0.25,0.25,0.25"
|
||||
density: 600
|
||||
mask:
|
||||
- MachineMask
|
||||
layer:
|
||||
- MidImpassable
|
||||
- LowImpassable
|
||||
- type: Tag
|
||||
tags:
|
||||
- Structure
|
||||
- type: Sprite
|
||||
noRot: true
|
||||
sprite: _CP14/Structures/Specific/Thaumaturgy/energy_monolith_big.rsi
|
||||
layers:
|
||||
- state: dimension_core
|
||||
drawdepth: Mobs
|
||||
offset: 0,0.4
|
||||
- type: PointLight
|
||||
enabled: true
|
||||
color: "#8f42ff"
|
||||
castShadows: false
|
||||
energy: 1
|
||||
radius: 5
|
||||
netsync: false
|
||||
- type: LightBehaviour
|
||||
behaviours:
|
||||
- !type:PulseBehaviour
|
||||
interpolate: Cubic
|
||||
maxDuration: 5
|
||||
minValue: 1.0
|
||||
maxValue: 40.0
|
||||
property: Energy
|
||||
isLooped: true
|
||||
enabled: true
|
||||
- type: AmbientSound
|
||||
volume: 5
|
||||
range: 10
|
||||
sound:
|
||||
path: /Audio/_CP14/Effects/demiplane_heartbeat.ogg
|
||||
- type: Damageable
|
||||
damageContainer: Inorganic
|
||||
damageModifierSet: CP14Rock
|
||||
- type: MeleeSound
|
||||
soundGroups:
|
||||
Brute:
|
||||
collection: GlassSmash
|
||||
- type: Destructible
|
||||
thresholds:
|
||||
- trigger:
|
||||
!type:DamageTrigger
|
||||
damage: 350
|
||||
behaviors:
|
||||
- !type:DoActsBehavior
|
||||
acts: ["Destruction"]
|
||||
- trigger:
|
||||
!type:DamageTrigger
|
||||
damage: 50
|
||||
behaviors:
|
||||
- !type:PlaySoundBehavior
|
||||
sound:
|
||||
collection: GlassBreak
|
||||
- !type:DoActsBehavior
|
||||
acts: ["Destruction"]
|
||||
@@ -261,4 +261,46 @@
|
||||
min: 2
|
||||
max: 3
|
||||
- !type:DoActsBehavior
|
||||
acts: ["Destruction"]
|
||||
acts: ["Destruction"]
|
||||
|
||||
- type: entity
|
||||
id: CP14WallDimensit
|
||||
parent: CP14BaseWall
|
||||
name: dimensit wall
|
||||
description: The solid form of the interdimensional continuum.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: _CP14/Structures/Walls/Natural/cave_dimensit.rsi
|
||||
- type: Icon
|
||||
sprite: _CP14/Structures/Walls/Natural/cave_dimensit.rsi
|
||||
- type: IconSmooth
|
||||
base: wall
|
||||
- type: Damageable
|
||||
damageContainer: Inorganic
|
||||
damageModifierSet: CP14Rock
|
||||
- type: MeleeSound
|
||||
soundGroups:
|
||||
Brute:
|
||||
collection: GlassSmash
|
||||
- type: Destructible
|
||||
thresholds:
|
||||
- trigger:
|
||||
!type:DamageTrigger
|
||||
damage: 350
|
||||
behaviors:
|
||||
- !type:DoActsBehavior
|
||||
acts: ["Destruction"]
|
||||
- trigger:
|
||||
!type:DamageTrigger
|
||||
damage: 30
|
||||
behaviors:
|
||||
- !type:PlaySoundBehavior
|
||||
sound:
|
||||
collection: GlassBreak
|
||||
- !type:DoActsBehavior
|
||||
acts: ["Destruction"]
|
||||
#- !type:SpawnEntitiesBehavior
|
||||
# spawn:
|
||||
# CP14StoneBlock1:
|
||||
# min: 5
|
||||
# max: 7
|
||||
18
Resources/Prototypes/_CP14/Parallax/astral.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
- type: parallax
|
||||
id: CP14Astral
|
||||
layers:
|
||||
- texture:
|
||||
!type:ImageParallaxTextureSource
|
||||
path: "/Textures/Parallaxes/KettleParallaxBG.png"
|
||||
slowness: 0.998046875
|
||||
scale: "1, 1"
|
||||
- texture:
|
||||
!type:GeneratedParallaxTextureSource
|
||||
id: "hq_wizard_stars"
|
||||
configPath: "/Prototypes/_CP14/Parallax/stars_purple.toml"
|
||||
slowness: 0.696625
|
||||
- texture:
|
||||
!type:GeneratedParallaxTextureSource
|
||||
id: "hq_wizard_stars"
|
||||
configPath: "/Prototypes/_CP14/Parallax/stars_purple_2.toml"
|
||||
slowness: 0.896625
|
||||
56
Resources/Prototypes/_CP14/Parallax/stars_purple.toml
Normal file
@@ -0,0 +1,56 @@
|
||||
# Clear to black.
|
||||
[[layers]]
|
||||
type = "clear"
|
||||
color = "#000000"
|
||||
|
||||
# Bright background nebula stars.
|
||||
[[layers]]
|
||||
type = "points"
|
||||
closecolor = "#aa47ad"
|
||||
count = 1000
|
||||
seed = 3472
|
||||
mask = true
|
||||
masknoise_type = "fbm"
|
||||
maskoctaves = 4
|
||||
maskpersistence = "0.5"
|
||||
maskpower = "0.35"
|
||||
masklacunarity = "1.5"
|
||||
maskfrequency = "3"
|
||||
maskthreshold = "0.37"
|
||||
maskseed = 3551
|
||||
|
||||
# Bright background nebula stars, dim edge.
|
||||
[[layers]]
|
||||
type = "points"
|
||||
closecolor = "#41244a"
|
||||
pointsize = 2
|
||||
count = 1000
|
||||
seed = 3472
|
||||
mask = true
|
||||
masknoise_type = "fbm"
|
||||
maskoctaves = 4
|
||||
maskpersistence = "0.5"
|
||||
maskpower = "0.35"
|
||||
masklacunarity = "1.5"
|
||||
maskfrequency = "3"
|
||||
maskthreshold = "0.37"
|
||||
maskseed = 3551
|
||||
|
||||
# Couple of bright pink stars.
|
||||
[[layers]]
|
||||
type = "points"
|
||||
closecolor = "#ff63ef"
|
||||
count = 30
|
||||
seed = 6454
|
||||
|
||||
# And their dim edge.
|
||||
[[layers]]
|
||||
type = "points"
|
||||
closecolor = "#301a43"
|
||||
pointsize = 2
|
||||
count = 30
|
||||
seed = 6454
|
||||
|
||||
# Colour-to-alpha.
|
||||
[[layers]]
|
||||
type = "toalpha"
|
||||
56
Resources/Prototypes/_CP14/Parallax/stars_purple_2.toml
Normal file
@@ -0,0 +1,56 @@
|
||||
# Clear to black.
|
||||
[[layers]]
|
||||
type = "clear"
|
||||
color = "#000000"
|
||||
|
||||
# Bright background nebula stars.
|
||||
[[layers]]
|
||||
type = "points"
|
||||
closecolor = "#aa47ad"
|
||||
count = 1000
|
||||
seed = 4810
|
||||
mask = true
|
||||
masknoise_type = "fbm"
|
||||
maskoctaves = 4
|
||||
maskpersistence = "0.5"
|
||||
maskpower = "0.35"
|
||||
masklacunarity = "1.5"
|
||||
maskfrequency = "3"
|
||||
maskthreshold = "0.37"
|
||||
maskseed = 3551
|
||||
|
||||
# Bright background nebula stars, dim edge.
|
||||
[[layers]]
|
||||
type = "points"
|
||||
closecolor = "#41244a"
|
||||
pointsize = 2
|
||||
count = 1000
|
||||
seed = 4810
|
||||
mask = true
|
||||
masknoise_type = "fbm"
|
||||
maskoctaves = 4
|
||||
maskpersistence = "0.5"
|
||||
maskpower = "0.35"
|
||||
masklacunarity = "1.5"
|
||||
maskfrequency = "3"
|
||||
maskthreshold = "0.37"
|
||||
maskseed = 3551
|
||||
|
||||
# Couple of bright pink stars.
|
||||
[[layers]]
|
||||
type = "points"
|
||||
closecolor = "#ff63ef"
|
||||
count = 30
|
||||
seed = 9019
|
||||
|
||||
# And their dim edge.
|
||||
[[layers]]
|
||||
type = "points"
|
||||
closecolor = "#301a43"
|
||||
pointsize = 2
|
||||
count = 30
|
||||
seed = 9019
|
||||
|
||||
# Colour-to-alpha.
|
||||
[[layers]]
|
||||
type = "toalpha"
|
||||
@@ -2,7 +2,10 @@
|
||||
id: T1Caves
|
||||
levels:
|
||||
min: 1
|
||||
max: 4
|
||||
max: 5
|
||||
icon:
|
||||
sprite: _CP14/Interface/Misc/demiplane_locations.rsi
|
||||
state: caves
|
||||
locationConfig: CP14DemiplaneCaves
|
||||
name: cp14-demiplane-location-cave
|
||||
tags:
|
||||
@@ -1,8 +1,11 @@
|
||||
- type: cp14DemiplaneLocation
|
||||
id: T1IceCaves
|
||||
levels:
|
||||
min: 1
|
||||
max: 10
|
||||
min: 4
|
||||
max: 7
|
||||
icon:
|
||||
sprite: _CP14/Interface/Misc/demiplane_locations.rsi
|
||||
state: ice_caves
|
||||
locationConfig: CP14DemiplaneIceCaves
|
||||
name: cp14-demiplane-location-ice-cave
|
||||
tags:
|
||||
@@ -1,8 +1,11 @@
|
||||
- type: cp14DemiplaneLocation
|
||||
id: T1MagmaCaves
|
||||
levels:
|
||||
min: 3
|
||||
min: 7
|
||||
max: 10
|
||||
icon:
|
||||
sprite: _CP14/Interface/Misc/demiplane_locations.rsi
|
||||
state: magma_caves
|
||||
locationConfig: CP14DemiplaneCavesRing
|
||||
name: cp14-demiplane-location-cave-magma
|
||||
tags:
|
||||
@@ -1,8 +1,11 @@
|
||||
- type: cp14DemiplaneLocation
|
||||
id: T1SwampGeode
|
||||
id: T1SwampCaves
|
||||
levels:
|
||||
min: 4
|
||||
max: 10
|
||||
min: 2
|
||||
max: 5
|
||||
icon:
|
||||
sprite: _CP14/Interface/Misc/demiplane_locations.rsi
|
||||
state: swamp_caves
|
||||
locationConfig: CP14DemiplaneSwampGeode
|
||||
name: cp14-demiplane-location-cave-grass
|
||||
tags:
|
||||
@@ -2,7 +2,10 @@
|
||||
id: T1GrasslandIsland
|
||||
levels:
|
||||
min: 1
|
||||
max: 4
|
||||
max: 2
|
||||
icon:
|
||||
sprite: _CP14/Interface/Misc/demiplane_locations.rsi
|
||||
state: grassland_island
|
||||
locationConfig: CP14DemiplaneGrasslandIsland
|
||||
name: cp14-demiplane-location-grassland-island
|
||||
tags:
|
||||
@@ -2,7 +2,10 @@
|
||||
id: T1GrasslandIslandRing
|
||||
levels:
|
||||
min: 1
|
||||
max: 4
|
||||
max: 2
|
||||
icon:
|
||||
sprite: _CP14/Interface/Misc/demiplane_locations.rsi
|
||||
state: grassland_island
|
||||
locationConfig: CP14DemiplaneGrasslandIslandRing
|
||||
name: cp14-demiplane-location-grassland-island
|
||||
tags:
|
||||
@@ -1,8 +1,11 @@
|
||||
- type: cp14DemiplaneLocation
|
||||
id: T1SnowIsland
|
||||
levels:
|
||||
min: 1
|
||||
max: 10
|
||||
min: 3
|
||||
max: 5
|
||||
icon:
|
||||
sprite: _CP14/Interface/Misc/demiplane_locations.rsi
|
||||
state: snow_island
|
||||
locationConfig: CP14DemiplaneSnowIsland
|
||||
name: cp14-demiplane-location-snow-island
|
||||
tags:
|
||||
@@ -1,8 +1,11 @@
|
||||
- type: cp14DemiplaneLocation
|
||||
id: T1LeafMaze
|
||||
levels:
|
||||
min: 4
|
||||
max: 10
|
||||
min: 3
|
||||
max: 5
|
||||
icon:
|
||||
sprite: _CP14/Interface/Misc/demiplane_locations.rsi
|
||||
state: leaf_maze
|
||||
locationConfig: CP14DemiplaneLeafMaze
|
||||
name: cp14-demiplane-location-leaf-maze
|
||||
tags:
|
||||
@@ -1,8 +1,11 @@
|
||||
- type: cp14DemiplaneLocation
|
||||
id: T1Wastelands
|
||||
levels:
|
||||
min: 1
|
||||
max: 4
|
||||
min: 5
|
||||
max: 7
|
||||
icon:
|
||||
sprite: _CP14/Interface/Misc/demiplane_locations.rsi
|
||||
state: wastelands
|
||||
locationConfig: CP14DemiplaneWastelandsIsland
|
||||
name: cp14-demiplane-location-wastelands
|
||||
tags:
|
||||
@@ -3,7 +3,7 @@
|
||||
- type: cp14DemiplaneModifier
|
||||
id: Chasm
|
||||
levels:
|
||||
min: 4
|
||||
min: 3
|
||||
max: 10
|
||||
name: cp14-modifier-chasm
|
||||
generationWeight: 0.6
|
||||
@@ -60,7 +60,7 @@
|
||||
maxGroupSize: 2
|
||||
|
||||
- type: cp14DemiplaneModifier
|
||||
id: ShadowKudzuDebug
|
||||
id: ShadowKudzu
|
||||
levels:
|
||||
min: 7
|
||||
max: 10
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
id: EnemyZombie
|
||||
levels:
|
||||
min: 1
|
||||
max: 4
|
||||
max: 6
|
||||
name: cp14-modifier-zombie
|
||||
generationWeight: 1.5
|
||||
categories:
|
||||
@@ -40,7 +40,7 @@
|
||||
id: MonsterMosquito
|
||||
levels:
|
||||
min: 1
|
||||
max: 4
|
||||
max: 5
|
||||
name: cp14-modifier-dyno
|
||||
categories:
|
||||
Danger: 0.2
|
||||
@@ -59,7 +59,7 @@
|
||||
id: SmallHydra
|
||||
levels:
|
||||
min: 1
|
||||
max: 4
|
||||
max: 5
|
||||
name: cp14-modifier-dyno
|
||||
categories:
|
||||
Danger: 0.3
|
||||
@@ -92,7 +92,7 @@
|
||||
- type: cp14DemiplaneModifier
|
||||
id: EnemyLurker
|
||||
levels:
|
||||
min: 3
|
||||
min: 1
|
||||
max: 10
|
||||
generationWeight: 0.33
|
||||
generationProb: 0.25
|
||||
@@ -163,22 +163,22 @@
|
||||
- type: cp14DemiplaneModifier
|
||||
id: MobSlimeElectric
|
||||
levels:
|
||||
min: 1
|
||||
min: 5
|
||||
max: 10
|
||||
name: cp14-modifier-slime
|
||||
categories:
|
||||
Danger: 0.3
|
||||
Danger: 0.35
|
||||
layers:
|
||||
- !type:OreDunGen
|
||||
entity: CP14MobSlimeElectric
|
||||
count: 6
|
||||
minGroupSize: 2
|
||||
maxGroupSize: 3
|
||||
minGroupSize: 1
|
||||
maxGroupSize: 1
|
||||
|
||||
- type: cp14DemiplaneModifier
|
||||
id: MobSlimeFire
|
||||
levels:
|
||||
min: 1
|
||||
min: 4
|
||||
max: 10
|
||||
name: cp14-modifier-slime
|
||||
categories:
|
||||
@@ -189,8 +189,8 @@
|
||||
- !type:OreDunGen
|
||||
entity: CP14MobSlimeFire
|
||||
count: 6
|
||||
minGroupSize: 2
|
||||
maxGroupSize: 3
|
||||
minGroupSize: 1
|
||||
maxGroupSize: 2
|
||||
|
||||
- type: cp14DemiplaneModifier
|
||||
id: MobSlimeIce
|
||||
@@ -206,8 +206,8 @@
|
||||
- !type:OreDunGen
|
||||
entity: CP14MobSlimeIce
|
||||
count: 6
|
||||
minGroupSize: 2
|
||||
maxGroupSize: 3
|
||||
minGroupSize: 1
|
||||
maxGroupSize: 2
|
||||
|
||||
- type: cp14DemiplaneModifier
|
||||
id: MobSlimeBase
|
||||
@@ -220,13 +220,13 @@
|
||||
- !type:OreDunGen
|
||||
entity: CP14MobSlimeBase
|
||||
count: 6
|
||||
minGroupSize: 2
|
||||
maxGroupSize: 3
|
||||
minGroupSize: 1
|
||||
maxGroupSize: 2
|
||||
|
||||
- type: cp14DemiplaneModifier
|
||||
id: MobWatcherIce
|
||||
levels:
|
||||
min: 1
|
||||
min: 3
|
||||
max: 10
|
||||
name: cp14-modifier-watcher
|
||||
categories:
|
||||
@@ -245,7 +245,7 @@
|
||||
- type: cp14DemiplaneModifier
|
||||
id: MobWatcherMagma
|
||||
levels:
|
||||
min: 1
|
||||
min: 3
|
||||
max: 10
|
||||
name: cp14-modifier-watcher
|
||||
categories:
|
||||
@@ -280,20 +280,4 @@
|
||||
entity: CP14SpawnPointGhostDemiplaneSkeletonMagicalT2
|
||||
count: 1
|
||||
minGroupSize: 0
|
||||
maxGroupSize: 1
|
||||
|
||||
- type: cp14DemiplaneModifier
|
||||
id: EnemySkeletonHidenT1
|
||||
levels:
|
||||
min: 6
|
||||
max: 10
|
||||
name: cp14-modifier-skeleton
|
||||
generationWeight: 1.0
|
||||
categories:
|
||||
Danger: 0.25
|
||||
layers:
|
||||
- !type:OreDunGen
|
||||
entity: CP14SpawnPointGhostDemiplaneSkeletonT1
|
||||
count: 1
|
||||
minGroupSize: 1
|
||||
maxGroupSize: 2
|
||||
maxGroupSize: 1
|
||||
@@ -4,7 +4,7 @@
|
||||
id: LootT1
|
||||
levels:
|
||||
min: 1
|
||||
max: 4
|
||||
max: 5
|
||||
generationWeight: 2
|
||||
categories:
|
||||
Reward: 0.35
|
||||
@@ -23,7 +23,7 @@
|
||||
name: cp14-modifier-rabbits
|
||||
generationWeight: 0.4
|
||||
categories:
|
||||
Reward: 0.2
|
||||
Reward: 0.1
|
||||
requiredTags:
|
||||
- CP14DemiplanePeacefulAnimals
|
||||
layers:
|
||||
@@ -58,7 +58,7 @@
|
||||
max: 10
|
||||
generationWeight: 0.4
|
||||
categories:
|
||||
Reward: 0.2
|
||||
Reward: 0.05
|
||||
requiredTags:
|
||||
- CP14DemiplaneAnimalsSwamp
|
||||
layers:
|
||||
@@ -90,6 +90,22 @@
|
||||
minGroupSize: 4
|
||||
maxGroupSize: 5
|
||||
|
||||
- type: cp14DemiplaneModifier
|
||||
id: Ruins
|
||||
levels:
|
||||
min: 0
|
||||
max: 10
|
||||
name: cp14-modifier-ruins
|
||||
categories:
|
||||
Reward: 0.15
|
||||
generationProb: 0.8
|
||||
layers:
|
||||
- !type:OreDunGen
|
||||
entity: CP14DemiplaneRuinsRoomSpawner
|
||||
count: 8
|
||||
minGroupSize: 1
|
||||
maxGroupSize: 1
|
||||
|
||||
# TIER 2
|
||||
|
||||
- type: cp14DemiplaneModifier
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
id: IronOre
|
||||
levels:
|
||||
min: 1
|
||||
max: 10
|
||||
max: 7
|
||||
name: cp14-modifier-iron-ore
|
||||
unique: false
|
||||
categories:
|
||||
@@ -25,7 +25,7 @@
|
||||
id: IronOreUnderground
|
||||
levels:
|
||||
min: 1
|
||||
max: 10
|
||||
max: 7
|
||||
name: cp14-modifier-iron-ore
|
||||
unique: false
|
||||
categories:
|
||||
@@ -46,7 +46,7 @@
|
||||
id: CopperOre
|
||||
levels:
|
||||
min: 1
|
||||
max: 4
|
||||
max: 2
|
||||
name: cp14-modifier-copper-ore
|
||||
unique: false
|
||||
categories:
|
||||
@@ -67,7 +67,7 @@
|
||||
id: CopperOreUnderground
|
||||
levels:
|
||||
min: 1
|
||||
max: 4
|
||||
max: 2
|
||||
name: cp14-modifier-copper-ore
|
||||
unique: false
|
||||
categories:
|
||||
@@ -89,8 +89,8 @@
|
||||
- type: cp14DemiplaneModifier
|
||||
id: GoldOre
|
||||
levels:
|
||||
min: 5
|
||||
max: 6
|
||||
min: 4
|
||||
max: 5
|
||||
name: cp14-modifier-gold-ore
|
||||
unique: false
|
||||
categories:
|
||||
@@ -110,8 +110,8 @@
|
||||
- type: cp14DemiplaneModifier
|
||||
id: GoldOreUnderground
|
||||
levels:
|
||||
min: 3
|
||||
max: 6
|
||||
min: 4
|
||||
max: 5
|
||||
name: cp14-modifier-gold-ore
|
||||
unique: false
|
||||
categories:
|
||||
|
||||
@@ -9,17 +9,12 @@
|
||||
maxGroupSize: 1
|
||||
|
||||
- type: cp14DemiplaneModifier
|
||||
id: Ruins
|
||||
levels:
|
||||
min: 0
|
||||
max: 10
|
||||
categories:
|
||||
Reward: 0.1
|
||||
generationProb: 0.8
|
||||
id: Core
|
||||
generationProb: 0
|
||||
layers:
|
||||
- !type:OreDunGen
|
||||
entity: CP14DemiplaneRuinsRoomSpawner
|
||||
count: 8
|
||||
entity: CP14DemiplanCoreRoomMarker
|
||||
count: 1
|
||||
minGroupSize: 1
|
||||
maxGroupSize: 1
|
||||
|
||||
@@ -37,16 +32,22 @@
|
||||
count: 20
|
||||
minGroupSize: 1
|
||||
maxGroupSize: 1
|
||||
|
||||
- type: cp14DemiplaneModifier
|
||||
id: DemiplaneDecor
|
||||
generationProb: 0
|
||||
layers:
|
||||
- !type:OreDunGen
|
||||
entity: CP14AstralCorrosion
|
||||
count: 15
|
||||
minGroupSize: 3
|
||||
maxGroupSize: 10
|
||||
|
||||
- type: cp14DemiplaneModifier
|
||||
id: TimeLimit10
|
||||
generationProb: 0
|
||||
name: cp14-modifier-time-limit-10
|
||||
components:
|
||||
- type: CP14DemiplaneTimedDestruction
|
||||
timeToDestruction: 600 # 10 minutes
|
||||
- !type:OreDunGen
|
||||
entityMask:
|
||||
- CP14WallStone
|
||||
- CP14WallDirt
|
||||
- CP14WallSnow
|
||||
entity: CP14WallDimensit
|
||||
count: 5
|
||||
minGroupSize: 3
|
||||
maxGroupSize: 5
|
||||
@@ -0,0 +1,55 @@
|
||||
- type: cp14SpecialDemiplane
|
||||
id: Test
|
||||
levels:
|
||||
min: 5
|
||||
max: 5
|
||||
location: T1GrasslandIsland
|
||||
|
||||
- type: cp14SpecialDemiplane
|
||||
id: Test2
|
||||
levels:
|
||||
min: 5
|
||||
max: 5
|
||||
location: T1Caves
|
||||
|
||||
- type: cp14SpecialDemiplane
|
||||
id: Test3
|
||||
levels:
|
||||
min: 5
|
||||
max: 5
|
||||
location: T1IceCaves
|
||||
|
||||
- type: cp14SpecialDemiplane
|
||||
id: Test4
|
||||
levels:
|
||||
min: 5
|
||||
max: 5
|
||||
location: T1MagmaCaves
|
||||
|
||||
- type: cp14SpecialDemiplane
|
||||
id: Test5
|
||||
levels:
|
||||
min: 5
|
||||
max: 5
|
||||
location: T1SnowIsland
|
||||
|
||||
- type: cp14SpecialDemiplane
|
||||
id: Test6
|
||||
levels:
|
||||
min: 5
|
||||
max: 5
|
||||
location: T1SnowIsland
|
||||
|
||||
- type: cp14SpecialDemiplane
|
||||
id: Test7
|
||||
levels:
|
||||
min: 9
|
||||
max: 10
|
||||
location: T1MagmaCaves
|
||||
|
||||
- type: cp14SpecialDemiplane
|
||||
id: Test8
|
||||
levels:
|
||||
min: 9
|
||||
max: 10
|
||||
location: T1Wastelands
|
||||
@@ -0,0 +1,50 @@
|
||||
- type: Tag
|
||||
id: CP14DemiplanCoreRoom
|
||||
|
||||
- type: entity
|
||||
id: CP14DemiplanCoreRoomMarker
|
||||
categories: [ ForkFiltered ]
|
||||
parent: BaseRoomMarker
|
||||
name: Demiplane Core room marker
|
||||
components:
|
||||
- type: RoomFill
|
||||
clearExisting: true
|
||||
roomWhitelist:
|
||||
tags:
|
||||
- CP14DemiplanCoreRoom
|
||||
|
||||
- type: dungeonRoom
|
||||
id: CP14DemiplanCoreRoom_1
|
||||
size: 7,7
|
||||
atlas: /Maps/_CP14/Dungeon/demiplane_core.yml
|
||||
ignoreTile: FloorShuttlePurple
|
||||
offset: 0,0
|
||||
tags:
|
||||
- CP14DemiplanCoreRoom
|
||||
|
||||
- type: dungeonRoom
|
||||
id: CP14DemiplanCoreRoom_2
|
||||
size: 7,7
|
||||
atlas: /Maps/_CP14/Dungeon/demiplane_core.yml
|
||||
ignoreTile: FloorShuttlePurple
|
||||
offset: 8,0
|
||||
tags:
|
||||
- CP14DemiplanCoreRoom
|
||||
|
||||
- type: dungeonRoom
|
||||
id: CP14DemiplanCoreRoom_3
|
||||
size: 7,7
|
||||
atlas: /Maps/_CP14/Dungeon/demiplane_core.yml
|
||||
ignoreTile: FloorShuttlePurple
|
||||
offset: 16,0
|
||||
tags:
|
||||
- CP14DemiplanCoreRoom
|
||||
|
||||
- type: dungeonRoom
|
||||
id: CP14DemiplanCoreRoom_4
|
||||
size: 7,7
|
||||
atlas: /Maps/_CP14/Dungeon/demiplane_core.yml
|
||||
ignoreTile: FloorShuttlePurple
|
||||
offset: 24,0
|
||||
tags:
|
||||
- CP14DemiplanCoreRoom
|
||||
@@ -16,7 +16,7 @@
|
||||
- type: dungeonRoom
|
||||
id: CP14DemiplanEnterRoom_1
|
||||
size: 7,7
|
||||
atlas: /Maps/_CP14/Dungeon/demiplan_enter.yml
|
||||
atlas: /Maps/_CP14/Dungeon/demiplane_enter.yml
|
||||
ignoreTile: FloorShuttlePurple
|
||||
offset: 0,0
|
||||
tags:
|
||||
@@ -25,7 +25,7 @@
|
||||
- type: dungeonRoom
|
||||
id: CP14DemiplanEnterRoom_2
|
||||
size: 7,7
|
||||
atlas: /Maps/_CP14/Dungeon/demiplan_enter.yml
|
||||
atlas: /Maps/_CP14/Dungeon/demiplane_enter.yml
|
||||
ignoreTile: FloorShuttlePurple
|
||||
offset: 8,0
|
||||
tags:
|
||||
@@ -34,7 +34,7 @@
|
||||
- type: dungeonRoom
|
||||
id: CP14DemiplanEnterRoom_3
|
||||
size: 7,7
|
||||
atlas: /Maps/_CP14/Dungeon/demiplan_enter.yml
|
||||
atlas: /Maps/_CP14/Dungeon/demiplane_enter.yml
|
||||
ignoreTile: FloorShuttlePurple
|
||||
offset: 16,0
|
||||
tags:
|
||||
@@ -43,7 +43,7 @@
|
||||
- type: dungeonRoom
|
||||
id: CP14DemiplanEnterRoom_4
|
||||
size: 7,7
|
||||
atlas: /Maps/_CP14/Dungeon/demiplan_enter.yml
|
||||
atlas: /Maps/_CP14/Dungeon/demiplane_enter.yml
|
||||
ignoreTile: FloorShuttlePurple
|
||||
offset: 24,0
|
||||
tags:
|
||||
@@ -52,7 +52,7 @@
|
||||
- type: dungeonRoom
|
||||
id: CP14DemiplanEnterRoom_5
|
||||
size: 7,7
|
||||
atlas: /Maps/_CP14/Dungeon/demiplan_enter.yml
|
||||
atlas: /Maps/_CP14/Dungeon/demiplane_enter.yml
|
||||
ignoreTile: FloorShuttlePurple
|
||||
offset: 0,8
|
||||
tags:
|
||||
@@ -61,7 +61,7 @@
|
||||
- type: dungeonRoom
|
||||
id: CP14DemiplanEnterRoom_6
|
||||
size: 9,7
|
||||
atlas: /Maps/_CP14/Dungeon/demiplan_enter.yml
|
||||
atlas: /Maps/_CP14/Dungeon/demiplane_enter.yml
|
||||
ignoreTile: FloorShuttlePurple
|
||||
offset: 8,8
|
||||
tags:
|
||||
|
||||
@@ -190,4 +190,21 @@
|
||||
effects:
|
||||
- !type:FlammableReaction
|
||||
multiplier: 1
|
||||
- !type:Ignite
|
||||
- !type:Ignite
|
||||
|
||||
- type: weather
|
||||
id: CP14DemiplaneDestructionStorm
|
||||
sprite:
|
||||
sprite: /Textures/Effects/weather.rsi
|
||||
state: snowfall_heavy
|
||||
alpha: 0.4
|
||||
offsetSpeed: 0.56, -0.36
|
||||
color: "#c034eb"
|
||||
config:
|
||||
- maxEntities: 4
|
||||
frequency: 3
|
||||
canAffectOnWeatherBlocker: false
|
||||
effects:
|
||||
- !type:SpawnEntityOnTop
|
||||
prob: 0.25
|
||||
entity: CP14SkyLightningPurple
|
||||
@@ -5,14 +5,13 @@ Demiplanes are one of the main ways for adventurers and the city as a whole to o
|
||||
|
||||
The main goal of exploration is for adventurers to obtain resources (ore, loot, etc.) and successfully return them back to their world.
|
||||
|
||||
As an adventurer, you can sell resources from the demiplane to artisans and other players at your own prices.
|
||||
As an adventurer, you can sell resources from the demiplane to artisans and other players at your own prices.
|
||||
|
||||
## What research and preparation looks like.
|
||||
|
||||
There are "keys" in the game world that allow you to temporarily activate a portal to move into a procedurally generated demiplane with enemies and resources. Within the location there will be generated exits from the demiplane that you will have to find on your own.
|
||||
|
||||
<Box>
|
||||
<GuideEntityEmbed Entity="CP14DemiplaneKeyT1"/>
|
||||
<GuideEntityEmbed Entity="CP14DemiplanRiftCore"/>
|
||||
</Box>.
|
||||
|
||||
@@ -42,11 +41,11 @@ To prepare for an expedition to the demiplane, you may need the following items:
|
||||
- Weapons for all members of the group.
|
||||
- Vials of healing potions or poison for weapons.
|
||||
- Sharpening stones to sharpen your weapons on the spot.
|
||||
- Armor for group members.
|
||||
- Armor for group members.
|
||||
- Magical items and/or crossbows (with ammunition) for dealing damage remotely.
|
||||
- A "key" to open the demiplane.
|
||||
- Extra bags or crates for collecting loot.
|
||||
- Belt lanterns or magical lighting.
|
||||
- Extra bags or crates for collecting loot.
|
||||
- Belt lanterns or magical lighting.
|
||||
- A supply of water and food for a short break from exploring.
|
||||
|
||||
## Cooperation tips
|
||||
@@ -58,4 +57,4 @@ The entire Demiplane is designed for adventurers to (and should) work as a team.
|
||||
- who will be your team leader during critical situations?
|
||||
- What will you do with dead and injured team members?
|
||||
|
||||
</Document>
|
||||
</Document>
|
||||
|
||||
@@ -5,14 +5,13 @@
|
||||
|
||||
Основная задача при исследовании - добыча ресурсов (руды, лут, и прочее) авантюристами и удачный возврат обратно в свой мир.
|
||||
|
||||
Как авантюрист, вы можете продавать ресурсы с демиплана ремесленникам и иным игрокам по собственным ценам.
|
||||
Как авантюрист, вы можете продавать ресурсы с демиплана ремесленникам и иным игрокам по собственным ценам.
|
||||
|
||||
## Как выглядит исследование и подготовка к ней.
|
||||
|
||||
В мире игры существуют «ключи», позволяющие временно активировать портал для перехода в процедурно сгенерированный демиплан с противниками и ресурсами. Внутри локации будут сгенерированы выходы с демиплана которые вам предстоит найти самим.
|
||||
|
||||
<Box>
|
||||
<GuideEntityEmbed Entity="CP14DemiplaneKeyT1"/>
|
||||
<GuideEntityEmbed Entity="CP14DemiplanRiftCore"/>
|
||||
</Box>
|
||||
|
||||
@@ -42,11 +41,11 @@
|
||||
- Оружие для всех участников группы.
|
||||
- Флаконы с зельями лечения или ядом для оружия.
|
||||
- Точильные камни для заточки вашего оружия на месте.
|
||||
- Броня для участников группы.
|
||||
- Броня для участников группы.
|
||||
- Магические предметы и/или арбалеты (с амуницией) для дистанционного нанесения урона.
|
||||
- "Ключ" для открытия демиплана.
|
||||
- Дополнительные сумки или ящики для сбора добычи.
|
||||
- Поясные фонари или магическое освещение.
|
||||
- Дополнительные сумки или ящики для сбора добычи.
|
||||
- Поясные фонари или магическое освещение.
|
||||
- Запас воды и еды для непродолжительного перерыва в исследовании.
|
||||
|
||||
## Советы по кооперации
|
||||
@@ -58,4 +57,4 @@
|
||||
- кто будет лидером вашей группы во время критических ситуаций?
|
||||
- что делать с убитыми и раненными членами группы?
|
||||
|
||||
</Document>
|
||||
</Document>
|
||||
|
||||
|
After Width: | Height: | Size: 364 B |
|
After Width: | Height: | Size: 305 B |
|
After Width: | Height: | Size: 429 B |
|
After Width: | Height: | Size: 463 B |
|
After Width: | Height: | Size: 430 B |
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"version": 1,
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"license": "CC-BY-SA-4.0",
|
||||
"copyright": "Created by TheShuEd (Github)",
|
||||
"states": [
|
||||
{
|
||||
"name": "caves"
|
||||
},
|
||||
{
|
||||
"name": "grassland_island"
|
||||
},
|
||||
{
|
||||
"name": "ice_caves"
|
||||
},
|
||||
{
|
||||
"name": "leaf_maze"
|
||||
},
|
||||
{
|
||||
"name": "magma_caves"
|
||||
},
|
||||
{
|
||||
"name": "snow_island"
|
||||
},
|
||||
{
|
||||
"name": "swamp_caves"
|
||||
},
|
||||
{
|
||||
"name": "wastelands"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 308 B |
|
After Width: | Height: | Size: 505 B |
|
After Width: | Height: | Size: 265 B |
|
Before Width: | Height: | Size: 219 B After Width: | Height: | Size: 219 B |
|
Before Width: | Height: | Size: 260 B After Width: | Height: | Size: 260 B |
|
Before Width: | Height: | Size: 240 B After Width: | Height: | Size: 240 B |
|
Before Width: | Height: | Size: 399 B After Width: | Height: | Size: 399 B |
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"version": 1,
|
||||
"size": {
|
||||
"x": 48,
|
||||
"y": 48
|
||||
},
|
||||
"license": "CC-BY-SA-4.0",
|
||||
"copyright": "Created by TheShuEd (Github)",
|
||||
"states": [
|
||||
{
|
||||
"name": "frame"
|
||||
},
|
||||
{
|
||||
"name": "hovered"
|
||||
},
|
||||
{
|
||||
"name": "selected"
|
||||
},
|
||||
{
|
||||
"name": "learned"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 191 B After Width: | Height: | Size: 191 B |
|
After Width: | Height: | Size: 997 B |
|
After Width: | Height: | Size: 307 B |
|
After Width: | Height: | Size: 385 B |
|
After Width: | Height: | Size: 485 B |
@@ -8,7 +8,7 @@
|
||||
"copyright": "Created by TheShuEd (Github)",
|
||||
"states": [
|
||||
{
|
||||
"name": "available"
|
||||
"name": "center"
|
||||
},
|
||||
{
|
||||
"name": "frame"
|
||||
|
After Width: | Height: | Size: 330 B |
|
Before Width: | Height: | Size: 373 B |
|
After Width: | Height: | Size: 1.8 KiB |
@@ -10,6 +10,9 @@
|
||||
{
|
||||
"name": "dimension"
|
||||
},
|
||||
{
|
||||
"name": "dimension_core"
|
||||
},
|
||||
{
|
||||
"name": "frame"
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"version": 1,
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 64
|
||||
},
|
||||
"license": "CC-BY-SA-4.0",
|
||||
"copyright": "Created by TheShuEd (Github)",
|
||||
"states": [
|
||||
{
|
||||
"name": "wall0",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "wall1",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "wall2",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "wall3",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "wall4",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "wall5",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "wall6",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "wall7",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "full"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 4.0 KiB |