technology auto guidebook (#21029)
* technology auto guidebook * boo-womp * boo-womp II
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
<BoxContainer xmlns="https://spacestation14.io"
|
||||
Orientation="Vertical">
|
||||
<BoxContainer Name="DisciplineContainer" Orientation="Vertical"/>
|
||||
</BoxContainer>
|
||||
@@ -0,0 +1,60 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Client.Guidebook.Richtext;
|
||||
using Content.Shared.Research.Prototypes;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Guidebook.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Control for embedding all the technologies in a discipline into a guidebook.
|
||||
/// </summary>
|
||||
[UsedImplicitly, GenerateTypedNameReferences]
|
||||
public sealed partial class GuideTechDisciplineEmbed : BoxContainer, IDocumentTag
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
|
||||
public GuideTechDisciplineEmbed()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
MouseFilter = MouseFilterMode.Stop;
|
||||
}
|
||||
|
||||
public GuideTechDisciplineEmbed(string group) : this()
|
||||
{
|
||||
var prototypes = _prototype.EnumeratePrototypes<TechnologyPrototype>()
|
||||
.Where(p => p.Discipline.Equals(group)).OrderBy(p => p.Tier).ThenBy(p => Loc.GetString(p.Name));
|
||||
foreach (var tech in prototypes)
|
||||
{
|
||||
var embed = new GuideTechnologyEmbed(tech);
|
||||
DisciplineContainer.AddChild(embed);
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryParseTag(Dictionary<string, string> args, [NotNullWhen(true)] out Control? control)
|
||||
{
|
||||
control = null;
|
||||
if (!args.TryGetValue("Discipline", out var group))
|
||||
{
|
||||
Logger.Error("Technology discipline embed tag is missing discipline argument");
|
||||
return false;
|
||||
}
|
||||
|
||||
var prototypes = _prototype.EnumeratePrototypes<TechnologyPrototype>()
|
||||
.Where(p => p.Discipline.Equals(group)).OrderBy(p => p.Tier).ThenBy(p => Loc.GetString(p.Name));
|
||||
foreach (var tech in prototypes)
|
||||
{
|
||||
var embed = new GuideTechnologyEmbed(tech);
|
||||
DisciplineContainer.AddChild(embed);
|
||||
}
|
||||
|
||||
control = this;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
22
Content.Client/Guidebook/Controls/GuideTechnologyEmbed.xaml
Normal file
22
Content.Client/Guidebook/Controls/GuideTechnologyEmbed.xaml
Normal file
@@ -0,0 +1,22 @@
|
||||
<BoxContainer xmlns="https://spacestation14.io"
|
||||
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
||||
xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"
|
||||
Orientation="Vertical"
|
||||
Margin="5 5 5 5">
|
||||
<PanelContainer HorizontalExpand="True">
|
||||
<PanelContainer.PanelOverride>
|
||||
<gfx:StyleBoxFlat BorderThickness="1" BorderColor="#777777"/>
|
||||
</PanelContainer.PanelOverride>
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<PanelContainer Name="DisciplineColorBackground" HorizontalExpand="True" VerticalExpand="False" MinHeight="15"/>
|
||||
<BoxContainer Orientation="Vertical" Margin="5 5 5 5">
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<RichTextLabel Name="NameLabel" VerticalAlignment="Bottom" HorizontalExpand="True"/>
|
||||
<TextureRect Name="TechTexture" VerticalAlignment="Center" HorizontalAlignment="Right"/>
|
||||
</BoxContainer>
|
||||
<customControls:HSeparator Margin="10 5 10 10"/>
|
||||
<RichTextLabel Name="DescriptionLabel"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</PanelContainer>
|
||||
</BoxContainer>
|
||||
@@ -0,0 +1,93 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Client.Guidebook.Richtext;
|
||||
using Content.Client.Message;
|
||||
using Content.Client.Research;
|
||||
using Content.Client.UserInterface.ControlExtensions;
|
||||
using Content.Shared.Research.Prototypes;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Guidebook.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Control for embedding a research technology into a guidebook.
|
||||
/// </summary>
|
||||
[UsedImplicitly, GenerateTypedNameReferences]
|
||||
public sealed partial class GuideTechnologyEmbed : BoxContainer, IDocumentTag, ISearchableControl
|
||||
{
|
||||
[Dependency] private readonly IEntitySystemManager _systemManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
|
||||
private readonly ResearchSystem _research;
|
||||
private readonly SpriteSystem _sprite;
|
||||
|
||||
public GuideTechnologyEmbed()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
_research = _systemManager.GetEntitySystem<ResearchSystem>();
|
||||
_sprite = _systemManager.GetEntitySystem<SpriteSystem>();
|
||||
MouseFilter = MouseFilterMode.Stop;
|
||||
}
|
||||
|
||||
public GuideTechnologyEmbed(string technology) : this()
|
||||
{
|
||||
GenerateControl(_prototype.Index<TechnologyPrototype>(technology));
|
||||
}
|
||||
|
||||
public GuideTechnologyEmbed(TechnologyPrototype technology) : this()
|
||||
{
|
||||
GenerateControl(technology);
|
||||
}
|
||||
|
||||
public bool CheckMatchesSearch(string query)
|
||||
{
|
||||
return this.ChildrenContainText(query);
|
||||
}
|
||||
|
||||
public void SetHiddenState(bool state, string query)
|
||||
{
|
||||
Visible = CheckMatchesSearch(query) ? state : !state;
|
||||
}
|
||||
|
||||
public bool TryParseTag(Dictionary<string, string> args, [NotNullWhen(true)] out Control? control)
|
||||
{
|
||||
control = null;
|
||||
if (!args.TryGetValue("Technology", out var id))
|
||||
{
|
||||
Logger.Error("Technology embed tag is missing technology prototype argument");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_prototype.TryIndex<TechnologyPrototype>(id, out var technology))
|
||||
{
|
||||
Logger.Error($"Specified technology prototype \"{id}\" is not a valid technology prototype");
|
||||
return false;
|
||||
}
|
||||
|
||||
GenerateControl(technology);
|
||||
|
||||
control = this;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void GenerateControl(TechnologyPrototype technology)
|
||||
{
|
||||
var discipline = _prototype.Index(technology.Discipline);
|
||||
|
||||
NameLabel.SetMarkup($"[bold]{Loc.GetString(technology.Name)}[/bold]");
|
||||
DescriptionLabel.SetMessage(_research.GetTechnologyDescription(technology, includePrereqs: true, disciplinePrototype: discipline));
|
||||
TechTexture.Texture = _sprite.Frame0(technology.Icon);
|
||||
|
||||
DisciplineColorBackground.PanelOverride = new StyleBoxFlat
|
||||
{
|
||||
BackgroundColor = discipline.Color
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -15,10 +16,13 @@ public sealed partial class MiniTechnologyCardControl : Control
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
var discipline = prototypeManager.Index<TechDisciplinePrototype>(technology.Discipline);
|
||||
var discipline = prototypeManager.Index(technology.Discipline);
|
||||
Background.ModulateSelfOverride = discipline.Color;
|
||||
Texture.Texture = spriteSys.Frame0(technology.Icon);
|
||||
NameLabel.SetMessage(Loc.GetString(technology.Name));
|
||||
Main.ToolTip = description.ToString();
|
||||
|
||||
var tooltip = new Tooltip();
|
||||
tooltip.SetMessage(description);
|
||||
Main.TooltipSupplier = _ => tooltip;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ public sealed partial class ResearchConsoleMenu : FancyWindow
|
||||
private readonly TechnologyDatabaseComponent? _technologyDatabase;
|
||||
private readonly ResearchSystem _research;
|
||||
private readonly SpriteSystem _sprite;
|
||||
private readonly AccessReaderSystem _accessReader = default!;
|
||||
private readonly AccessReaderSystem _accessReader;
|
||||
|
||||
public readonly EntityUid Entity;
|
||||
|
||||
@@ -55,7 +55,7 @@ public sealed partial class ResearchConsoleMenu : FancyWindow
|
||||
|
||||
foreach (var tech in allTech)
|
||||
{
|
||||
var mini = new MiniTechnologyCardControl(tech, _prototype, _sprite, GetTechnologyDescription(tech, false));
|
||||
var mini = new MiniTechnologyCardControl(tech, _prototype, _sprite, _research.GetTechnologyDescription(tech));
|
||||
AvailableCardsContainer.AddChild(mini);
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ public sealed partial class ResearchConsoleMenu : FancyWindow
|
||||
foreach (var techId in _technologyDatabase.CurrentTechnologyCards)
|
||||
{
|
||||
var tech = _prototype.Index<TechnologyPrototype>(techId);
|
||||
var cardControl = new TechnologyCardControl(tech, _prototype, _sprite, GetTechnologyDescription(tech), state.Points, hasAccess);
|
||||
var cardControl = new TechnologyCardControl(tech, _prototype, _sprite, _research.GetTechnologyDescription(tech, includeTier: false), state.Points, hasAccess);
|
||||
cardControl.OnPressed += () => OnTechnologyCardPressed?.Invoke(techId);
|
||||
TechnologyCardsContainer.AddChild(cardControl);
|
||||
}
|
||||
@@ -82,37 +82,11 @@ public sealed partial class ResearchConsoleMenu : FancyWindow
|
||||
foreach (var unlocked in _technologyDatabase.UnlockedTechnologies)
|
||||
{
|
||||
var tech = _prototype.Index<TechnologyPrototype>(unlocked);
|
||||
var cardControl = new MiniTechnologyCardControl(tech, _prototype, _sprite, GetTechnologyDescription(tech, false));
|
||||
var cardControl = new MiniTechnologyCardControl(tech, _prototype, _sprite, _research.GetTechnologyDescription(tech, false));
|
||||
UnlockedCardsContainer.AddChild(cardControl);
|
||||
}
|
||||
}
|
||||
|
||||
public FormattedMessage GetTechnologyDescription(TechnologyPrototype technology, bool includeCost = true)
|
||||
{
|
||||
var description = new FormattedMessage();
|
||||
if (includeCost)
|
||||
{
|
||||
description.AddMarkup(Loc.GetString("research-console-cost", ("amount", technology.Cost)));
|
||||
description.PushNewline();
|
||||
}
|
||||
description.AddMarkup(Loc.GetString("research-console-unlocks-list-start"));
|
||||
foreach (var recipe in technology.RecipeUnlocks)
|
||||
{
|
||||
var recipeProto = _prototype.Index<LatheRecipePrototype>(recipe);
|
||||
description.PushNewline();
|
||||
description.AddMarkup(Loc.GetString("research-console-unlocks-list-entry",
|
||||
("name",recipeProto.Name)));
|
||||
}
|
||||
foreach (var generic in technology.GenericUnlocks)
|
||||
{
|
||||
description.PushNewline();
|
||||
description.AddMarkup(Loc.GetString("research-console-unlocks-list-entry-generic",
|
||||
("name", Loc.GetString(generic.UnlockDescription))));
|
||||
}
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
public void UpdateInformationPanel(ResearchConsoleBoundInterfaceState state)
|
||||
{
|
||||
var amountMsg = new FormattedMessage();
|
||||
|
||||
@@ -72,7 +72,7 @@ public sealed class TechnologyDiskSystem : EntitySystem
|
||||
var tier = int.Parse(weightedRandom.Pick(_random));
|
||||
|
||||
//get a list of every distinct recipe in all the technologies.
|
||||
var techs = new List<string>();
|
||||
var techs = new List<ProtoId<LatheRecipePrototype>>();
|
||||
foreach (var tech in _prototype.EnumeratePrototypes<TechnologyPrototype>())
|
||||
{
|
||||
if (tech.Tier != tier)
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.Research.Prototypes;
|
||||
@@ -19,57 +17,57 @@ public sealed class TechnologyPrototype : IPrototype
|
||||
/// The name of the technology.
|
||||
/// Supports locale strings
|
||||
/// </summary>
|
||||
[DataField("name", required: true)]
|
||||
public string Name = string.Empty;
|
||||
[DataField(required: true)]
|
||||
public LocId Name = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// An icon used to visually represent the technology in UI.
|
||||
/// </summary>
|
||||
[DataField("icon", required: true)]
|
||||
[DataField(required: true)]
|
||||
public SpriteSpecifier Icon = default!;
|
||||
|
||||
/// <summary>
|
||||
/// What research discipline this technology belongs to.
|
||||
/// </summary>
|
||||
[DataField("discipline", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<TechDisciplinePrototype>))]
|
||||
public string Discipline = default!;
|
||||
[DataField(required: true)]
|
||||
public ProtoId<TechDisciplinePrototype> Discipline;
|
||||
|
||||
/// <summary>
|
||||
/// What tier research is this?
|
||||
/// The tier governs how much lower-tier technology
|
||||
/// needs to be unlocked before this one.
|
||||
/// </summary>
|
||||
[DataField("tier", required: true)]
|
||||
[DataField(required: true)]
|
||||
public int Tier;
|
||||
|
||||
/// <summary>
|
||||
/// Hidden tech is not ever available at the research console.
|
||||
/// </summary>
|
||||
[DataField("hidden")]
|
||||
[DataField]
|
||||
public bool Hidden;
|
||||
|
||||
/// <summary>
|
||||
/// How much research is needed to unlock.
|
||||
/// </summary>
|
||||
[DataField("cost")]
|
||||
[DataField]
|
||||
public int Cost = 10000;
|
||||
|
||||
/// <summary>
|
||||
/// A list of <see cref="TechnologyPrototype"/>s that need to be unlocked in order to unlock this technology.
|
||||
/// </summary>
|
||||
[DataField("technologyPrerequisites", customTypeSerializer: typeof(PrototypeIdListSerializer<TechnologyPrototype>))]
|
||||
public IReadOnlyList<string> TechnologyPrerequisites = new List<string>();
|
||||
[DataField]
|
||||
public List<ProtoId<TechnologyPrototype>> TechnologyPrerequisites = new();
|
||||
|
||||
/// <summary>
|
||||
/// A list of <see cref="LatheRecipePrototype"/>s that are unlocked by this technology
|
||||
/// </summary>
|
||||
[DataField("recipeUnlocks", customTypeSerializer: typeof(PrototypeIdListSerializer<LatheRecipePrototype>))]
|
||||
public IReadOnlyList<string> RecipeUnlocks = new List<string>();
|
||||
[DataField]
|
||||
public List<ProtoId<LatheRecipePrototype>> RecipeUnlocks = new();
|
||||
|
||||
/// <summary>
|
||||
/// A list of non-standard effects that are done when this technology is unlocked.
|
||||
/// </summary>
|
||||
[DataField("genericUnlocks")]
|
||||
[DataField]
|
||||
public IReadOnlyList<GenericUnlock> GenericUnlocks = new List<GenericUnlock>();
|
||||
}
|
||||
|
||||
@@ -80,13 +78,13 @@ public partial record struct GenericUnlock()
|
||||
/// What event is raised when this is unlocked?
|
||||
/// Used for doing non-standard logic.
|
||||
/// </summary>
|
||||
[DataField("purchaseEvent")]
|
||||
[DataField]
|
||||
public object? PurchaseEvent = null;
|
||||
|
||||
/// <summary>
|
||||
/// A player facing tooltip for what the unlock does.
|
||||
/// Supports locale strings.
|
||||
/// </summary>
|
||||
[DataField("unlockDescription")]
|
||||
[DataField]
|
||||
public string UnlockDescription = string.Empty;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using Content.Shared.Research.Components;
|
||||
using Content.Shared.Research.Prototypes;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.Research.Systems;
|
||||
|
||||
@@ -40,7 +41,7 @@ public abstract class SharedResearchSystem : EntitySystem
|
||||
|
||||
component.CurrentTechnologyCards.Add(selected.ID);
|
||||
}
|
||||
Dirty(component);
|
||||
Dirty(uid, component);
|
||||
}
|
||||
|
||||
public List<TechnologyPrototype> GetAvailableTechnologies(EntityUid uid, TechnologyDatabaseComponent? component = null)
|
||||
@@ -142,6 +143,59 @@ public abstract class SharedResearchSystem : EntitySystem
|
||||
return tier - 1;
|
||||
}
|
||||
|
||||
public FormattedMessage GetTechnologyDescription(
|
||||
TechnologyPrototype technology,
|
||||
bool includeCost = true,
|
||||
bool includeTier = true,
|
||||
bool includePrereqs = false,
|
||||
TechDisciplinePrototype? disciplinePrototype = null)
|
||||
{
|
||||
var description = new FormattedMessage();
|
||||
if (includeTier)
|
||||
{
|
||||
disciplinePrototype ??= PrototypeManager.Index(technology.Discipline);
|
||||
description.AddMarkup(Loc.GetString("research-console-tier-discipline-info",
|
||||
("tier", technology.Tier), ("color", disciplinePrototype.Color), ("discipline", Loc.GetString(disciplinePrototype.Name))));
|
||||
description.PushNewline();
|
||||
}
|
||||
|
||||
if (includeCost)
|
||||
{
|
||||
description.AddMarkup(Loc.GetString("research-console-cost", ("amount", technology.Cost)));
|
||||
description.PushNewline();
|
||||
}
|
||||
|
||||
if (includePrereqs && technology.TechnologyPrerequisites.Any())
|
||||
{
|
||||
description.AddMarkup(Loc.GetString("research-console-prereqs-list-start"));
|
||||
foreach (var recipe in technology.TechnologyPrerequisites)
|
||||
{
|
||||
var techProto = PrototypeManager.Index(recipe);
|
||||
description.PushNewline();
|
||||
description.AddMarkup(Loc.GetString("research-console-prereqs-list-entry",
|
||||
("text", Loc.GetString(techProto.Name))));
|
||||
}
|
||||
description.PushNewline();
|
||||
}
|
||||
|
||||
description.AddMarkup(Loc.GetString("research-console-unlocks-list-start"));
|
||||
foreach (var recipe in technology.RecipeUnlocks)
|
||||
{
|
||||
var recipeProto = PrototypeManager.Index(recipe);
|
||||
description.PushNewline();
|
||||
description.AddMarkup(Loc.GetString("research-console-unlocks-list-entry",
|
||||
("name",recipeProto.Name)));
|
||||
}
|
||||
foreach (var generic in technology.GenericUnlocks)
|
||||
{
|
||||
description.PushNewline();
|
||||
description.AddMarkup(Loc.GetString("research-console-unlocks-list-entry-generic",
|
||||
("text", Loc.GetString(generic.UnlockDescription))));
|
||||
}
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether a technology is unlocked on this database or not.
|
||||
/// </summary>
|
||||
|
||||
@@ -34,6 +34,7 @@ guide-entry-botanicals = Botanicals
|
||||
guide-entry-cloning = Cloning
|
||||
guide-entry-cryogenics = Cryogenics
|
||||
guide-entry-science = Science
|
||||
guide-entry-technologies = Technologies
|
||||
guide-entry-anomalous-research = Anomalous Research
|
||||
guide-entry-scanners-and-vessels = Scanners and Vessels
|
||||
guide-entry-ape = A.P.E.
|
||||
|
||||
@@ -14,5 +14,7 @@ research-console-cost = Cost: [color=orchid]{$amount}[/color]
|
||||
research-console-unlocks-list-start = Unlocks:
|
||||
research-console-unlocks-list-entry = - [color=yellow]{$name}[/color]
|
||||
research-console-unlocks-list-entry-generic = - [color=green]{$text}[/color]
|
||||
research-console-prereqs-list-start = Requires:
|
||||
research-console-prereqs-list-entry = - [color=orchid]{$text}[/color]
|
||||
|
||||
research-console-no-access-popup = No access!
|
||||
|
||||
@@ -3,11 +3,18 @@
|
||||
name: guide-entry-science
|
||||
text: "/ServerInfo/Guidebook/Science/Science.xml"
|
||||
children:
|
||||
- Technologies
|
||||
- AnomalousResearch
|
||||
- Xenoarchaeology
|
||||
- Robotics
|
||||
- MachineUpgrading
|
||||
|
||||
- type: guideEntry
|
||||
id: Technologies
|
||||
name: guide-entry-technologies
|
||||
text: "/ServerInfo/Guidebook/Science/Technologies.xml"
|
||||
filterEnabled: True
|
||||
|
||||
- type: guideEntry
|
||||
id: AnomalousResearch
|
||||
name: guide-entry-anomalous-research
|
||||
|
||||
@@ -10,7 +10,9 @@ Science, often called Research and Development, is a job made up of both generat
|
||||
</Box>
|
||||
The most important thing inside your department is the R&D server, which stores unlocked technologies, and the R&D computer, which allows you to unlock technologies.
|
||||
|
||||
Each technology costs [color=#a4885c]Research Points[/color] and unlocks recipes at lathes. Some technologies will also have prerequesites you have to unlock before you can research them.
|
||||
Each technology costs [color=#a4885c]Research Points[/color] and unlocks recipes at lathes. Some technologies will also have prerequisites you have to unlock before you can research them.
|
||||
|
||||
Information about the different technologies can be viewed [textlink="on the technology guidebook page" link="Technologies"].
|
||||
|
||||
## Disciplines
|
||||
Technologies are spread over 5 different Disciplines:
|
||||
|
||||
23
Resources/ServerInfo/Guidebook/Science/Technologies.xml
Normal file
23
Resources/ServerInfo/Guidebook/Science/Technologies.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<Document>
|
||||
# Technologies
|
||||
|
||||
All technologies have a cost and a tier requirement in order to be researched. Unlocking them adds a variety of recipes that can be printed at various lathes.
|
||||
|
||||
The different technologies and their respective discipline are listed below.
|
||||
|
||||
## Industrial
|
||||
<GuideTechDisciplineEmbed Discipline="Industrial"/>
|
||||
|
||||
## Biochemical
|
||||
<GuideTechDisciplineEmbed Discipline="Biochemical"/>
|
||||
|
||||
## Arsenal
|
||||
<GuideTechDisciplineEmbed Discipline="Arsenal"/>
|
||||
|
||||
## Experimental
|
||||
<GuideTechDisciplineEmbed Discipline="Experimental"/>
|
||||
|
||||
## Civilian Services
|
||||
<GuideTechDisciplineEmbed Discipline="CivilianServices"/>
|
||||
|
||||
</Document>
|
||||
Reference in New Issue
Block a user