Skills system (#247)

* init basic skill system

* add skill requirement to advanced melee weapon

* working hard

* more hard work

* shot skill issue

* Now the skills give you the components

* add job special autolearning skills

* traits recreating

* some tweaks

* remove bg and components for now

* sharpening now require skills

* add alchemist role on maps

* pestle skill issue
This commit is contained in:
Ed
2024-06-15 16:55:04 +03:00
committed by GitHub
parent 39bb249eb3
commit c5a8e96dca
39 changed files with 937 additions and 239 deletions

View File

@@ -1,5 +1,6 @@
using Content.Server.Body.Components;
using Content.Server.Body.Systems;
using Content.Shared._CP14.Skills;
using Content.Shared.Chemistry;
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Components.SolutionManager;
@@ -31,6 +32,8 @@ public sealed class InjectorSystem : SharedInjectorSystem
private bool TryUseInjector(Entity<InjectorComponent> injector, EntityUid target, EntityUid user)
{
RaiseLocalEvent(injector, new CP14TrySkillIssueEvent(user)); //CP14 Skill issue event
// Handle injecting/drawing for solutions
if (injector.Comp.ToggleState == InjectorToggleMode.Inject)
{

View File

@@ -33,6 +33,13 @@ public sealed partial class CP14AlchemyExtractionSystem : EntitySystem
_audio.PlayPvs(pestle.HitSound, mortar);
var ev = new PestleGrindingEvent()
{
User = args.User,
Target = args.Target,
};
RaiseLocalEvent(args.Used, ev);
if (!_random.Prob(pestle.Probability))
return;
@@ -86,3 +93,12 @@ public sealed partial class CP14AlchemyExtractionSystem : EntitySystem
_solutionContainer.TryAddSolution(solutionEnt.Value, juiceSolution);
}
}
/// <summary>
/// is triggered on the pestle when the player uses it to grind something.
/// </summary>
public sealed class PestleGrindingEvent : EntityEventArgs
{
public EntityUid User;
public EntityUid Target;
}

View File

@@ -11,7 +11,6 @@ namespace Content.Server._CP14.MagicEnergy;
public sealed partial class CP14MagicEnergyCrystalSlotSystem : SharedCP14MagicEnergyCrystalSlotSystem
{
[Dependency] private readonly ItemSlotsSystem _itemSlots = default!;
[Dependency] private readonly CP14MagicEnergySystem _magicEnergy = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;

View File

@@ -52,7 +52,7 @@ public sealed class CP14SharpeningSystem : EntitySystem
if (!TryComp<CP14SharpenedComponent>(item, out var sharpened))
continue;
SharpThing(stone, item, sharpened);
SharpThing(stone, item, sharpened, args.User);
return;
}
}
@@ -65,18 +65,28 @@ public sealed class CP14SharpeningSystem : EntitySystem
if (TryComp<UseDelayComponent>(stone, out var useDelay) && _useDelay.IsDelayed( new Entity<UseDelayComponent>(stone, useDelay)))
return;
SharpThing(stone, args.Target.Value, sharpened);
SharpThing(stone, args.Target.Value, sharpened, args.User);
}
private void SharpThing(Entity<CP14SharpeningStoneComponent> stone, EntityUid target, CP14SharpenedComponent component)
private void SharpThing(Entity<CP14SharpeningStoneComponent> stone, EntityUid target, CP14SharpenedComponent component, EntityUid user)
{
_audio.PlayPvs(stone.Comp.SharpeningSound, target);
Spawn("EffectSparks", Transform(target).Coordinates);
var ev = new SharpingEvent()
{
User = user,
Target = target,
};
RaiseLocalEvent(stone, ev);
_damageableSystem.TryChangeDamage(stone, stone.Comp.SelfDamage);
_damageableSystem.TryChangeDamage(target, stone.Comp.TargetDamage);
if (!ev.Canceled)
{
_audio.PlayPvs(stone.Comp.SharpeningSound, target);
Spawn("EffectSparks", Transform(target).Coordinates);
component.Sharpness = MathHelper.Clamp01(component.Sharpness + stone.Comp.SharpnessHeal);
_damageableSystem.TryChangeDamage(stone, stone.Comp.SelfDamage);
_damageableSystem.TryChangeDamage(target, stone.Comp.TargetDamage);
component.Sharpness = MathHelper.Clamp01(component.Sharpness + stone.Comp.SharpnessHeal);
}
_useDelay.TryResetDelay(stone);
}
@@ -110,3 +120,13 @@ public sealed class CP14SharpeningSystem : EntitySystem
}
}
/// <summary>
/// Caused on a sharpening stone when someone tries to sharpen an object with it
/// </summary>
public sealed class SharpingEvent : EntityEventArgs
{
public bool Canceled = false;
public EntityUid User;
public EntityUid Target;
}

View File

@@ -0,0 +1,169 @@
using System.Numerics;
using Content.Server._CP14.Alchemy;
using Content.Server._CP14.MeleeWeapon;
using Content.Server.Popups;
using Content.Shared._CP14.Skills;
using Content.Shared._CP14.Skills.Components;
using Content.Shared.Chemistry.Components;
using Content.Shared.Damage;
using Content.Shared.Examine;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Popups;
using Content.Shared.Stunnable;
using Content.Shared.Throwing;
using Content.Shared.Weapons.Melee;
using Content.Shared.Weapons.Melee.Events;
using Content.Shared.Weapons.Ranged.Systems;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
namespace Content.Server._CP14.Skills;
public sealed partial class CP14SkillSystem : SharedCP14SkillSystem
{
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly DamageableSystem _damageable = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly ThrowingSystem _throwing = default!;
[Dependency] private readonly SharedHandsSystem _hands = default!;
public override void Initialize()
{
SubscribeLocalEvent<CP14SkillRequirementComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<CP14SkillRequirementComponent, GunShotEvent>(OnGunShot);
SubscribeLocalEvent<CP14SkillRequirementComponent, MeleeHitEvent>(OnMeleeHit);
SubscribeLocalEvent<CP14SkillRequirementComponent, CP14TrySkillIssueEvent>(OnSimpleSkillIssue);
SubscribeLocalEvent<CP14SkillRequirementComponent, SharpingEvent>(OnSharpning);
SubscribeLocalEvent<CP14SkillRequirementComponent, PestleGrindingEvent>(OnPestleGrinding);
}
private void OnExamined(Entity<CP14SkillRequirementComponent> requirement, ref ExaminedEvent args)
{
var text = string.Empty;
text += "\n" + Loc.GetString("cp14-skill-label") + "\n";
var canUse = HasEnoughSkillToUse(args.Examiner, requirement, out var missingSkills);
text += Loc.GetString(requirement.Comp.NeedAll ? "cp14-skill-examined-need-all" : "cp14-skill-examined", ("item", MetaData(requirement).EntityName)) + "\n";
foreach (var skill in requirement.Comp.RequiredSkills)
{
var name = _proto.Index(skill).Name;
if (name == null)
continue;
var color = missingSkills.Contains(skill) ? "#c23030" : "#3fc488";
text += Loc.GetString("cp14-skill-examined-skill", ("color", color), ("skill", Loc.GetString(name))) + "\n";
}
args.PushMarkup(text);
}
private void OnPestleGrinding(Entity<CP14SkillRequirementComponent> requirement, ref PestleGrindingEvent args)
{
if (!_random.Prob(requirement.Comp.FuckupChance))
return;
if (HasEnoughSkillToUse(args.User, requirement, out _))
return;
_popup.PopupEntity(Loc.GetString("cp14-skill-issue-push", ("item", MetaData(args.Target).EntityName)),
args.User,
args.User,
PopupType.Large);
_hands.TryDrop(args.User, args.Target);
_throwing.TryThrow(args.Target, _random.NextAngle().ToWorldVec(), 1, args.User);
}
private void OnSharpning(Entity<CP14SkillRequirementComponent> requirement, ref SharpingEvent args)
{
if (!_random.Prob(requirement.Comp.FuckupChance))
return;
if (HasEnoughSkillToUse(args.User, requirement, out _))
return;
switch (_random.Next(2))
{
case 0:
_popup.PopupEntity(Loc.GetString("cp14-skill-issue-sharp-weapon-harm", ("item", MetaData(args.Target).EntityName)), args.User, args.User, PopupType.Large);
var weaponDamage = new DamageSpecifier();
weaponDamage.DamageDict.Add("Blunt", _random.NextFloat(5));
_damageable.TryChangeDamage(args.Target, weaponDamage);
break;
case 1:
_popup.PopupEntity(Loc.GetString("cp14-skill-issue-sharp-self-harm"), args.User, args.User, PopupType.Large);
var damage = new DamageSpecifier();
if (TryComp<MeleeWeaponComponent>(requirement, out var melee))
damage = melee.Damage;
else
damage.DamageDict.Add("Slash", _random.NextFloat(10));
_damageable.TryChangeDamage(args.User, damage);
break;
}
}
private void OnSimpleSkillIssue(Entity<CP14SkillRequirementComponent> requirement, ref CP14TrySkillIssueEvent args)
{
if (!_random.Prob(requirement.Comp.FuckupChance))
return;
if (HasEnoughSkillToUse(args.User, requirement, out _))
return;
BasicSkillIssue(args.User, requirement);
}
private void OnMeleeHit(Entity<CP14SkillRequirementComponent> requirement, ref MeleeHitEvent args)
{
if (!_random.Prob(requirement.Comp.FuckupChance))
return;
if (HasEnoughSkillToUse(args.User, requirement, out _))
return;
switch (_random.Next(2))
{
case 0:
BasicSkillIssue(args.User, requirement);
break;
case 1:
_popup.PopupEntity(Loc.GetString("cp14-skill-issue-self-harm"), args.User, args.User, PopupType.Large);
var damage = new DamageSpecifier();
if (TryComp<MeleeWeaponComponent>(requirement, out var melee))
damage = melee.Damage;
else
damage.DamageDict.Add("Blunt", _random.NextFloat(10));
_damageable.TryChangeDamage(args.User, damage);
break;
}
}
private void OnGunShot(Entity<CP14SkillRequirementComponent> requirement, ref GunShotEvent args)
{
if (!_random.Prob(requirement.Comp.FuckupChance))
return;
if (HasEnoughSkillToUse(args.User, requirement, out _))
return;
_popup.PopupEntity(Loc.GetString("cp14-skill-issue-recoil"), args.User, args.User, PopupType.Large);
_hands.TryDrop(args.User, requirement);
_throwing.TryThrow(requirement, _random.NextAngle().ToWorldVec(), _random.NextFloat(5), args.User);
var damage = new DamageSpecifier();
damage.DamageDict.Add("Blunt", _random.NextFloat(10));
_damageable.TryChangeDamage(args.User, damage);
}
private void BasicSkillIssue(EntityUid user, EntityUid item, float throwPower = 1)
{
_popup.PopupEntity(Loc.GetString("cp14-skill-issue-drops", ("item", MetaData(item).EntityName)), user, user, PopupType.Large);
_hands.TryDrop(user, item);
_throwing.TryThrow(item, _random.NextAngle().ToWorldVec(), throwPower, user);
}
}

View File

@@ -387,10 +387,10 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
var ev = new AttemptMeleeEvent();
RaiseLocalEvent(weaponUid, ref ev);
//CrystallPun melee improvment
//CrystallPunk melee improvment
if (weapon.CPSwingBeverage)
weapon.SwingLeft = !weapon.SwingLeft;
//CrystallPun melee improvment end
//CrystallPunk melee improvment end
if (ev.Cancelled)
{

View File

@@ -0,0 +1,26 @@
using Content.Shared._CP14.Skills.Prototypes;
using Content.Shared.Roles;
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.Skills.Components;
/// <summary>
/// a component that can be hung on an entity to immediately teach it some skills
/// </summary>
[UsedImplicitly]
public sealed partial class CP14AddSkillSpecial : JobSpecial
{
[DataField, ViewVariables(VVAccess.ReadOnly)]
public List<ProtoId<CP14SkillPrototype>> Skills = new();
public override void AfterEquip(EntityUid mob)
{
var entMan = IoCManager.Resolve<IEntityManager>();
var skillSystem = entMan.System<SharedCP14SkillSystem>();
foreach (var skill in Skills)
{
skillSystem.TryLearnSkill(mob, skill);
}
}
}

View File

@@ -0,0 +1,14 @@
using Content.Shared._CP14.Skills.Prototypes;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.Skills.Components;
/// <summary>
/// The ability to add a skill to an entity and quickly teach it some skills
/// </summary>
[RegisterComponent, Access(typeof(SharedCP14SkillSystem))]
public sealed partial class CP14AutoAddSkillComponent : Component
{
[DataField]
public List<ProtoId<CP14SkillPrototype>> Skills = new();
}

View File

@@ -0,0 +1,27 @@
using Content.Shared._CP14.Skills.Prototypes;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.Skills.Components;
/// <summary>
/// Limits the use of this entity behind certain skills
/// </summary>
[RegisterComponent, Access(typeof(SharedCP14SkillSystem))]
public sealed partial class CP14SkillRequirementComponent : Component
{
/// <summary>
/// Is it necessary to have ALL the skills on the list to be able to use this entity?
/// If not, one of any skill will suffice
/// </summary>
[DataField]
public bool NeedAll = false;
/// <summary>
/// the chances of something going wrong when using wihout skill
/// </summary>
[DataField]
public float FuckupChance = 0.5f;
[DataField(required: true)]
public List<ProtoId<CP14SkillPrototype>> RequiredSkills = new();
}

View File

@@ -0,0 +1,14 @@
using Content.Shared._CP14.Skills.Prototypes;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.Skills.Components;
/// <summary>
/// a list of skills learned by this entity
/// </summary>
[RegisterComponent, Access(typeof(SharedCP14SkillSystem))]
public sealed partial class CP14SkillsStorageComponent : Component
{
[DataField, ViewVariables(VVAccess.ReadOnly)]
public List<ProtoId<CP14SkillPrototype>> Skills { get; private set; }= new();
}

View File

@@ -0,0 +1,23 @@
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.Skills.Prototypes;
/// <summary>
/// A prototype of the lock category. Need a roundstart mapping to ensure that keys and locks will fit together despite randomization.
/// </summary>
[Prototype("CP14Skill")]
public sealed partial class CP14SkillPrototype : IPrototype
{
[ViewVariables]
[IdDataField]
public string ID { get; private set; } = default!;
[DataField(required: true)]
public LocId? Name{ get; private set; }
[DataField]
public LocId? Desc{ get; private set; }
[DataField]
public ComponentRegistry Components = new();
}

View File

@@ -0,0 +1,114 @@
using Content.Shared._CP14.Skills.Components;
using Content.Shared._CP14.Skills.Prototypes;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
namespace Content.Shared._CP14.Skills;
public partial class SharedCP14SkillSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _proto = default!;
public override void Initialize()
{
SubscribeLocalEvent<CP14SkillsStorageComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<CP14AutoAddSkillComponent, MapInitEvent>(AutoAddSkill);
}
private void AutoAddSkill(Entity<CP14AutoAddSkillComponent> ent, ref MapInitEvent args)
{
foreach (var skill in ent.Comp.Skills)
{
TryLearnSkill(ent, skill);
}
RemComp(ent, ent.Comp);
}
private void OnMapInit(Entity<CP14SkillsStorageComponent> ent, ref MapInitEvent args)
{
foreach (var skill in ent.Comp.Skills)
{
TryLearnSkill(ent, skill, force: true);
}
}
public bool HasEnoughSkillToUse(EntityUid user, EntityUid target, out List<ProtoId<CP14SkillPrototype>> missingSkills)
{
missingSkills = new();
if (!TryComp<CP14SkillRequirementComponent>(target, out var requirement) || requirement.RequiredSkills.Count == 0)
return true;
if (!TryComp<CP14SkillsStorageComponent>(user, out var skillStorage))
{
missingSkills = requirement.RequiredSkills;
return false;
}
var success = requirement.NeedAll;
foreach (var skill in requirement.RequiredSkills)
{
var hasSkill = skillStorage.Skills.Contains(skill);
if (requirement.NeedAll && !hasSkill)
{
missingSkills.Add(skill);
success = false;
}
else if (!requirement.NeedAll && hasSkill)
{
success = true;
}
else if (!requirement.NeedAll && !hasSkill)
{
missingSkills.Add(skill);
}
}
return success;
}
public bool TryLearnSkill(EntityUid uid, ProtoId<CP14SkillPrototype> skill, bool force = false)
{
if (!TryComp<CP14SkillsStorageComponent>(uid, out var skillStorage))
return false;
if (!skillStorage.Skills.Contains(skill))
{
skillStorage.Skills.Add(skill);
if (!force)
return false;
}
var proto = _proto.Index(skill);
EntityManager.AddComponents(uid, proto.Components);
return true;
}
public bool TryForgotSkill(EntityUid uid, ProtoId<CP14SkillPrototype> skill)
{
if (!TryComp<CP14SkillsStorageComponent>(uid, out var skillStorage))
return false;
if (!skillStorage.Skills.Contains(skill))
return false;
skillStorage.Skills.Remove(skill);
var proto = _proto.Index(skill);
EntityManager.RemoveComponents(uid, proto.Components);
return true;
}
}
public sealed partial class CP14TrySkillIssueEvent : EntityEventArgs
{
public readonly EntityUid User;
public CP14TrySkillIssueEvent(EntityUid uid)
{
User = uid;
}
}

View File

@@ -0,0 +1,5 @@
cp14-skill-label = [bold]Skill requirements[/bold]
cp14-skill-examined = You need to have one of the following skills to use {$item}:
cp14-skill-examined-need-all = You need to have all of the following skills in order to use {$item}:
cp14-skill-examined-skill = [color={$color}] - {$skill} [/color]

View File

@@ -0,0 +1,6 @@
cp14-skill-issue-drops = The {$item} falls awkwardly out of your hands!
cp14-skill-issue-recoil = You don't hold the recoil!
cp14-skill-issue-self-harm = You're accidentally hitting on yourself!
cp14-skill-issue-sharp-self-harm = You accidentally cut yourself!
cp14-skill-issue-sharp-weapon-harm = You accidentally damaged the {$item}!
cp14-skill-issue-push = You accidentally drop {$item}!

View File

@@ -0,0 +1,11 @@
cp14-skill-name-alchemy = Alchemy
cp14-skill-desc-alchemy = You are experienced enough to use complex alchemical equipment with confidence.
cp14-skill-name-blacksmith = Blacksmithing
cp14-skill-desc-blacksmith = You know the intricacies of working with metal
cp14-skill-name-warcraft = Mastery of martial weapons
cp14-skill-desc-warcraft = You're good with a serious, martial weapon.
cp14-skill-name-firearms = Firearms shooting
cp14-skill-desc-firearms = You are experienced enough to use firearms.

View File

@@ -0,0 +1,28 @@
cp14-trait-category-physical = Physical features
cp14-trait-category-background = Background
cp14-trait-category-speech = Speech peculiarities
# Physical
cp14-trait-blindness-name = Blindness
cp14-trait-blindness-desc = You are blind from birth, and no magic can heal you.
cp14-trait-poor-vision-name = Myopia
cp14-trait-poor-vision-desc = A couple of meters forward, and everything blurs before your eyes.
cp14-trait-narcolepsy-name = Slumbering Sickness
cp14-trait-narcolepsy-desc = You feel lethargic and periodically fall asleep on the flat.
cp14-trait-muted-name = Muted
cp14-trait-muted-desc = All you can do is mumble incoherently. The benefits of verbal communication are not available to you.
cp14-trait-snoring-name = Loud snoring
cp14-trait-snoring-desc = It is simply impossible to sleep next to you because you snore terribly loudly at everything.
# Backgrounds
cp14-trait-bg-entertainer-name = Entertainer
cp14-trait-bg-entertainer-desc = You have to thrive in front of an audience. You know the way how to entertain them, entrance them and also even how to inspire them. Your poetics able to stir the hearts like those who awakening grief or joy, anger or laughter. Their spirits can be raised by your music and also it captures their sorrow. Actually, your dance steps are captivate and also your humor will cuts to the quick. Finally, your art is your life whatever the techniques you use.
cp14-trait-bg-soldier-name = Soldier
cp14-trait-bg-soldier-desc = War has been your life for as long as you care to remember. You trained as a youth, studied the use of weapons and armor, learned basic survival techniques, including how to stay alive on the battlefield. You might have been part of a standing national army or a mercenary company, or perhaps a member of a local militia who rose to prominence during a recent war.

View File

@@ -0,0 +1,5 @@
cp14-skill-label = [bold]Требования к навыкам[/bold]
cp14-skill-examined = Вам нужно владеть одним из следующих навыков, чтобы использовать {$item}:
cp14-skill-examined-need-all = Вам нужно владеть всеми следующими навыками, чтобы использовать {$item}:
cp14-skill-examined-skill = [color={$color}] - {$skill} [/color]

View File

@@ -0,0 +1,6 @@
cp14-skill-issue-drops = {$item} неловко вываливается из ваших рук!
cp14-skill-issue-recoil = Вы не удерживаете отдачу!
cp14-skill-issue-self-harm = Вы случайно попадаете по себе!
cp14-skill-issue-sharp-self-harm = Вы случайно порезались!
cp14-skill-issue-sharp-weapon-harm = Вы случайно повредили {$item}!
cp14-skill-issue-push = Вы случайно роняете {$item}!

View File

@@ -0,0 +1,11 @@
cp14-skill-name-alchemy = Алхимия
cp14-skill-desc-alchemy = Вы достаточно опытны, чтобы уверенно пользоваться сложным алхимическим оборудованием.
cp14-skill-name-blacksmith = Кузнечное дело
cp14-skill-desc-blacksmith = Вы знаете все тонкости работы с металлом.
cp14-skill-name-warcraft = Владение воинским оружием
cp14-skill-desc-warcraft = Вы хорошо управляетесь с серьезным, воинским оружием.
cp14-skill-name-firearms = Стрельба из огнестрела
cp14-skill-desc-firearms = Вы достаточно опытны, чтобы пользоваться огнестрельным оружием.

View File

@@ -0,0 +1,28 @@
cp14-trait-category-physical = Физические особенности
cp14-trait-category-background = Предыстория
cp14-trait-category-speech = Особенности речи
# Physical
cp14-trait-blindness-name = Слепота
cp14-trait-blindness-desc = Вы слепы от рождения, и никакая магия не способна исцелить вас.
cp14-trait-poor-vision-name = Близорукость
cp14-trait-poor-vision-desc = Пара метров вперед, и все расплывается перед вашими глазами.
cp14-trait-narcolepsy-name = Дремотная Хворь
cp14-trait-narcolepsy-desc = Вы чувствуете себя вялым, и периодически засыпаете на ровном месте.
cp14-trait-muted-name = Немота
cp14-trait-muted-desc = Все что вы можете - бессвязно мычать. Блага вербальной коммуникации недоступны вам.
cp14-trait-snoring-name = Громкий храп
cp14-trait-snoring-desc = Спать рядом с вами просто невозможно, потому что во все вы жутко громко храпите.
# Backgrounds
cp14-trait-bg-entertainer-name = Артист
cp14-trait-bg-entertainer-desc = Вам нравится выступать на публике. Вы знаете, как их развлечь, очаровать и даже воодушевить. Ваша поэзия может трогать сердца слушателей, пробуждать в них горе или радость, смех или гнев. Ваша музыка ободряет их или заставляет скорбеть. Ваши танцы захватывают, а шутки всегда смешны. Чем бы вы ни занимались, ваша жизнь тесно связана с искусством.
cp14-trait-bg-soldier-name = Солдат
cp14-trait-bg-soldier-desc = Сколько вы помните, в вашей жизни всегда была война. С молодости вы проходили тренировки, учились использовать оружие и доспехи, изучали технику выживания, включая то, как оставаться живым на поле боя. Вы могли быть частью армии страны или отряда наёмников, а может, были местным ополченцем во время войны.

View File

@@ -46339,41 +46339,11 @@ entities:
- type: Transform
pos: -6.5,-0.5
parent: 2
- uid: 649
components:
- type: Transform
pos: 1.5,0.5
parent: 2
- uid: 650
components:
- type: Transform
pos: -4.5,4.5
parent: 2
- uid: 651
components:
- type: Transform
pos: -0.5,4.5
parent: 2
- uid: 652
components:
- type: Transform
pos: 1.5,4.5
parent: 2
- uid: 653
components:
- type: Transform
pos: -0.5,0.5
parent: 2
- uid: 654
components:
- type: Transform
pos: -0.5,-3.5
parent: 2
- uid: 655
components:
- type: Transform
pos: 1.5,-3.5
parent: 2
- uid: 656
components:
- type: Transform
@@ -46409,6 +46379,38 @@ entities:
- type: Transform
pos: -12.5,4.5
parent: 2
- proto: CP14SpawnPointAlchemist
entities:
- uid: 284
components:
- type: Transform
pos: -0.5,-3.5
parent: 2
- uid: 649
components:
- type: Transform
pos: 1.5,4.5
parent: 2
- uid: 651
components:
- type: Transform
pos: -0.5,0.5
parent: 2
- uid: 652
components:
- type: Transform
pos: 1.5,-3.5
parent: 2
- uid: 653
components:
- type: Transform
pos: -0.5,4.5
parent: 2
- uid: 655
components:
- type: Transform
pos: 1.5,0.5
parent: 2
- proto: CP14TableWooden
entities:
- uid: 85
@@ -46756,12 +46758,6 @@ entities:
rot: 1.5707963267948966 rad
pos: -1.5,3.5
parent: 2
- uid: 284
components:
- type: Transform
rot: 1.5707963267948966 rad
pos: -1.5,4.5
parent: 2
- uid: 285
components:
- type: Transform
@@ -46874,6 +46870,11 @@ entities:
- type: Transform
pos: -13.5,3.5
parent: 2
- uid: 654
components:
- type: Transform
pos: -1.5,4.5
parent: 2
- uid: 664
components:
- type: Transform

View File

@@ -1,8 +1,8 @@
- type: traitCategory
id: Disabilities
name: trait-category-disabilities
- type: traitCategory
id: SpeechTraits
name: trait-category-speech
maxTraitPoints: 2
#- type: traitCategory
# id: Disabilities
# name: trait-category-disabilities
#
#- type: traitCategory
# id: SpeechTraits
# name: trait-category-speech
# maxTraitPoints: 2

View File

@@ -1,91 +1,92 @@
- type: trait
id: Blindness
name: trait-blindness-name
description: trait-blindness-desc
traitGear: WhiteCane
category: Disabilities
whitelist:
components:
- Blindable
components:
- type: PermanentBlindness
- type: trait
id: PoorVision
name: trait-poor-vision-name
description: trait-poor-vision-desc
traitGear: ClothingEyesGlasses
category: Disabilities
whitelist:
components:
- Blindable
components:
- type: PermanentBlindness
blindness: 4
- type: trait
id: Narcolepsy
name: trait-narcolepsy-name
description: trait-narcolepsy-desc
category: Disabilities
components:
- type: Narcolepsy
timeBetweenIncidents: 300, 600
durationOfIncident: 10, 30
- type: trait
id: Pacifist
name: trait-pacifist-name
description: trait-pacifist-desc
category: Disabilities
components:
- type: Pacified
- type: trait
id: Unrevivable
name: trait-unrevivable-name
description: trait-unrevivable-desc
category: Disabilities
components:
- type: Unrevivable
- type: trait
id: Muted
name: trait-muted-name
description: trait-muted-desc
category: Disabilities
blacklist:
components:
- BorgChassis
components:
- type: Muted
- type: trait
id: LightweightDrunk
name: trait-lightweight-name
description: trait-lightweight-desc
category: Disabilities
components:
- type: LightweightDrunk
boozeStrengthMultiplier: 2
- type: trait
id: Paracusia
name: trait-paracusia-name
description: trait-paracusia-desc
category: Disabilities
components:
- type: Paracusia
minTimeBetweenIncidents: 0.1
maxTimeBetweenIncidents: 300
maxSoundDistance: 7
sounds:
collection: Paracusia
- type: trait
id: Snoring
name: trait-snoring-name
description: trait-snoring-desc
category: Disabilities
components:
- type: Snoring
#- type: trait
# id: Blindness
# name: trait-blindness-name
# description: trait-blindness-desc
# traitGear: WhiteCane
# category: Disabilities
# whitelist:
# components:
# - Blindable
# components:
# - type: PermanentBlindness
#
#- type: trait
# id: PoorVision
# name: trait-poor-vision-name
# description: trait-poor-vision-desc
# traitGear: ClothingEyesGlasses
# category: Disabilities
# whitelist:
# components:
# - Blindable
# components:
# - type: PermanentBlindness
# blindness: 4
#
#- type: trait
# id: Narcolepsy
# name: trait-narcolepsy-name
# description: trait-narcolepsy-desc
# category: Disabilities
# components:
# - type: Narcolepsy
# timeBetweenIncidents: 300, 600
# durationOfIncident: 10, 30
#
#- type: trait
# id: Pacifist
# name: trait-pacifist-name
# description: trait-pacifist-desc
# category: Disabilities
# components:
# - type: Pacified
#
#- type: trait
# id: Unrevivable
# name: trait-unrevivable-name
# description: trait-unrevivable-desc
# category: Disabilities
# components:
# - type: Unrevivable
#
#- type: trait
# id: Muted
# name: trait-muted-name
# description: trait-muted-desc
# category: Disabilities
# blacklist:
# components:
# - BorgChassis
# components:
# - type: Muted
#
#- type: trait
# id: LightweightDrunk
# name: trait-lightweight-name
# description: trait-lightweight-desc
# category: Disabilities
# components:
# - type: LightweightDrunk
# boozeStrengthMultiplier: 2
#
#- type: trait
# id: Paracusia
# name: trait-paracusia-name
# description: trait-paracusia-desc
# category: Disabilities
# components:
# - type: Paracusia
# minTimeBetweenIncidents: 0.1
# maxTimeBetweenIncidents: 300
# maxSoundDistance: 7
# sounds:
# collection: Paracusia
#
#- type: trait
# id: Snoring
# name: trait-snoring-name
# description: trait-snoring-desc
# category: Disabilities
# components:
# - type: Snoring
#

View File

@@ -1,88 +1,89 @@
# Free
- type: trait
id: Accentless
name: trait-accentless-name
description: trait-accentless-desc
category: SpeechTraits
components:
- type: Accentless
removes:
- type: LizardAccent
- type: MothAccent
- type: ReplacementAccent
accent: dwarf
# 1 Cost
- type: trait
id: SouthernAccent
name: trait-southern-name
description: trait-southern-desc
category: SpeechTraits
cost: 1
components:
- type: SouthernAccent
- type: trait
id: PirateAccent
name: trait-pirate-accent-name
description: trait-pirate-accent-desc
category: SpeechTraits
cost: 1
components:
- type: PirateAccent
- type: trait
id: CowboyAccent
name: trait-cowboy-name
description: trait-cowboy-desc
category: SpeechTraits
cost: 1
components:
- type: ReplacementAccent
accent: cowboy
- type: trait
id: ItalianAccent
name: trait-italian-name
description: trait-italian-desc
category: SpeechTraits
cost: 1
components:
- type: ReplacementAccent
accent: italian
- type: trait
id: Liar
name: trait-liar-name
description: trait-liar-desc
category: SpeechTraits
cost: 1
components:
- type: ReplacementAccent
accent: liar
# 2 Cost
- type: trait
id: SocialAnxiety
name: trait-socialanxiety-name
description: trait-socialanxiety-desc
category: SpeechTraits
cost: 2
components:
- type: StutteringAccent
matchRandomProb: 0.1
fourRandomProb: 0
threeRandomProb: 0
cutRandomProb: 0
- type: trait
id: FrontalLisp
name: trait-frontal-lisp-name
description: trait-frontal-lisp-desc
category: SpeechTraits
cost: 2
components:
- type: FrontalLisp
## Free
#
#- type: trait
# id: Accentless
# name: trait-accentless-name
# description: trait-accentless-desc
# category: SpeechTraits
# components:
# - type: Accentless
# removes:
# - type: LizardAccent
# - type: MothAccent
# - type: ReplacementAccent
# accent: dwarf
#
## 1 Cost
#
#- type: trait
# id: SouthernAccent
# name: trait-southern-name
# description: trait-southern-desc
# category: SpeechTraits
# cost: 1
# components:
# - type: SouthernAccent
#
#- type: trait
# id: PirateAccent
# name: trait-pirate-accent-name
# description: trait-pirate-accent-desc
# category: SpeechTraits
# cost: 1
# components:
# - type: PirateAccent
#
#- type: trait
# id: CowboyAccent
# name: trait-cowboy-name
# description: trait-cowboy-desc
# category: SpeechTraits
# cost: 1
# components:
# - type: ReplacementAccent
# accent: cowboy
#
#- type: trait
# id: ItalianAccent
# name: trait-italian-name
# description: trait-italian-desc
# category: SpeechTraits
# cost: 1
# components:
# - type: ReplacementAccent
# accent: italian
#
#- type: trait
# id: Liar
# name: trait-liar-name
# description: trait-liar-desc
# category: SpeechTraits
# cost: 1
# components:
# - type: ReplacementAccent
# accent: liar
#
## 2 Cost
#
#- type: trait
# id: SocialAnxiety
# name: trait-socialanxiety-name
# description: trait-socialanxiety-desc
# category: SpeechTraits
# cost: 2
# components:
# - type: StutteringAccent
# matchRandomProb: 0.1
# fourRandomProb: 0
# threeRandomProb: 0
# cutRandomProb: 0
#
#- type: trait
# id: FrontalLisp
# name: trait-frontal-lisp-name
# description: trait-frontal-lisp-desc
# category: SpeechTraits
# cost: 2
# components:
# - type: FrontalLisp
#

View File

@@ -7,6 +7,20 @@
components:
- type: SpawnPoint
job_id: CP14Adventurer
- type: Sprite
layers:
- state: green
- state: zookeeper #TODO Replace
- type: entity
id: CP14SpawnPointAlchemist
parent: SpawnPointJobBase
name: alchemist
categories:
- Spawner
components:
- type: SpawnPoint
job_id: CP14Alchemist
- type: Sprite
layers:
- state: green

View File

@@ -291,6 +291,7 @@
Asphyxiation: -1.0
- type: FireVisuals
alternateState: Standing #TODO - custom visuals
- type: CP14SkillsStorage
- type: entity
save: false

View File

@@ -84,6 +84,10 @@
sprite: _CP14/Objects/Specific/Alchemy/mortar_pestle.rsi
state: pestle
- type: CP14Pestle
- type: CP14SkillRequirement
fuckupChance: 0.05
requiredSkills:
- Alchemy
- type: entity
id: CP14Mortar

View File

@@ -24,4 +24,9 @@
- !type:DoActsBehavior
acts: ["Destruction"]
- type: CP14SharpeningStone
sharpnessHeal: 0.1
sharpnessHeal: 0.1
- type: CP14SkillRequirement
fuckupChance: 0.6
requiredSkills:
- Warcraft
- Blacksmith

View File

@@ -43,4 +43,8 @@
- type: HeldSpeedModifier
- type: MeleeThrowOnHit
lifetime: 0.05
speed: 5
speed: 5
- type: CP14SkillRequirement
fuckupChance: 0.5
requiredSkills:
- Warcraft

View File

@@ -43,4 +43,8 @@
- type: ClothingSpeedModifier
walkModifier: 0.9
sprintModifier: 0.8
- type: HeldSpeedModifier
- type: HeldSpeedModifier
- type: CP14SkillRequirement
fuckupChance: 0.5
requiredSkills:
- Warcraft

View File

@@ -18,4 +18,8 @@
whitelist:
tags:
- SpeedLoaderRifle
proto: CartridgeRifle # TODO custom projectiles
proto: CartridgeRifle # TODO custom projectiles
- type: CP14SkillRequirement
fuckupChance: 0.55
requiredSkills:
- Firearms

View File

@@ -26,6 +26,10 @@
proto: CP14CartridgeBulletRifle
- type: UseDelay
delay: 2
- type: CP14SkillRequirement
fuckupChance: 0.85
requiredSkills:
- Firearms
- type: entity
name: crush

View File

@@ -42,4 +42,9 @@
sharpnessHeal: 0.1
targetDamage:
types:
blunt: 0.5
blunt: 0.5
- type: CP14SkillRequirement
fuckupChance: 0.5
requiredSkills:
- Warcraft
- Blacksmith

View File

@@ -33,3 +33,4 @@
- type: StationJobs
availableJobs:
CP14Adventurer: [ -1, -1 ]
CP14Alchemist: [ -1, -1 ]

View File

@@ -6,6 +6,10 @@
startingGear: CP14AdventurerGear
icon: "CP14JobIconAdventurer"
supervisors: cp14-job-supervisors-command
special:
- !type:CP14AddSkillSpecial
skills:
- Warcraft
- type: job
id: CP14Alchemist
@@ -15,6 +19,10 @@
startingGear: CP14AdventurerGear #TODO
icon: "CP14JobIconAlchemist"
supervisors: cp14-job-supervisors-command
special:
- !type:CP14AddSkillSpecial
skills:
- Alchemy
- type: startingGear
id: CP14AdventurerGear

View File

@@ -0,0 +1,19 @@
- type: CP14Skill
id: Alchemy
name: cp14-skill-name-alchemy
desc: cp14-skill-desc-alchemy
- type: CP14Skill
id: Blacksmith
name: cp14-skill-name-blacksmith
desc: cp14-skill-desc-blacksmith
- type: CP14Skill
id: Warcraft
name: cp14-skill-name-warcraft
desc: cp14-skill-desc-warcraft
- type: CP14Skill
id: Firearms
name: cp14-skill-name-firearms
desc: cp14-skill-desc-firearms

View File

@@ -0,0 +1,21 @@
#- type: trait
# id: CP14BackgroundSoldier
# name: cp14-trait-bg-soldier-name
# description: cp14-trait-bg-soldier-desc
# traitGear: CP14BaseTwoHandedSword
# cost: 1
# category: CP14Background
# components:
# - type: CP14AutoAddSkill
# skills:
# - Warcraft
#
#- type: trait
# id: CP14BackgroundEntertainer
# name: cp14-trait-bg-entertainer-name
# description: cp14-trait-bg-entertainer-desc
# traitGear: AcousticGuitarInstrument
# cost: 1
# category: CP14Background
# components:
# - type: CP14AutoAddSkill

View File

@@ -0,0 +1,14 @@
- type: traitCategory
id: CP14PhysicalTraits
name: cp14-trait-category-physical
maxTraitPoints: 1
- type: traitCategory
id: CP14Background
name: cp14-trait-category-background
maxTraitPoints: 1
- type: traitCategory
id: CP14Speech
name: cp14-trait-category-speech
maxTraitPoints: 2

View File

@@ -0,0 +1,62 @@
# -2
- type: trait
id: CP14Blindness
name: cp14-trait-blindness-name
description: cp14-trait-blindness-desc
#traitGear: WhiteCane
category: CP14PhysicalTraits
cost: -2
whitelist:
components:
- Blindable
components:
- type: PermanentBlindness
# -1
- type: trait
id: CP14PoorVision
name: cp14-trait-poor-vision-name
description: cp14-trait-poor-vision-desc
#traitGear: ClothingEyesGlasses
category: CP14PhysicalTraits
cost: -1
whitelist:
components:
- Blindable
components:
- type: PermanentBlindness
blindness: 4
- type: trait
id: CP14Narcolepsy
name: cp14-trait-narcolepsy-name
description: cp14-trait-narcolepsy-desc
category: CP14PhysicalTraits
cost: -1
components:
- type: Narcolepsy
timeBetweenIncidents: 300, 600
durationOfIncident: 10, 30
- type: trait
id: CP14Muted
name: cp14-trait-muted-name
description: cp14-trait-muted-desc
cost: -1
category: CP14PhysicalTraits
components:
- type: Muted
# 0
- type: trait
id: CP14Snoring
name: cp14-trait-snoring-name
description: cp14-trait-snoring-desc
category: CP14PhysicalTraits
components:
- type: Snoring
# 1