diff --git a/Content.Client/Weapons/Ranged/Systems/GunSystem.cs b/Content.Client/Weapons/Ranged/Systems/GunSystem.cs index 9e50cab3e10..60edb4e6c43 100644 --- a/Content.Client/Weapons/Ranged/Systems/GunSystem.cs +++ b/Content.Client/Weapons/Ranged/Systems/GunSystem.cs @@ -3,6 +3,7 @@ using Content.Client.Weapons.Ranged.Components; using Content.Shared.Camera; using Content.Shared.CombatMode; +using Content.Shared.Mech.Components; using Content.Shared.Weapons.Ranged; using Content.Shared.Weapons.Ranged.Components; using Content.Shared.Weapons.Ranged.Events; @@ -141,6 +142,11 @@ public override void Update(float frameTime) var entity = entityNull.Value; + if (TryComp(entity, out var mechPilot)) + { + entity = mechPilot.Mech; + } + if (!TryGetGun(entity, out var gunUid, out var gun)) { return; diff --git a/Content.Server/Atmos/EntitySystems/FlammableSystem.cs b/Content.Server/Atmos/EntitySystems/FlammableSystem.cs index 53fcb720766..924048ba596 100644 --- a/Content.Server/Atmos/EntitySystems/FlammableSystem.cs +++ b/Content.Server/Atmos/EntitySystems/FlammableSystem.cs @@ -12,6 +12,7 @@ using Content.Shared.Damage; using Content.Shared.Database; using Content.Shared.Interaction; +using Content.Shared.Mech.Components; using Content.Shared.Physics; using Content.Shared.Popups; using Content.Shared.Projectiles; @@ -305,6 +306,11 @@ public void Ignite(EntityUid uid, EntityUid ignitionSource, FlammableComponent? if (!Resolve(uid, ref flammable)) return; + // I would rather there be a cancellable event for this but I really don't wanna fuck with this janky system more than I have too. + // FlammableSystem rework when? + if (TryComp(uid, out var mechPilot) && TryComp(mechPilot.Mech, out var mech) && mech.Airtight) + return; + if (flammable.AlwaysCombustible) { flammable.FireStacks = Math.Max(flammable.FirestacksOnIgnite, flammable.FireStacks); diff --git a/Content.Server/Mech/Equipment/EntitySystems/MechGunSystem.cs b/Content.Server/Mech/Equipment/EntitySystems/MechGunSystem.cs new file mode 100644 index 00000000000..d0fc53256ad --- /dev/null +++ b/Content.Server/Mech/Equipment/EntitySystems/MechGunSystem.cs @@ -0,0 +1,75 @@ +using Content.Server.Mech.Systems; +using Content.Server.Power.Components; +using Content.Server.Power.EntitySystems; +using Content.Shared.Mech.Components; +using Content.Shared.Mech.Equipment.Components; +using Content.Shared.Throwing; +using Content.Shared.Weapons.Ranged.Systems; +using Robust.Shared.Random; + +namespace Content.Server.Mech.Equipment.EntitySystems; +public sealed class MechGunSystem : EntitySystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly ThrowingSystem _throwing = default!; + [Dependency] private readonly MechSystem _mech = default!; + [Dependency] private readonly BatterySystem _battery = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(MechGunShot); + } + + private void MechGunShot(EntityUid uid, MechEquipmentComponent component, ref GunShotEvent args) + { + if (!component.EquipmentOwner.HasValue) + return; + + if (!TryComp(component.EquipmentOwner.Value, out var mech)) + return; + + if (TryComp(uid, out var battery)) + { + ChargeGunBattery(uid, battery); + return; + } + + // In most guns the ammo itself isn't shot but turned into cassings + // and a new projectile is spawned instead, meaning that args.Ammo + // is most likely inside the equipment container (for some odd reason) + + // I'm not even sure why this is needed since GunSystem.Shoot() has a + // container check before ejecting, but yet it still puts the spent ammo inside the mech + foreach (var (ent, _) in args.Ammo) + { + if (ent.HasValue && mech.EquipmentContainer.Contains(ent.Value)) + { + mech.EquipmentContainer.Remove(ent.Value); + _throwing.TryThrow(ent.Value, _random.NextVector2(), _random.Next(5)); + } + } + } + + private void ChargeGunBattery(EntityUid uid, BatteryComponent component) + { + if (!TryComp(uid, out var mechEquipment) || !mechEquipment.EquipmentOwner.HasValue) + return; + + if (!TryComp(mechEquipment.EquipmentOwner.Value, out var mech)) + return; + + var maxCharge = component.MaxCharge; + var currentCharge = component.CurrentCharge; + + var chargeDelta = maxCharge - currentCharge; + + if (chargeDelta <= 0 || mech.Energy - chargeDelta < 0) + return; + + if (!_mech.TryChangeEnergy(mechEquipment.EquipmentOwner.Value, -chargeDelta, mech)) + return; + + _battery.SetCharge(uid, component.MaxCharge, component); + } +} \ No newline at end of file diff --git a/Content.Server/Mech/Systems/MechSystem.cs b/Content.Server/Mech/Systems/MechSystem.cs index eef9bcb8ecd..0ce61be7efb 100644 --- a/Content.Server/Mech/Systems/MechSystem.cs +++ b/Content.Server/Mech/Systems/MechSystem.cs @@ -1,4 +1,5 @@ using System.Linq; +using Content.Server.Atmos.Components; using Content.Server.Atmos.EntitySystems; using Content.Server.Mech.Components; using Content.Server.Power.Components; diff --git a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs index b8f8f122111..3b7a297f31f 100644 --- a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs +++ b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs @@ -3,6 +3,7 @@ using Content.Server.Administration.Logs; using Content.Server.Cargo.Systems; using Content.Server.Interaction; +using Content.Server.Mech.Equipment.Components; using Content.Server.Power.EntitySystems; using Content.Server.Stunnable; using Content.Server.Weapons.Ranged.Components; @@ -11,6 +12,7 @@ using Content.Shared.Database; using Content.Shared.Effects; using Content.Shared.Interaction.Components; +using Content.Shared.Mech.Equipment.Components; using Content.Shared.Projectiles; using Content.Shared.Weapons.Melee; using Content.Shared.Weapons.Ranged; @@ -170,9 +172,12 @@ public override void Shoot(EntityUid gunUid, GunComponent gun, List<(EntityUid? // Something like ballistic might want to leave it in the container still if (!cartridge.DeleteOnSpawn && !Containers.IsEntityInContainer(ent!.Value)) + { EjectCartridge(ent.Value, angle); + } Dirty(ent!.Value, cartridge); + break; // Ammo shoots itself case AmmoComponent newAmmo: diff --git a/Content.Shared/Mech/EntitySystems/SharedMechSystem.cs b/Content.Shared/Mech/EntitySystems/SharedMechSystem.cs index 7e44dea5078..e47cad9a782 100644 --- a/Content.Shared/Mech/EntitySystems/SharedMechSystem.cs +++ b/Content.Shared/Mech/EntitySystems/SharedMechSystem.cs @@ -15,6 +15,7 @@ using Content.Shared.Movement.Systems; using Content.Shared.Popups; using Content.Shared.Weapons.Melee; +using Content.Shared.Weapons.Ranged.Events; using Robust.Shared.Containers; using Robust.Shared.Network; using Robust.Shared.Serialization; @@ -43,7 +44,9 @@ public override void Initialize() { SubscribeLocalEvent(OnToggleEquipmentAction); SubscribeLocalEvent(OnEjectPilotEvent); + SubscribeLocalEvent(RelayInteractionEvent); + SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnDestruction); SubscribeLocalEvent(OnGetAdditionalAccess); diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs index 36b5bbd1927..b632f8dfee1 100644 --- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs @@ -11,6 +11,7 @@ using Content.Shared.Gravity; using Content.Shared.Hands; using Content.Shared.Hands.Components; +using Content.Shared.Mech.Components; using Content.Shared.Item; // Delta-V: Felinids in duffelbags can't shoot. using Content.Shared.Popups; using Content.Shared.Projectiles; @@ -126,13 +127,15 @@ private void OnShootRequest(RequestShootEvent msg, EntitySessionEventArgs args) { var user = args.SenderSession.AttachedEntity; - if (user == null || - !_combatMode.IsInCombatMode(user) || - !TryGetGun(user.Value, out var ent, out var gun) || - HasComp(user)) // Delta-V: Felinids in duffelbags can't shoot. - { + if (user == null || !_combatMode.IsInCombatMode(user)) return; - } + + if (TryComp(user.Value, out var mechPilot)) + user = mechPilot.Mech; + + if (!TryGetGun(user.Value, out var ent, out var gun)) + return; + if (ent != GetEntity(msg.Gun)) return; @@ -146,14 +149,19 @@ private void OnStopShootRequest(RequestStopShootEvent ev, EntitySessionEventArgs { var gunUid = GetEntity(ev.Gun); - if (args.SenderSession.AttachedEntity == null || - !TryComp(gunUid, out var gun) || - !TryGetGun(args.SenderSession.AttachedEntity.Value, out _, out var userGun)) - { + var user = args.SenderSession.AttachedEntity; + + if (user == null) return; - } + - if (userGun != gun) + if (TryComp(user.Value, out var mechPilot)) + user = mechPilot.Mech; + + if (!TryGetGun(user.Value, out var ent, out var gun)) + return; + + if (ent != gunUid) return; StopShooting(gunUid, gun); @@ -172,6 +180,15 @@ public bool TryGetGun(EntityUid entity, out EntityUid gunEntity, [NotNullWhen(tr gunEntity = default; gunComp = null; + if (TryComp(entity, out var mech) && + mech.CurrentSelectedEquipment.HasValue && + TryComp(mech.CurrentSelectedEquipment.Value, out var mechGun)) + { + gunEntity = mech.CurrentSelectedEquipment.Value; + gunComp = mechGun; + return true; + } + if (EntityManager.TryGetComponent(entity, out HandsComponent? hands) && hands.ActiveHandEntity is { } held && TryComp(held, out GunComponent? gun)) @@ -267,8 +284,11 @@ private void AttemptShoot(EntityUid user, EntityUid gunUid, GunComponent gun) var shots = 0; var lastFire = gun.NextFire; + Log.Debug($"Nextfire={gun.NextFire} curTime={curTime}"); + while (gun.NextFire <= curTime) { + Log.Debug("Shots++"); gun.NextFire += fireRate; shots++; } @@ -292,6 +312,8 @@ private void AttemptShoot(EntityUid user, EntityUid gunUid, GunComponent gun) throw new ArgumentOutOfRangeException($"No implemented shooting behavior for {gun.SelectedMode}!"); } + Log.Debug($"Shots fired: {shots}"); + var attemptEv = new AttemptShootEvent(user, null); RaiseLocalEvent(gunUid, ref attemptEv); diff --git a/Resources/Prototypes/Damage/modifier_sets.yml b/Resources/Prototypes/Damage/modifier_sets.yml index 31dd47a9e16..b5699972327 100644 --- a/Resources/Prototypes/Damage/modifier_sets.yml +++ b/Resources/Prototypes/Damage/modifier_sets.yml @@ -336,3 +336,50 @@ flatReductions: # can't punch the endoskeleton to death Blunt: 5 + +# Synths +- type: damageModifierSet + id: Synth + coefficients: + Blunt: 1.0 + Slash: 0.4 + Piercing: 1.5 + Cold: 0.0 + Heat: 2.5 + Shock: 3.0 + Poison: 0.0 + Radiation: 0.0 + Asphyxiation: 0.0 + Bloodloss: 0.0 + Cellular: 0.0 + flatReductions: + Blunt: 5 + +# Vatgrown +- type: damageModifierSet + id: Terra + coefficients: + Blunt: 2.0 + Slash: 2.0 + Piercing: 2.0 + Cold: 1.0 + Heat: 1.5 + Shock: 10.0 + Poison: 5.0 + Radiation: 1.0 + Asphyxiation: 2.5 + Bloodloss: 1.0 + Cellular: 1.0 + +# Mechs +- type: damageModifierSet + id: FireRestMetallic + parent: Metallic + flatReductions: + Heat: 1000 + +- type: damageModifierSet + id: FireResStrongMetallic + parent: StrongMetallic + flatReductions: + Heat: 1000 diff --git a/Resources/Prototypes/Datasets/Names/terragov_first.yml b/Resources/Prototypes/Datasets/Names/terragov_first.yml new file mode 100644 index 00000000000..cdad36a6b9d --- /dev/null +++ b/Resources/Prototypes/Datasets/Names/terragov_first.yml @@ -0,0 +1,53 @@ +- type: dataset + id: names_terra_first + values: + - Sgt. + - Capt. + - Pvt. + - Maj. + - Lt. + - Cpl. + - Col. + - Pvt. + - Sgt. + - Capt. + - Pvt. + - Lt. + - Cpl. + - Maj. + - Col. + - Sgt. + - Capt. + - Pvt. + - Lt. + - Cpl. + - Maj. + - Col. + - Sgt. + - Capt. + - Pvt. + - Lt. + - Cpl. + - Maj. + - Col. + - Sgt. + - Capt. + - Pvt. + - Lt. + - Cpl. + - Maj. + - Col. + - Sgt. + - Capt. + - Pvt. + - Lt. + - Cpl. + - Maj. + - Col. + - Sgt. + - Capt. + - Pvt. + - Lt. + - Cpl. + - Maj. + - Col. diff --git a/Resources/Prototypes/Datasets/Names/terragov_last.yml b/Resources/Prototypes/Datasets/Names/terragov_last.yml new file mode 100644 index 00000000000..c7658a5e764 --- /dev/null +++ b/Resources/Prototypes/Datasets/Names/terragov_last.yml @@ -0,0 +1,54 @@ +- type: dataset + id: names_terra_last + values: + - Thompson + - Ramirez + - Nguyen + - Patel + - Williams + - Gonzalez + - Lee + - Martinez + - Johnson + - Brown + - Jones + - Garcia + - Smith + - Khan + - Wilson + - Davis + - Anderson + - Rodriguez + - Taylor + - Hernandez + - Miller + - Martinez + - Clark + - Lewis + - Scott + - Baker + - Green + - Young + - Allen + - Hill + - Adams + - Wright + - King + - Carter + - Thomas + - Turner + - White + - Walker + - Hall + - Lewis + - Moore + - Jackson + - Harris + - Martin + - Thompson + - Garcia + - Clark + - Rodriguez + - Baker + - Martinez + diff --git a/Resources/Prototypes/Entities/Mobs/Player/Vatgrown.yml b/Resources/Prototypes/Entities/Mobs/Player/Vatgrown.yml new file mode 100644 index 00000000000..ac77c1ef08e --- /dev/null +++ b/Resources/Prototypes/Entities/Mobs/Player/Vatgrown.yml @@ -0,0 +1,24 @@ +- type: entity + save: false + name: Urist McFreedom + parent: BaseMobVatgrown + id: MobVatgrown + +# Terragov Agent +- type: entity + save: false + name: Terragov Marine + parent: BaseMobVatgrown + id: MobTerragovAgent + components: + - type: Loadout + prototypes: + - TerragovGear + - type: RandomMetadata + nameSegments: + - names_terra_first + - names_terra_last + - type: GhostRole + name: Terragov Marine + description: Terragov has deployed you on a special mission. Complete your task, then return to base. + - type: GhostTakeoverAvailable \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Mobs/Player/human.yml b/Resources/Prototypes/Entities/Mobs/Player/human.yml index b5938936ab3..5e4eb2f5411 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/human.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/human.yml @@ -88,11 +88,13 @@ - names_ninja_title - names_ninja +# Urist Agent - type: entity save: false name: Urist McHands parent: BaseMobHuman id: MobUristAgent + suffix: Agent components: - type: Loadout prototypes: diff --git a/Resources/Prototypes/Entities/Mobs/Species/ipc.yml b/Resources/Prototypes/Entities/Mobs/Species/ipc.yml index 376fd0528ad..5b9e03ff416 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/ipc.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/ipc.yml @@ -63,8 +63,8 @@ - type: HumanoidAppearance species: IPC - type: Damageable - damageContainer: Biological - damageModifierSet: Metallic + damageContainer: Inorganic + damageModifierSet: Synth - type: Icon sprite: Mobs/Species/IPC/parts.rsi state: full diff --git a/Resources/Prototypes/Entities/Mobs/Species/vatgrown.yml b/Resources/Prototypes/Entities/Mobs/Species/vatgrown.yml new file mode 100644 index 00000000000..b83de140a3c --- /dev/null +++ b/Resources/Prototypes/Entities/Mobs/Species/vatgrown.yml @@ -0,0 +1,26 @@ +# Anything human specific (e.g. UI, input) goes under MobHuman +- type: entity + parent: BaseMobSpeciesOrganic + id: BaseMobVatgrown + name: Urist McFreedom + abstract: true + components: + - type: Hunger + - type: Icon # It will not have an icon in the adminspawn menu without this. Body parts seem fine for whatever reason. + sprite: Mobs/Species/Human/parts.rsi + state: full + - type: Thirst + - type: Carriable # Carrying system from nyanotrasen. + - type: Damageable + damageContainer: Biological + damageModifierSet: Terra + - type: Butcherable + butcheringType: Spike + spawned: + - id: FoodMeatHuman + amount: 5 + +- type: entity + parent: BaseSpeciesDummy + id: MobVatgrownDummy + noSpawn: true diff --git a/Resources/Prototypes/Entities/Objects/Specific/Mech/mecha_weaponry.yml b/Resources/Prototypes/Entities/Objects/Specific/Mech/mecha_weaponry.yml new file mode 100644 index 00000000000..844ebc8e133 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Specific/Mech/mecha_weaponry.yml @@ -0,0 +1,160 @@ +- type: entity + id: MechDebugGun + parent: BaseMechEquipment + name: L6M "Decimator" + description: A L6 SAW retrofitted with mechsuit mounting brackets. + components: + - type: Sprite + sprite: Objects/Weapons/Guns/LMGs/l6.rsi + layers: + - state: base + map: ["enum.GunVisualLayers.Base"] + - state: mag-3 + map: ["enum.GunVisualLayers.Mag"] + - type: Gun # TODO: make bullets go less... everywhere + minAngle: 24 + maxAngle: 45 + angleIncrease: 4 + angleDecay: 16 + fireRate: 8 + selectedMode: FullAuto + availableModes: + - FullAuto + soundGunshot: + path: /Audio/Weapons/Guns/Gunshots/lmg.ogg + soundEmpty: + path: /Audio/Weapons/Guns/Empty/lmg_empty.ogg + - type: ChamberMagazineAmmoProvider + - type: AmmoCounter + - type: ItemSlots + slots: + gun_magazine: + name: Magazine + startingItem: MagazineLightRifleBox + insertSound: /Audio/Weapons/Guns/MagIn/batrifle_magin.ogg + ejectSound: /Audio/Weapons/Guns/MagOut/batrifle_magout.ogg + priority: 2 + whitelist: + tags: + - MagazineLightRifleBox + gun_chamber: + name: Chamber + startingItem: CartridgeLightRifle + priority: 1 + whitelist: + tags: + - CartridgeLightRifle + - type: ContainerContainer + containers: + gun_magazine: !type:ContainerSlot + gun_chamber: !type:ContainerSlot + - type: StaticPrice + price: 500 + +- type: entity + id: BaseMechLaserWeapon + parent: BaseMechEquipment + abstract: true + components: + - type: Sprite + - type: AmmoCounter + - type: Gun + fireRate: 2 + selectedMode: FullAuto + availableModes: + - FullAuto + soundGunshot: + path: /Audio/Weapons/Guns/Gunshots/laser.ogg + - type: Battery + maxCharge: 1000 + startingCharge: 1000 + - type: MagazineVisuals + magState: mag + steps: 5 + zeroVisible: false + - type: Appearance + - type: StaticPrice + price: 500 + +- type: entity + name: pow pow + parent: BaseMechLaserWeapon + id: MechDebugLaser + description: A weapon using light amplified by the stimulated emission of radiation. + components: + - type: Sprite + sprite: Objects/Weapons/Guns/Battery/laser_retro.rsi # TODO: put actual sprite + layers: + - state: base + map: ["enum.GunVisualLayers.Base"] + - state: mag-unshaded-4 + map: ["enum.GunVisualLayers.MagUnshaded"] + shader: unshaded + - type: HitscanBatteryAmmoProvider + proto: RedMediumLaser + fireCost: 62.5 + - type: MagazineVisuals + magState: mag + steps: 5 + zeroVisible: true + - type: Appearance + +- type: entity + parent: BaseMechEquipment + id: WeaponMechLauncher + name: SGL-6 Grenade Launcher + description: PLOOP + components: + - type: Sprite + sprite: Objects/Weapons/Guns/Launchers/china_lake.rsi + layers: + - state: icon + map: ["enum.GunVisualLayers.Base"] + - type: AmmoCounter + - type: Gun + fireRate: 1 + selectedMode: SemiAuto + availableModes: + - SemiAuto + soundGunshot: + path: /Audio/Weapons/Guns/Gunshots/grenade_launcher.ogg + - type: BallisticAmmoProvider + whitelist: + tags: + - Grenade + capacity: 6 + proto: GrenadeFrag + soundInsert: + path: /Audio/Weapons/Guns/MagIn/batrifle_magin.ogg + +- type: entity + parent: BaseMechEquipment + id: WeaponTeslaGun + name: MKI Tesla Cannon + description: The power of the primordial element of lightning, now attatched to your mech. + components: + - type: Sprite + sprite: Objects/Weapons/Guns/Battery/tesla_gun.rsi + layers: + - state: base + map: ["enum.GunVisualLayers.Base"] + - state: mag-unshaded-4 + map: ["enum.GunVisualLayers.MagUnshaded"] + shader: unshaded + - type: Gun + projectileSpeed: 10 + soundGunshot: + path: /Audio/Effects/Lightning/lightningshock.ogg + params: + variation: 0.2 + - type: Battery + maxCharge: 1000 + startingCharge: 1000 + - type: ProjectileBatteryAmmoProvider + proto: TeslaGunBullet + fireCost: 300 + - type: MagazineVisuals + magState: mag + steps: 5 + zeroVisible: true + - type: Appearance diff --git a/Resources/Prototypes/Entities/Objects/Specific/Mech/mechs.yml b/Resources/Prototypes/Entities/Objects/Specific/Mech/mechs.yml index 0e132541e1e..02c64acf0a7 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Mech/mechs.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Mech/mechs.yml @@ -288,3 +288,134 @@ containers: mech-battery-slot: - PowerCellHigh + +# Combat Mechs + +- type: entity + parent: BaseMech + id: MechMarauder + components: + - type: Sprite + drawdepth: Mobs + noRot: true + sprite: Objects/Specific/Mech/mecha.rsi + layers: + - map: [ "enum.MechVisualLayers.Base" ] + state: marauder + - type: FootstepModifier + footstepSoundCollection: + path: /Audio/Mecha/sound_mecha_powerloader_step.ogg + - type: Mech + baseState: marauder + openState: marauder-open + brokenState: marauder-broken + airtight: true + maxIntegrity: 500 + mechToPilotDamageMultiplier: 0.35 + - type: Reflect # Smol chance to reflect bullets/lasers + - type: MeleeWeapon + hidden: true + attackRate: 0.70 #Big slow arms + damage: + types: + Blunt: 50 #THWACK + Structural: 55 + - type: Damageable + damageContainer: Inorganic + damageModifierSet: FireResStrongMetallic # Yes this thing is also fire resistant + - type: MovementSpeedModifier + baseWalkSpeed: 2.0 + baseSprintSpeed: 3.0 + +- type: entity + parent: MechMarauder + id: MechMarauderBattery + suffix: Battery + components: + - type: ContainerFill + containers: + mech-battery-slot: + - PowerCellHigh + +- type: entity + parent: BaseMech + id: MechDarkGygax + components: + - type: Magboots + - type: Sprite + drawdepth: Mobs + noRot: true + sprite: Objects/Specific/Mech/mecha.rsi + layers: + - map: [ "enum.MechVisualLayers.Base" ] + state: darkgygax + - type: FootstepModifier + footstepSoundCollection: + path: /Audio/Mecha/sound_mecha_powerloader_step.ogg + - type: Mech + baseState: darkgygax + openState: darkgygax-open + brokenState: darkgygax-broken + airtight: true + maxIntegrity: 300 + mechToPilotDamageMultiplier: 0.35 + - type: Reflect # Smol chance to reflect bullets/lasers + - type: MeleeWeapon + hidden: true + attackRate: 0.90 #Big slow arms + damage: + types: + Blunt: 35 #THWACK + Structural: 40 + - type: Damageable + damageContainer: Inorganic + damageModifierSet: FireResStrongMetallic # Yes this thing is also fire resistant + - type: MovementSpeedModifier + baseWalkSpeed: 2.5 + baseSprintSpeed: 3.5 + +- type: entity + parent: MechDarkGygax + id: MechDarkGygaxBattery + suffix: Battery + components: + - type: ContainerFill + containers: + mech-battery-slot: + - PowerCellHigh + +- type: entity + parent: BaseMech + id: MechMauler + components: + - type: Sprite + drawdepth: Mobs + noRot: true + sprite: Objects/Specific/Mech/mecha.rsi + layers: + - map: [ "enum.MechVisualLayers.Base" ] + state: mauler + - type: FootstepModifier + footstepSoundCollection: + path: /Audio/Mecha/sound_mecha_powerloader_step.ogg + - type: Mech + baseState: mauler + openState: mauler-open + brokenState: mauler-broken + airtight: true + maxIntegrity: 500 + mechToPilotDamageMultiplier: 0.35 + - type: Reflect # Smol chance to reflect bullets/lasers + - type: MeleeWeapon + hidden: true + attackRate: 0.70 #Big slow arms + damage: + types: + Blunt: 50 #THWACK + Structural: 55 + - type: Damageable + damageContainer: Inorganic + damageModifierSet: FireResStrongMetallic # Yes this thing is also fire resistant + - type: MovementSpeedModifier + baseWalkSpeed: 2.0 + baseSprintSpeed: 3.0 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml index 935e335c2a4..9d933ac89b2 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml @@ -991,3 +991,46 @@ Heat: 20 # Slightly more damage than the 17heat from the Captain's Hitscan lasgun soundHit: collection: MeatLaserImpact + +# Mechs + +- type: entity + name: energy pulse + id: EnergyPulse + parent: BaseBullet + noSpawn: true + components: + - type: Reflective + reflective: + - Energy + - type: FlyBySound + sound: + collection: EnergyMiss + params: + volume: 5 + - type: Sprite + sprite: Objects/Weapons/Guns/Projectiles/projectiles_tg.rsi + layers: + - state: omnilaser + shader: unshaded + - type: Physics + - type: Fixtures + fixtures: + projectile: + shape: + !type:PhysShapeAabb + bounds: "-0.15,-0.3,0.15,0.3" + hard: false + mask: + - Impassable + - BulletImpassable + fly-by: *flybyfixture + - type: Ammo + - type: Projectile + impactEffect: BulletImpactEffectDisabler + damage: + types: + Heat: 16 + soundHit: + path: "/Audio/Weapons/tap.ogg" + soundForce: true diff --git a/Resources/Prototypes/Roles/Jobs/Fun/misc_startinggear.yml b/Resources/Prototypes/Roles/Jobs/Fun/misc_startinggear.yml index 434a7c1083e..a4e0d8713cb 100644 --- a/Resources/Prototypes/Roles/Jobs/Fun/misc_startinggear.yml +++ b/Resources/Prototypes/Roles/Jobs/Fun/misc_startinggear.yml @@ -322,3 +322,35 @@ shoes: ClothingShoesClownBanana jumpsuit: ClothingUniformJumpsuitClownBanana mask: ClothingMaskClownBanana + +# Terragov +- type: startingGear + id: TerragovGear + equipment: + jumpsuit: ClothingUniformJumpsuitMercenary + outerClothing: ClothingOuterVestWebMerc + back: ClothingBackpackMerc + shoes: ClothingShoesBootsMerc + gloves: ClothingHandsMercGlovesCombat + eyes: ClothingEyesGlassesMercenary + head: ClothingHeadHelmetMerc + id: PassengerPDA + ears: ClothingHeadsetFreelance + mask: ClothingMaskGasMerc + belt: ClothingBeltMercWebbing + +- type: startingGear + id: TerragovGearNukie + equipment: + jumpsuit: ClothingUniformJumpsuitMercenary + outerClothing: ClothingOuterHardsuitERTCentcomm + back: ClothingBackpackMerc + shoes: ClothingShoesBootsMerc + gloves: ClothingHandsMercGlovesCombat + eyes: ClothingEyesGlassesMercenary + head: ClothingHeadHelmetMerc + id: PassengerPDA + ears: ClothingHeadsetFreelance + mask: ClothingMaskGasMerc + belt: ClothingBeltMercWebbing + diff --git a/Resources/Prototypes/Species/vatgrown.yml b/Resources/Prototypes/Species/vatgrown.yml new file mode 100644 index 00000000000..7e361a3b63d --- /dev/null +++ b/Resources/Prototypes/Species/vatgrown.yml @@ -0,0 +1,160 @@ +- type: species + id: Vatgrown + name: Vatgrown + roundStart: false + prototype: MobVatgrown + sprites: MobHumanSprites + markingLimits: MobHumanMarkingLimits + dollPrototype: MobHumanDummy + skinColoration: HumanToned + +# The lack of a layer means that +# this person cannot have round-start anything +# applied to that layer. It has to instead +# be defined as a 'custom base layer' +# in either the mob's starting marking prototype, +# or it has to be added in C#. +- type: speciesBaseSprites + id: MobHumanSprites + sprites: + Head: MobHumanHead + Hair: MobHumanoidAnyMarking + FacialHair: MobHumanoidAnyMarking + Snout: MobHumanoidAnyMarking + Chest: MobHumanTorso + Eyes: MobHumanoidEyes + LArm: MobHumanLArm + RArm: MobHumanRArm + LHand: MobHumanLHand + RHand: MobHumanRHand + LLeg: MobHumanLLeg + RLeg: MobHumanRLeg + LFoot: MobHumanLFoot + RFoot: MobHumanRFoot + Tail: MobHumanoidAnyMarking # Nyanotrasen - Felinid + HeadTop: MobHumanoidAnyMarking # Nyanotrasen - Felinid & Oni + +- type: markingPoints + id: MobHumanMarkingLimits + points: + Hair: + points: 1 + required: false + FacialHair: + points: 1 + required: false + Snout: + points: 1 + required: false + Tail: # the cat tail joke + points: 0 + required: false + HeadTop: # the cat ear joke + points: 0 + required: false + Chest: + points: 1 + required: false + Legs: + points: 2 + required: false + Arms: + points: 2 + required: false + +- type: humanoidBaseSprite + id: MobHumanoidEyes + baseSprite: + sprite: Mobs/Customization/eyes.rsi + state: eyes + +- type: humanoidBaseSprite + id: MobHumanoidAnyMarking + +- type: humanoidBaseSprite + id: MobHumanoidMarkingMatchSkin + markingsMatchSkin: true + +- type: humanoidBaseSprite + id: MobHumanHead + baseSprite: + sprite: Mobs/Species/Human/parts.rsi + state: head_m + +- type: humanoidBaseSprite + id: MobHumanHeadMale + baseSprite: + sprite: Mobs/Species/Human/parts.rsi + state: head_m + +- type: humanoidBaseSprite + id: MobHumanHeadFemale + baseSprite: + sprite: Mobs/Species/Human/parts.rsi + state: head_f + +- type: humanoidBaseSprite + id: MobHumanTorso + baseSprite: + sprite: Mobs/Species/Human/parts.rsi + state: torso_m + +- type: humanoidBaseSprite + id: MobHumanTorsoMale + baseSprite: + sprite: Mobs/Species/Human/parts.rsi + state: torso_m + +- type: humanoidBaseSprite + id: MobHumanTorsoFemale + baseSprite: + sprite: Mobs/Species/Human/parts.rsi + state: torso_f + +- type: humanoidBaseSprite + id: MobHumanLLeg + baseSprite: + sprite: Mobs/Species/Human/parts.rsi + state: l_leg + +- type: humanoidBaseSprite + id: MobHumanLArm + baseSprite: + sprite: Mobs/Species/Human/parts.rsi + state: l_arm + +- type: humanoidBaseSprite + id: MobHumanLHand + baseSprite: + sprite: Mobs/Species/Human/parts.rsi + state: l_hand + +- type: humanoidBaseSprite + id: MobHumanLFoot + baseSprite: + sprite: Mobs/Species/Human/parts.rsi + state: l_foot + +- type: humanoidBaseSprite + id: MobHumanRLeg + baseSprite: + sprite: Mobs/Species/Human/parts.rsi + state: r_leg + +- type: humanoidBaseSprite + id: MobHumanRArm + baseSprite: + sprite: Mobs/Species/Human/parts.rsi + state: r_arm + +- type: humanoidBaseSprite + id: MobHumanRHand + baseSprite: + sprite: Mobs/Species/Human/parts.rsi + state: r_hand + +- type: humanoidBaseSprite + id: MobHumanRFoot + baseSprite: + sprite: Mobs/Species/Human/parts.rsi + state: r_foot