diff --git a/Content.Server/_CP14/ModularCraft/Modifiers/EditArmor.cs b/Content.Server/_CP14/ModularCraft/Modifiers/EditArmor.cs new file mode 100644 index 0000000000..a6888bfa0f --- /dev/null +++ b/Content.Server/_CP14/ModularCraft/Modifiers/EditArmor.cs @@ -0,0 +1,22 @@ +using Content.Shared._CP14.ModularCraft; +using Content.Shared._CP14.ModularCraft.Components; +using Content.Shared.Armor; +using Content.Shared.Damage; + +namespace Content.Server._CP14.ModularCraft.Modifiers; + +public sealed partial class EditArmor : CP14ModularCraftModifier +{ + [DataField(required: true)] + public DamageModifierSet Modifiers = new(); + + public override void Effect(EntityManager entManager, Entity start, Entity? part) + { + if (!entManager.TryGetComponent(start, out var armor)) + return; + + var armorSystem = entManager.System(); + + armorSystem.EditArmorCoefficients(start, Modifiers, armor); + } +} diff --git a/Content.Server/_CP14/ModularCraft/Modifiers/EditClothingSpeed.cs b/Content.Server/_CP14/ModularCraft/Modifiers/EditClothingSpeed.cs new file mode 100644 index 0000000000..6fdc67d07e --- /dev/null +++ b/Content.Server/_CP14/ModularCraft/Modifiers/EditClothingSpeed.cs @@ -0,0 +1,26 @@ +using Content.Shared._CP14.ModularCraft; +using Content.Shared._CP14.ModularCraft.Components; +using Content.Shared.Armor; +using Content.Shared.Clothing; +using Content.Shared.Damage; + +namespace Content.Server._CP14.ModularCraft.Modifiers; + +public sealed partial class EditClothingSpeed : CP14ModularCraftModifier +{ + [DataField] + public float WalkModifier = 1f; + + [DataField] + public float SprintModifier = 1f; + + public override void Effect(EntityManager entManager, Entity start, Entity? part) + { + if (!entManager.TryGetComponent(start, out var speed)) + return; + + var speedModifierSystem = entManager.System(); + + speedModifierSystem.EditSpeedModifiers(start, WalkModifier, SprintModifier, speed); + } +} diff --git a/Content.Server/_CP14/ModularCraft/Modifiers/EditManacostModify.cs b/Content.Server/_CP14/ModularCraft/Modifiers/EditManacostModify.cs new file mode 100644 index 0000000000..7864826922 --- /dev/null +++ b/Content.Server/_CP14/ModularCraft/Modifiers/EditManacostModify.cs @@ -0,0 +1,40 @@ +using Content.Shared._CP14.ModularCraft; +using Content.Shared._CP14.ModularCraft.Components; +using Content.Shared._CP14.MagicManacostModify; +using Content.Shared._CP14.MagicRitual.Prototypes; +using Content.Shared.FixedPoint; +using Robust.Shared.Prototypes; + +namespace Content.Server._CP14.ModularCraft.Modifiers; + +public sealed partial class EditManacostModify : CP14ModularCraftModifier +{ + [DataField] + public Dictionary, FixedPoint2> Modifiers = new(); + + [DataField] + public FixedPoint2 GlobalModifier = 1f; + + public override void Effect(EntityManager entManager, Entity start, Entity? part) + { + if (!entManager.TryGetComponent(start, out var manacostModifyComp)) + return; + + foreach (var (magicType, modifier) in Modifiers) + { + if (manacostModifyComp.Modifiers.ContainsKey(magicType)) + { + if (modifier >= 1f) + manacostModifyComp.Modifiers[magicType] += modifier - 1f; + else + manacostModifyComp.Modifiers[magicType] -= 1f - modifier; + } + else + { + manacostModifyComp.Modifiers[magicType] = modifier; + } + } + + manacostModifyComp.GlobalModifier += GlobalModifier; + } +} diff --git a/Content.Shared/Armor/SharedArmorSystem.cs b/Content.Shared/Armor/SharedArmorSystem.cs index 010ee5e65b..55cb39397d 100644 --- a/Content.Shared/Armor/SharedArmorSystem.cs +++ b/Content.Shared/Armor/SharedArmorSystem.cs @@ -79,4 +79,30 @@ public abstract class SharedArmorSystem : EntitySystem return msg; } + + //CP14 public armor edit API + public void EditArmorCoefficients(EntityUid uid, DamageModifierSet modifiers, ArmorComponent? armor = null) + { + if (!Resolve(uid, ref armor)) + return; + + //Merge old and new coefficients + foreach (var (armorType, coefficient) in modifiers.Coefficients) + { + if (armor.Modifiers.Coefficients.ContainsKey(armorType)) + armor.Modifiers.Coefficients[armorType] += coefficient; + else + armor.Modifiers.Coefficients[armorType] = coefficient; + } + + //Merge old and new flat reductions + foreach (var (armorType, reduction) in modifiers.FlatReduction) + { + if (armor.Modifiers.FlatReduction.ContainsKey(armorType)) + armor.Modifiers.FlatReduction[armorType] += reduction; + else + armor.Modifiers.FlatReduction[armorType] = reduction; + } + } + //CP14 public armor edit API end } diff --git a/Content.Shared/Clothing/ClothingSpeedModifierSystem.cs b/Content.Shared/Clothing/ClothingSpeedModifierSystem.cs index 56758654ed..8673e856a1 100644 --- a/Content.Shared/Clothing/ClothingSpeedModifierSystem.cs +++ b/Content.Shared/Clothing/ClothingSpeedModifierSystem.cs @@ -116,4 +116,20 @@ public sealed class ClothingSpeedModifierSystem : EntitySystem _movementSpeed.RefreshMovementSpeedModifiers(container.Owner); } } + + //CP14 - Public API for edit component + public void EditSpeedModifiers(EntityUid uid, float walkModifier, float sprintModifier, ClothingSpeedModifierComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + component.WalkModifier += walkModifier; + component.SprintModifier += sprintModifier; + + if (_container.TryGetContainingContainer((uid, null, null), out var container)) + { + _movementSpeed.RefreshMovementSpeedModifiers(container.Owner); + } + } + //CP14 - Public API for edit component end } diff --git a/Content.Shared/_CP14/MagicManacostModify/CP14MagicManacostModifyComponent.cs b/Content.Shared/_CP14/MagicManacostModify/CP14MagicManacostModifyComponent.cs index 688957520e..26c325c8bb 100644 --- a/Content.Shared/_CP14/MagicManacostModify/CP14MagicManacostModifyComponent.cs +++ b/Content.Shared/_CP14/MagicManacostModify/CP14MagicManacostModifyComponent.cs @@ -7,7 +7,7 @@ namespace Content.Shared._CP14.MagicManacostModify; /// /// Changes the manacost of spells for the bearer /// -[RegisterComponent, Access(typeof(CP14MagicManacostModifySystem))] +[RegisterComponent] public sealed partial class CP14MagicManacostModifyComponent : Component { [DataField] diff --git a/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.cs b/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.cs index 9064f18faa..85575b0d8a 100644 --- a/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.cs +++ b/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.cs @@ -52,9 +52,27 @@ public abstract partial class CP14SharedMagicSystem : EntitySystem SubscribeLocalEvent(OnMagicEffectInit); SubscribeLocalEvent(OnMagicEffectShutdown); + SubscribeLocalEvent(OnStartCast); + SubscribeLocalEvent(OnEndCast); + SubscribeLocalEvent(OnStaminaConsume); } + private void OnStartCast(Entity ent, ref CP14StartCastMagicEffectEvent args) + { + var caster = EnsureComp(args.Performer); + + caster.CastedSpells.Add(ent); + } + + private void OnEndCast(Entity ent, ref CP14EndCastMagicEffectEvent args) + { + if (TryComp(args.Performer, out var caster)) + { + caster.CastedSpells.Remove(ent); + } + } + public override void Update(float frameTime) { base.Update(frameTime); diff --git a/Content.Shared/_CP14/MagicSpell/Components/CP14MagicCasterComponent.cs b/Content.Shared/_CP14/MagicSpell/Components/CP14MagicCasterComponent.cs new file mode 100644 index 0000000000..bb73fec3d1 --- /dev/null +++ b/Content.Shared/_CP14/MagicSpell/Components/CP14MagicCasterComponent.cs @@ -0,0 +1,11 @@ +namespace Content.Shared._CP14.MagicSpell.Components; + +/// +/// +/// +[RegisterComponent, Access(typeof(CP14SharedMagicSystem))] +public sealed partial class CP14MagicCasterComponent : Component +{ + [DataField] + public List CastedSpells = new(); +} diff --git a/Content.Shared/_CP14/MagicSpell/Spells/C14SpellInterruptSpell.cs b/Content.Shared/_CP14/MagicSpell/Spells/C14SpellInterruptSpell.cs new file mode 100644 index 0000000000..d8ab0f5567 --- /dev/null +++ b/Content.Shared/_CP14/MagicSpell/Spells/C14SpellInterruptSpell.cs @@ -0,0 +1,39 @@ +using Content.Shared._CP14.MagicSpell.Components; +using Content.Shared.Electrocution; + +namespace Content.Shared._CP14.MagicSpell.Spells; + +public sealed partial class CP14SpellInterruptSpell : CP14SpellEffect +{ + [DataField] + public TimeSpan Duration = TimeSpan.FromSeconds(5); + + [DataField] + public int Damage = 10; + + public override void Effect(EntityManager entManager, CP14SpellEffectBaseArgs args) + { + if (args.Target is null) + return; + + if (!entManager.TryGetComponent(args.Target.Value, out var caster)) + return; + + var interrupt = false; + foreach (var spell in caster.CastedSpells) + { + if (entManager.HasComponent(spell)) + { + interrupt = true; + break; + } + } + + if (!interrupt) + return; + + var electrocutionSystem = entManager.System(); + + electrocutionSystem.TryDoElectrocution(args.Target.Value, args.User, Damage, Duration, true, ignoreInsulation: true ); + } +} diff --git a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Healing/magical_acceleration.yml b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Healing/magical_acceleration.yml index 142ac1f7a7..3b8befd4f9 100644 --- a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Healing/magical_acceleration.yml +++ b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Healing/magical_acceleration.yml @@ -41,4 +41,26 @@ shader: unshaded color: "#4097bd" - type: PointLight - color: "#4097bd" \ No newline at end of file + color: "#4097bd" + +- type: entity + parent: CP14BaseSpellScrollHealing + id: CP14SpellScrollMagicalAcceleration + name: magical accseleration spell scroll + components: + - type: CP14SpellStorage + spells: + - CP14ActionSpellMagicalAcceleration + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + CP14Ash1: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Meta/T0_counter_spell.yml b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Meta/T0_counter_spell.yml new file mode 100644 index 0000000000..6fd4dc5a73 --- /dev/null +++ b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Meta/T0_counter_spell.yml @@ -0,0 +1,73 @@ +- type: entity + id: CP14ActionSpellCounterSpell + name: counter spell + description: By affecting the magical energy itself, you can interrupt the cast of someone else's spell. + components: + - type: Sprite + sprite: _CP14/Effects/Magic/spells_icons.rsi + state: counter_spell + - type: CP14MagicEffectCastSlowdown + speedMultiplier: 0.7 + - type: CP14MagicEffectManaCost + manaCost: 15 + - type: CP14MagicEffect + magicType: Meta + telegraphyEffects: + - !type:CP14SpellSpawnEntityOnTarget + spawns: + - CP14ImpactEffectCounterSpell + effects: + - !type:CP14SpellInterruptSpell + - type: CP14MagicEffectCastingVisual + proto: CP14RuneCounterSpell + - type: EntityTargetAction + whitelist: + components: + - CP14MagicEnergyContainer + itemIconStyle: BigAction + interactOnMiss: false + sound: !type:SoundPathSpecifier + path: /Audio/Magic/rumble.ogg + icon: + sprite: _CP14/Effects/Magic/spells_icons.rsi + state: counter_spell + event: !type:CP14DelayedEntityTargetActionEvent + cooldown: 10 + castDelay: 0.75 + breakOnMove: false + +- type: entity + id: CP14RuneCounterSpell + parent: CP14BaseMagicRune + categories: [ HideSpawnMenu ] + components: + - type: PointLight + color: "#5096d4" + - type: Sprite + layers: + - state: medium_circle + color: "#5096d4" + shader: unshaded + +- type: entity + id: CP14ImpactEffectCounterSpell + parent: CP14BaseMagicImpact + categories: [ HideSpawnMenu ] + components: + - type: Sprite + layers: + - state: circle_decrease + color: "#5096d4" + shader: unshaded + - state: circle_increase + color: "#5096d4" + shader: unshaded + +- type: entity + parent: CP14BaseSpellScrollMeta + id: CP14SpellScrollCounterSpell + name: counter spell spell scroll #Spell spell spell spell + components: + - type: CP14SpellStorage + spells: + - CP14ActionSpellCounterSpell \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Entities/Markers/Spawners/Random/Loot/demiplane.yml b/Resources/Prototypes/_CP14/Entities/Markers/Spawners/Random/Loot/demiplane.yml index ce0aee38ad..e51e6dc0e1 100644 --- a/Resources/Prototypes/_CP14/Entities/Markers/Spawners/Random/Loot/demiplane.yml +++ b/Resources/Prototypes/_CP14/Entities/Markers/Spawners/Random/Loot/demiplane.yml @@ -37,6 +37,8 @@ - id: CP14SpellScrollFlashLight - id: CP14SpellScrollWaterCreation - id: CP14SpellScrollPlantGrowth + - id: CP14SpellScrollCounterSpell + - id: CP14ActionSpellMagicalAcceleration - id: CP14EnergyCrystalSmallEmpty - id: CP14BaseSharpeningStone - id: CP14ScrapCopper diff --git a/Resources/Prototypes/_CP14/Loadouts/Jobs/general.yml b/Resources/Prototypes/_CP14/Loadouts/Jobs/general.yml index e2831ad891..808d0d7849 100644 --- a/Resources/Prototypes/_CP14/Loadouts/Jobs/general.yml +++ b/Resources/Prototypes/_CP14/Loadouts/Jobs/general.yml @@ -590,7 +590,7 @@ id: CP14GeneralSpells name: cp14-loadout-general-spells minLimit: 0 - maxLimit: 2 + maxLimit: 3 loadouts: - CP14ActionSpellFlameCreation - CP14ActionSpellCureWounds @@ -600,6 +600,7 @@ - CP14ActionSpellSphereOfLight - CP14ActionSpellManaConsume - CP14ActionSpellManaGift + - CP14ActionSpellCounterSpell - CP14ActionSpellShadowGrab - CP14ActionSpellWaterCreation - CP14ActionSpellFreeze @@ -772,6 +773,19 @@ traits: - CP14ManaWasting +- type: loadout + id: CP14ActionSpellCounterSpell + dummyEntity: CP14ActionSpellCounterSpell + actions: + - CP14ActionSpellCounterSpell + effects: + - !type:JobRequirementLoadoutEffect + requirement: + !type:TraitsRequirement + inverted: true + traits: + - CP14ManaWasting + - type: loadout id: CP14ActionSpellBeerCreation dummyEntity: CP14ActionSpellBeerCreation diff --git a/Resources/Textures/_CP14/Effects/Magic/cast_impact.rsi/circle_increase.png b/Resources/Textures/_CP14/Effects/Magic/cast_impact.rsi/circle_increase.png new file mode 100644 index 0000000000..caade16d0c Binary files /dev/null and b/Resources/Textures/_CP14/Effects/Magic/cast_impact.rsi/circle_increase.png differ diff --git a/Resources/Textures/_CP14/Effects/Magic/cast_impact.rsi/meta.json b/Resources/Textures/_CP14/Effects/Magic/cast_impact.rsi/meta.json index b4a0239093..035f9b2875 100644 --- a/Resources/Textures/_CP14/Effects/Magic/cast_impact.rsi/meta.json +++ b/Resources/Textures/_CP14/Effects/Magic/cast_impact.rsi/meta.json @@ -22,6 +22,21 @@ ] ] }, + { + "name": "circle_increase", + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, { "name": "particles_down", "delays": [ diff --git a/Resources/Textures/_CP14/Effects/Magic/spells_icons.rsi/counter_spell.png b/Resources/Textures/_CP14/Effects/Magic/spells_icons.rsi/counter_spell.png new file mode 100644 index 0000000000..d528bb3e5f Binary files /dev/null and b/Resources/Textures/_CP14/Effects/Magic/spells_icons.rsi/counter_spell.png differ diff --git a/Resources/Textures/_CP14/Effects/Magic/spells_icons.rsi/meta.json b/Resources/Textures/_CP14/Effects/Magic/spells_icons.rsi/meta.json index 6862220d00..8a2d6547d4 100644 --- a/Resources/Textures/_CP14/Effects/Magic/spells_icons.rsi/meta.json +++ b/Resources/Textures/_CP14/Effects/Magic/spells_icons.rsi/meta.json @@ -5,11 +5,14 @@ "y": 32 }, "license": "All right reserved", - "copyright": "Created by .kreks., cure_poison, cure_burn, mana_gift, water creation, plant_growth, beer creation, sprint, tiefling_revenge, demi_arrow, rift_shield, rift_arrow, signal_light_blue, signal_light_red, freeze, magical_acceleration, kick, signal_light_yellow and resurrection by TheShuEd", + "copyright": "Created by .kreks., cure_poison, cure_burn, mana_gift, water creation, plant_growth, beer creation, sprint, tiefling_revenge, demi_arrow, rift_shield, rift_arrow, signal_light_blue, signal_light_red, freeze, counter_spell, magical_acceleration, kick, signal_light_yellow and resurrection by TheShuEd", "states": [ { "name": "beer_creation" }, + { + "name": "counter_spell" + }, { "name": "cure_burn" },