Spell T0 traits, recategorize magic (#540)

* move to gurps magic types

* spell traits, categorize spells

* Update TraitSystem.cs

* magic spells item provider

* Update twoHandedStaffs.yml

* Update CP14MagicManacostModifySystem.cs

* Update CP14SpellStorageSystem.cs
This commit is contained in:
Ed
2024-11-06 18:02:37 +03:00
committed by GitHub
parent 0f091b4cdf
commit 7e4fb90e02
31 changed files with 202 additions and 86 deletions

View File

@@ -1,4 +1,6 @@
using Content.Server.Actions;
using Content.Server.GameTicking;
using Content.Shared.Actions;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Roles;
@@ -14,6 +16,7 @@ public sealed class TraitSystem : EntitySystem
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly SharedHandsSystem _sharedHandsSystem = default!;
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
[Dependency] private readonly ActionsSystem _action = default!; //CP14
public override void Initialize()
{
@@ -45,8 +48,16 @@ public sealed class TraitSystem : EntitySystem
_whitelistSystem.IsBlacklistPass(traitPrototype.Blacklist, args.Mob))
continue;
// CP14 start - add all spells to player mind
foreach (var spell in traitPrototype.Actions)
{
_action.AddAction(args.Mob, spell);
}
//CP14 end
// Add all components required by the prototype
EntityManager.AddComponents(args.Mob, traitPrototype.Components, false);
if (traitPrototype.Components.Count > 0) //CP14 added check
EntityManager.AddComponents(args.Mob, traitPrototype.Components, false);
// Add item required by the trait
if (traitPrototype.TraitGear == null)

View File

@@ -41,7 +41,7 @@ public sealed partial class TraitPrototype : IPrototype
/// The components that get added to the player, when they pick this trait.
/// </summary>
[DataField]
public ComponentRegistry Components { get; private set; } = default!;
public ComponentRegistry Components { get; private set; } = new(); //CP14 new()
/// <summary>
/// Gear that is given to the player, when they pick this trait.
@@ -60,4 +60,10 @@ public sealed partial class TraitPrototype : IPrototype
/// </summary>
[DataField]
public ProtoId<TraitCategoryPrototype>? Category;
/// <summary>
/// CP14 - adding permanent spells into players mind
/// </summary>
[DataField]
public List<EntProtoId> Actions = new();
}

View File

@@ -2,13 +2,13 @@ using Content.Shared._CP14.MagicRitual.Prototypes;
using Content.Shared.FixedPoint;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicClothing;
namespace Content.Shared._CP14.MagicManacostModify;
/// <summary>
/// Changes the manacost of spells for the bearer
/// </summary>
[RegisterComponent, Access(typeof(CP14MagicClothingSystem))]
public sealed partial class CP14MagicClothingManacostModifyComponent : Component
[RegisterComponent, Access(typeof(CP14MagicManacostModifySystem))]
public sealed partial class CP14MagicManacostModifyComponent : Component
{
[DataField]
public Dictionary<ProtoId<CP14MagicTypePrototype>, FixedPoint2> Modifiers = new();

View File

@@ -2,15 +2,14 @@
using Content.Shared._CP14.MagicRitual.Prototypes;
using Content.Shared._CP14.MagicSpell.Events;
using Content.Shared.Examine;
using Content.Shared.FixedPoint;
using Content.Shared.Inventory;
using Content.Shared.Verbs;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Shared._CP14.MagicClothing;
namespace Content.Shared._CP14.MagicManacostModify;
public sealed partial class CP14MagicClothingSystem : EntitySystem
public sealed partial class CP14MagicManacostModifySystem : EntitySystem
{
[Dependency] private readonly ExamineSystemShared _examine = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
@@ -18,11 +17,12 @@ public sealed partial class CP14MagicClothingSystem : EntitySystem
{
base.Initialize();
SubscribeLocalEvent<CP14MagicClothingManacostModifyComponent, InventoryRelayedEvent<CP14CalculateManacostEvent>>(OnCalculateManacost);
SubscribeLocalEvent<CP14MagicClothingManacostModifyComponent, GetVerbsEvent<ExamineVerb>>(OnVerbExamine);
SubscribeLocalEvent<CP14MagicManacostModifyComponent, InventoryRelayedEvent<CP14CalculateManacostEvent>>(OnCalculateManacost);
SubscribeLocalEvent<CP14MagicManacostModifyComponent, CP14CalculateManacostEvent>(OnCalculateManacost);
SubscribeLocalEvent<CP14MagicManacostModifyComponent, GetVerbsEvent<ExamineVerb>>(OnVerbExamine);
}
private void OnVerbExamine(Entity<CP14MagicClothingManacostModifyComponent> ent, ref GetVerbsEvent<ExamineVerb> args)
private void OnVerbExamine(Entity<CP14MagicManacostModifyComponent> ent, ref GetVerbsEvent<ExamineVerb> args)
{
if (!args.CanInteract || !args.CanAccess)
return;
@@ -37,7 +37,7 @@ public sealed partial class CP14MagicClothingSystem : EntitySystem
Loc.GetString("armor-examinable-verb-message"));
}
private FormattedMessage GetMagicClothingExamine(CP14MagicClothingManacostModifyComponent comp)
private FormattedMessage GetMagicClothingExamine(CP14MagicManacostModifyComponent comp)
{
var msg = new FormattedMessage();
msg.AddMarkupOrThrow(Loc.GetString("cp14-clothing-magic-examine"));
@@ -65,13 +65,18 @@ public sealed partial class CP14MagicClothingSystem : EntitySystem
return msg;
}
private void OnCalculateManacost(Entity<CP14MagicClothingManacostModifyComponent> ent, ref InventoryRelayedEvent<CP14CalculateManacostEvent> args)
private void OnCalculateManacost(Entity<CP14MagicManacostModifyComponent> ent, ref InventoryRelayedEvent<CP14CalculateManacostEvent> args)
{
args.Args.Multiplier += (float)ent.Comp.GlobalModifier;
OnCalculateManacost(ent, ref args.Args);
}
if (args.Args.MagicType is not null && ent.Comp.Modifiers.TryGetValue(args.Args.MagicType.Value, out var modifier))
private void OnCalculateManacost(Entity<CP14MagicManacostModifyComponent> ent, ref CP14CalculateManacostEvent args)
{
args.Multiplier += (float)ent.Comp.GlobalModifier;
if (args.MagicType is not null && ent.Comp.Modifiers.TryGetValue(args.MagicType.Value, out var modifier))
{
args.Args.Multiplier *= (float)modifier;
args.Multiplier *= (float)modifier;
}
}
}

View File

@@ -4,7 +4,9 @@ using Content.Shared._CP14.MagicEnergy.Components;
using Content.Shared._CP14.MagicSpell.Components;
using Content.Shared._CP14.MagicSpell.Events;
using Content.Shared._CP14.MagicSpell.Spells;
using Content.Shared._CP14.MagicSpellStorage;
using Content.Shared.DoAfter;
using Content.Shared.FixedPoint;
using Content.Shared.Hands.Components;
using Content.Shared.Popups;
using Content.Shared.Speech.Muting;
@@ -50,7 +52,6 @@ public partial class CP14SharedMagicSystem : EntitySystem
private void OnMagicEffectInit(Entity<CP14MagicEffectComponent> ent, ref MapInitEvent args)
{
var meta = MetaData(ent);
var sb = new StringBuilder();
@@ -62,6 +63,16 @@ public partial class CP14SharedMagicSystem : EntitySystem
sb.Append($"\n {Loc.GetString("cp14-magic-magic-type")}: [color={indexedMagic.Color.ToHex()}]{Loc.GetString(indexedMagic.Name)}[/color]");
}
if (TryComp<CP14MagicEffectVerbalAspectComponent>(ent, out var verbal))
{
sb.Append("\n" + Loc.GetString("cp14-magic-verbal-aspect"));
}
if (TryComp<CP14MagicEffectSomaticAspectComponent>(ent, out var somatic))
{
sb.Append("\n" + Loc.GetString("cp14-magic-somatic-aspect") + " " + somatic.FreeHandRequired);
}
_meta.SetEntityDescription(ent, sb.ToString());
}
@@ -73,14 +84,7 @@ public partial class CP14SharedMagicSystem : EntitySystem
return;
}
var manaCost = ent.Comp.ManaCost;
if (ent.Comp.CanModifyManacost)
{
var manaEv = new CP14CalculateManacostEvent(args.Caster, ent.Comp.ManaCost, ent.Comp.MagicType);
RaiseLocalEvent(args.Caster, manaEv);
manaCost = manaEv.GetManacost();
}
var manaCost = CalculateManacost(ent, args.Caster);
if (!_magicEnergy.HasEnergy(args.Caster, manaCost, magicContainer, ent.Comp.Safe))
{
@@ -283,15 +287,25 @@ public partial class CP14SharedMagicSystem : EntitySystem
return;
var manaCost = CalculateManacost(ent, args.Caster.Value);
_magicEnergy.TryConsumeEnergy(args.Caster.Value, manaCost, safe: ent.Comp.Safe);
}
private FixedPoint2 CalculateManacost(Entity<CP14MagicEffectComponent> ent, EntityUid caster)
{
var manaCost = ent.Comp.ManaCost;
if (ent.Comp.CanModifyManacost)
{
var manaEv = new CP14CalculateManacostEvent(args.Caster.Value, ent.Comp.ManaCost, ent.Comp.MagicType);
RaiseLocalEvent(args.Caster.Value, manaEv);
var manaEv = new CP14CalculateManacostEvent(caster, ent.Comp.ManaCost, ent.Comp.MagicType);
RaiseLocalEvent(caster, manaEv);
if (TryComp<CP14ProvidedBySpellStorageComponent>(ent, out var provided) && provided.SpellStorage is not null)
RaiseLocalEvent(provided.SpellStorage.Value, manaEv);
manaCost = manaEv.GetManacost();
}
_magicEnergy.TryConsumeEnergy(args.Caster.Value, manaCost, safe: ent.Comp.Safe);
return manaCost;
}
}

View File

@@ -0,0 +1,11 @@
namespace Content.Shared._CP14.MagicSpellStorage;
/// <summary>
/// Located on the action entity, stores a reference to the object from which the action was created.
/// </summary>
[RegisterComponent, Access(typeof(CP14SpellStorageSystem))]
public sealed partial class CP14ProvidedBySpellStorageComponent : Component
{
[DataField]
public Entity<CP14SpellStorageComponent>? SpellStorage;
}

View File

@@ -5,6 +5,7 @@ using Content.Shared.Clothing.Components;
using Content.Shared.Hands;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Mind;
using Robust.Shared.Network;
namespace Content.Shared._CP14.MagicSpellStorage;
@@ -18,10 +19,12 @@ public sealed partial class CP14SpellStorageSystem : EntitySystem
[Dependency] private readonly SharedMindSystem _mind = default!;
[Dependency] private readonly CP14SharedMagicAttuningSystem _attuning = default!;
[Dependency] private readonly SharedHandsSystem _hands = default!;
[Dependency] private readonly INetManager _net = default!;
public override void Initialize()
{
SubscribeLocalEvent<CP14SpellStorageComponent, MapInitEvent>(OnMagicStorageInit);
SubscribeLocalEvent<CP14SpellStorageComponent, ComponentShutdown>(OnMagicStorageShutdown);
SubscribeLocalEvent<CP14SpellStorageAccessHoldingComponent, GotEquippedHandEvent>(OnEquippedHand);
SubscribeLocalEvent<CP14SpellStorageAccessHoldingComponent, AddedAttuneToMindEvent>(OnHandAddedAttune);
@@ -38,16 +41,33 @@ public sealed partial class CP14SpellStorageSystem : EntitySystem
/// </summary>
private void OnMagicStorageInit(Entity<CP14SpellStorageComponent> mStorage, ref MapInitEvent args)
{
if (_net.IsClient)
return;
foreach (var spell in mStorage.Comp.Spells)
{
var spellEnt = _actionContainer.AddAction(mStorage, spell);
if (spellEnt is null)
continue;
var provided = EntityManager.EnsureComponent<CP14ProvidedBySpellStorageComponent>(spellEnt.Value);
provided.SpellStorage = mStorage;
mStorage.Comp.SpellEntities.Add(spellEnt.Value);
}
}
private void OnMagicStorageShutdown(Entity<CP14SpellStorageComponent> mStorage, ref ComponentShutdown args)
{
if (_net.IsClient)
return;
foreach (var spell in mStorage.Comp.SpellEntities)
{
QueueDel(spell);
}
}
private void OnEquippedHand(Entity<CP14SpellStorageAccessHoldingComponent> ent, ref GotEquippedHandEvent args)
{
if (!TryComp<CP14SpellStorageComponent>(ent, out var spellStorage))

View File

@@ -710,6 +710,7 @@ public $TYPE$ $NAME$;</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=loadout/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=LOOC/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Magboots/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Manacost/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=metabolizable/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=metagaming/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=mommi/@EntryIndexedValue">True</s:Boolean>

View File

@@ -1,11 +1,14 @@
cp14-magic-type-abjuration = Abjuration
cp14-magic-type-conjuration = Conjuration
cp14-magic-type-divination = Divination
cp14-magic-type-enchantment = Enchantment
cp14-magic-type-evocation = Evocation
cp14-magic-type-illusion = Illusion
cp14-magic-type-necromancy = Necromancy
cp14-magic-type-transmutation = Transmutation
cp14-magic-type-fire = Fire
cp14-magic-type-water = Water
cp14-magic-type-earth = Earth
cp14-magic-type-healing = Healing
cp14-magic-type-light-darkness = Light and darkness
cp14-magic-type-meta = Metamagic
cp14-magic-type-gate = Gate
cp14-magic-type-movement = Movement
cp14-magic-manacost = Manacost
cp14-magic-magic-type = Magic type
cp14-magic-verbal-aspect = Requires the ability to speak
cp14-magic-somatic-aspect = Requires a free hand:

View File

@@ -1,6 +1,7 @@
cp14-trait-category-physical = Physical features
cp14-trait-category-background = Background
cp14-trait-category-speech = Speech peculiarities
cp14-trait-category-magic = Known spells
# Physical
@@ -19,6 +20,14 @@ cp14-trait-muted-desc = All you can do is mumble incoherently. The benefits of v
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.
# Magic spells
cp14-trait-spell-flamecreation-name = flame creation
cp14-trait-spell-flamecreation-desc = A artificial flame forms in your hand, illuminating your surroundings. You can throw it to use it as a disposable weapon.
cp14-trait-spell-managift-name = mana gift
cp14-trait-spell-managift-desc = You can transfer a small amount of your magical energy to a target entity or magical object.
# Backgrounds
cp14-trait-bg-entertainer-name = Entertainer

View File

@@ -1,11 +1,14 @@
cp14-magic-type-abjuration = Ограждение
cp14-magic-type-conjuration = Призыв
cp14-magic-type-divination = Прорицание
cp14-magic-type-enchantment = Очарование
cp14-magic-type-evocation = Воплощение
cp14-magic-type-illusion = Иллюзии
cp14-magic-type-necromancy = Некромантия
cp14-magic-type-transmutation = Трансмутация
cp14-magic-type-fire = Огонь
cp14-magic-type-water = Вода
cp14-magic-type-earth = Земля
cp14-magic-type-healing = Исцеление
cp14-magic-type-light-darkness = Свет и тьма
cp14-magic-type-meta = Метамагия
cp14-magic-type-gate = Пространство
cp14-magic-type-movement = Движение
cp14-magic-manacost = Затраты маны
cp14-magic-magic-type = Тип магии
cp14-magic-verbal-aspect = Требуется возможность говорить
cp14-magic-somatic-aspect = Требуются свободные руки:

View File

@@ -1,6 +1,7 @@
cp14-trait-category-physical = Физические особенности
cp14-trait-category-background = Предыстория
cp14-trait-category-speech = Особенности речи
cp14-trait-category-magic = Известные заклинания
# Physical
@@ -19,6 +20,14 @@ cp14-trait-muted-desc = Все что вы можете - бессвязно м
cp14-trait-snoring-name = Громкий храп
cp14-trait-snoring-desc = Спать рядом с вами просто невозможно, потому что во все вы жутко громко храпите.
# Magic spells
cp14-trait-spell-flamecreation-name = создание пламени
cp14-trait-spell-flamecreation-desc = A artificial flame forms in your hand, illuminating your surroundings. You can throw it to use it as a disposable weapon.
cp14-trait-spell-managift-name = передача маны
cp14-trait-spell-managift-desc = You can transfer a small amount of your magical energy to a target entity or magical object.
# Backgrounds
cp14-trait-bg-entertainer-name = Артист

View File

@@ -6,7 +6,7 @@
- type: CP14MagicEffectCastSlowdown
speedMultiplier: -0.9
- type: CP14MagicEffect
magicType: Evocation
magicType: Earth
manaCost: 15
telegraphyEffects:
- !type:CP14SpellSpawnEntityOnTarget

View File

@@ -4,7 +4,7 @@
description: A artificial flame forms in your hand, illuminating your surroundings. You can throw it to use it as a disposable weapon.
components:
- type: CP14MagicEffect
magicType: Conjuration
magicType: Fire
manaCost: 5
effects:
- !type:CP14SpellSpawnEntityOnTarget

View File

@@ -6,7 +6,7 @@
- type: CP14MagicEffectCastSlowdown
speedMultiplier: -0.7
- type: CP14MagicEffect
magicType: Evocation
magicType: Fire
manaCost: 20
effects:
- !type:CP14SpellSpawnEntityOnUser

View File

@@ -6,7 +6,7 @@
- type: CP14MagicEffectCastSlowdown
speedMultiplier: -0.4
- type: CP14MagicEffect
magicType: Conjuration
magicType: Gate
manaCost: 20
telegraphyEffects:
- !type:CP14SpellSpawnEntityOnTarget

View File

@@ -6,7 +6,7 @@
- type: CP14MagicEffectCastSlowdown
speedMultiplier: -0.5
- type: CP14MagicEffect
magicType: Evocation
magicType: Healing
manaCost: 20
telegraphyEffects:
- !type:CP14SpellSpawnEntityOnTarget

View File

@@ -4,7 +4,7 @@
description: Creates a flash of bright, blinding light.
components:
- type: CP14MagicEffect
magicType: Abjuration
magicType: LightDarkness
manaCost: 10
telegraphyEffects:
- !type:CP14SpellSpawnEntityOnTarget

View File

@@ -4,7 +4,7 @@
description: Materialization of a bright and safe light source.
components:
- type: CP14MagicEffect
magicType: Conjuration
magicType: LightDarkness
manaCost: 10
effects:
- !type:CP14SpellSpawnEntityOnTarget

View File

@@ -4,7 +4,7 @@
description: You can transfer a small amount of your magical energy to a target entity or magical object.
components:
- type: CP14MagicEffect
magicType: Necromancy
magicType: Meta
manaCost: 12
canModifyManacost: false
telegraphyEffects:

View File

@@ -4,7 +4,7 @@
description: You attract a ghostly hand that draws an object or entity to you
components:
- type: CP14MagicEffect
magicType: Transmutation
magicType: Movement
manaCost: 10
telegraphyEffects:
- !type:CP14SpellSpawnEntityOnTarget

View File

@@ -4,7 +4,7 @@
description: Materialization of a temporary sharp ice throwing dagger
components:
- type: CP14MagicEffect
magicType: Evocation
magicType: Water
manaCost: 15
effects:
- !type:CP14SpellSpawnEntityOnTarget

View File

@@ -6,7 +6,7 @@
- type: CP14MagicEffectCastSlowdown
speedMultiplier: -0.25
- type: CP14MagicEffect
magicType: Evocation
magicType: Water
manaCost: 5
effects:
- !type:CP14SpellProjectile

View File

@@ -125,7 +125,7 @@
sprite: _CP14/Clothing/Head/Roles/General/triangularhat.rsi
- type: Clothing
sprite: _CP14/Clothing/Head/Roles/General/triangularhat.rsi
- type: CP14MagicClothingManacostModify
- type: CP14MagicManacostModify
globalModifier: 0.8
- type: entity
@@ -138,5 +138,5 @@
sprite: _CP14/Clothing/Head/Roles/General/triangularhat_golden.rsi
- type: Clothing
sprite: _CP14/Clothing/Head/Roles/General/triangularhat_golden.rsi
- type: CP14MagicClothingManacostModify
- type: CP14MagicManacostModify
globalModifier: 0.8

View File

@@ -103,7 +103,6 @@
- type: CP14MagicEffectCastSlowdown
speedMultiplier: -1.0
- type: CP14MagicEffect
magicType: Conjuration
manaCost: 5
telegraphyEffects:
- !type:CP14SpellSpawnEntityOnTarget

View File

@@ -44,3 +44,6 @@
- type: CP14SpellStorage
spells:
- CP14ActionSpellCureWounds
- type: CP14MagicManacostModify
modifiers:
Healing: 1.1

View File

@@ -1,39 +1,39 @@
- type: magicType
id: Abjuration
name: cp14-magic-type-abjuration #Ограждение
color: "#c94328"
id: Fire
name: cp14-magic-type-fire
color: "#d9741c"
- type: magicType
id: Conjuration
name: cp14-magic-type-conjuration #Призыв
color: "#8e28c9"
id: Water
name: cp14-magic-type-water
color: "#1c94d9"
- type: magicType
id: Divination
name: cp14-magic-type-divination #Прорицание
color: "#81d3e3"
id: Earth
name: cp14-magic-type-earth
color: "#70533f"
- type: magicType
id: Enchantment
name: cp14-magic-type-enchantment #Очарование
color: "#7147a1"
id: Healing
name: cp14-magic-type-healing
color: "#89e04f"
- type: magicType
id: Evocation
name: cp14-magic-type-evocation #Воплощение
color: "#47a14a"
id: LightDarkness
name: cp14-magic-type-light-darkness
color: "#ba97b8"
- type: magicType
id: Illusion
name: cp14-magic-type-illusion #Иллюзия
color: "#cc1275"
id: Meta
name: cp14-magic-type-meta
color: "#dcffdb"
- type: magicType
id: Necromancy
name: cp14-magic-type-necromancy #Некромантия
color: "#4dc4a4"
id: Gate
name: cp14-magic-type-gate
color: "#32597d"
- type: magicType
id: Transmutation
name: cp14-magic-type-transmutation #Трансмутация
color: "#3333d4"
id: Movement
name: cp14-magic-type-movement
color: "#63ceff"

View File

@@ -1,3 +1,8 @@
- type: traitCategory
id: CP14Magic
name: cp14-trait-category-magic
maxTraitPoints: 1
- type: traitCategory
id: CP14PhysicalTraits
name: cp14-trait-category-physical

View File

@@ -0,0 +1,17 @@
- type: trait
id: CP14MagicFlameCreation
name: cp14-trait-spell-flamecreation-name
description: cp14-trait-spell-flamecreation-desc
cost: 1
category: CP14Magic
actions:
- CP14ActionSpellFlameCreation
- type: trait
id: CP14MagicManaGift
name: cp14-trait-spell-managift-name
description: cp14-trait-spell-managift-desc
cost: 1
category: CP14Magic
actions:
- CP14ActionSpellManaGift

View File

@@ -5,7 +5,7 @@
"y": 32
},
"license": "CLA",
"copyright": "Created by Nimfar11 (github)",
"copyright": "Created by TheShuEd (github)",
"states": [
{
"name": "subterranean_leap"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 950 B

After

Width:  |  Height:  |  Size: 381 B