Torches + Cotton (#1246)

* torches add, wallmount crystals deletion

* cotton

* Update buy.yml

* craftis

* delete elemental quartz

* energy crystal resprite and rewamp

* fix

* Update misc.yml

* а

* delete rituals

* riat

* Update migration.yml

* Delete CP14ClientRitualSystem.cs

* Update statues.yml

* fix

* Update wallmount_lamp.yml

* fix
This commit is contained in:
Ed
2025-04-30 17:28:38 +03:00
committed by GitHub
parent ad2fc18356
commit 2358bc46d6
127 changed files with 520 additions and 2831 deletions

View File

@@ -1,35 +0,0 @@
using Content.Shared._CP14.MagicRitual;
using Robust.Client.GameObjects;
namespace Content.Server._CP14.MagicRituals;
public partial class CP14ClientRitualSystem : CP14SharedRitualSystem
{
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CP14MagicRitualComponent, AppearanceChangeEvent>(OnAppearanceChange);
}
private void OnAppearanceChange(Entity<CP14MagicRitualComponent> ent, ref AppearanceChangeEvent args)
{
if (args.Sprite == null)
return;
if (!args.Sprite.LayerMapTryGet(ent.Comp.RitualLayerMap, out var ritualLayer))
return;
if (_appearance.TryGetData<Color>(ent, RitualVisuals.Color, out var ritualColor, args.Component))
{
args.Sprite.LayerSetColor(ritualLayer, ritualColor);
}
if (_appearance.TryGetData<bool>(ent, RitualVisuals.Enabled, out var enabled, args.Component))
{
args.Sprite.LayerSetVisible(ritualLayer, enabled);
}
}
}

View File

@@ -1,53 +0,0 @@
using Content.Shared._CP14.MagicRitual;
using Robust.Shared.GameObjects;
using Robust.Shared.Prototypes;
namespace Content.IntegrationTests.Tests._CP14;
#nullable enable
[TestFixture]
public sealed class CP14RitualTest
{
/// <summary>
/// States that all edges of the ritual phase have triggers.
/// </summary>
[Test]
public async Task RitualHasAllTriggersTest()
{
await using var pair = await PoolManager.GetServerClient();
var server = pair.Server;
var compFactory = server.ResolveDependency<IComponentFactory>();
var protoManager = server.ResolveDependency<IPrototypeManager>();
await server.WaitAssertion(() =>
{
Assert.Multiple(() =>
{
foreach (var proto in protoManager.EnumeratePrototypes<EntityPrototype>())
{
if (!proto.TryGetComponent(out CP14MagicRitualPhaseComponent? phase, compFactory))
continue;
if (phase.DeadEnd)
{
Assert.That(phase.Edges.Count == 0, $"{proto} is a ritual node, but has no paths to other nodes. Either add deadEnd = true, or add paths to other nodes.");
}
else
{
Assert.That(phase.Edges.Count > 0, $"{proto} is a deadEnd ritual node, but has {phase.Edges.Count} edges! Remove all edges, or make it a non dead-end node");
}
foreach (var edge in phase.Edges)
{
Assert.That(edge.Triggers.Count > 0, $"{proto} is ritual node, but edge to {edge.Target} has no triggers and cannot be activated.");
}
}
});
});
await pair.CleanReturnAsync();
}
}

View File

@@ -59,7 +59,7 @@ public partial class CP14MagicEnergySystem
if (TryComp<MobStateComponent>(uid, out var mobState) && !_mobState.IsAlive(uid, mobState))
continue;
draw.NextUpdateTime = _gameTiming.CurTime + TimeSpan.FromSeconds(draw.Delay);
draw.NextUpdateTime += TimeSpan.FromSeconds(draw.Delay);
ChangeEnergy((uid, magicContainer), draw.Energy, out _, out _, draw.Safe);
}

View File

@@ -1,86 +0,0 @@
using Content.Shared._CP14.MagicRitual;
using Content.Shared._CP14.MagicRitualTrigger.Triggers;
using Content.Shared.Humanoid;
using Content.Shared.Mobs;
using Content.Shared.Whitelist;
namespace Content.Server._CP14.MagicRitualTrigger;
public partial class CP14RitualTriggerSystem
{
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
private void InitializeSacrifice()
{
SubscribeLocalEvent<MobStateChangedEvent>(OnMobStateChanged);
}
private void OnMobStateChanged(MobStateChangedEvent ev)
{
if (ev.NewMobState != MobState.Dead)
return;
var deathXform = Transform(ev.Target);
SacrificeSpecies(ev, deathXform);
SacrificeWhitelist(ev, deathXform);
}
private void SacrificeSpecies(MobStateChangedEvent ev, TransformComponent deathXform)
{
if (!TryComp<HumanoidAppearanceComponent>(ev.Target, out var humanoid))
return;
var query = EntityQueryEnumerator<CP14RitualSacrificeSpeciesTriggerComponent, CP14MagicRitualPhaseComponent, TransformComponent>();
while (query.MoveNext(out var uid, out var sacrifice, out var phase, out var xform))
{
if (!deathXform.Coordinates.TryDistance(EntityManager, xform.Coordinates, out var distance))
continue;
foreach (var trigger in sacrifice.Triggers)
{
if (distance > trigger.Range)
continue;
if (trigger.Edge is null)
continue;
if (trigger.Species != humanoid.Species)
continue;
TriggerRitualPhase((uid, phase), trigger.Edge.Value.Target);
}
}
}
private void SacrificeWhitelist(MobStateChangedEvent ev, TransformComponent deathXform)
{
var query = EntityQueryEnumerator<CP14RitualSacrificeWhitelistTriggerComponent, CP14MagicRitualPhaseComponent, TransformComponent>();
while (query.MoveNext(out var uid, out var sacrifice, out var phase, out var xform))
{
if (!deathXform.Coordinates.TryDistance(EntityManager, xform.Coordinates, out var distance))
continue;
foreach (var trigger in sacrifice.Triggers)
{
if (distance > trigger.Range)
continue;
if (trigger.Edge is null)
continue;
var entProto = MetaData(ev.Target).EntityPrototype;
if (entProto is null)
continue;
if (!_whitelist.IsValid(trigger.Whitelist, ev.Target))
continue;
TriggerRitualPhase((uid, phase), trigger.Edge.Value.Target);
}
}
}
}

View File

@@ -1,43 +0,0 @@
using Content.Shared._CP14.MagicRitual;
using Content.Shared._CP14.MagicRitualTrigger.Triggers;
using Robust.Shared.Timing;
namespace Content.Server._CP14.MagicRitualTrigger;
public partial class CP14RitualTriggerSystem
{
[Dependency] private readonly IGameTiming _timing = default!;
private void InitializeTimer()
{
SubscribeLocalEvent<CP14RitualTimerTriggerComponent, MapInitEvent>(OnMapInit);
}
private void OnMapInit(Entity<CP14RitualTimerTriggerComponent> ent, ref MapInitEvent args)
{
foreach (var trigger in ent.Comp.Triggers)
{
trigger.TriggerTime = _timing.CurTime + TimeSpan.FromSeconds(trigger.Delay);
}
}
private void UpdateTimer(float frameTime)
{
var query = EntityQueryEnumerator<CP14RitualTimerTriggerComponent, CP14MagicRitualPhaseComponent>();
while (query.MoveNext(out var uid, out var timer, out var phase))
{
foreach (var trigger in timer.Triggers)
{
if (_timing.CurTime < trigger.TriggerTime || trigger.TriggerTime == TimeSpan.Zero)
continue;
if (trigger.Edge is null)
continue;
TriggerRitualPhase((uid, phase), trigger.Edge.Value.Target);
trigger.TriggerTime = TimeSpan.Zero;
}
}
}
}

View File

@@ -1,36 +0,0 @@
using System.Text.RegularExpressions;
using Content.Server.Speech;
using Content.Shared._CP14.MagicRitual;
using Content.Shared._CP14.MagicRitualTrigger.Triggers;
namespace Content.Server._CP14.MagicRitualTrigger;
public partial class CP14RitualTriggerSystem
{
private void InitializeVoice()
{
SubscribeLocalEvent<CP14RitualVoiceTriggerComponent, ListenEvent>(OnListenEvent);
}
private void OnListenEvent(Entity<CP14RitualVoiceTriggerComponent> ent, ref ListenEvent args)
{
if (!TryComp<CP14MagicRitualPhaseComponent>(ent, out var phase))
return;
// Lowercase the phrase and remove all punctuation marks
var message = Regex.Replace(args.Message.Trim().ToLower(), @"[^\w\s]", "");
foreach (var trigger in ent.Comp.Triggers)
{
var triggerMessage = Regex.Replace(trigger.Message.ToLower(), @"[^\w\s]", "");
if (triggerMessage != message)
continue;
if (trigger.Edge is null)
continue;
TriggerRitualPhase((ent.Owner, phase), trigger.Edge.Value.Target);
}
}
}

View File

@@ -1,28 +0,0 @@
using Content.Shared._CP14.MagicRitual;
using Content.Shared._CP14.MagicRitualTrigger;
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.MagicRitualTrigger;
public partial class CP14RitualTriggerSystem : CP14SharedRitualTriggerSystem
{
public override void Initialize()
{
InitializeTimer();
InitializeVoice();
InitializeSacrifice();
}
public override void Update(float frameTime)
{
base.Update(frameTime);
UpdateTimer(frameTime);
}
private void TriggerRitualPhase(Entity<CP14MagicRitualPhaseComponent> ent, EntProtoId nextPhase)
{
var evConfirmed = new CP14RitualTriggerEvent(nextPhase);
RaiseLocalEvent(ent, evConfirmed);
}
}

View File

@@ -1,167 +0,0 @@
using System.Text;
using Content.Server._CP14.MagicRituals.Components;
using Content.Shared._CP14.MagicRitual;
using Content.Shared.Paper;
using Content.Shared.Verbs;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.MagicRituals;
public sealed partial class CP14RitualSystem
{
[Dependency] private readonly PaperSystem _paper = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
private void InitializeDescriber()
{
SubscribeLocalEvent<CP14PaperPhaseDescriberComponent, GetVerbsEvent<Verb>>(OnDescriberVerbs);
SubscribeLocalEvent<CP14PaperPhaseDescriberComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<CP14PaperPhaseDescriberComponent, ComponentShutdown>(OnShutdown);
}
private void OnShutdown(Entity<CP14PaperPhaseDescriberComponent> ent, ref ComponentShutdown args)
{
QueueDel(ent.Comp.CurrentPhase);
}
private void OnMapInit(Entity<CP14PaperPhaseDescriberComponent> ent, ref MapInitEvent args)
{
SetPhase(ent, ent.Comp.StartPhase);
}
private void SetPhase(Entity<CP14PaperPhaseDescriberComponent> ent, EntProtoId newProto, bool saveHistory = true)
{
var oldPhase = ent.Comp.CurrentPhase;
if (oldPhase is not null && saveHistory)
{
var oldProto = MetaData(oldPhase.Value).EntityPrototype;
if (oldProto is not null && oldProto != newProto)
{
ent.Comp.SearchHistory.Add(oldProto);
if (ent.Comp.SearchHistory.Count > 50)
ent.Comp.SearchHistory.RemoveAt(0);
}
}
QueueDel(oldPhase);
var newPhase = Spawn(newProto, MapCoordinates.Nullspace);
ent.Comp.CurrentPhase = newPhase;
if (!TryComp<PaperComponent>(ent, out var paper))
return;
_paper.SetContent((ent, paper), GetPhaseDescription(newPhase));
_audio.PlayPvs(ent.Comp.UseSound, ent);
}
private void BackPhase(Entity<CP14PaperPhaseDescriberComponent> ent)
{
if (ent.Comp.SearchHistory.Count > 0)
SetPhase(ent, ent.Comp.SearchHistory[^1], false);
}
private void OnDescriberVerbs(Entity<CP14PaperPhaseDescriberComponent> ent, ref GetVerbsEvent<Verb> args)
{
if (!args.CanAccess || !args.CanInteract)
return;
if (!TryComp<CP14MagicRitualPhaseComponent>(ent.Comp.CurrentPhase, out var phase))
return;
if (!TryComp<CP14MagicRitualPhaseComponent>(ent.Comp.CurrentPhase.Value, out var phaseComp))
return;
foreach (var edge in phaseComp.Edges)
{
if (!_proto.TryIndex(edge.Target, out var indexedTarget))
continue;
Verb verb = new()
{
Text = Loc.GetString("cp14-ritual-describer-verb-item", ("name", indexedTarget.Name)),
Category = VerbCategory.CP14RitualBook,
Priority = 1,
Act = () => SetPhase(ent, edge.Target),
};
args.Verbs.Add(verb);
}
foreach (var hyperlink in ent.Comp.Hyperlinks)
{
if (!_proto.TryIndex(hyperlink, out var indexedTarget))
continue;
Verb verb = new()
{
Text = Loc.GetString("cp14-ritual-describer-verb-hyperlink", ("name", indexedTarget.Name)),
Category = VerbCategory.CP14RitualBook,
Priority = 0,
Act = () => SetPhase(ent, hyperlink),
};
args.Verbs.Add(verb);
}
if (ent.Comp.SearchHistory.Count > 0)
{
Verb verb = new()
{
Text = Loc.GetString("cp14-ritual-describer-verb-back"),
Category = VerbCategory.CP14RitualBook,
Priority = -1,
Act = () => BackPhase(ent),
};
args.Verbs.Add(verb);
}
}
private string GetPhaseDescription(EntityUid uid)
{
if (!TryComp<CP14MagicRitualPhaseComponent>(uid, out var phase))
return string.Empty;
return GetPhaseDescription((uid, phase));
}
private string GetPhaseDescription(Entity<CP14MagicRitualPhaseComponent> ent)
{
var sb = new StringBuilder();
sb.Append($"[color=#e6a132][head=1]{MetaData(ent).EntityName}[/head][/color] \n \n");
sb.Append($"[italic]{MetaData(ent).EntityDescription}[/italic] \n \n");
sb.Append(Loc.GetString("cp14-ritual-intro") + "\n \n \n");
foreach (var edge in ent.Comp.Edges)
{
if (!_proto.TryIndex(edge.Target, out var targetIndexed))
continue;
sb.Append($"[color=#b5783c][head=3]{targetIndexed.Name}[/head][/color]" + "\n");
//TRIGGERS
if (edge.Triggers.Count > 0)
{
sb.Append($"[bold]{Loc.GetString("cp14-ritual-trigger-header")}[/bold] \n");
foreach (var trigger in edge.Triggers)
sb.Append(trigger.GetGuidebookTriggerDescription(_proto, _entitySystem) + "\n");
}
//REQUIREMENTS
if (edge.Requirements.Count > 0)
{
sb.Append($"[bold]{Loc.GetString("cp14-ritual-req-header")}[/bold] \n");
foreach (var req in edge.Requirements)
sb.Append(req.GetGuidebookRequirementDescription(_proto, _entitySystem) + "\n");
}
//ACTIONS
if (edge.Actions.Count > 0)
{
sb.Append($"[bold]{Loc.GetString("cp14-ritual-effect-header")}[/bold] \n");
foreach (var act in edge.Actions)
sb.Append(act.GetGuidebookEffectDescription(_proto, _entitySystem) + "\n");
}
}
return sb.ToString();
}
}

View File

@@ -1,22 +0,0 @@
using Content.Shared._CP14.MagicRitual;
using Robust.Server.GameObjects;
namespace Content.Server._CP14.MagicRituals;
public sealed partial class CP14RitualSystem
{
[Dependency] private readonly AppearanceSystem _appearance = default!;
private void InitializeVisuals()
{
SubscribeLocalEvent<CP14MagicRitualPhaseComponent, CP14RitualPhaseBoundEvent>(OnPhaseBound);
}
private void OnPhaseBound(Entity<CP14MagicRitualPhaseComponent> ent, ref CP14RitualPhaseBoundEvent args)
{
if (!TryComp<CP14MagicRitualComponent>(args.Ritual, out var ritual))
return;
_pointLight.SetColor(ent, ent.Comp.PhaseColor);
_appearance.SetData(args.Ritual, RitualVisuals.Color, ent.Comp.PhaseColor);
}
}

View File

@@ -1,201 +0,0 @@
using System.Text;
using Content.Server.Speech.Components;
using Content.Shared._CP14.MagicRitual;
using Content.Shared.DoAfter;
using Content.Shared.Examine;
using Content.Shared.Verbs;
using Robust.Server.GameObjects;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Timing;
namespace Content.Server._CP14.MagicRituals;
public partial class CP14RitualSystem : CP14SharedRitualSystem
{
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
[Dependency] private readonly IEntitySystemManager _entitySystem = default!;
[Dependency] private readonly PointLightSystem _pointLight = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly TransformSystem _transform = default!;
public override void Initialize()
{
base.Initialize();
InitializeDescriber();
InitializeVisuals();
SubscribeLocalEvent<CP14MagicRitualComponent, CP14ActivateRitualDoAfter>(OnActivateRitual);
SubscribeLocalEvent<CP14MagicRitualComponent, GetVerbsEvent<AlternativeVerb>>(OnAlternativeVerb);
SubscribeLocalEvent<CP14MagicRitualPhaseComponent, CP14RitualTriggerEvent>(OnPhaseTrigger);
SubscribeLocalEvent<CP14MagicRitualOrbComponent, ExaminedEvent>(OnOrbExamine);
}
private void OnActivateRitual(Entity<CP14MagicRitualComponent> ent, ref CP14ActivateRitualDoAfter args)
{
//if (args.Cancelled || args.Handled)
// return;
//
//args.Handled = true;
//
//StartRitual(ent);
}
private void OnAlternativeVerb(Entity<CP14MagicRitualComponent> ent, ref GetVerbsEvent<AlternativeVerb> args)
{
//if (!args.CanInteract || ent.Comp.CurrentPhase is not null)
// return;
//
//var user = args.User;
//AlternativeVerb verb = new()
//{
// Act = () =>
// {
// var doAfterArgs =
// new DoAfterArgs(EntityManager, user, ent.Comp.ActivationTime, new CP14ActivateRitualDoAfter(), ent, ent)
// {
// BreakOnDamage = true,
// BreakOnMove = true,
// };
//
// _doAfter.TryStartDoAfter(doAfterArgs);
// },
// Text = Loc.GetString("cp14-ritual-verb-text"),
// Priority = 1,
//};
//args.Verbs.Add(verb);
}
private void OnOrbExamine(Entity<CP14MagicRitualOrbComponent> ent, ref ExaminedEvent args)
{
//var sb = new StringBuilder();
//sb.Append(Loc.GetString("cp14-ritual-orb-examine", ("name", MetaData(ent).EntityName)) + "\n");
//foreach (var orbType in ent.Comp.Powers)
//{
// if (!_proto.TryIndex(orbType.Key, out var indexedType))
// continue;
//
// sb.Append($"[color={indexedType.Color.ToHex()}]");
// sb.Append(Loc.GetString("cp14-ritual-entry-item",
// ("name", Loc.GetString(indexedType.Name)),
// ("count", orbType.Value)));
// sb.Append($"[/color] \n");
//}
//
//args.PushMarkup(sb.ToString());
}
private void OnPhaseTrigger(Entity<CP14MagicRitualPhaseComponent> phase, ref CP14RitualTriggerEvent args)
{
//if (phase.Comp.Ritual is null)
// return;
//
//if (!TryComp<CP14MagicRitualComponent>(phase, out var ritualComp))
// return;
//
//RitualPhaseEdge? selectedEdge = null;
//foreach (var edge in phase.Comp.Edges)
//{
// if (edge.Target == args.NextPhase)
// {
// selectedEdge = edge;
// break;
// }
//}
//
//if (selectedEdge is null)
// return;
//
//var passed = true;
//foreach (var req in selectedEdge.Value.Requirements)
//{
// if (!req.Check(EntityManager, phase, ritualComp.Stability)) //lol
// {
// ChangeRitualStability(phase.Comp.Ritual.Value, -req.FailStabilityCost);
// passed = false;
// break;
// }
//}
//
//if (!passed)
// return;
//
//foreach (var action in selectedEdge.Value.Actions)
//{
// action.Effect(EntityManager, _transform, phase);
//}
//
//ChangePhase(phase.Comp.Ritual.Value, args.NextPhase);
}
public void StartRitual(EntityUid uid, CP14MagicRitualComponent? ritual = null)
{
//if (!Resolve(uid, ref ritual, false))
// return;
//
//EndRitual(uid);
//
//var ev = new CP14RitualStartEvent(uid);
//RaiseLocalEvent(uid, ev);
//
//ChangePhase(uid, ritual.StartPhase);
//_appearance.SetData(uid, RitualVisuals.Enabled, true);
}
private void ChangePhase(EntityUid uid, EntProtoId newPhase, CP14MagicRitualComponent? ritual = null)
{
//if (!Resolve(uid, ref ritual, false))
// return;
//
//QueueDel(ritual.CurrentPhase);
//
//var newPhaseEnt = Spawn(newPhase, Transform(uid).Coordinates);
//_transform.SetParent(newPhaseEnt, uid);
//var newPhaseComp = EnsureComp<CP14MagicRitualPhaseComponent>(newPhaseEnt);
//
//ritual.CurrentPhase = newPhaseEnt;
//newPhaseComp.Ritual = uid;
//
//foreach (var edge in newPhaseComp.Edges)
//{
// foreach (var trigger in edge.Triggers)
// {
// trigger.Initialize(EntityManager, ritual.CurrentPhase.Value, edge);
// }
//}
//
//var ev = new CP14RitualPhaseBoundEvent(uid, newPhaseEnt);
//RaiseLocalEvent(uid, ev);
//RaiseLocalEvent(newPhaseEnt, ev);
//
//if (newPhaseComp.DeadEnd)
// EndRitual(uid);
}
public void EndRitual(EntityUid uid, CP14MagicRitualComponent? ritual = null)
{
//if (!Resolve(uid, ref ritual, false))
// return;
//
//if (ritual.CurrentPhase is null)
// return;
//
//QueueDel(ritual.CurrentPhase);
//ritual.CurrentPhase = null;
//
//var ev = new CP14RitualEndEvent(uid);
//RaiseLocalEvent(uid, ev);
//
//_appearance.SetData(uid, RitualVisuals.Enabled, false);
//
//foreach (var orb in ritual.Orbs)
//{
// QueueDel(orb);
//}
}
}

View File

@@ -1,31 +0,0 @@
using Content.Shared._CP14.MagicRitual;
using Robust.Shared.Audio;
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.MagicRituals.Components;
/// <summary>
///
/// </summary>
[RegisterComponent, Access(typeof(CP14RitualSystem))]
public sealed partial class CP14PaperPhaseDescriberComponent : Component
{
[DataField(required: true)]
public EntProtoId StartPhase = default!;
[DataField]
public EntityUid? CurrentPhase = null;
public List<EntProtoId> SearchHistory = new();
[DataField]
public List<EntProtoId> Hyperlinks = new();
public SoundSpecifier UseSound = new SoundCollectionSpecifier("CP14Book")
{
Params = AudioParams.Default
.WithVariation(0.05f)
.WithVolume(0.5f),
};
}

View File

@@ -37,7 +37,10 @@ public sealed partial class CP14FireplaceComponent : Component
public float FuelDrainingPerUpdate = 1f;
[DataField]
public TimeSpan UpdateFrequency = TimeSpan.FromSeconds(2f);
public bool DeleteOnEmpty = false;
[DataField]
public TimeSpan UpdateFrequency = TimeSpan.FromSeconds(1f);
[DataField]
public TimeSpan NextUpdateTime = TimeSpan.Zero;

View File

@@ -88,7 +88,7 @@ public sealed partial class CP14FireplaceSystem : EntitySystem
if (_timing.CurTime <= fireplace.NextUpdateTime)
continue;
fireplace.NextUpdateTime = _timing.CurTime + fireplace.UpdateFrequency;
fireplace.NextUpdateTime += fireplace.UpdateFrequency;
if (fireplace.Fuel >= fireplace.FuelDrainingPerUpdate)
{
@@ -102,6 +102,12 @@ public sealed partial class CP14FireplaceSystem : EntitySystem
ConsumeFuel(uid, fireplace, fuel.Value);
flammable.FirestackFade = -fireplace.FireFadeDelta;
if (flammable.FireStacks == 0 && fireplace.DeleteOnEmpty)
{
QueueDel(uid);
return;
}
}
}
}

View File

@@ -1,44 +0,0 @@
using System.Text;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitual.Actions;
/// <summary>
/// Adds a key-orb to the ritual.
/// </summary>
public sealed partial class AddOrb : CP14RitualAction
{
[DataField(required: true)]
public Dictionary<EntProtoId, int> Orbs = new();
public override string? GetGuidebookEffectDescription(IPrototypeManager prototype, IEntitySystemManager entSys)
{
var sb = new StringBuilder();
sb.Append(Loc.GetString("cp14-ritual-effect-add-orb")+ "\n");
foreach (var orb in Orbs)
{
if (!prototype.TryIndex(orb.Key, out var indexedOrb))
continue;
sb.Append(Loc.GetString("cp14-ritual-entry-item", ("name", indexedOrb.Name), ("count", orb.Value)) + "\n");
}
return sb.ToString();
}
public override void Effect(EntityManager entManager, SharedTransformSystem transform, Entity<CP14MagicRitualPhaseComponent> phase)
{
if (phase.Comp.Ritual is null)
return;
var ritual = entManager.System<CP14SharedRitualSystem>();
foreach (var orb in Orbs)
{
for (var i = 0; i < orb.Value; i++)
{
ritual.AddOrbToRitual(phase.Comp.Ritual.Value, orb.Key);
}
}
}
}

View File

@@ -1,75 +0,0 @@
using System.Text;
using Content.Shared.EntityEffects;
using Content.Shared.Whitelist;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitual.Actions;
/// <summary>
/// Filters the nearest X entities by whitelist and applies the specified EntityEffects on them
/// </summary>
public sealed partial class ApplyEntityEffect : CP14RitualAction
{
[DataField]
public float CheckRange = 1f;
[DataField]
public EntityWhitelist? Whitelist;
[DataField]
public LocId? WhitelistDesc;
[DataField(required: true, serverOnly: true)]
public List<EntityEffect> Effects = new();
[DataField]
public int MaxEntities = 1;
public override string? GetGuidebookEffectDescription(IPrototypeManager prototype, IEntitySystemManager entSys)
{
var sb = new StringBuilder();
sb.Append(Loc.GetString("cp14-ritual-range", ("range", CheckRange)) + "\n");
sb.Append(Loc.GetString("cp14-ritual-effect-apply-effect", ("count", MaxEntities), ("range", CheckRange)) + "\n");
if (WhitelistDesc is not null)
{
sb.Append(Loc.GetString(WhitelistDesc));
sb.Append("\n");
}
foreach (var effect in Effects)
{
sb.Append("- " + effect.GuidebookEffectDescription(prototype, entSys) + "\n");
}
sb.Append("\n");
return sb.ToString();
}
public override void Effect(EntityManager entManager, SharedTransformSystem transform, Entity<CP14MagicRitualPhaseComponent> phase)
{
var lookup = entManager.System<EntityLookupSystem>();
var whitelist = entManager.System<EntityWhitelistSystem>();
var entitiesAround = lookup.GetEntitiesInRange(phase, CheckRange, LookupFlags.Uncontained);
var count = 0;
foreach (var entity in entitiesAround)
{
if (Whitelist is not null && !whitelist.IsValid(Whitelist, entity))
continue;
foreach (var effect in Effects)
{
effect.Effect(new EntityEffectBaseArgs(entity, entManager));
}
entManager.Spawn(VisualEffect, transform.GetMapCoordinates(entity));
count++;
if (count >= MaxEntities)
break;
}
}
}

View File

@@ -1,19 +0,0 @@
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitual.Actions;
[ImplicitDataDefinitionForInheritors]
[MeansImplicitUse]
public abstract partial class CP14RitualAction
{
/// <summary>
/// Effect appearing in place of interacted entities
/// </summary>
[DataField("vfx")]
public EntProtoId? VisualEffect = "CP14DustEffect";
public abstract void Effect(EntityManager entManager, SharedTransformSystem transform, Entity<CP14MagicRitualPhaseComponent> phase);
public abstract string? GetGuidebookEffectDescription(IPrototypeManager prototype, IEntitySystemManager entSys);
}

View File

@@ -1,41 +0,0 @@
using System.Text;
using Content.Shared._CP14.MagicRitual.Prototypes;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitual.Actions;
/// <summary>
/// Removes the orb key from the ritual.
/// </summary>
public sealed partial class ConsumeOrb : CP14RitualAction
{
[DataField(required: true)]
public ProtoId<CP14MagicTypePrototype> MagicType = new();
[DataField(required: true)]
public int Count = 0;
public override string? GetGuidebookEffectDescription(IPrototypeManager prototype, IEntitySystemManager entSys)
{
if (!prototype.TryIndex(MagicType, out var indexedType))
return null;
var sb = new StringBuilder();
sb.Append(Loc.GetString("cp14-ritual-effect-consume-orb", ("name", Loc.GetString(indexedType.Name)), ("count", Count))+ "\n");
return sb.ToString();
}
public override void Effect(EntityManager entManager, SharedTransformSystem transform, Entity<CP14MagicRitualPhaseComponent> phase)
{
if (phase.Comp.Ritual is null)
return;
var ritual = entManager.System<CP14SharedRitualSystem>();
for (var i = 0; i < Count; i++)
{
ritual.ConsumeOrbType(phase.Comp.Ritual.Value, MagicType);
}
}
}

View File

@@ -1,104 +0,0 @@
using System.Text;
using Content.Shared.Stacks;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitual.Actions;
public sealed partial class ConsumeResource : CP14RitualAction
{
[DataField]
public float CheckRange = 1f;
[DataField]
public Dictionary<EntProtoId, int> RequiredEntities = new ();
[DataField]
public Dictionary<ProtoId<StackPrototype>, int> RequiredStacks = new();
public override string? GetGuidebookEffectDescription(IPrototypeManager prototype, IEntitySystemManager entSys)
{
var sb = new StringBuilder();
sb.Append(Loc.GetString("cp14-ritual-effect-consume-resource", ("range", CheckRange)) + "\n");
foreach (var entity in RequiredEntities)
{
if (!prototype.TryIndex(entity.Key, out var indexed))
continue;
sb.Append(Loc.GetString("cp14-ritual-entry-item", ("name", indexed.Name), ("count", entity.Value)) + "\n");
}
foreach (var stack in RequiredStacks)
{
if (!prototype.TryIndex(stack.Key, out var indexed))
continue;
sb.Append(Loc.GetString("cp14-ritual-entry-item", ("name", Loc.GetString(indexed.Name)), ("count", stack.Value)) + "\n");
}
return sb.ToString();
}
public override void Effect(EntityManager entManager, SharedTransformSystem transform, Entity<CP14MagicRitualPhaseComponent> phase)
{
var lookup = entManager.System<EntityLookupSystem>();
var stack = entManager.System<SharedStackSystem>();
var entitiesAround = lookup.GetEntitiesInRange(phase, CheckRange, LookupFlags.Uncontained);
foreach (var reqEnt in RequiredEntities)
{
var requiredCount = reqEnt.Value;
foreach (var entity in entitiesAround)
{
if (!entManager.TryGetComponent<MetaDataComponent>(entity, out var metaData))
continue;
if (!entManager.HasComponent<TransformComponent>(entity))
continue;
var entProto = metaData.EntityPrototype;
if (entProto is null)
continue;
if (entProto.ID == reqEnt.Key && requiredCount > 0)
{
if (VisualEffect is not null)
entManager.Spawn(VisualEffect.Value, transform.GetMapCoordinates(entity));
entManager.DeleteEntity(entity);
requiredCount--;
}
}
}
foreach (var reqStack in RequiredStacks)
{
var requiredCount = reqStack.Value;
foreach (var entity in entitiesAround)
{
if (!entManager.TryGetComponent<StackComponent>(entity, out var stackComp))
continue;
if (stackComp.StackTypeId != reqStack.Key)
continue;
var count = (int)MathF.Min(requiredCount, stackComp.Count);
if (stackComp.Count - count <= 0)
entManager.DeleteEntity(entity);
else
stack.SetCount(entity, stackComp.Count - count, stackComp);
requiredCount -= count;
if (VisualEffect is not null)
entManager.Spawn(VisualEffect.Value, transform.GetMapCoordinates(entity));
}
}
}
}

View File

@@ -1,27 +0,0 @@
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitual.Actions;
public sealed partial class EditStability : CP14RitualAction
{
[DataField(required: true)]
public float Mod;
public override void Effect(EntityManager entManager, SharedTransformSystem transform, Entity<CP14MagicRitualPhaseComponent> phase)
{
var ritual = entManager.System<CP14SharedRitualSystem>();
if (phase.Comp.Ritual is not null)
ritual.ChangeRitualStability(phase.Comp.Ritual.Value, Mod);
}
public override string? GetGuidebookEffectDescription(IPrototypeManager prototype, IEntitySystemManager entSys)
{
return Mod switch
{
> 0 => Loc.GetString("cp14-ritual-effect-stability-add", ("count", Mod * 100)) + "\n",
< 0 => Loc.GetString("cp14-ritual-effect-stability-minus", ("count", -Mod * 100)) + "\n",
_ => null,
};
}
}

View File

@@ -1,44 +0,0 @@
using System.Text;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitual.Actions;
/// <summary>
/// Creates an entity in the coordinates of the ritual.
/// </summary> TODO: EntityTable support?
public sealed partial class SpawnEntity : CP14RitualAction
{
[DataField(required: true)]
public Dictionary<EntProtoId, int> Spawns = new();
[DataField]
public LocId? Name;
public override string? GetGuidebookEffectDescription(IPrototypeManager prototype, IEntitySystemManager entSys)
{
var sb = new StringBuilder();
sb.Append(Loc.GetString("cp14-ritual-effect-spawn-entity")+ "\n");
foreach (var spawn in Spawns)
{
if (!prototype.TryIndex(spawn.Key, out var indexed))
return null;
sb.Append(Loc.GetString("cp14-ritual-entry-item",
("name", Name is null ? indexed.Name : Loc.GetString(Name)),
("count", spawn.Value)) + "\n");
}
return sb.ToString();
}
public override void Effect(EntityManager entManager, SharedTransformSystem transform, Entity<CP14MagicRitualPhaseComponent> phase)
{
foreach (var spawn in Spawns)
{
for (var i = 0; i < spawn.Value; i++)
{
entManager.Spawn(spawn.Key, transform.GetMapCoordinates(phase));
}
}
}
}

View File

@@ -1,37 +0,0 @@
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitual;
/// <summary>
/// Ritual Behavior Controller. Creates and removes entities of magical phases
/// </summary>
[RegisterComponent, Access(typeof(CP14SharedRitualSystem))]
public sealed partial class CP14MagicRitualComponent : Component
{
[DataField(required: true)]
public EntProtoId StartPhase;
[DataField]
public EntityUid? CurrentPhase;
[DataField]
public float Stability = 1f;
[DataField]
public float ActivationTime = 5f;
[DataField]
public string RitualLayerMap = "ritual";
[DataField]
public int MaxOrbCapacity = 3;
[DataField]
public float RitualRadius = 5;
[DataField]
public TimeSpan TriggerTime = TimeSpan.Zero;
[DataField]
public List<EntityUid> Orbs = new();
}

View File

@@ -1,86 +0,0 @@
using Content.Shared.DoAfter;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
namespace Content.Shared._CP14.MagicRitual;
/// <summary>
/// Called out a ritual when any of its phase triggers are activated
/// </summary>
public sealed class CP14RitualTriggerEvent : EntityEventArgs
{
public EntProtoId NextPhase;
public CP14RitualTriggerEvent(EntProtoId phase)
{
NextPhase = phase;
}
}
/// <summary>
/// Called out at a ritual when his stability is altered
/// </summary>
public sealed class CP14RitualStabilityChangedEvent : EntityEventArgs
{
public float OldStability;
public float NewStability;
public CP14RitualStabilityChangedEvent(float oldS, float newS)
{
OldStability = oldS;
NewStability = newS;
}
}
/// <summary>
/// Called on both the ritual and the phase when they link together
/// </summary>
public sealed class CP14RitualPhaseBoundEvent : EntityEventArgs
{
public EntityUid Ritual;
public EntityUid Phase;
public CP14RitualPhaseBoundEvent(EntityUid r, EntityUid p)
{
Ritual = r;
Phase = p;
}
}
/// <summary>
/// Invoked at the ritual holder entity when the ritual is complete and the phase entities have been removed
/// </summary>
public sealed class CP14RitualEndEvent : EntityEventArgs
{
public EntityUid Ritual;
public CP14RitualEndEvent(EntityUid r)
{
Ritual = r;
}
}
/// <summary>
/// Invoked at the ritual holder entity when the ritual begins, and invokes the starting phase
/// </summary>
public sealed class CP14RitualStartEvent : EntityEventArgs
{
public EntityUid Ritual;
public CP14RitualStartEvent(EntityUid r)
{
Ritual = r;
}
}
[Serializable, NetSerializable]
public sealed partial class CP14ActivateRitualDoAfter : SimpleDoAfterEvent
{
}
[Serializable, NetSerializable]
public enum RitualVisuals
{
Color,
Enabled,
}

View File

@@ -1,14 +0,0 @@
using Content.Shared._CP14.MagicRitual.Prototypes;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitual;
/// <summary>
/// “Key” in the concept of rituals. An entity that can be a key to a ritual, and holds certain characteristics that can be spent, or by which a phase transition requirement check can be made.
/// </summary>
[RegisterComponent, Access(typeof(CP14SharedRitualSystem))]
public sealed partial class CP14MagicRitualOrbComponent : Component
{
[DataField]
public Dictionary<ProtoId<CP14MagicTypePrototype>, int> Powers = new();
}

View File

@@ -1,41 +0,0 @@
using Content.Shared._CP14.MagicRitual.Actions;
using Content.Shared._CP14.MagicRitual.Requirements;
using Content.Shared._CP14.MagicRitualTrigger;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitual;
/// <summary>
/// Magical entity that reacts to world events
/// </summary>
[RegisterComponent, Access(typeof(CP14SharedRitualSystem))]
public sealed partial class CP14MagicRitualPhaseComponent : Component
{
/// <summary>
/// A link to the ritual itself in which this phase is found
/// </summary>
[DataField]
public EntityUid? Ritual;
[DataField]
public Color PhaseColor = Color.White;
[DataField]
public List<RitualPhaseEdge> Edges = new();
/// <summary>
/// by moving to this node, the ritual will end instantly.
/// </summary>
[DataField]
public bool DeadEnd = false;
}
[DataRecord]
public partial record struct RitualPhaseEdge()
{
public EntProtoId Target { get; set; }
public List<CP14RitualTrigger> Triggers { get; set; } = new();
public List<CP14RitualRequirement> Requirements { get; set; } = new();
public List<CP14RitualAction> Actions { get; set; } = new();
}

View File

@@ -1,70 +0,0 @@
using Content.Shared._CP14.MagicRitual.Prototypes;
using Content.Shared.Follower;
using Robust.Shared.Network;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitual;
public partial class CP14SharedRitualSystem : EntitySystem
{
[Dependency] private readonly FollowerSystem _followerSystem = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly INetManager _net = default!;
public void ChangeRitualStability(EntityUid uid, float dStab, CP14MagicRitualComponent? ritual = null)
{
//if (!Resolve(uid, ref ritual))
// return;
//
//var newS = MathHelper.Clamp01(ritual.Stability + dStab);
//
//var ev = new CP14RitualStabilityChangedEvent(ritual.Stability, newS);
//RaiseLocalEvent(uid, ev);
//
//ritual.Stability = newS;
}
public void AddOrbToRitual(EntityUid uid, EntProtoId orb, CP14MagicRitualComponent? ritual = null)
{
//if (_net.IsClient)
// return;
//
//if (!Resolve(uid, ref ritual))
// return;
//
//if (!_proto.TryIndex(orb, out var indexedOrb))
// return;
//
//if (ritual.Orbs.Count >= ritual.MaxOrbCapacity)
// return;
//
//var spawnedOrb = Spawn(orb, _transform.GetMapCoordinates(uid));
//
//if (!TryComp<CP14MagicRitualOrbComponent>(spawnedOrb, out var orbComp))
//{
// QueueDel(spawnedOrb);
// return;
//}
//
//_followerSystem.StartFollowingEntity(spawnedOrb, uid);
//ritual.Orbs.Add((spawnedOrb, orbComp));
}
public void ConsumeOrbType(EntityUid uid, ProtoId<CP14MagicTypePrototype> magicType, CP14MagicRitualComponent? ritual = null)
{
//if (!Resolve(uid, ref ritual))
// return;
//
//foreach (var orb in ritual.Orbs)
//{
// var powers = orb.Comp.Powers;
// if (!powers.ContainsKey(magicType))
// continue;
//
// ritual.Orbs.Remove(orb);
// QueueDel(orb);
// return;
//}
}
}

View File

@@ -1,19 +0,0 @@
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitual.Requirements;
[ImplicitDataDefinitionForInheritors]
[MeansImplicitUse]
public abstract partial class CP14RitualRequirement
{
/// <summary>
/// If this checks fails, the ritual will lose some of its stability.
/// </summary>
[DataField]
public float FailStabilityCost;
public abstract bool Check(EntityManager entManager, Entity<CP14MagicRitualPhaseComponent> phaseEnt, float stability);
public abstract string? GetGuidebookRequirementDescription(IPrototypeManager prototype, IEntitySystemManager entSys);
}

View File

@@ -1,66 +0,0 @@
using System.Text;
using Content.Shared._CP14.MagicRitual.Prototypes;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitual.Requirements;
/// <summary>
/// Requires specific daytime period
/// </summary>
public sealed partial class RequiredOrbs : CP14RitualRequirement
{
[DataField]
public ProtoId<CP14MagicTypePrototype> MagicType = new();
[DataField]
public int? Min;
[DataField]
public int? Max;
public override string? GetGuidebookRequirementDescription(IPrototypeManager prototype, IEntitySystemManager entSys)
{
var sb = new StringBuilder();
if (!prototype.TryIndex(MagicType, out var indexedType))
return null;
sb.Append(Loc.GetString("cp14-ritual-required-orbs", ("name", Loc.GetString(indexedType.Name))) + " ");
if (Min is not null && Max is not null)
sb.Append(Loc.GetString("cp14-ritual-required-orbs-item-minmax", ("min", Min), ("max", Max))+ "\n");
else if (Min is not null)
sb.Append(Loc.GetString("cp14-ritual-required-orbs-item-min", ("min", Min))+ "\n");
else if (Max is not null)
sb.Append(Loc.GetString("cp14-ritual-required-orbs-item-min", ("max", Max))+ "\n");
return sb.ToString();
}
public override bool Check(EntityManager entManager, Entity<CP14MagicRitualPhaseComponent> phaseEnt, float stability)
{
//if (phaseEnt.Comp.Ritual is null)
// return false;
//
//if (!entManager.TryGetComponent<CP14MagicRitualComponent>(phaseEnt, out var ritualComp))
// return false;
//
//var count = 0;
//foreach (var orb in ritualComp.Orbs)
//{
// foreach (var power in orb.Comp.Powers)
// {
// if (power.Key == MagicType)
// count += power.Value;
// }
//}
//
//if (Min is not null && Max is not null)
// return count >= Min && count <= Max;
//if (Min is not null)
// return count >= Min;
//if (Max is not null)
// return count <= Max;
//
return false;
}
}

View File

@@ -1,113 +0,0 @@
using System.Text;
using Content.Shared.Stacks;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitual.Requirements;
/// <summary>
/// Requires certain specific entities to be near the ritual. TODO: Replace with Whitelist
/// </summary>
public sealed partial class RequiredResource : CP14RitualRequirement
{
[DataField]
public float CheckRange = 3f;
[DataField]
public Dictionary<EntProtoId, int> RequiredEntities = new ();
[DataField]
public Dictionary<ProtoId<StackPrototype>, int> RequiredStacks = new();
/// <summary>
/// Effect appearing in place of used entities
/// </summary>
[DataField("vfx")]
public EntProtoId? Effect = "CP14DustEffect";
public override string? GetGuidebookRequirementDescription(IPrototypeManager prototype, IEntitySystemManager entSys)
{
var sb = new StringBuilder();
sb.Append(Loc.GetString("cp14-ritual-required-resource", ("range", CheckRange)) + "\n");
foreach (var entity in RequiredEntities)
{
if (!prototype.TryIndex(entity.Key, out var indexed))
continue;
sb.Append(Loc.GetString("cp14-ritual-entry-item", ("name", indexed.Name), ("count", entity.Value)) + "\n");
}
foreach (var stack in RequiredStacks)
{
if (!prototype.TryIndex(stack.Key, out var indexed))
continue;
sb.Append(Loc.GetString("cp14-ritual-entry-item", ("name", Loc.GetString(indexed.Name)), ("count", stack.Value)) + "\n");
}
return sb.ToString();
}
public override bool Check(EntityManager entManager, Entity<CP14MagicRitualPhaseComponent> phaseEnt, float stability)
{
var _lookup = entManager.System<EntityLookupSystem>();
var _transform = entManager.System<SharedTransformSystem>();
var entitiesAround = _lookup.GetEntitiesInRange(phaseEnt, CheckRange, LookupFlags.Uncontained);
var passed = true;
foreach (var reqEnt in RequiredEntities)
{
var requiredCount = reqEnt.Value;
foreach (var entity in entitiesAround)
{
if (!entManager.TryGetComponent<MetaDataComponent>(entity, out var metaData))
continue;
if (!entManager.TryGetComponent<TransformComponent>(entity, out var xform))
continue;
var entProto = metaData.EntityPrototype;
if (entProto is null)
continue;
if (entProto.ID == reqEnt.Key && requiredCount > 0)
{
if (Effect is not null)
entManager.Spawn(Effect.Value, _transform.GetMapCoordinates(entity));
requiredCount--;
}
}
if (requiredCount > 0)
passed = false;
}
foreach (var reqStack in RequiredStacks)
{
var requiredCount = reqStack.Value;
foreach (var entity in entitiesAround)
{
if (!entManager.TryGetComponent<StackComponent>(entity, out var stack))
continue;
if (stack.StackTypeId != reqStack.Key)
continue;
var count = (int)MathF.Min(requiredCount, stack.Count);
requiredCount -= count;
if (Effect is not null)
entManager.Spawn(Effect.Value, _transform.GetMapCoordinates(entity));
}
if (requiredCount > 0)
passed = false;
}
return passed;
}
}

View File

@@ -1,37 +0,0 @@
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitual.Requirements;
/// <summary>
/// Requires that the stability of the ritual be within specified limits. If the stability is above or below the specified values, the check will fail
/// </summary>
public sealed partial class RequiredStability : CP14RitualRequirement
{
[DataField]
public float Min = 0;
[DataField]
public float Max = 1;
public override string? GetGuidebookRequirementDescription(IPrototypeManager prototype, IEntitySystemManager entSys)
{
return Min switch
{
> 0 when Max < 1 =>
Loc.GetString("cp14-ritual-required-stability-minmax", ("min", Min*100), ("max", Max*100)),
> 0 => Loc.GetString("cp14-ritual-required-stability-min", ("min", Min*100)),
< 0 => Loc.GetString("cp14-ritual-required-stability-max", ("min", Max*100)),
_ => null,
};
}
public override bool Check(EntityManager entManager, Entity<CP14MagicRitualPhaseComponent> phaseEnt, float stability)
{
if (phaseEnt.Comp.Ritual is null)
return false;
if (!entManager.TryGetComponent<CP14MagicRitualComponent>(phaseEnt, out var ritualComp))
return false;
return !(ritualComp.Stability < Min) && !(ritualComp.Stability > Max);
}
}

View File

@@ -1,17 +0,0 @@
using Content.Shared._CP14.MagicRitual;
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitualTrigger;
[ImplicitDataDefinitionForInheritors]
[MeansImplicitUse]
public abstract partial class CP14RitualTrigger
{
[DataField]
public RitualPhaseEdge? Edge = null;
public abstract void Initialize(EntityManager entManager, Entity<CP14MagicRitualPhaseComponent> ritual, RitualPhaseEdge edge);
public abstract string? GetGuidebookTriggerDescription(IPrototypeManager prototype, IEntitySystemManager entSys);
}

View File

@@ -1,5 +0,0 @@
namespace Content.Shared._CP14.MagicRitualTrigger;
public partial class CP14SharedRitualTriggerSystem : EntitySystem
{
}

View File

@@ -1,34 +0,0 @@
using Content.Shared._CP14.MagicRitual;
using Content.Shared.Humanoid.Prototypes;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitualTrigger.Triggers;
/// <summary>
/// triggers when a creature of a certain race dies within range of the ritual.
/// </summary>
public sealed partial class CP14SacrificeSpeciesTrigger : CP14RitualTrigger
{
[DataField]
public float Range = 3f;
[DataField(required: true)]
public ProtoId<SpeciesPrototype> Species = default!;
public override void Initialize(EntityManager entManager, Entity<CP14MagicRitualPhaseComponent> ritual, RitualPhaseEdge edge)
{
entManager.EnsureComponent<CP14RitualSacrificeSpeciesTriggerComponent>(ritual, out var trigger);
trigger.Triggers.Add(this);
Edge = edge;
}
public override string? GetGuidebookTriggerDescription(IPrototypeManager prototype, IEntitySystemManager entSys)
{
if (!prototype.TryIndex(Species, out var indexedSpecies))
return null;
return Loc.GetString("cp14-ritual-trigger-sacrifice",
("name", Loc.GetString(indexedSpecies.Name)),
("range", Range));
}
}

View File

@@ -1,8 +0,0 @@
namespace Content.Shared._CP14.MagicRitualTrigger.Triggers;
[RegisterComponent]
public sealed partial class CP14RitualSacrificeSpeciesTriggerComponent : Component
{
[DataField]
public HashSet<CP14SacrificeSpeciesTrigger> Triggers = new();
}

View File

@@ -1,34 +0,0 @@
using Content.Shared._CP14.MagicRitual;
using Content.Shared.Whitelist;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitualTrigger.Triggers;
/// <summary>
/// Triggers when a creature passing the whitelist dies within range of the ritual.
/// </summary>
public sealed partial class CP14SacrificeWhitelistTrigger : CP14RitualTrigger
{
[DataField]
public float Range = 3f;
[DataField(required: true)]
public EntityWhitelist Whitelist = default!;
[DataField(required: true)]
public LocId WhitelistDesc = default!;
public override void Initialize(EntityManager entManager, Entity<CP14MagicRitualPhaseComponent> ritual, RitualPhaseEdge edge)
{
entManager.EnsureComponent<CP14RitualSacrificeWhitelistTriggerComponent>(ritual, out var trigger);
trigger.Triggers.Add(this);
Edge = edge;
}
public override string? GetGuidebookTriggerDescription(IPrototypeManager prototype, IEntitySystemManager entSys)
{
return Loc.GetString("cp14-ritual-trigger-sacrifice",
("name", Loc.GetString(WhitelistDesc)),
("range", Range));
}
}

View File

@@ -1,8 +0,0 @@
namespace Content.Shared._CP14.MagicRitualTrigger.Triggers;
[RegisterComponent]
public sealed partial class CP14RitualSacrificeWhitelistTriggerComponent : Component
{
[DataField]
public HashSet<CP14SacrificeWhitelistTrigger> Triggers = new();
}

View File

@@ -1,28 +0,0 @@
using Content.Shared._CP14.MagicRitual;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitualTrigger.Triggers;
/// <summary>
/// Triggers the phase transition after a certain period of time
/// </summary>
public sealed partial class CP14TimerTrigger : CP14RitualTrigger
{
[DataField]
public float Delay = 10f;
[DataField]
public TimeSpan TriggerTime = TimeSpan.Zero;
public override void Initialize(EntityManager entManager, Entity<CP14MagicRitualPhaseComponent> ritual, RitualPhaseEdge edge)
{
entManager.EnsureComponent<CP14RitualTimerTriggerComponent>(ritual, out var trigger);
trigger.Triggers.Add(this);
Edge = edge;
}
public override string? GetGuidebookTriggerDescription(IPrototypeManager prototype, IEntitySystemManager entSys)
{
return Loc.GetString("cp14-ritual-trigger-timer-stable", ("time", Delay));
}
}

View File

@@ -1,8 +0,0 @@
namespace Content.Shared._CP14.MagicRitualTrigger.Triggers;
[RegisterComponent]
public sealed partial class CP14RitualTimerTriggerComponent : Component
{
[DataField]
public HashSet<CP14TimerTrigger> Triggers = new();
}

View File

@@ -1,28 +0,0 @@
using Content.Shared._CP14.MagicRitual;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitualTrigger.Triggers;
/// <summary>
/// Triggers a phase transition when the Ritual hears a certain message
/// </summary>
public sealed partial class CP14VoiceTrigger : CP14RitualTrigger
{
[DataField]
public string Message = string.Empty;
[DataField]
public int Speakers = 1;
public override void Initialize(EntityManager entManager, Entity<CP14MagicRitualPhaseComponent> ritual, RitualPhaseEdge edge)
{
entManager.EnsureComponent<CP14RitualVoiceTriggerComponent>(ritual, out var trigger);
trigger.Triggers.Add(this);
Edge = edge;
}
public override string? GetGuidebookTriggerDescription(IPrototypeManager prototype, IEntitySystemManager entSys)
{
return Loc.GetString("cp14-ritual-trigger-voice", ("phrase", Message), ("count", Speakers));
}
}

View File

@@ -1,8 +0,0 @@
namespace Content.Shared._CP14.MagicRitualTrigger.Triggers;
[RegisterComponent]
public sealed partial class CP14RitualVoiceTriggerComponent : Component
{
[DataField]
public HashSet<CP14VoiceTrigger> Triggers = new();
}

View File

@@ -29,6 +29,8 @@
amount: 3
- id: CP14SeedPepper
amount: 3
- id: CP14SeedCotton
amount: 3
- type: storePositionBuy
@@ -182,9 +184,7 @@
components:
- type: StorageFill
contents:
- id: CP14EnergyCrystalSmallEmpty
amount: 5
- id: CP14EnergyCrystalMediumEmpty
amount: 3
amount: 5
- id: CP14ManaOperationGlove
amount: 2

View File

@@ -48,26 +48,6 @@
proto: CP14SpellScrollBeerCreation
count: 1
- type: storePositionSell
id: CP14EnergyCrystalSmallEmpty
special: true
price: 70
factions:
- Sylphoria
service: !type:CP14SellPrototypeService
proto: CP14EnergyCrystalSmallEmpty
count: 5
- type: storePositionSell
id: CP14EnergyCrystalMediumEmpty
special: true
price: 80
factions:
- Sylphoria
service: !type:CP14SellPrototypeService
proto: CP14EnergyCrystalMediumEmpty
count: 3
- type: storePositionSell
id: CP14ClothingRingIceShards
special: true

View File

@@ -100,7 +100,7 @@
- id: CP14BaseLightCrossbow
- id: CP14CrossboltIron
amount: 5
- id: CP14EnergyCrystalSmall
- id: CP14EnergyCrystalMedium
- id: CP14CrystalLampBlueEmpty
- type: entity
@@ -118,7 +118,7 @@
- id: CP14BaseShield
- id: CP14ModularGripIronLongGuard
amount: 2
- id: CP14EnergyCrystalSmall
- id: CP14EnergyCrystalMedium
- id: CP14CrystalLampBlueEmpty
- id: CP14StampGuardCommander

View File

@@ -75,7 +75,7 @@
- id: CP14CrystalLampBlueEmpty
- id: CP14CrystalLampOrangeEmpty
- id: CP14Rope
- id: CP14EnergyCrystalSmall
- id: CP14EnergyCrystalMediumEmpty
- id: CP14d20Dice
- id: CP14d6Dice
- id: CP14CopperCoin5

View File

@@ -64,8 +64,6 @@
- id: CP14FoodMeatLambCutletCooked
- id: CP14ModularInlayQuartzFire
- id: CP14CopperCoin1
- id: CP14CrystalShardFire
weight: 3
- type: entity
id: CP14AreaEntityEffectSlimeIgnite

View File

@@ -77,8 +77,6 @@
- id: CP14Snowball
- id: CP14CopperCoin1
- id: CP14ModularInlayQuartzWater
- id: CP14CrystalShardWater
weight: 3
- type: entity
id: CP14AreaEntityEffectSlimeFroze

View File

@@ -1,13 +1,12 @@
- type: entity
id: CP14Wheat
parent: ProduceBase
parent: BaseItem
name: wheat bushel
description: You have the choice of either planting the grains again or grinding them into flour.
categories: [ ForkFiltered ]
components:
- type: Item
size: Tiny
- type: Produce
- type: Sprite
sprite: _CP14/Objects/Flora/Farm/wheat.rsi
layers:
@@ -22,3 +21,27 @@
tags:
- CP14Wheat
- CP14FarmFood
- type: entity
id: CP14Cotton
parent: BaseItem
name: cotton
description: A plant raw fiber used to make cotton fabric.
categories: [ ForkFiltered ]
components:
- type: Item
size: Tiny
- type: Sprite
sprite: _CP14/Objects/Flora/Farm/cotton.rsi
layers:
- state: base1
map: ["random"]
- type: RandomSprite
available:
- random:
base1: ""
base2: ""
base3: ""
- type: Tag
tags:
- CP14FarmFood

View File

@@ -0,0 +1,29 @@
- type: entity
id: CP14CrystalShardQuartz
parent: BaseItem
name: quartz shard
description: Natural quartz crystals that can absorb the magical energy of the world around them.
categories: [ ForkFiltered ]
components:
- type: Tag
tags:
- CP14FitInMortar
- type: Item
size: Tiny
- type: Sprite
sprite: _CP14/Structures/Flora/Crystal/crystal_shard.rsi
layers:
- state: shard0
map: ["random"]
- type: RandomSprite
available:
- random:
shard0: ""
shard1: ""
shard2: ""
shard3: ""
- type: Extractable
juiceSolution:
reagents:
- ReagentId: CP14GroundQuartz
Quantity: 7

View File

@@ -100,3 +100,16 @@
- state: sage
- type: CP14Seed
plantProto: CP14PlantSage
- type: entity
id: CP14SeedCotton
name: cotton seeds
description: Cotton seeds. It's time to grow some pants!
parent: CP14BaseSeed
components:
- type: Sprite
layers:
- state: bag
- state: cotton
- type: CP14Seed
plantProto: CP14PlantCotton

View File

@@ -13,60 +13,19 @@
- type: CP14MagicEnergyContainer
- type: CP14MagicEnergyExaminable
- type: entity
id: CP14EnergyCrystalSmall
parent: CP14EnergyCrystalBase
name: small energyshard
suffix: Full
components:
- type: Sprite
layers:
- state: small1
shader: unshaded
map: ["random"]
- state: small_connector
- type: RandomSprite
available:
- random:
small1: ""
small2: ""
small3: ""
- type: CP14MagicEnergyContainer
energy: 30
maxEnergy: 30
- type: entity
id: CP14EnergyCrystalSmallEmpty
parent: CP14EnergyCrystalSmall
suffix: Empty
components:
- type: CP14MagicEnergyContainer
energy: 0
- type: entity
id: CP14EnergyCrystalMedium
parent: CP14EnergyCrystalBase
name: energyshard
suffix: Full
components:
- type: PointLight
radius: 1.2
- type: Sprite
layers:
- state: medium1
shader: unshaded
map: ["random"]
- state: medium
- state: medium_connector
- type: RandomSprite
available:
- random:
medium1: ""
medium2: ""
medium3: ""
- type: CP14MagicEnergyContainer
energy: 100
maxEnergy: 100
energy: 50
maxEnergy: 50
- type: entity
id: CP14EnergyCrystalMediumEmpty

View File

@@ -1,6 +1,8 @@
- type: entity
id: CP14Torch
parent: BaseItem
parent:
- BaseItem
- CP14BaseTorch
name: torch
description: At its core, a stick burning on one side. Used to light up the area.
categories: [ ForkFiltered ]
@@ -15,30 +17,6 @@
shape:
- 0,0,0,2
storedRotation: -65
- type: CP14FlammableAmbientSound
- type: AmbientSound
enabled: false
volume: -5
range: 5
sound:
path: /Audio/Ambience/Objects/fireplace.ogg
- type: Appearance
- type: Reactive
groups:
Flammable: [ Touch ]
Extinguish: [ Touch ]
- type: Flammable
fireSpread: false
canResistFire: false
alwaysCombustible: true
canExtinguish: true
firestacksOnIgnite: 0.5
damage:
types:
Heat: 0
- type: CP14Fireplace
maxFuelLimit: 200
fuel: 200
- type: FireVisuals
sprite: _CP14/Objects/Tools/torch.rsi
normalState: lit-overlay
@@ -58,17 +36,6 @@
Empty: { state: torch-spent }
Medium: { state: torch-unlit }
Full: { state: torch-unlit }
- type: Damageable
damageContainer: Inorganic
damageModifierSet: Wood
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 50
behaviors:
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: CP14DelayedIgnitionSource
- type: CP14IgnitionModifier
hideCaution: true
@@ -86,7 +53,7 @@
- type: UseDelay
- type: ExtinguishOnInteract
extinguishAttemptSound:
path: /Audio/Items/candle_blowing.ogg #TODO sound
path: /Audio/Items/candle_blowing.ogg
params:
variation: 0.05
volume: 10

View File

@@ -1,25 +0,0 @@
- type: entity
parent: BookBase
id: CP14RitualGrimoire
name: ritualist's grimoire
description: a book that holds the knowledge of hundreds of ritualists before you. Use it on an active ritual to get all the information about its current state.
categories: [ ForkFiltered ]
components:
- type: Sprite
sprite: Objects/Misc/books.rsi
layers:
- state: paper
- state: cover_old
color: "#a6161d"
- state: decor_bottom
color: "#6e1022"
- state: decor_wingette
color: "#4a101b"
- state: icon_pentagramm
color: "#911129"
- state: detail_bookmark
color: red
- type: CP14PaperPhaseDescriber
startPhase: CP14_NeutralCluster_Root
hyperlinks:
- CP14_NeutralCluster_Root

View File

@@ -1,55 +0,0 @@
- type: entity
parent: CP14BaseRitualPhase
abstract: true
id: CP14_NeutralCluster_Base
components:
- type: CP14MagicRitualPhase
phaseColor: "#FFFFFF"
- type: ActiveListener
range: 3
- type: entity
parent: CP14_NeutralCluster_Base
id: CP14_NeutralCluster_Root
name: Te-Se-Ra
description: The perfect energetic position to begin any ritual.
categories: [ HideSpawnMenu ]
components:
- type: CP14MagicRitualPhase
edges:
- target: CP14_NeutralCluster_00
triggers:
- !type:CP14SacrificeWhitelistTrigger
whitelist:
components:
- MobState
whitelistDesc: cp14-ritual-category-all-living
- type: entity
parent: CP14_NeutralCluster_Base
id: CP14_NeutralCluster_00
name: Li-Ra
categories: [ HideSpawnMenu ]
components:
- type: CP14MagicRitualPhase
edges:
- target: CP14RitualEnd
triggers:
- !type:CP14VoiceTrigger
message: "Vespere nebula"
actions:
- !type:ApplyEntityEffect
maxEntities: 3
vfx: CP14ImpactEffectCureWounds
whitelist:
components:
- HumanoidAppearance
effects:
- !type:HealthChange
damage:
types:
Asphyxiation: -50
Bloodloss: -10
- !type:ModifyBleedAmount
- !type:ModifyBloodLevel
- !type:Jitter

View File

@@ -1,23 +0,0 @@
- type: entity
id: CP14BaseRitualPhase
abstract: true
components:
- type: CP14MagicRitualPhase
- type: Tag
tags:
- HideContextMenu
- type: PointLight
- type: EmitSoundOnSpawn
sound:
path: /Audio/Effects/tesla_consume.ogg
params:
variation: 0.3
- type: entity
parent: CP14BaseRitualPhase
id: CP14RitualEnd
name: end of ritual
categories: [ HideSpawnMenu ]
components:
- type: CP14MagicRitualPhase
deadEnd: true

View File

@@ -1,39 +0,0 @@
- type: entity
id: CP14BaseRitualOrb
abstract: true
components:
- type: Transform
- type: Physics
canCollide: false
- type: Sprite
sprite: _CP14/Effects/Magic/ritual_orbs.rsi
drawDepth: Mobs
noRot: true
#- type: entity
# parent: CP14BaseRitualOrb
# id: CP14RitualOrbCreation
# name: creation orb
# categories: [ HideSpawnMenu]
# components:
# - type: CP14MagicRitualOrb
# powers:
# Creation: 1
# - type: Sprite
# layers:
# - state: creation
# shader: unshaded
#
#- type: entity
# parent: CP14BaseRitualOrb
# id: CP14RitualOrbDestruction
# name: destruction orb
# categories: [ HideSpawnMenu]
# components:
# - type: CP14MagicRitualOrb
# powers:
# Destruction: 1
# - type: Sprite
# layers:
# - state: destruction
# shader: unshaded

View File

@@ -11,10 +11,6 @@
sprite: _CP14/Structures/Decoration/statue_gob.rsi
layers:
- state: gob
- state: eyes
map: ["ritual"]
visible: false
shader: unshaded
- state: wire
map: ["wire"]
visible: false
@@ -55,8 +51,6 @@
CP14StoneBlock1:
min: 4
max: 5
- type: CP14MagicRitual
startPhase: CP14_NeutralCluster_Root
- type: Appearance
- type: HolidayVisuals
holidays:
@@ -82,10 +76,6 @@
- type: Sprite
layers:
- state: gob_vines
- state: eyes
map: ["ritual"]
visible: false
shader: unshaded
- state: wire
map: ["wire"]
visible: false
@@ -102,10 +92,6 @@
- type: Sprite
layers:
- state: gob_ruined
- state: eyes
map: ["ritual"]
visible: false
shader: unshaded
- state: wire
map: ["wire"]
visible: false
@@ -122,10 +108,6 @@
- type: Sprite
layers:
- state: gob_ruined_vines
- state: eyes
map: ["ritual"]
visible: false
shader: unshaded
- state: wire
map: ["wire"]
visible: false
@@ -146,10 +128,6 @@
sprite: _CP14/Structures/Decoration/angel_statue.rsi
layers:
- state: statue1
- state: glow
map: ["ritual"]
visible: false
shader: unshaded
drawdepth: Mobs
offset: "0.0,0.5"
- type: Fixtures
@@ -184,8 +162,6 @@
CP14StoneBlock1:
min: 4
max: 5
- type: CP14MagicRitual
startPhase: CP14_NeutralCluster_Root
- type: Appearance
- type: entity
@@ -196,10 +172,6 @@
- type: Sprite
layers:
- state: statue2
- state: glow
map: ["ritual"]
visible: false
shader: unshaded
- type: entity
id: CP14StatueAngelLimestone
@@ -209,10 +181,6 @@
- type: Sprite
layers:
- state: statue3
- state: glow
map: ["ritual"]
visible: false
shader: unshaded
- type: entity
id: CP14StatueStoneHeadHigh

View File

@@ -68,7 +68,7 @@
# Normal
- type: entity
id: CP14CrystalEmpty
id: CP14CrystalQuartz
suffix: Normal
parent: CP14CrystalBase
components:
@@ -89,171 +89,8 @@
collection: GlassBreak
- !type:SpawnEntitiesBehavior
spawn:
CP14CrystalShardBase:
CP14CrystalShardQuartz:
min: 1
max: 2
- !type:TriggerBehavior
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: entity
id: CP14CrystalEarth
parent: CP14CrystalBase
suffix: Terra
components:
- type: PointLight
color: "#70533f"
- type: Sprite
color: "#70533f"
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 15
behaviors:
- !type:PlaySoundBehavior
sound:
collection: GlassBreak
- !type:SpawnEntitiesBehavior
spawn:
CP14CrystalShardEarth:
min: 1
max: 2
- !type:TriggerBehavior
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: entity
id: CP14CrystalFire
parent: CP14CrystalBase
suffix: Ignis
components:
- type: PointLight
color: "#d9741c"
- type: Sprite
color: "#d9741c"
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 15
behaviors:
- !type:PlaySoundBehavior
sound:
collection: GlassBreak
- !type:SpawnEntitiesBehavior
spawn:
CP14CrystalShardFire:
min: 1
max: 2
- !type:TriggerBehavior
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: entity
id: CP14CrystalWater
parent: CP14CrystalBase
suffix: Aqua
components:
- type: PointLight
color: "#1c94d9"
- type: Sprite
color: "#1c94d9"
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 15
behaviors:
- !type:PlaySoundBehavior
sound:
collection: GlassBreak
- !type:SpawnEntitiesBehavior
spawn:
CP14CrystalShardWater:
min: 1
max: 2
- !type:TriggerBehavior
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: entity
id: CP14CrystalAir
parent: CP14CrystalBase
suffix: Aer
components:
- type: PointLight
color: "#fdfe86"
- type: Sprite
color: "#fdfe86"
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 15
behaviors:
- !type:PlaySoundBehavior
sound:
collection: GlassBreak
- !type:SpawnEntitiesBehavior
spawn:
CP14CrystalShardAir:
min: 1
max: 2
- !type:TriggerBehavior
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: entity
id: CP14CrystalOrder
parent: CP14CrystalBase
suffix: Ordo
components:
- type: PointLight
color: "#d9d9d9"
- type: Sprite
color: "#d9d9d9"
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 15
behaviors:
- !type:PlaySoundBehavior
sound:
collection: GlassBreak
- !type:SpawnEntitiesBehavior
spawn:
CP14CrystalShardOrder:
min: 1
max: 2
- !type:TriggerBehavior
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: entity
id: CP14CrystalChaos
parent: CP14CrystalBase
suffix: Perditio
components:
- type: PointLight
color: "#5c5c5c"
- type: Sprite
color: "#5c5c5c"
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 15
behaviors:
- !type:PlaySoundBehavior
sound:
collection: GlassBreak
- !type:SpawnEntitiesBehavior
spawn:
CP14CrystalShardChaos:
min: 1
max: 2
- !type:TriggerBehavior
- !type:DoActsBehavior
acts: [ "Destruction" ]
acts: [ "Destruction" ]

View File

@@ -1,102 +0,0 @@
- type: entity
id: CP14CrystalShardBase
parent: BaseItem
name: quartz shard
description: Natural quartz crystals that can absorb the magical energy of the world around them.
categories: [ ForkFiltered ]
components:
- type: Tag
tags:
- CP14FitInMortar
- type: Item
size: Tiny
- type: Sprite
sprite: _CP14/Structures/Flora/Crystal/crystal_shard.rsi
layers:
- state: shard0
map: ["random"]
- type: RandomSprite
available:
- random:
shard0: ""
shard1: ""
shard2: ""
shard3: ""
- type: Extractable
juiceSolution:
reagents:
- ReagentId: CP14GroundQuartz
Quantity: 7
- type: entity
parent: CP14CrystalShardBase
id: CP14CrystalShardEarth
name: terra quartz shard
components:
- type: Sprite
color: "#70533f"
- type: CP14MagicEssenceContainer
essences:
Earth: 3
Crystal: 1
- type: entity
parent: CP14CrystalShardBase
id: CP14CrystalShardFire
name: ignis quartz shard
components:
- type: Sprite
color: "#d9741c"
- type: CP14MagicEssenceContainer
essences:
Fire: 3
Crystal: 1
- type: entity
parent: CP14CrystalShardBase
id: CP14CrystalShardWater
name: aqua quartz shard
components:
- type: Sprite
color: "#1c94d9"
- type: CP14MagicEssenceContainer
essences:
Water: 3
Crystal: 1
- type: entity
parent: CP14CrystalShardBase
id: CP14CrystalShardAir
name: aer quartz shard
components:
- type: Sprite
color: "#fdfe86"
- type: CP14MagicEssenceContainer
essences:
Air: 3
Crystal: 1
- type: entity
parent: CP14CrystalShardBase
id: CP14CrystalShardOrder
name: ordo quartz shard
components:
- type: Sprite
color: "#d9d9d9"
- type: CP14MagicEssenceContainer
essences:
Order: 3
Crystal: 1
- type: entity
parent: CP14CrystalShardBase
id: CP14CrystalShardChaos
name: perditio quartz shard
components:
- type: Sprite
color: "#5c5c5c"
- type: CP14MagicEssenceContainer
essences:
Chaos: 3
Crystal: 1

View File

@@ -0,0 +1,26 @@
- type: entity
id: CP14PlantCotton
parent: CP14GatherablePlantSingleHarvestBase
name: cotton
description: In a way, you're growing future clothes.
components:
- type: Sprite
offset: 0, 0.5
drawdepth: Mobs
layers:
- state: liq-1
map: ["enum.SolutionContainerLayers.Fill"]
visible: false
- state: grow-1
sprite: _CP14/Structures/Flora/Farm/cotton.rsi
map: ["enum.PlantVisualLayers.Base"]
- type: CP14PlantGatherable
loot:
All: CP14GatherCotton
- type: entityLootTable
id: CP14GatherCotton
entries:
- id: CP14Cotton
amount: 4
maxAmount: 6

View File

@@ -0,0 +1,184 @@
- type: entity
id: CP14BaseTorch
abstract: true
description: A good, reliable light source. Too bad it doesn't last.
categories: [ ForkFiltered ]
components:
- type: InteractionOutline
- type: Damageable
damageContainer: Inorganic
damageModifierSet: Wood
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 30
behaviors:
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: CP14FlammableAmbientSound
- type: AmbientSound
enabled: false
volume: -15
range: 5
sound:
path: /Audio/Ambience/Objects/fireplace.ogg
- type: Reactive
groups:
Flammable: [ Touch ]
Extinguish: [ Touch ]
- type: Flammable
fireSpread: false
canResistFire: false
alwaysCombustible: true
canExtinguish: true
firestacksOnIgnite: 0.5
damage:
types:
Heat: 0
- type: CP14Fireplace
deleteOnEmpty: true
maxFuelLimit: 1800
fuel: 1800
- type: Appearance
- type: CP14IgnitionModifier
hideCaution: true
- type: entity
id: CP14FloorTorch
parent:
- CP14BaseTorch
- BaseStructure
name: floor torch
components:
- type: Sprite
noRot: true
drawdepth: Mobs
sprite: _CP14/Structures/Furniture/torch_floor.rsi
offset: 0, 0.3
layers:
- state: base
map: ["fuel"]
- type: Fixtures
fixtures:
fix1:
shape:
!type:PhysShapeAabb
bounds: "-0.2,-0.2,0.2,0.2"
density: 1000
layer:
- LowImpassable
- MidImpassable
- type: FireVisuals
sprite: _CP14/Structures/Furniture/torch_floor.rsi
normalState: fire
- type: GenericVisualizer
visuals:
enum.FireplaceFuelVisuals.Status:
fuel:
Empty: { state: burned }
Medium: { state: base }
Full: { state: base }
- type: Construction
graph: CP14FloorTorch
node: CP14FloorTorch
- type: entity
parent: CP14FloorTorch
id: CP14FloorTorchIgnited
suffix: Ignited
components:
- type: CP14AutoIgnite
- type: entity
id: CP14FloorTorchAlwaysPowered
name: floor torch
parent: BaseStructure
categories: [ ForkFiltered ]
suffix: Debug, Infinite
components:
- type: Sprite
noRot: true
drawdepth: Mobs
sprite: _CP14/Structures/Furniture/torch_floor.rsi
offset: 0, 0.3
layers:
- state: base
- state: fire
shader: unshaded
- type: Fixtures
fixtures:
fix1:
shape:
!type:PhysShapeAabb
bounds: "-0.2,-0.2,0.2,0.2"
density: 1000
layer:
- LowImpassable
- MidImpassable
- type: PointLight
color: "#e67c34"
energy: 2
radius: 8
- type: AmbientSound
enabled: true
volume: -15
range: 5
sound:
path: /Audio/Ambience/Objects/fireplace.ogg
- type: entity
id: CP14WallmountTorch
parent:
- CP14BaseTorch
- CP14BaseWallmount
name: wallmount torch
components:
- type: Sprite
sprite: _CP14/Structures/Furniture/wallmount_torch.rsi
layers:
- state: base
map: ["fuel"]
- type: FireVisuals
sprite: _CP14/Structures/Furniture/wallmount_torch.rsi
normalState: fire
- type: GenericVisualizer
visuals:
enum.FireplaceFuelVisuals.Status:
fuel:
Empty: { state: burned }
Medium: { state: base }
Full: { state: base }
- type: Construction
graph: CP14WallmountTorch
node: CP14WallmountTorch
- type: entity
parent: CP14WallmountTorch
id: CP14WallmountTorchIgnited
suffix: Ignited
components:
- type: CP14AutoIgnite
- type: entity
id: CP14WallmountTorchAlwaysPowered
name: wallmount torch
parent: CP14BaseWallmount
suffix: Debug, Infinite
components:
- type: Sprite
sprite: _CP14/Structures/Furniture/wallmount_torch.rsi
layers:
- state: base
- state: fire
shader: unshaded
- type: PointLight
color: "#e67c34"
energy: 2
radius: 8
- type: AmbientSound
enabled: true
volume: -15
range: 5
sound:
path: /Audio/Ambience/Objects/fireplace.ogg

View File

@@ -15,90 +15,6 @@
- type: Physics
canCollide: false
- type: entity
id: CP14WallmountTorch
name: wallmount torch
parent: CP14BaseWallmount
description: A good, reliable light source. Too bad it doesn't last.
components:
- type: Sprite
sprite: _CP14/Structures/Furniture/wallmount_torch.rsi
layers:
- state: base
map: ["fuel"]
- type: Damageable
damageContainer: Inorganic
damageModifierSet: Wood
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 80
behaviors:
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: CP14FlammableAmbientSound
- type: AmbientSound
enabled: false
volume: -15
range: 5
sound:
path: /Audio/Ambience/Objects/fireplace.ogg
- type: Reactive
groups:
Flammable: [ Touch ]
Extinguish: [ Touch ]
- type: Flammable
fireSpread: false
canResistFire: false
alwaysCombustible: true
canExtinguish: true
firestacksOnIgnite: 0.5
damage:
types:
Heat: 0
- type: CP14Fireplace
maxFuelLimit: 200
fuel: 200
- type: FireVisuals
sprite: _CP14/Structures/Furniture/wallmount_torch.rsi
normalState: fire
- type: Appearance
- type: GenericVisualizer
visuals:
enum.FireplaceFuelVisuals.Status:
fuel:
Empty: { state: burned }
Medium: { state: base }
Full: { state: base }
- type: Construction
graph: CP14WallmountTorch
node: CP14WallmountTorch
- type: CP14IgnitionModifier
hideCaution: true
- type: entity
id: CP14WallmountTorchAlwaysPowered
name: always powered wallmount torch
parent: CP14BaseWallmount
components:
- type: Sprite
sprite: _CP14/Structures/Furniture/wallmount_torch.rsi
layers:
- state: base
- state: fire
shader: unshaded
- type: PointLight
color: "#e67c34"
energy: 2
radius: 8
- type: AmbientSound
enabled: true
volume: -15
range: 5
sound:
path: /Audio/Ambience/Objects/fireplace.ogg
- type: entity
id: CP14WallmountBarShelfA
name: bar shelf

View File

@@ -22,7 +22,7 @@
- type: PointLight
energy: 1
radius: 8
color: "#b2ceeb"
color: "#dfe7f0"
enabled: false
- type: Appearance
- type: GenericVisualizer
@@ -41,14 +41,14 @@
thresholds:
- trigger:
!type:DamageTrigger
damage: 40
damage: 20
behaviors:
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: CP14MagicLantern
- type: CP14MagicEnergyDraw
energy: -0.1
delay: 6
delay: 12
- type: Construction
graph: CP14WallmountLampEmpty
node: CP14WallmountLampEmpty
@@ -75,7 +75,7 @@
- type: ItemSlots
slots:
crystal_slot:
startingItem: CP14EnergyCrystalSmall
startingItem: CP14EnergyCrystalMedium
insertSound:
path: /Audio/_CP14/Items/crystal_insert.ogg
params:

View File

@@ -1,135 +0,0 @@
# Wallmount crystall
- type: entity
id: CP14WallmountCrystalBase
parent:
- CP14BaseWallmount
abstract: true
name: sparkling quartz
description: bioluminescent quartz crystals that can take on any color - a very handy light source in a deep caves. Unfortunately, the luminous properties are very hard to preserve.
categories: [ ForkFiltered ]
components:
- type: Sprite
drawdepth: Mobs
sprite: _CP14/Structures/Wallmount/wallmount_crystal.rsi
layers:
- state: crystal1
map: ["random"]
shader: unshaded
- type: MeleeSound
soundGroups:
Brute:
collection: GlassSmash
- type: Damageable
damageContainer: Inorganic
damageModifierSet: Glass
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 80
behaviors:
- !type:DoActsBehavior
acts: [ "Destruction" ]
- trigger:
!type:DamageTrigger
damage: 20
behaviors:
- !type:PlaySoundBehavior
sound:
collection: GlassBreak
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: Fixtures
fixtures:
fix1:
shape:
!type:PhysShapeAabb
bounds: "0.49,0.49,-0.49,0.36"
density: 60
mask:
- MachineMask
layer:
- MidImpassable
- LowImpassable
- type: RandomSprite
available:
- random:
crystal1: Inherit
crystal2: Inherit
crystal3: Inherit
- type: PointLight
radius: 1.5
energy: 1
- type: entity
id: CP14WallmountCrystalRubies
parent: CP14WallmountCrystalBase
suffix: Red
components:
- type: Sprite
color: "#ff3d0b"
- type: RandomSprite
cP14InheritBaseColor: "#ff3d0b"
- type: PointLight
color: "#ff3d0b"
- type: entity
id: CP14WallmountCrystalTopazes
parent: CP14WallmountCrystalBase
suffix: Yellow
components:
- type: Sprite
color: "#ffe269"
- type: RandomSprite
cP14InheritBaseColor: "#ffe269"
- type: PointLight
color: "#ffe269"
- type: entity
id: CP14WallmountCrystalEmeralds
parent: CP14WallmountCrystalBase
suffix: Green
components:
- type: Sprite
color: "#30be81"
- type: RandomSprite
cP14InheritBaseColor: "#30be81"
- type: PointLight
color: "#30be81"
- type: entity
id: CP14WallmountCrystalSapphires
parent: CP14WallmountCrystalBase
suffix: Cyan
components:
- type: Sprite
color: "#5eabeb"
- type: RandomSprite
cP14InheritBaseColor: "#5eabeb"
- type: PointLight
color: "#5eabeb"
- type: entity
id: CP14WallmountCrystalAmethysts
parent: CP14WallmountCrystalBase
suffix: Purple
components:
- type: Sprite
color: "#a878d1"
- type: RandomSprite
cP14InheritBaseColor: "#a878d1"
- type: PointLight
color: "#a878d1"
- type: entity
id: CP14WallmountCrystalDiamonds
parent: CP14WallmountCrystalBase
suffix: White
components:
- type: Sprite
color: "#f8f8f8"
- type: RandomSprite
cP14InheritBaseColor: "#f8f8f8"
- type: PointLight
color: "#f8f8f8"

View File

@@ -1,151 +1,15 @@
- type: cp14DemiplaneModifier
id: CrystalNormal
id: Quartz
levels:
min: 1
max: 3
generationWeight: 0.1
max: 8
categories:
Reward: 0.1
layers:
- !type:OreDunGen
tileMask:
- CP14FloorBase
entity: CP14CrystalEmpty
entity: CP14CrystalQuartz
count: 30
minGroupSize: 1
maxGroupSize: 5
# TIER 2
- type: cp14DemiplaneModifier
id: CrystalFire
levels:
min: 4
max: 10
generationWeight: 0.1
categories:
Reward: 0.1
requiredTags:
- CP14DemiplaneHot
layers:
- !type:OreDunGen
entity: CP14CrystalFire
count: 30
minGroupSize: 1
maxGroupSize: 5
- !type:OreDunGen
entity: CP14EssenceNodeFire
count: 3
minGroupSize: 1
maxGroupSize: 1
- type: cp14DemiplaneModifier
id: CrystalEarth
levels:
min: 4
max: 10
generationWeight: 0.1
categories:
Reward: 0.1
requiredTags:
- CP14DemiplaneUnderground
blacklistTags:
- CP14DemiplaneOpenSky
layers:
- !type:OreDunGen
entity: CP14CrystalEarth
count: 30
minGroupSize: 1
maxGroupSize: 5
- !type:OreDunGen
entity: CP14EssenceNodeEarth
count: 3
minGroupSize: 1
maxGroupSize: 1
- type: cp14DemiplaneModifier
id: CrystalWater
levels:
min: 4
max: 10
generationWeight: 0.1
categories:
Reward: 0.1
requiredTags:
- CP14DemiplaneWater
layers:
- !type:OreDunGen
entity: CP14CrystalWater
count: 30
minGroupSize: 1
maxGroupSize: 5
- !type:OreDunGen
entity: CP14EssenceNodeWater
count: 3
minGroupSize: 1
maxGroupSize: 1
- type: cp14DemiplaneModifier
id: CrystalAir
levels:
min: 4
max: 10
generationWeight: 0.1
categories:
Reward: 0.1
requiredTags:
- CP14DemiplaneOpenSky
blacklistTags:
- CP14DemiplaneUnderground
layers:
- !type:OreDunGen
entity: CP14CrystalAir
count: 30
minGroupSize: 1
maxGroupSize: 5
- !type:OreDunGen
entity: CP14EssenceNodeAir
count: 3
minGroupSize: 1
maxGroupSize: 1
- type: cp14DemiplaneModifier
id: CrystalOrder
levels:
min: 4
max: 10
generationWeight: 0.1
categories:
Reward: 0.1
layers:
- !type:OreDunGen
entity: CP14CrystalOrder
count: 30
minGroupSize: 1
maxGroupSize: 5
- !type:OreDunGen
entity: CP14EssenceNodeOrder
count: 3
minGroupSize: 1
maxGroupSize: 1
- type: cp14DemiplaneModifier
id: CrystalChaos
levels:
min: 4
max: 10
generationWeight: 0.1
categories:
Reward: 0.1
layers:
- !type:OreDunGen
entity: CP14CrystalChaos
count: 30
minGroupSize: 1
maxGroupSize: 5
- !type:OreDunGen
entity: CP14EssenceNodeChaos
count: 3
minGroupSize: 1
maxGroupSize: 1
maxGroupSize: 5

View File

@@ -9,10 +9,10 @@
- to: CP14Bonfire
steps:
- material: CP14Stone
amount: 3
amount: 2
doAfter: 2
- stackGroup: WoodenPlanks
amount: 2
amount: 1
doAfter: 2
- node: CP14Bonfire

View File

@@ -11,7 +11,7 @@
- !type:SnapToGrid { }
steps:
- stackGroup: WoodenPlanks
amount: 5
amount: 2
doAfter: 3
- node: CP14mannequin
entity: CP14Mannequin
@@ -21,7 +21,7 @@
- !type:EmptyAllContainers
- !type:SpawnPrototype
prototype: CP14WoodenPlanks1
amount: 5
amount: 2
steps:
- tool: CP14Hammering
doAfter: 3

View File

@@ -9,7 +9,7 @@
- to: CP14WallmountOrdersBorder
steps:
- stackGroup: WoodenPlanks
amount: 3
amount: 1
doAfter: 3
- node: CP14WallmountOrdersBorder

View File

@@ -9,8 +9,8 @@
- to: CP14WallmountTorch
steps:
- stackGroup: WoodenPlanks
amount: 3
doAfter: 3
amount: 1
doAfter: 1
- material: CP14Cloth
amount: 1
doAfter: 1
@@ -18,6 +18,26 @@
- node: CP14WallmountTorch
entity: CP14WallmountTorch
- type: constructionGraph
id: CP14FloorTorch
start: start
graph:
- node: start
actions:
- !type:DestroyEntity {}
edges:
- to: CP14FloorTorch
steps:
- stackGroup: WoodenPlanks
amount: 1
doAfter: 1
- material: CP14Cloth
amount: 1
doAfter: 1
- node: CP14FloorTorch
entity: CP14FloorTorch
- type: constructionGraph
id: CP14WallmountLampEmpty
start: start

View File

@@ -9,7 +9,7 @@
category: construction-category-structures
icon:
sprite: _CP14/Structures/Furniture/wallmount_torch.rsi
state: fire
state: base
objectType: Structure
placementMode: SnapgridCenter
canBuildInImpassable: false
@@ -18,6 +18,24 @@
- !type:TileNotBlocked
- !type:CP14WallRequired
- type: construction
crystallPunkAllowed: true
name: floor torch
description: A good, reliable light source. Too bad it doesn't last.
id: CP14FloorTorch
graph: CP14FloorTorch
startNode: start
targetNode: CP14FloorTorch
category: construction-category-structures
icon:
sprite: _CP14/Structures/Furniture/torch_floor.rsi
state: base
objectType: Structure
placementMode: SnapgridCenter
canBuildInImpassable: false
conditions:
- !type:TileNotBlocked
- type: construction
crystallPunkAllowed: true
name: crystal wall lamp

View File

@@ -7,7 +7,7 @@
- to: cp14torch
steps:
- material: CP14WoodenPlanks
amount: 3
amount: 1
- material: CP14Cloth
amount: 1
doAfter: 4

View File

@@ -288,3 +288,16 @@
count: 1
result: CP14LockMithril
- type: CP14Recipe
id: CP14EnergyCrystalMediumEmpty
tag: CP14RecipeAnvil
category: Tools
craftTime: 2
requirements:
- !type:ProtoIdResource
protoId: CP14CrystalShardQuartz
count: 1
- !type:StackResource
stack: CP14CopperBar
count: 1
result: CP14EnergyCrystalMediumEmpty

View File

@@ -60,7 +60,7 @@
protoId: CP14FoodPepper
count: 1
result: CP14SeedPepper
resultCount: 3
resultCount: 2
- type: CP14Recipe
id: CP14SeedSage
@@ -71,4 +71,15 @@
protoId: CP14WildSage
count: 1
result: CP14SeedSage
resultCount: 1
resultCount: 2
- type: CP14Recipe
id: CP14SeedCotton
tag: CP14RecipeCooking
craftTime: 1
requirements:
- !type:ProtoIdResource
protoId: CP14Cotton
count: 1
result: CP14SeedCotton
resultCount: 2

View File

@@ -159,7 +159,7 @@
- !type:StackGroupResource
group: WoodenPlanks
- !type:ProtoIdResource
protoId: CP14CrystalShardBase
protoId: CP14CrystalShardQuartz
result: CP14CrayonWhite
- type: CP14Recipe

View File

@@ -41,10 +41,11 @@
- type: CP14Recipe
id: CP14GlassSheet1
tag: CP14RecipeMeltingFurnace
craftTime: 4
craftTime: 2
requirements:
- !type:ProtoIdResource
protoId: CP14CrystalShardBase
protoId: CP14CrystalShardQuartz
count: 1
result: CP14GlassSheet1
- type: CP14Recipe

View File

@@ -1,3 +1,13 @@
- type: CP14Recipe
id: CP14ClothMaterialCotton
tag: CP14RecipeSewing
craftTime: 2
requirements:
- !type:ProtoIdResource
protoId: CP14Cotton
count: 2
result: CP14Cloth1
- type: CP14Recipe
id: CP14ClothingShirtCottonBlue
tag: CP14RecipeSewing

View File

@@ -19,8 +19,8 @@
id: CP14AlchemistGear
storage:
back:
- CP14EnergyCrystalSmall
- CP14EnergyCrystalSmall
- CP14EnergyCrystalMedium
- CP14EnergyCrystalMedium
equipment:
belt1: CP14WalletFilledTest
keys: CP14KeyRingAlchemist

View File

@@ -11,8 +11,8 @@
id: CP14ApprenticeGear
storage:
back:
- CP14EnergyCrystalSmall
- CP14EnergyCrystalSmall
- CP14EnergyCrystalMedium
- CP14EnergyCrystalMedium
equipment:
keys: CP14BaseKeyRing
belt1: CP14WalletFilledTest

View File

@@ -15,8 +15,8 @@
id: CP14BlacksmithGear
storage:
back:
- CP14EnergyCrystalSmall
- CP14EnergyCrystalSmall
- CP14EnergyCrystalMedium
- CP14EnergyCrystalMedium
equipment:
belt1: CP14WalletFilledTest
keys: CP14KeyRingBlacksmith

View File

@@ -11,7 +11,7 @@
id: CP14InnkeeperGear
storage:
back:
- CP14EnergyCrystalSmall
- CP14EnergyCrystalMedium
equipment:
belt1: CP14WalletFilledTest
keys: CP14KeyRingInnkeeper

View File

@@ -11,8 +11,8 @@
id: CP14AdventurerGear
storage:
back:
- CP14EnergyCrystalSmall
- CP14EnergyCrystalSmall
- CP14EnergyCrystalMedium
- CP14EnergyCrystalMedium
equipment:
keys: CP14BaseKeyRing
belt1: CP14WalletFilledTest

View File

@@ -29,7 +29,7 @@
id: CP14GuildmasterGear
storage:
back:
- CP14EnergyCrystalSmall
- CP14EnergyCrystalMedium
equipment:
belt1: CP14WalletFilledTest
keys: CP14KeyRingGuildmaster

View File

@@ -14,8 +14,8 @@
id: CP14MerchantGear
storage:
back:
- CP14EnergyCrystalSmall
- CP14EnergyCrystalSmall
- CP14EnergyCrystalMedium
- CP14EnergyCrystalMedium
equipment:
belt1: CP14WalletFilledTest
keys: CP14KeyRingMerchant

View File

@@ -19,14 +19,6 @@
<GuideEntityEmbed Entity="CP14LumiMushroom"/>
<GuideEntityEmbed Entity="CP14BloodFlower"/>
</Box>
<Box>
<GuideEntityEmbed Entity="CP14CrystalAir"/>
<GuideEntityEmbed Entity="CP14CrystalWater"/>
<GuideEntityEmbed Entity="CP14CrystalFire"/>
<GuideEntityEmbed Entity="CP14CrystalOrder"/>
<GuideEntityEmbed Entity="CP14CrystalChaos"/>
<GuideEntityEmbed Entity="CP14CrystalEarth"/>
</Box>
Most "raw" ingredients can first be ground using a mortar and pestle:

View File

@@ -19,14 +19,6 @@
<GuideEntityEmbed Entity="CP14LumiMushroom"/>
<GuideEntityEmbed Entity="CP14BloodFlower"/>
</Box>
<Box>
<GuideEntityEmbed Entity="CP14CrystalAir"/>
<GuideEntityEmbed Entity="CP14CrystalWater"/>
<GuideEntityEmbed Entity="CP14CrystalFire"/>
<GuideEntityEmbed Entity="CP14CrystalOrder"/>
<GuideEntityEmbed Entity="CP14CrystalChaos"/>
<GuideEntityEmbed Entity="CP14CrystalEarth"/>
</Box>
Большая часть таких "сырых" ингредиентов может быть сначала измельчена при помощи пестика и ступки:

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 B

View File

@@ -0,0 +1,20 @@
{
"version": 1,
"license": "CC-BY-SA-4.0",
"copyright": "Created by TheShuEd",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "base1"
},
{
"name": "base2"
},
{
"name": "base3"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

View File

@@ -39,6 +39,9 @@
},
{
"name": "sage"
},
{
"name": "cotton"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 276 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 B

After

Width:  |  Height:  |  Size: 316 B

View File

@@ -5,28 +5,10 @@
"y": 32
},
"license": "CC-BY-SA-3.0",
"copyright": "Created by TheShuEd (Github) ",
"copyright": "Created by TheShuEd (Github)",
"states": [
{
"name": "small1"
},
{
"name": "small2"
},
{
"name": "small3"
},
{
"name": "small_connector"
},
{
"name": "medium1"
},
{
"name": "medium2"
},
{
"name": "medium3"
"name": "medium"
},
{
"name": "medium_connector"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 B

Some files were not shown because too many files have changed in this diff Show More