Skill requirements (#1085)
* prerequites refactor * tiefling only spells * metamagic update * sort trying * goblin speed port
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using Content.Client._CP14.UserInterface.Systems.Skill;
|
||||
using Content.Client.UserInterface.Systems.Actions;
|
||||
using Content.Client.UserInterface.Systems.Admin;
|
||||
using Content.Client.UserInterface.Systems.Bwoink;
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Numerics;
|
||||
using Content.Shared._CP14.Skill;
|
||||
using Content.Shared._CP14.Skill.Components;
|
||||
using Content.Shared._CP14.Skill.Prototypes;
|
||||
using Content.Shared._CP14.Skill.Restrictions;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
@@ -130,19 +131,25 @@ public sealed partial class CP14SkillTreeGraphControl : BoxContainer
|
||||
|
||||
var fromPos = skill.SkillUiPosition * GridSize * UIScale + _globalOffset;
|
||||
|
||||
foreach (var prerequisite in skill.Prerequisites)
|
||||
foreach (var req in skill.Restrictions)
|
||||
{
|
||||
if (!_proto.TryIndex(prerequisite, out var prerequisiteSkill))
|
||||
continue;
|
||||
switch (req)
|
||||
{
|
||||
case NeedPrerequisite prerequisite:
|
||||
if (!_proto.TryIndex(prerequisite.Prerequisite, out var prerequisiteSkill))
|
||||
continue;
|
||||
|
||||
if (prerequisiteSkill.Tree != Tree)
|
||||
continue;
|
||||
if (prerequisiteSkill.Tree != Tree)
|
||||
continue;
|
||||
|
||||
var learned = playerSkills.Contains(skill.ID);
|
||||
var learned = playerSkills.Contains(skill.ID);
|
||||
|
||||
var toPos = prerequisiteSkill.SkillUiPosition * GridSize * UIScale + _globalOffset;
|
||||
var color = learned ? Color.White : Color.FromSrgb(new Color(0.7f, 0.7f, 0.7f));
|
||||
handle.DrawLine(fromPos, toPos, color);
|
||||
var toPos = prerequisiteSkill.SkillUiPosition * GridSize * UIScale + _globalOffset;
|
||||
var color = learned ? Color.White : Color.FromSrgb(new Color(0.7f, 0.7f, 0.7f));
|
||||
handle.DrawLine(fromPos, toPos, color);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,9 +160,7 @@ public sealed partial class CP14SkillTreeGraphControl : BoxContainer
|
||||
continue;
|
||||
|
||||
//TODO: Not optimized, recalculates every frame. Needs to be calculated on state update and cached.
|
||||
var learned = playerSkills.Contains(skill.ID);
|
||||
var available = _skillSystem.CanLearnSkill(_player.Value, skill.ID);
|
||||
var canBeLearned = learned || skill.Prerequisites.All(prerequisite => playerSkills.Contains(prerequisite));
|
||||
var canBeLearned = _skillSystem.CanLearnSkill(_player.Value, skill, _player.Value.Comp);
|
||||
var pos = skill.SkillUiPosition * GridSize * UIScale + _globalOffset;
|
||||
|
||||
// Base skill icon
|
||||
@@ -190,6 +195,9 @@ public sealed partial class CP14SkillTreeGraphControl : BoxContainer
|
||||
handle.DrawTextureRect(hoveredTexture, hoveredQuad, Color.White);
|
||||
}
|
||||
|
||||
var learned = playerSkills.Contains(skill.ID);
|
||||
var allowedToLearn = _skillSystem.AllowedToLearn(_player.Value, skill, _player.Value.Comp);
|
||||
|
||||
// Learned Skill
|
||||
if (learned)
|
||||
{
|
||||
@@ -198,7 +206,7 @@ public sealed partial class CP14SkillTreeGraphControl : BoxContainer
|
||||
var learnedQuad = new UIBox2(pos - learnedSize / 2, pos + learnedSize / 2);
|
||||
handle.DrawTextureRect(learnedTexture, learnedQuad, Color.White);
|
||||
}
|
||||
else if (available)
|
||||
else if (canBeLearned)
|
||||
{
|
||||
var availableTexture = Tree.AvailableIcon.Frame0();
|
||||
var availableSize = new Vector2(availableTexture.Width, availableTexture.Height) * 2;
|
||||
@@ -206,11 +214,12 @@ public sealed partial class CP14SkillTreeGraphControl : BoxContainer
|
||||
handle.DrawTextureRect(availableTexture, availableQuad, Color.White);
|
||||
}
|
||||
|
||||
var iconColor = Color.White;
|
||||
if (!learned)
|
||||
iconColor = Color.FromSrgb(new Color(0.7f, 0.7f, 0.7f));
|
||||
if (!canBeLearned && !learned)
|
||||
iconColor = Color.FromSrgb(new Color(0f, 0f, 0f));
|
||||
var iconColor = allowedToLearn switch
|
||||
{
|
||||
true when !learned => Color.FromSrgb(new Color(0.7f, 0.7f, 0.7f)),
|
||||
false when !learned => Color.FromSrgb(new Color(0f, 0f, 0f)),
|
||||
_ => Color.White
|
||||
};
|
||||
|
||||
handle.DrawTextureRect(baseTexture, baseQuad, iconColor);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using Content.Client._CP14.Skill;
|
||||
using Content.Client._CP14.Skill.Ui;
|
||||
using Content.Client._CP14.UserInterface.Systems.Skill.Window;
|
||||
@@ -18,7 +19,7 @@ using Robust.Shared.Input.Binding;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.UserInterface.Systems.Character;
|
||||
namespace Content.Client._CP14.UserInterface.Systems.Skill;
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed class CP14SkillUIController : UIController, IOnStateEntered<GameplayState>, IOnStateExited<GameplayState>,
|
||||
@@ -26,12 +27,13 @@ public sealed class CP14SkillUIController : UIController, IOnStateEntered<Gamepl
|
||||
{
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||
[UISystemDependency] private readonly CP14ClientSkillSystem _skill = default!;
|
||||
|
||||
private CP14SkillWindow? _window;
|
||||
private CP14SkillPrototype? _selectedSkill;
|
||||
|
||||
private MenuButton? SkillButton => UIManager.GetActiveUIWidgetOrNull<MenuBar.Widgets.GameTopMenuBar>()?.CP14SkillButton;
|
||||
private MenuButton? SkillButton => UIManager.GetActiveUIWidgetOrNull<Client.UserInterface.Systems.MenuBar.Widgets.GameTopMenuBar>()?.CP14SkillButton;
|
||||
|
||||
public void OnStateEntered(GameplayState state)
|
||||
{
|
||||
@@ -142,8 +144,23 @@ public sealed class CP14SkillUIController : UIController, IOnStateEntered<Gamepl
|
||||
{
|
||||
var msg = new FormattedMessage();
|
||||
|
||||
if (_player.LocalEntity == null)
|
||||
return msg;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
//Description
|
||||
msg.TryAddMarkup(_skill.GetSkillDescription(skill) + "\n", out _);
|
||||
sb.Append(_skill.GetSkillDescription(skill) + "\n \n");
|
||||
|
||||
//Restrictions
|
||||
foreach (var req in skill.Restrictions)
|
||||
{
|
||||
var color = req.Check(_entManager, _player.LocalEntity.Value) ? "green" : "red";
|
||||
|
||||
sb.Append($"- [color={color}]{req.GetDescription(_entManager, _proto)}[/color]\n");
|
||||
}
|
||||
|
||||
msg.TryAddMarkup(sb.ToString(), out _);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
@@ -138,11 +138,43 @@ public abstract partial class CP14SharedSkillSystem : EntitySystem
|
||||
public bool CanLearnSkill(EntityUid target,
|
||||
ProtoId<CP14SkillPrototype> skill,
|
||||
CP14SkillStorageComponent? component = null)
|
||||
{
|
||||
if (!_proto.TryIndex(skill, out var indexedSkill))
|
||||
return false;
|
||||
|
||||
return CanLearnSkill(target, indexedSkill, component);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the player can learn the specified skill.
|
||||
/// </summary>
|
||||
public bool CanLearnSkill(EntityUid target,
|
||||
CP14SkillPrototype skill,
|
||||
CP14SkillStorageComponent? component = null)
|
||||
{
|
||||
if (!Resolve(target, ref component, false))
|
||||
return false;
|
||||
|
||||
if (!_proto.TryIndex(skill, out var indexedSkill))
|
||||
if (!AllowedToLearn(target, skill, component))
|
||||
return false;
|
||||
|
||||
//Experience check
|
||||
if (!component.Progress.TryGetValue(skill.Tree, out var currentExp))
|
||||
return false;
|
||||
if (currentExp < skill.LearnCost)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is it allowed to learn this skill? The player may not have enough points to learn it, but has already met all the requirements to learn it.
|
||||
/// </summary>
|
||||
public bool AllowedToLearn(EntityUid target,
|
||||
CP14SkillPrototype skill,
|
||||
CP14SkillStorageComponent? component = null)
|
||||
{
|
||||
if (!Resolve(target, ref component, false))
|
||||
return false;
|
||||
|
||||
//Already learned
|
||||
@@ -150,22 +182,16 @@ public abstract partial class CP14SharedSkillSystem : EntitySystem
|
||||
return false;
|
||||
|
||||
//Check max cap
|
||||
if (component.SkillsSumExperience + indexedSkill.LearnCost >= component.ExperienceMaxCap)
|
||||
if (component.SkillsSumExperience + skill.LearnCost >= component.ExperienceMaxCap)
|
||||
return false;
|
||||
|
||||
//Prerequisite check
|
||||
foreach (var prerequisite in indexedSkill.Prerequisites)
|
||||
//Restrictions check
|
||||
foreach (var req in skill.Restrictions)
|
||||
{
|
||||
if (!HaveSkill(target, prerequisite, component))
|
||||
if (!req.Check(EntityManager, target))
|
||||
return false;
|
||||
}
|
||||
|
||||
//Experience check
|
||||
if (!component.Progress.TryGetValue(indexedSkill.Tree, out var currentExp))
|
||||
return false;
|
||||
if (currentExp < indexedSkill.LearnCost)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Linq;
|
||||
using Content.Shared._CP14.Skill.Components;
|
||||
using Content.Shared._CP14.Skill.Prototypes;
|
||||
using Content.Shared.Administration;
|
||||
@@ -11,21 +12,43 @@ public abstract partial class CP14SharedSkillSystem
|
||||
{
|
||||
[Dependency] private readonly ISharedAdminManager _admin = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
|
||||
private IEnumerable<CP14SkillPrototype>? _allSkills;
|
||||
private void InitializeAdmin()
|
||||
{
|
||||
SubscribeLocalEvent<CP14SkillStorageComponent, GetVerbsEvent<Verb>>(OnGetAdminVerbs);
|
||||
|
||||
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypeReloaded);
|
||||
|
||||
UpdateCachedSkill();
|
||||
}
|
||||
|
||||
private void OnPrototypeReloaded(PrototypesReloadedEventArgs ev)
|
||||
{
|
||||
if (!ev.WasModified<CP14SkillPrototype>())
|
||||
return;
|
||||
|
||||
UpdateCachedSkill();
|
||||
}
|
||||
|
||||
private void UpdateCachedSkill()
|
||||
{
|
||||
_allSkills = _proto.EnumeratePrototypes<CP14SkillPrototype>().ToList().OrderBy(skill => skill.Tree.Id).ThenBy(skill => skill.Name);
|
||||
}
|
||||
|
||||
|
||||
private void OnGetAdminVerbs(Entity<CP14SkillStorageComponent> ent, ref GetVerbsEvent<Verb> args)
|
||||
{
|
||||
if (!_admin.HasAdminFlag(args.User, AdminFlags.Admin))
|
||||
return;
|
||||
|
||||
if (_allSkills is null)
|
||||
return;
|
||||
|
||||
var target = args.Target;
|
||||
|
||||
//Add Skill
|
||||
foreach (var skill in _proto.EnumeratePrototypes<CP14SkillPrototype>())
|
||||
foreach (var skill in _allSkills)
|
||||
{
|
||||
if (ent.Comp.LearnedSkills.Contains(skill))
|
||||
continue;
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
using Content.Shared.Actions;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Skill.Specials;
|
||||
namespace Content.Shared._CP14.Skill.Effects;
|
||||
|
||||
public sealed partial class AddAction : CP14SkillEffect
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public EntProtoId Action;
|
||||
|
||||
public override void AddSkill(EntityManager entManager, EntityUid target)
|
||||
public override void AddSkill(IEntityManager entManager, EntityUid target)
|
||||
{
|
||||
var actionsSystem = entManager.System<SharedActionsSystem>();
|
||||
|
||||
actionsSystem.AddAction(target, Action);
|
||||
}
|
||||
|
||||
public override void RemoveSkill(EntityManager entManager, EntityUid target)
|
||||
public override void RemoveSkill(IEntityManager entManager, EntityUid target)
|
||||
{
|
||||
var actionsSystem = entManager.System<SharedActionsSystem>();
|
||||
|
||||
@@ -34,19 +34,13 @@ public sealed partial class AddAction : CP14SkillEffect
|
||||
}
|
||||
}
|
||||
|
||||
public override string? GetName(EntityManager entMagager, IPrototypeManager protoManager)
|
||||
public override string? GetName(IEntityManager entMagager, IPrototypeManager protoManager)
|
||||
{
|
||||
if (!protoManager.TryIndex(Action, out var indexedAction))
|
||||
return String.Empty;
|
||||
|
||||
return indexedAction.Name;
|
||||
return !protoManager.TryIndex(Action, out var indexedAction) ? string.Empty : indexedAction.Name;
|
||||
}
|
||||
|
||||
public override string? GetDescription(EntityManager entMagager, IPrototypeManager protoManager)
|
||||
public override string? GetDescription(IEntityManager entMagager, IPrototypeManager protoManager)
|
||||
{
|
||||
if (!protoManager.TryIndex(Action, out var indexedAction))
|
||||
return String.Empty;
|
||||
|
||||
return indexedAction.Description;
|
||||
return !protoManager.TryIndex(Action, out var indexedAction) ? string.Empty : indexedAction.Description;
|
||||
}
|
||||
}
|
||||
17
Content.Shared/_CP14/Skill/Effects/CP14SkillEffect.cs
Normal file
17
Content.Shared/_CP14/Skill/Effects/CP14SkillEffect.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Skill.Effects;
|
||||
|
||||
[ImplicitDataDefinitionForInheritors]
|
||||
[MeansImplicitUse]
|
||||
public abstract partial class CP14SkillEffect
|
||||
{
|
||||
public abstract void AddSkill(IEntityManager entManager, EntityUid target);
|
||||
|
||||
public abstract void RemoveSkill(IEntityManager entManager, EntityUid target);
|
||||
|
||||
public abstract string? GetName(IEntityManager entMagager, IPrototypeManager protoManager);
|
||||
|
||||
public abstract string? GetDescription(IEntityManager entMagager, IPrototypeManager protoManager);
|
||||
}
|
||||
69
Content.Shared/_CP14/Skill/Effects/ReplaceAction.cs
Normal file
69
Content.Shared/_CP14/Skill/Effects/ReplaceAction.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using Content.Shared.Actions;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Skill.Effects;
|
||||
|
||||
public sealed partial class ReplaceAction : CP14SkillEffect
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public EntProtoId OldAction;
|
||||
|
||||
[DataField(required: true)]
|
||||
public EntProtoId NewAction;
|
||||
|
||||
public override void AddSkill(IEntityManager entManager, EntityUid target)
|
||||
{
|
||||
var actionsSystem = entManager.System<SharedActionsSystem>();
|
||||
|
||||
//Remove old action
|
||||
foreach (var (uid, _) in actionsSystem.GetActions(target))
|
||||
{
|
||||
if (!entManager.TryGetComponent<MetaDataComponent>(uid, out var metaData))
|
||||
continue;
|
||||
|
||||
if (metaData.EntityPrototype == null)
|
||||
continue;
|
||||
|
||||
if (metaData.EntityPrototype != OldAction)
|
||||
continue;
|
||||
|
||||
actionsSystem.RemoveAction(target, uid);
|
||||
}
|
||||
|
||||
//Add new one
|
||||
actionsSystem.AddAction(target, NewAction);
|
||||
}
|
||||
|
||||
public override void RemoveSkill(IEntityManager entManager, EntityUid target)
|
||||
{
|
||||
var actionsSystem = entManager.System<SharedActionsSystem>();
|
||||
|
||||
//Remove old action
|
||||
foreach (var (uid, _) in actionsSystem.GetActions(target))
|
||||
{
|
||||
if (!entManager.TryGetComponent<MetaDataComponent>(uid, out var metaData))
|
||||
continue;
|
||||
|
||||
if (metaData.EntityPrototype == null)
|
||||
continue;
|
||||
|
||||
if (metaData.EntityPrototype != NewAction)
|
||||
continue;
|
||||
|
||||
actionsSystem.RemoveAction(target, uid);
|
||||
}
|
||||
|
||||
//Add new one
|
||||
actionsSystem.AddAction(target, OldAction);
|
||||
}
|
||||
|
||||
public override string? GetName(IEntityManager entMagager, IPrototypeManager protoManager)
|
||||
{
|
||||
return !protoManager.TryIndex(NewAction, out var indexedAction) ? string.Empty : indexedAction.Name;
|
||||
}
|
||||
|
||||
public override string? GetDescription(IEntityManager entMagager, IPrototypeManager protoManager)
|
||||
{
|
||||
return !protoManager.TryIndex(NewAction, out var indexedAction) ? string.Empty : indexedAction.Description;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared._CP14.Skill.Specials;
|
||||
using Content.Shared._CP14.Skill.Effects;
|
||||
using Content.Shared._CP14.Skill.Restrictions;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -37,12 +38,6 @@ public sealed partial class CP14SkillPrototype : IPrototype
|
||||
[DataField]
|
||||
public float LearnCost = 1f;
|
||||
|
||||
/// <summary>
|
||||
/// Prerequisites for this skill. This is used to determine if the player can learn the skill. If the player does not have all the prerequisites, they cannot learn the skill.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public HashSet<ProtoId<CP14SkillPrototype>> Prerequisites = new();
|
||||
|
||||
/// <summary>
|
||||
/// Skill UI position. This is used to determine where the skill will be displayed in the skill tree UI.
|
||||
/// </summary>
|
||||
@@ -61,4 +56,10 @@ public sealed partial class CP14SkillPrototype : IPrototype
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public CP14SkillEffect? Effect;
|
||||
|
||||
/// <summary>
|
||||
/// Skill restriction. Limiters on learning. Any reason why a player cannot learn this skill.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public List<CP14SkillRestriction> Restrictions = new();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Skill.Restrictions;
|
||||
|
||||
[ImplicitDataDefinitionForInheritors]
|
||||
[MeansImplicitUse]
|
||||
public abstract partial class CP14SkillRestriction
|
||||
{
|
||||
public abstract bool Check(IEntityManager entManager, EntityUid target);
|
||||
|
||||
public abstract string GetDescription(IEntityManager entManager, IPrototypeManager protoManager);
|
||||
}
|
||||
27
Content.Shared/_CP14/Skill/Restrictions/NeedPrerequisite.cs
Normal file
27
Content.Shared/_CP14/Skill/Restrictions/NeedPrerequisite.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using Content.Shared._CP14.Skill.Components;
|
||||
using Content.Shared._CP14.Skill.Prototypes;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Skill.Restrictions;
|
||||
|
||||
public sealed partial class NeedPrerequisite : CP14SkillRestriction
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public ProtoId<CP14SkillPrototype> Prerequisite = new();
|
||||
|
||||
public override bool Check(IEntityManager entManager, EntityUid target)
|
||||
{
|
||||
if (!entManager.TryGetComponent<CP14SkillStorageComponent>(target, out var skillStorage))
|
||||
return false;
|
||||
|
||||
var learned = skillStorage.LearnedSkills;
|
||||
return learned.Contains(Prerequisite);
|
||||
}
|
||||
|
||||
public override string GetDescription(IEntityManager entManager, IPrototypeManager protoManager)
|
||||
{
|
||||
var skillSystem = entManager.System<CP14SharedSkillSystem>();
|
||||
|
||||
return Loc.GetString("cp14-skill-req-prerequisite", ("name", skillSystem.GetSkillName(Prerequisite)));
|
||||
}
|
||||
}
|
||||
26
Content.Shared/_CP14/Skill/Restrictions/SpeciesWhitelist.cs
Normal file
26
Content.Shared/_CP14/Skill/Restrictions/SpeciesWhitelist.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Humanoid.Prototypes;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Skill.Restrictions;
|
||||
|
||||
public sealed partial class SpeciesWhitelist : CP14SkillRestriction
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public ProtoId<SpeciesPrototype> Species = new();
|
||||
|
||||
public override bool Check(IEntityManager entManager, EntityUid target)
|
||||
{
|
||||
if (!entManager.TryGetComponent<HumanoidAppearanceComponent>(target, out var appearance))
|
||||
return false;
|
||||
|
||||
return appearance.Species == Species;
|
||||
}
|
||||
|
||||
public override string GetDescription(IEntityManager entManager, IPrototypeManager protoManager)
|
||||
{
|
||||
var species = protoManager.Index(Species);
|
||||
|
||||
return Loc.GetString("cp14-skill-req-species", ("name", Loc.GetString(species.Name)));
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Skill.Specials;
|
||||
|
||||
[ImplicitDataDefinitionForInheritors]
|
||||
[MeansImplicitUse]
|
||||
public abstract partial class CP14SkillEffect
|
||||
{
|
||||
public abstract void AddSkill(EntityManager entManager, EntityUid target);
|
||||
|
||||
public abstract void RemoveSkill(EntityManager entManager, EntityUid target);
|
||||
|
||||
public abstract string? GetName(EntityManager entMagager, IPrototypeManager protoManager);
|
||||
|
||||
public abstract string? GetDescription(EntityManager entMagager, IPrototypeManager protoManager);
|
||||
}
|
||||
2
Resources/Locale/en-US/_CP14/skill/requirements.ftl
Normal file
2
Resources/Locale/en-US/_CP14/skill/requirements.ftl
Normal file
@@ -0,0 +1,2 @@
|
||||
cp14-skill-req-prerequisite = Skill "{$name}" must be learned.
|
||||
cp14-skill-req-species = Available only to species "{$name}"
|
||||
2
Resources/Locale/ru-RU/_CP14/skill/requirements.ftl
Normal file
2
Resources/Locale/ru-RU/_CP14/skill/requirements.ftl
Normal file
@@ -0,0 +1,2 @@
|
||||
cp14-skill-req-prerequisite = Навык "{$name}" должен быть изучен.
|
||||
cp14-skill-req-species = Доступно только расе "{$name}"
|
||||
@@ -24,8 +24,8 @@
|
||||
- !type:Polymorph
|
||||
prototype: CP14Sheep
|
||||
- type: CP14MagicEffectVerbalAspect
|
||||
startSpeech: "Pellis dolorem..."
|
||||
endSpeech: "non novit"
|
||||
startSpeech: "Pascam et custodiam..."
|
||||
endSpeech: "pecora tua"
|
||||
- type: CP14MagicEffectCastingVisual
|
||||
proto: CP14RuneSheepPolymorph
|
||||
- type: EntityTargetAction
|
||||
|
||||
@@ -1,13 +1,3 @@
|
||||
- type: entity
|
||||
id: CP14DummyActionSpellManaManipulation
|
||||
name: Mana manipulation
|
||||
description: You can manipulate mana by giving it to other objects or taking it from them.
|
||||
categories: [ HideSpawnMenu ]
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: _CP14/Actions/Spells/meta.rsi
|
||||
state: mana
|
||||
|
||||
- type: entity
|
||||
id: CP14ActionSpellManaGift
|
||||
name: Mana transfer
|
||||
@@ -54,6 +44,25 @@
|
||||
castTime: 10
|
||||
breakOnMove: true
|
||||
|
||||
- type: entity
|
||||
id: CP14ActionSpellManaGiftElf
|
||||
parent: CP14ActionSpellManaGift
|
||||
name: Carefull mana transfer
|
||||
description: You transfer mana at a tremendous rate without dealing damage to the target.
|
||||
components:
|
||||
- type: CP14MagicEffectManaCost
|
||||
manaCost: 20
|
||||
- type: CP14MagicEffect
|
||||
effects:
|
||||
- !type:CP14SpellSpawnEntityOnTarget
|
||||
spawns:
|
||||
- CP14ImpactEffectManaGift
|
||||
- !type:CP14SpellApplyEntityEffect
|
||||
effects:
|
||||
- !type:CP14ManaChange
|
||||
manaDelta: 20
|
||||
safe: true
|
||||
|
||||
- type: entity
|
||||
id: CP14RuneManaGift
|
||||
parent: CP14BaseMagicRune
|
||||
@@ -1,12 +1,12 @@
|
||||
- type: loadoutGroup
|
||||
id: CP14SkillTree
|
||||
name: cp14-loadout-skill-tree
|
||||
minLimit: 0
|
||||
minLimit: 2
|
||||
maxLimit: 2
|
||||
loadouts:
|
||||
- CP14SkillTreePyrokinetic
|
||||
- CP14SkillTreeHydrosophistry
|
||||
- CP14SkillTreeMetamagic
|
||||
- CP14SkillTreeHydrosophistry
|
||||
- CP14SkillTreePyrokinetic
|
||||
- CP14SkillTreeIllusion
|
||||
- CP14SkillTreeHealing
|
||||
- CP14SkillTreeAtlethic
|
||||
|
||||
@@ -16,4 +16,21 @@
|
||||
sprite: _CP14/Actions/Spells/physical.rsi
|
||||
state: sprint
|
||||
effect: !type:AddAction
|
||||
action: CP14ActionSpellSprint
|
||||
action: CP14ActionSpellSprint
|
||||
|
||||
- type: cp14Skill
|
||||
id: CP14ActionSpellSprintGoblin
|
||||
skillUiPosition: 2, 2
|
||||
learnCost: 0
|
||||
tree: Atlethic
|
||||
icon:
|
||||
sprite: _CP14/Actions/Spells/physical.rsi
|
||||
state: sprint
|
||||
effect: !type:ReplaceAction
|
||||
oldAction: CP14ActionSpellSprint
|
||||
newAction: CP14ActionSpellSprintGoblin
|
||||
restrictions:
|
||||
- !type:NeedPrerequisite
|
||||
prerequisite: CP14ActionSpellSprint
|
||||
- !type:SpeciesWhitelist
|
||||
species: CP14Goblin
|
||||
@@ -27,6 +27,9 @@
|
||||
state: beer_creation
|
||||
effect: !type:AddAction
|
||||
action: CP14ActionSpellBeerCreation
|
||||
restrictions:
|
||||
- !type:SpeciesWhitelist
|
||||
species: CP14Dwarf
|
||||
|
||||
- type: cp14Skill
|
||||
id: CP14ActionSpellIceShards
|
||||
|
||||
@@ -20,16 +20,50 @@
|
||||
action: CP14ActionSpellManaGift
|
||||
|
||||
- type: cp14Skill
|
||||
id: CP14ActionSpellManaConsume
|
||||
id: CP14ActionSpellManaGiftElf
|
||||
skillUiPosition: 2, 2
|
||||
learnCost: 0.5
|
||||
tree: Metamagic
|
||||
icon:
|
||||
sprite: _CP14/Actions/Spells/meta.rsi
|
||||
state: mana_gift
|
||||
effect: !type:ReplaceAction
|
||||
oldAction: CP14ActionSpellManaGift
|
||||
newAction: CP14ActionSpellManaGiftElf
|
||||
restrictions:
|
||||
- !type:NeedPrerequisite
|
||||
prerequisite: CP14ActionSpellManaGift
|
||||
- !type:SpeciesWhitelist
|
||||
species: CP14Elf
|
||||
|
||||
- type: cp14Skill
|
||||
id: CP14ActionSpellManaConsume
|
||||
skillUiPosition: 0, 4
|
||||
learnCost: 0.5
|
||||
tree: Metamagic
|
||||
icon:
|
||||
sprite: _CP14/Actions/Spells/meta.rsi
|
||||
state: mana_consume
|
||||
effect: !type:AddAction
|
||||
action: CP14ActionSpellManaConsume
|
||||
|
||||
- type: cp14Skill
|
||||
id: CP14ActionSpellManaConsumeElf
|
||||
skillUiPosition: 2, 4
|
||||
learnCost: 0.5
|
||||
tree: Metamagic
|
||||
icon:
|
||||
sprite: _CP14/Actions/Spells/meta.rsi
|
||||
state: mana_consume
|
||||
effect: !type:ReplaceAction
|
||||
oldAction: CP14ActionSpellManaConsume
|
||||
newAction: CP14ActionSpellManaConsumeElf
|
||||
restrictions:
|
||||
- !type:NeedPrerequisite
|
||||
prerequisite: CP14ActionSpellManaConsume
|
||||
- !type:SpeciesWhitelist
|
||||
species: CP14Elf
|
||||
|
||||
- type: cp14Skill
|
||||
id: CP14ActionSpellMagicBallade
|
||||
skillUiPosition: 0, 6
|
||||
|
||||
@@ -10,10 +10,26 @@
|
||||
|
||||
- type: cp14Skill
|
||||
id: CP14ActionSpellHellBallade
|
||||
skillUiPosition: 0, 10
|
||||
skillUiPosition: 0, 2
|
||||
tree: Pyrokinetic
|
||||
icon:
|
||||
sprite: _CP14/Actions/Spells/fire.rsi
|
||||
state: fire_music
|
||||
effect: !type:AddAction
|
||||
action: CP14ActionSpellHellBallade
|
||||
action: CP14ActionSpellHellBallade
|
||||
restrictions:
|
||||
- !type:SpeciesWhitelist
|
||||
species: CP14Tiefling
|
||||
|
||||
- type: cp14Skill
|
||||
id: CP14ActionSpellTieflingInnerFire
|
||||
skillUiPosition: 0, 4
|
||||
tree: Pyrokinetic
|
||||
icon:
|
||||
sprite: _CP14/Actions/Spells/fire.rsi
|
||||
state: tiefling_revenge
|
||||
effect: !type:AddAction
|
||||
action: CP14ActionSpellTieflingInnerFire
|
||||
restrictions:
|
||||
- !type:SpeciesWhitelist
|
||||
species: CP14Tiefling
|
||||
Reference in New Issue
Block a user