diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm
index 22b52e6203..591351032b 100644
--- a/code/game/mecha/combat/gygax.dm
+++ b/code/game/mecha/combat/gygax.dm
@@ -48,7 +48,7 @@
..()
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot
ME.attach(src)
- ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang/clusterbang
+ ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/clusterbang
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/teleporter
ME.attach(src)
diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm
index 1c1bfdff22..16c6dd72f5 100644
--- a/code/game/mecha/equipment/mecha_equipment.dm
+++ b/code/game/mecha/equipment/mecha_equipment.dm
@@ -19,6 +19,7 @@
var/salvageable = 1
var/required_type = /obj/mecha //may be either a type or a list of allowed types
var/equip_type = null //mechaequip2
+ var/allow_duplicate = 0
/obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(target=1)
sleep(equip_cooldown)
@@ -103,15 +104,19 @@
return 0
return 1
+/obj/item/mecha_parts/mecha_equipment/proc/handle_movement_action() //Any modules that have special effects or needs when moving.
+ return
+
/obj/item/mecha_parts/mecha_equipment/proc/action(atom/target)
return
/obj/item/mecha_parts/mecha_equipment/proc/can_attach(obj/mecha/M as obj)
//if(M.equipment.len >= M.max_equip)
// return 0
- for(var/obj/item/mecha_parts/mecha_equipment/ME in M.equipment) //Exact duplicate components aren't allowed.
- if(ME.type == src.type)
- return 0
+ if(!allow_duplicate)
+ for(var/obj/item/mecha_parts/mecha_equipment/ME in M.equipment) //Exact duplicate components aren't allowed.
+ if(ME.type == src.type)
+ return 0
if(equip_type == EQUIP_HULL && M.hull_equipment.len < M.max_hull_equip)
return 1
if(equip_type == EQUIP_WEAPON && M.weapon_equipment.len < M.max_weapon_equip)
diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm
index 70edf23665..ae01d0c6b5 100644
--- a/code/game/mecha/equipment/tools/medical_tools.dm
+++ b/code/game/mecha/equipment/tools/medical_tools.dm
@@ -12,6 +12,7 @@
var/inject_amount = 5
required_type = /obj/mecha/medical
salvageable = 0
+ allow_duplicate = 1
/obj/item/mecha_parts/mecha_equipment/tool/sleeper/New()
..()
diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm
index e5e7c929f7..da9d052cc2 100644
--- a/code/game/mecha/equipment/tools/tools.dm
+++ b/code/game/mecha/equipment/tools/tools.dm
@@ -236,7 +236,6 @@
/obj/item/mecha_parts/mecha_equipment/tool/extinguisher/on_reagent_change()
return
-
/obj/item/mecha_parts/mecha_equipment/tool/rcd
name = "mounted RCD"
desc = "An exosuit-mounted Rapid Construction Device. (Can be attached to: Any exosuit)"
@@ -827,6 +826,88 @@
A.use_power(delta*ER.coeff, pow_chan)
return
+/obj/item/mecha_parts/mecha_equipment/combat_shield
+ name = "linear combat shield"
+ desc = "A shield generator that forms a rectangular, unidirectionally projectile-blocking wall in front of the exosuit."
+ icon_state = "shield"
+ origin_tech = list(TECH_PHORON = 3, TECH_MAGNET = 6, TECH_ILLEGAL = 4)
+ equip_cooldown = 5
+ energy_drain = 20
+ range = 0
+
+ var/obj/item/shield_projector/line/exosuit/my_shield = null
+ var/my_shield_type = /obj/item/shield_projector/line/exosuit
+ var/icon/drone_overlay
+
+ equip_type = EQUIP_HULL
+
+/obj/item/mecha_parts/mecha_equipment/combat_shield/New()
+ ..()
+ my_shield = new my_shield_type
+ my_shield.shield_regen_delay = equip_cooldown
+ my_shield.my_tool = src
+ return
+
+/obj/item/mecha_parts/mecha_equipment/combat_shield/critfail()
+ ..()
+ my_shield.adjust_health(-200)
+ return
+
+/obj/item/mecha_parts/mecha_equipment/combat_shield/Destroy()
+ chassis.overlays -= drone_overlay
+ my_shield.forceMove(src)
+ my_shield.destroy_shields()
+ my_shield.my_tool = null
+ my_shield.my_mecha = null
+ qdel(my_shield)
+ my_shield = null
+ ..()
+
+/obj/item/mecha_parts/mecha_equipment/combat_shield/attach(obj/mecha/M as obj)
+ ..()
+ if(chassis)
+ my_shield.shield_health = my_shield.shield_health / 2
+ my_shield.my_mecha = chassis
+ my_shield.forceMove(chassis)
+
+ drone_overlay = new(src.icon, icon_state = "shield_droid")
+ M.overlays += drone_overlay
+ return
+
+/obj/item/mecha_parts/mecha_equipment/combat_shield/detach()
+ chassis.overlays -= drone_overlay
+ ..()
+ my_shield.destroy_shields()
+ my_shield.my_mecha = null
+ my_shield.shield_health = my_shield.max_shield_health
+ my_shield.forceMove(src)
+ return
+
+/obj/item/mecha_parts/mecha_equipment/combat_shield/handle_movement_action()
+ if(chassis)
+ my_shield.update_shield_positions()
+ return
+
+/obj/item/mecha_parts/mecha_equipment/combat_shield/proc/toggle_shield()
+ ..()
+ if(chassis)
+ my_shield.attack_self(chassis.occupant)
+ if(my_shield.active)
+ set_ready_state(0)
+ log_message("Activated.")
+ else
+ set_ready_state(1)
+ log_message("Deactivated.")
+
+/obj/item/mecha_parts/mecha_equipment/combat_shield/Topic(href, href_list)
+ ..()
+ if(href_list["toggle_shield"])
+ toggle_shield()
+ return
+
+/obj/item/mecha_parts/mecha_equipment/combat_shield/get_equip_info()
+ if(!chassis) return
+ return "* [src.name] - [my_shield.active?"Dea":"A"]ctivate"
/obj/item/mecha_parts/mecha_equipment/generator
@@ -1072,6 +1153,7 @@
var/mob/living/carbon/occupant = null
var/door_locked = 1
salvageable = 0
+ allow_duplicate = 1
equip_type = EQUIP_HULL
diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm
index 7ffc0dd49b..23419b4eba 100644
--- a/code/game/mecha/equipment/weapons/weapons.dm
+++ b/code/game/mecha/equipment/weapons/weapons.dm
@@ -47,13 +47,45 @@
if(auto_rearm)
projectiles = projectiles_per_shot
// set_ready_state(0)
+
+ var/target_for_log
+ if(ismob(target))
+ target_for_log = target
+ else
+ target_for_log = "[target.name]"
+
+ add_attack_logs(chassis.occupant,target_for_log,"Fired exosuit weapon [src.name] (MANUAL)")
+
do_after_cooldown()
+
return
/obj/item/mecha_parts/mecha_equipment/weapon/proc/Fire(atom/A, atom/target)
var/obj/item/projectile/P = A
+ P.dispersion = deviation
+ process_accuracy(P, chassis.occupant, target)
P.launch(target)
+/obj/item/mecha_parts/mecha_equipment/weapon/proc/process_accuracy(obj/projectile, mob/living/user, atom/target)
+ var/obj/item/projectile/P = projectile
+ if(!istype(P))
+ return
+
+ // Certain statuses make it harder to aim, blindness especially. Same chances as melee, however guns accuracy uses multiples of 15.
+ if(user.eye_blind)
+ P.accuracy -= 75
+ if(user.eye_blurry)
+ P.accuracy -= 30
+ if(user.confused)
+ P.accuracy -= 45
+
+ // Some modifiers make it harder or easier to hit things.
+ for(var/datum/modifier/M in user.modifiers)
+ if(!isnull(M.accuracy))
+ P.accuracy += M.accuracy
+ if(!isnull(M.accuracy_dispersion))
+ P.dispersion = max(P.dispersion + M.accuracy_dispersion, 0)
+
/obj/item/mecha_parts/mecha_equipment/weapon/energy
name = "general energy weapon"
auto_rearm = 1
@@ -61,42 +93,111 @@
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser
equip_cooldown = 8
name = "\improper CH-PS \"Immolator\" laser"
+ desc = "A laser carbine's firing system mounted on a high-powered exosuit weapon socket."
icon_state = "mecha_laser"
energy_drain = 30
projectile = /obj/item/projectile/beam
fire_sound = 'sound/weapons/Laser.ogg'
+ origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 3, TECH_MAGNET = 3)
+
+/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/xray
+ equip_cooldown = 6
+ name = "\improper CH-XS \"Penetrator\" laser"
+ desc = "A large, mounted variant of the anti-armor xray rifle."
+ icon_state = "mecha_xray"
+ energy_drain = 150
+ projectile = /obj/item/projectile/beam/xray
+ fire_sound = 'sound/weapons/eluger.ogg'
+
+ origin_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 3, TECH_PHORON = 3, TECH_POWER = 3)
+
+/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/xray/rigged
+ equip_cooldown = 12
+ name = "jury-rigged xray rifle"
+ desc = "A modified wormhole modulation array and meson-scanning control system allow this abomination to produce concentrated blasts of xrays."
+ energy_drain = 175
+ icon_state = "mecha_xray-rig"
+
+ equip_type = EQUIP_UTILITY
+
/obj/item/mecha_parts/mecha_equipment/weapon/energy/riggedlaser
- equip_cooldown = 30
+ equip_cooldown = 15
name = "jury-rigged welder-laser"
desc = "While not regulation, this inefficient weapon can be attached to working exo-suits in desperate, or malicious, times."
icon_state = "mecha_laser-rig"
- energy_drain = 80
+ energy_drain = 60
projectile = /obj/item/projectile/beam
fire_sound = 'sound/weapons/Laser.ogg'
required_type = list(/obj/mecha/combat, /obj/mecha/working)
equip_type = EQUIP_UTILITY
+ origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 2, TECH_MAGNET = 2)
+
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy
equip_cooldown = 15
name = "\improper CH-LC \"Solaris\" laser cannon"
+ desc = "In the Solaris, the lasing medium is enclosed in a tube lined with plutonium-239 and subjected to extreme neutron flux in a nuclear reactor core. This incredible technology may help YOU achieve high excitation rates with massive laser volumes!"
icon_state = "mecha_laser"
energy_drain = 60
projectile = /obj/item/projectile/beam/heavylaser
fire_sound = 'sound/weapons/lasercannonfire.ogg'
+ origin_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 4, TECH_MAGNET = 4)
+
+/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/rigged
+ equip_cooldown = 25
+ name = "jury-rigged emitter cannon"
+ desc = "While not regulation, this mining tool can be used as an inefficient weapon on working exo-suits in desperate, or malicious, times."
+ icon_state = "mecha_emitter"
+ energy_drain = 80
+ projectile = /obj/item/projectile/beam/heavylaser/fakeemitter
+ fire_sound = 'sound/weapons/emitter.ogg'
+
+ equip_type = EQUIP_UTILITY
+
+ origin_tech = list(TECH_COMBAT = 4, TECH_MAGNET = 4, TECH_PHORON = 3, TECH_ILLEGAL = 1)
+
+/obj/item/mecha_parts/mecha_equipment/weapon/energy/phase
+ equip_cooldown = 6
+ name = "\improper NT-PE \"Scorpio\" phase-emitter"
+ desc = "A specialist energy weapon intended for use against hostile wildlife."
+ description_fluff = "Essentially an Orion mounted inside a modified Gaia case."
+ icon_state = "mecha_phase"
+ energy_drain = 25
+ projectile = /obj/item/projectile/energy/phase
+ fire_sound = 'sound/weapons/Taser.ogg'
+
+ equip_type = EQUIP_UTILITY
+
+ origin_tech = list(TECH_MATERIAL = 1, TECH_COMBAT = 2, TECH_MAGNET = 2)
+
/obj/item/mecha_parts/mecha_equipment/weapon/energy/ion
equip_cooldown = 40
name = "mkIV ion heavy cannon"
+ desc = "An upscaled variant of anti-mechanical weaponry constructed by NT, such as the EW Halicon."
icon_state = "mecha_ion"
energy_drain = 120
projectile = /obj/item/projectile/ion
fire_sound = 'sound/weapons/Laser.ogg'
+ origin_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 4, TECH_MAGNET = 4)
+
+/obj/item/mecha_parts/mecha_equipment/weapon/energy/ion/rigged
+ equip_cooldown = 30
+ name = "jury-rigged ion cannon"
+ desc = "A tesla coil modified to amplify an ionic wave, and use it as a projectile."
+ icon_state = "mecha_ion-rig"
+ energy_drain = 100
+ projectile = /obj/item/projectile/ion/pistol
+
+ equip_type = EQUIP_UTILITY
+
/obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse
equip_cooldown = 30
name = "eZ-13 mk2 heavy pulse rifle"
+ desc = "An experimental Anti-Everything weapon."
icon_state = "mecha_pulse"
energy_drain = 120
origin_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 6, TECH_POWER = 4)
@@ -108,24 +209,34 @@
icon_state = "pulse1_bl"
var/life = 20
- Bump(atom/A)
- A.bullet_act(src, def_zone)
- src.life -= 10
- if(life <= 0)
- qdel(src)
- return
+/obj/item/projectile/beam/pulse/heavy/Bump(atom/A)
+ A.bullet_act(src, def_zone)
+ src.life -= 10
+ if(life <= 0)
+ qdel(src)
+ return
/obj/item/mecha_parts/mecha_equipment/weapon/energy/taser
name = "\improper PBT \"Pacifier\" mounted taser"
+ desc = "A large taser of similar design as those used in standard NT turrets, for use on an Exosuit."
icon_state = "mecha_taser"
energy_drain = 20
equip_cooldown = 8
projectile = /obj/item/projectile/beam/stun
fire_sound = 'sound/weapons/Taser.ogg'
+/obj/item/mecha_parts/mecha_equipment/weapon/energy/taser/rigged
+ name = "jury-rigged static rifle"
+ desc = "A vaguely functional taser analog, inside an extinguisher casing."
+ icon_state = "mecha_taser-rig"
+ energy_drain = 30
+ projectile = /obj/item/projectile/beam/stun/weak
+
+ equip_type = EQUIP_UTILITY
/obj/item/mecha_parts/mecha_equipment/weapon/honker
name = "sound emission device"
+ desc = "A perfectly normal bike-horn, for your exosuit."
icon_state = "mecha_honker"
energy_drain = 300
equip_cooldown = 150
@@ -133,7 +244,7 @@
equip_type = EQUIP_SPECIAL
-/obj/item/mecha_parts/mecha_equipment/honker/action(target)
+/obj/item/mecha_parts/mecha_equipment/weapon/honker/action(target)
if(!chassis)
return 0
if(energy_drain && chassis.get_charge() < energy_drain)
@@ -165,41 +276,78 @@
name = "general ballisic weapon"
var/projectile_energy_cost
- get_equip_info()
- return "[..()]\[[src.projectiles]\][(src.projectiles < initial(src.projectiles))?" - Rearm":null]"
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/get_equip_info()
+ return "[..()]\[[src.projectiles]\][(src.projectiles < initial(src.projectiles))?" - Rearm":null]"
- proc/rearm()
- if(projectiles < initial(projectiles))
- var/projectiles_to_add = initial(projectiles) - projectiles
- while(chassis.get_charge() >= projectile_energy_cost && projectiles_to_add)
- projectiles++
- projectiles_to_add--
- chassis.use_power(projectile_energy_cost)
- send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info())
- log_message("Rearmed [src.name].")
- return
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/proc/rearm()
+ if(projectiles < initial(projectiles))
+ var/projectiles_to_add = initial(projectiles) - projectiles
+ while(chassis.get_charge() >= projectile_energy_cost && projectiles_to_add)
+ projectiles++
+ projectiles_to_add--
+ chassis.use_power(projectile_energy_cost)
+ send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info())
+ log_message("Rearmed [src.name].")
+ return
- Topic(href, href_list)
- ..()
- if (href_list["rearm"])
- src.rearm()
- return
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/Topic(href, href_list)
+ ..()
+ if (href_list["rearm"])
+ src.rearm()
+ return
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/mortar
+ name = "\improper HEP RC 4 \"Skyfall\""
+ desc = "A Hephaestus exosuit-mounted mortar for use on planetary-or-similar bodies."
+ description_info = "This weapon cannot be fired indoors, underground, or on-station."
+ icon_state = "mecha_mortar"
+ equip_cooldown = 30
+ fire_sound = 'sound/weapons/cannon.ogg'
+ fire_volume = 100
+ projectiles = 3
+ deviation = 0.6
+ projectile = /obj/item/projectile/arc/fragmentation/mortar
+ projectile_energy_cost = 600
+
+ origin_tech = list(TECH_MATERIAL = 4, TECH_COMBAT = 5, TECH_ILLEGAL = 3)
+
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/mortar/action_checks(atom/target)
+ var/turf/MT = get_turf(chassis)
+ var/turf/TT = get_turf(target)
+ if(!MT.outdoors || !TT.outdoors)
+ to_chat(chassis.occupant, "\The [src]'s control system prevents you from firing due to a blocked firing arc.")
+ return 0
+ return ..()
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot
name = "\improper LBX AC 10 \"Scattershot\""
+ desc = "A massive shotgun designed to fill a large area with pellets."
icon_state = "mecha_scatter"
equip_cooldown = 20
- projectile = /obj/item/projectile/bullet/pistol/medium
- fire_sound = 'sound/weapons/Gunshot.ogg'
+ projectile = /obj/item/projectile/bullet/pellet/shotgun/flak
+ fire_sound = 'sound/weapons/gunshot/shotgun.ogg'
fire_volume = 80
projectiles = 40
projectiles_per_shot = 4
deviation = 0.7
projectile_energy_cost = 25
+ origin_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 4)
+
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot/rigged
+ name = "jury-rigged shrapnel cannon"
+ desc = "The remains of some unfortunate RCD now doomed to kill, rather than construct."
+ icon_state = "mecha_scatter-rig"
+ equip_cooldown = 30
+ fire_volume = 100
+ projectiles = 20
+ deviation = 1
+
+ equip_type = EQUIP_UTILITY
+
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg
name = "\improper Ultra AC 2"
+ desc = "A superior version of the standard Solgov Autocannon MK2 design."
icon_state = "mecha_uac2"
equip_cooldown = 10
projectile = /obj/item/projectile/bullet/pistol/medium
@@ -210,6 +358,16 @@
projectile_energy_cost = 20
fire_cooldown = 2
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg/rigged
+ name = "jury-rigged machinegun"
+ desc = "The cross between a jackhammer and a whole lot of zipguns."
+ icon_state = "mecha_uac2-rig"
+ equip_cooldown = 12
+ projectile = /obj/item/projectile/bullet/pistol
+ deviation = 0.5
+
+ equip_type = EQUIP_UTILITY
+
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack
var/missile_speed = 2
var/missile_range = 30
@@ -219,6 +377,7 @@
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flare
name = "\improper BNI Flare Launcher"
+ desc = "A flare-gun, but bigger."
icon_state = "mecha_flaregun"
projectile = /obj/item/device/flashlight/flare
fire_sound = 'sound/weapons/tablehit1.ogg'
@@ -239,6 +398,7 @@
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive
name = "\improper SRM-8 missile rack"
+ desc = "A missile battery that holds eight missiles."
icon_state = "mecha_missilerack"
projectile = /obj/item/missile
fire_sound = 'sound/weapons/rpg.ogg'
@@ -256,17 +416,40 @@
icon_state = "missile"
var/primed = null
throwforce = 15
+ var/devastation = 0
+ var/heavy_blast = 1
+ var/light_blast = 2
+ var/flash_blast = 4
+
+/obj/item/missile/proc/warhead_special(var/target)
+ explosion(target, devastation, heavy_blast, light_blast, flash_blast)
+ return
/obj/item/missile/throw_impact(atom/hit_atom)
if(primed)
- explosion(hit_atom, 0, 1, 2, 4)
+ warhead_special(hit_atom)
qdel(src)
else
..()
return
-/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang
+/obj/item/missile/light
+ throwforce = 10
+ heavy_blast = 0
+
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive/rigged
+ name = "jury-rigged rocket pod"
+ desc = "A series of pipes, tubes, and cables that resembles a rocket pod."
+ icon_state = "mecha_missilerack-rig"
+ projectile = /obj/item/missile/light
+ projectiles = 3
+ projectile_energy_cost = 800
+
+ equip_type = EQUIP_UTILITY
+
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade
name = "\improper SGL-6 grenade launcher"
+ desc = "A grenade launcher produced for SWAT use; fires flashbangs."
icon_state = "mecha_grenadelnchr"
projectile = /obj/item/weapon/grenade/flashbang
fire_sound = 'sound/effects/bang.ogg'
@@ -276,22 +459,64 @@
equip_cooldown = 60
var/det_time = 20
-/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang/Fire(atom/movable/AM, atom/target, turf/aimloc)
- ..()
- var/obj/item/weapon/grenade/flashbang/F = AM
- spawn(det_time)
- F.detonate()
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/rigged
+ name = "jury-rigged pneumatic flashlauncher"
+ desc = "A grenade launcher constructed out of estranged blueprints; fires flashbangs."
+ icon_state = "mecha_grenadelnchr-rig"
+ projectiles = 3
+ missile_speed = 1
+ det_time = 25
-/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang/clusterbang//Because I am a heartless bastard -Sieve
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/Fire(atom/movable/AM, atom/target, turf/aimloc)
+ var/obj/item/weapon/grenade/G = AM
+ if(istype(G))
+ G.det_time = det_time
+ G.activate(chassis.occupant) //Grenades actually look primed and dangerous, handle their own stuff.
+
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/clusterbang//Because I am a heartless bastard -Sieve
name = "\improper SOP-6 grenade launcher"
+ desc = "A grenade launcher produced for use by government uprising subjugation forces, or that's what you might guess; fires matryoshka flashbangs."
projectile = /obj/item/weapon/grenade/flashbang/clusterbang
-/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang/clusterbang/limited/get_equip_info()//Limited version of the clusterbang launcher that can't reload
+ origin_tech = list(TECH_COMBAT= 5, TECH_MATERIAL = 5, TECH_ILLEGAL = 3)
+
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/clusterbang/limited/get_equip_info()//Limited version of the clusterbang launcher that can't reload
return "* [chassis.selected==src?"":""][src.name][chassis.selected==src?"":""]\[[src.projectiles]\]"
-/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang/clusterbang/limited/rearm()
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/clusterbang/limited/rearm()
return//Extra bit of security
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/concussion
+ name = "\improper SGL-9 grenade launcher"
+ desc = "A military-grade grenade launcher that fires disorienting concussion grenades."
+ icon_state = "mecha_grenadelnchr"
+ projectile = /obj/item/weapon/grenade/concussion
+ missile_speed = 1
+ projectile_energy_cost = 900
+ equip_cooldown = 50
+ det_time = 25
+
+ origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 4, TECH_ILLEGAL = 1)
+
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/frag
+ name = "\improper HEP-I 5 grenade launcher"
+ desc = "A military-grade grenade launcher that fires anti-personnel fragmentation grenades."
+ icon_state = "mecha_fraglnchr"
+ projectile = /obj/item/weapon/grenade/explosive
+ projectiles = 4
+ missile_speed = 1
+
+ origin_tech = list(TECH_COMBAT = 5, TECH_ENGINEERING = 5, TECH_MATERIAL = 5, TECH_ILLEGAL = 3)
+
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/frag/mini
+ name = "\improper HEP-MI 6 grenade launcher"
+ desc = "A military-grade grenade launcher that fires miniaturized anti-personnel fragmentation grenades."
+ projectile = /obj/item/weapon/grenade/explosive/mini
+ projectile_energy_cost = 500
+ equip_cooldown = 25
+
+ origin_tech = list(TECH_COMBAT = 4, TECH_ENGINEERING = 2, TECH_MATERIAL = 3, TECH_ILLEGAL = 2)
+
//////////////
//Fire-based//
//////////////
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 0812602eeb..1a1bee23c3 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -395,6 +395,7 @@
return domove(direction)
/obj/mecha/proc/domove(direction)
+
return call((proc_res["dyndomove"]||src), "dyndomove")(direction)
/obj/mecha/proc/dyndomove(direction)
@@ -423,6 +424,12 @@
return 1
return 0
+/obj/mecha/proc/handle_equipment_movement()
+ for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment)
+ if(ME.chassis == src) //Sanity
+ ME.handle_movement_action()
+ return
+
/obj/mecha/proc/mechturn(direction)
set_dir(direction)
playsound(src,'sound/mecha/mechturn.ogg',40,1)
@@ -432,6 +439,7 @@
var/result = step(src,direction)
if(result)
playsound(src,"mechstep",40,1)
+ handle_equipment_movement()
return result
@@ -439,6 +447,7 @@
var/result = step_rand(src)
if(result)
playsound(src,"mechstep",40,1)
+ handle_equipment_movement()
return result
/obj/mecha/Bump(var/atom/obstacle)
@@ -1877,81 +1886,82 @@
/datum/global_iterator/mecha_tank_give_air
delay = 15
- process(var/obj/mecha/mecha)
- if(mecha.internal_tank)
- var/datum/gas_mixture/tank_air = mecha.internal_tank.return_air()
- var/datum/gas_mixture/cabin_air = mecha.cabin_air
+/datum/global_iterator/mecha_tank_give_air/process(var/obj/mecha/mecha)
+ if(mecha.internal_tank)
+ var/datum/gas_mixture/tank_air = mecha.internal_tank.return_air()
+ var/datum/gas_mixture/cabin_air = mecha.cabin_air
- var/release_pressure = mecha.internal_tank_valve
- var/cabin_pressure = cabin_air.return_pressure()
- var/pressure_delta = min(release_pressure - cabin_pressure, (tank_air.return_pressure() - cabin_pressure)/2)
- var/transfer_moles = 0
- if(pressure_delta > 0) //cabin pressure lower than release pressure
- if(tank_air.temperature > 0)
- transfer_moles = pressure_delta*cabin_air.volume/(cabin_air.temperature * R_IDEAL_GAS_EQUATION)
- var/datum/gas_mixture/removed = tank_air.remove(transfer_moles)
- cabin_air.merge(removed)
- else if(pressure_delta < 0) //cabin pressure higher than release pressure
- var/datum/gas_mixture/t_air = mecha.get_turf_air()
- pressure_delta = cabin_pressure - release_pressure
+ var/release_pressure = mecha.internal_tank_valve
+ var/cabin_pressure = cabin_air.return_pressure()
+ var/pressure_delta = min(release_pressure - cabin_pressure, (tank_air.return_pressure() - cabin_pressure)/2)
+ var/transfer_moles = 0
+ if(pressure_delta > 0) //cabin pressure lower than release pressure
+ if(tank_air.temperature > 0)
+ transfer_moles = pressure_delta*cabin_air.volume/(cabin_air.temperature * R_IDEAL_GAS_EQUATION)
+ var/datum/gas_mixture/removed = tank_air.remove(transfer_moles)
+ cabin_air.merge(removed)
+ else if(pressure_delta < 0) //cabin pressure higher than release pressure
+ var/datum/gas_mixture/t_air = mecha.get_turf_air()
+ pressure_delta = cabin_pressure - release_pressure
+ if(t_air)
+ pressure_delta = min(cabin_pressure - t_air.return_pressure(), pressure_delta)
+ if(pressure_delta > 0) //if location pressure is lower than cabin pressure
+ transfer_moles = pressure_delta*cabin_air.volume/(cabin_air.temperature * R_IDEAL_GAS_EQUATION)
+ var/datum/gas_mixture/removed = cabin_air.remove(transfer_moles)
if(t_air)
- pressure_delta = min(cabin_pressure - t_air.return_pressure(), pressure_delta)
- if(pressure_delta > 0) //if location pressure is lower than cabin pressure
- transfer_moles = pressure_delta*cabin_air.volume/(cabin_air.temperature * R_IDEAL_GAS_EQUATION)
- var/datum/gas_mixture/removed = cabin_air.remove(transfer_moles)
- if(t_air)
- t_air.merge(removed)
- else //just delete the cabin gas, we're in space or some shit
- qdel(removed)
- else
- return stop()
- return
+ t_air.merge(removed)
+ else //just delete the cabin gas, we're in space or some shit
+ qdel(removed)
+ else
+ return stop()
+ return
/datum/global_iterator/mecha_intertial_movement //inertial movement in space
delay = 7
- process(var/obj/mecha/mecha as obj,direction)
- if(direction)
- if(!step(mecha, direction)||mecha.check_for_support())
- src.stop()
- else
+/datum/global_iterator/mecha_intertial_movement/process(var/obj/mecha/mecha as obj,direction)
+ if(direction)
+ if(!step(mecha, direction)||mecha.check_for_support())
src.stop()
- return
+ mecha.handle_equipment_movement()
+ else
+ src.stop()
+ return
/datum/global_iterator/mecha_internal_damage // processing internal damage
- process(var/obj/mecha/mecha)
- if(!mecha.hasInternalDamage())
- return stop()
- if(mecha.hasInternalDamage(MECHA_INT_FIRE))
- if(!mecha.hasInternalDamage(MECHA_INT_TEMP_CONTROL) && prob(5))
- mecha.clearInternalDamage(MECHA_INT_FIRE)
- if(mecha.internal_tank)
- if(mecha.internal_tank.return_pressure()>mecha.internal_tank.maximum_pressure && !(mecha.hasInternalDamage(MECHA_INT_TANK_BREACH)))
- mecha.setInternalDamage(MECHA_INT_TANK_BREACH)
- var/datum/gas_mixture/int_tank_air = mecha.internal_tank.return_air()
- if(int_tank_air && int_tank_air.volume>0) //heat the air_contents
- int_tank_air.temperature = min(6000+T0C, int_tank_air.temperature+rand(10,15))
- if(mecha.cabin_air && mecha.cabin_air.volume>0)
- mecha.cabin_air.temperature = min(6000+T0C, mecha.cabin_air.temperature+rand(10,15))
- if(mecha.cabin_air.temperature>mecha.max_temperature/2)
- mecha.take_damage(4/round(mecha.max_temperature/mecha.cabin_air.temperature,0.1),"fire")
- if(mecha.hasInternalDamage(MECHA_INT_TEMP_CONTROL)) //stop the mecha_preserve_temp loop datum
- mecha.pr_int_temp_processor.stop()
- if(mecha.hasInternalDamage(MECHA_INT_TANK_BREACH)) //remove some air from internal tank
- if(mecha.internal_tank)
- var/datum/gas_mixture/int_tank_air = mecha.internal_tank.return_air()
- var/datum/gas_mixture/leaked_gas = int_tank_air.remove_ratio(0.10)
- if(mecha.loc && hascall(mecha.loc,"assume_air"))
- mecha.loc.assume_air(leaked_gas)
- else
- qdel(leaked_gas)
- if(mecha.hasInternalDamage(MECHA_INT_SHORT_CIRCUIT))
- if(mecha.get_charge())
- mecha.spark_system.start()
- mecha.cell.charge -= min(20,mecha.cell.charge)
- mecha.cell.maxcharge -= min(20,mecha.cell.maxcharge)
- return
+/datum/global_iterator/mecha_internal_damage/process(var/obj/mecha/mecha)
+ if(!mecha.hasInternalDamage())
+ return stop()
+ if(mecha.hasInternalDamage(MECHA_INT_FIRE))
+ if(!mecha.hasInternalDamage(MECHA_INT_TEMP_CONTROL) && prob(5))
+ mecha.clearInternalDamage(MECHA_INT_FIRE)
+ if(mecha.internal_tank)
+ if(mecha.internal_tank.return_pressure()>mecha.internal_tank.maximum_pressure && !(mecha.hasInternalDamage(MECHA_INT_TANK_BREACH)))
+ mecha.setInternalDamage(MECHA_INT_TANK_BREACH)
+ var/datum/gas_mixture/int_tank_air = mecha.internal_tank.return_air()
+ if(int_tank_air && int_tank_air.volume>0) //heat the air_contents
+ int_tank_air.temperature = min(6000+T0C, int_tank_air.temperature+rand(10,15))
+ if(mecha.cabin_air && mecha.cabin_air.volume>0)
+ mecha.cabin_air.temperature = min(6000+T0C, mecha.cabin_air.temperature+rand(10,15))
+ if(mecha.cabin_air.temperature>mecha.max_temperature/2)
+ mecha.take_damage(4/round(mecha.max_temperature/mecha.cabin_air.temperature,0.1),"fire")
+ if(mecha.hasInternalDamage(MECHA_INT_TEMP_CONTROL)) //stop the mecha_preserve_temp loop datum
+ mecha.pr_int_temp_processor.stop()
+ if(mecha.hasInternalDamage(MECHA_INT_TANK_BREACH)) //remove some air from internal tank
+ if(mecha.internal_tank)
+ var/datum/gas_mixture/int_tank_air = mecha.internal_tank.return_air()
+ var/datum/gas_mixture/leaked_gas = int_tank_air.remove_ratio(0.10)
+ if(mecha.loc && hascall(mecha.loc,"assume_air"))
+ mecha.loc.assume_air(leaked_gas)
+ else
+ qdel(leaked_gas)
+ if(mecha.hasInternalDamage(MECHA_INT_SHORT_CIRCUIT))
+ if(mecha.get_charge())
+ mecha.spark_system.start()
+ mecha.cell.charge -= min(20,mecha.cell.charge)
+ mecha.cell.maxcharge -= min(20,mecha.cell.maxcharge)
+ return
/////////////
diff --git a/code/game/objects/items/weapons/grenades/concussion.dm b/code/game/objects/items/weapons/grenades/concussion.dm
new file mode 100644
index 0000000000..073b5ed9d1
--- /dev/null
+++ b/code/game/objects/items/weapons/grenades/concussion.dm
@@ -0,0 +1,85 @@
+//Concussion, or 'dizzyness' grenades.
+
+/obj/item/weapon/grenade/concussion
+ name = "concussion grenade"
+ desc = "A polymer concussion grenade, optimized for disorienting personnel without causing large amounts of injury."
+ icon_state = "concussion"
+ item_state = "grenade"
+
+ var/blast_radius = 5
+
+/obj/item/weapon/grenade/concussion/detonate()
+ ..()
+ concussion_blast(get_turf(src), blast_radius)
+ qdel(src)
+ return
+
+/obj/proc/concussion_blast(atom/target, var/radius = 5)
+ var/turf/T = get_turf(target)
+ if(is_below_sound_pressure(T))
+ visible_message("Whump.")
+ return
+ playsound(src.loc, 'sound/effects/bang.ogg', 75, 1, -3)
+ if(istype(T))
+ for(var/mob/living/L in orange(T, radius))
+ if(ishuman(L))
+ var/mob/living/carbon/human/H = L
+ to_chat(H, "WHUMP.")
+
+ var/ear_safety = 0
+
+ H.get_ear_protection()
+
+ var/bang_effectiveness = H.species.sound_mod
+
+ if((get_dist(H, T) <= round(radius * 0.3 * bang_effectiveness) || src.loc == H.loc || src.loc == H))
+ if(ear_safety > 0)
+ H.Confuse(2)
+ else
+ H.Confuse(8)
+ H.Weaken(1)
+ if ((prob(14) || (H == src.loc && prob(70))))
+ H.ear_damage += rand(1, 10)
+ else
+ H.ear_damage += rand(0, 5)
+ H.ear_deaf = max(H.ear_deaf,15)
+ if(H.client)
+ if(prob(50))
+ H.client.spinleft()
+ else
+ H.client.spinright()
+
+ else if(get_dist(H, T) <= round(radius * 0.5 * bang_effectiveness))
+ if(!ear_safety)
+ H.Confuse(6)
+ H.ear_damage += rand(0, 3)
+ H.ear_deaf = max(H.ear_deaf,10)
+
+ if(H.client)
+ if(prob(50))
+ H.client.spinleft()
+ else
+ H.client.spinright()
+
+ else if(!ear_safety && get_dist(H, T) <= (radius * bang_effectiveness))
+ H.Confuse(4)
+ H.ear_damage += rand(0, 1)
+ H.ear_deaf = max(H.ear_deaf,5)
+
+ if(H.ear_damage >= 15)
+ to_chat(H, "Your ears start to ring badly!")
+
+ if(prob(H.ear_damage - 5))
+ to_chat(H, "You can't hear anything!")
+ H.sdisabilities |= DEAF
+ else if(H.ear_damage >= 5)
+ to_chat(H, "Your ears start to ring!")
+ if(istype(L, /mob/living/silicon/robot))
+ var/mob/living/silicon/robot/R = L
+ if(L.client)
+ if(prob(50))
+ L.client.spinleft()
+ else
+ L.client.spinright()
+ to_chat(R, "Gyroscopic failure.")
+ return
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/grenades/explosive.dm b/code/game/objects/items/weapons/grenades/explosive.dm
index a45348e3b9..f38fba5720 100644
--- a/code/game/objects/items/weapons/grenades/explosive.dm
+++ b/code/game/objects/items/weapons/grenades/explosive.dm
@@ -31,6 +31,10 @@
damage = 15
armor_penetration = 20
+/obj/item/projectile/bullet/pellet/fragment/weak
+ damage = 4
+ armor_penetration = 40
+
/obj/item/weapon/grenade/explosive
name = "fragmentation grenade"
desc = "A fragmentation grenade, optimized for harming personnel without causing massive structural damage."
@@ -98,3 +102,12 @@
num_fragments = 200 //total number of fragments produced by the grenade
//The radius of the circle used to launch projectiles. Lower values mean less projectiles are used but if set too low gaps may appear in the spread pattern
+
+/obj/item/weapon/grenade/explosive/mini
+ name = "mini fragmentation grenade"
+ desc = "A miniaturized fragmentation grenade, this one poses relatively little threat on its own."
+ icon_state = "minifrag"
+ fragment_types = list(/obj/item/projectile/bullet/pellet/fragment)
+ num_fragments = 20
+ spread_range = 3
+ explosion_size = 1
diff --git a/code/game/objects/structures/loot_piles.dm b/code/game/objects/structures/loot_piles.dm
index 60807e253d..f8d9977823 100644
--- a/code/game/objects/structures/loot_piles.dm
+++ b/code/game/objects/structures/loot_piles.dm
@@ -744,7 +744,7 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
uncommon_loot = list(
/obj/item/mecha_parts/mecha_equipment/shocker,
- /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang,
+ /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade,
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser,
/obj/item/mecha_parts/mecha_equipment/weapon/energy/taser,
/obj/item/device/kit/paint/gygax,
@@ -784,7 +784,7 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
uncommon_loot = list(
/obj/item/mecha_parts/mecha_equipment/shocker,
- /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang,
+ /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade,
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser,
/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster,
/obj/item/device/kit/paint/durand,
diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm
index 843edf3f7f..5c441f1e28 100644
--- a/code/modules/mining/mine_turfs.dm
+++ b/code/modules/mining/mine_turfs.dm
@@ -208,7 +208,7 @@ var/list/mining_overlay_cache = list()
/turf/simulated/mineral/bullet_act(var/obj/item/projectile/Proj)
// Emitter blasts
- if(istype(Proj, /obj/item/projectile/beam/emitter))
+ if(istype(Proj, /obj/item/projectile/beam/emitter) || istype(Proj, /obj/item/projectile/beam/heavylaser/fakeemitter))
emitter_blasts_taken++
if(emitter_blasts_taken > 2) // 3 blasts per tile
mined_ore = 1
diff --git a/code/modules/projectiles/projectile/arc.dm b/code/modules/projectiles/projectile/arc.dm
index 6e434b1e99..1cd86cc5cf 100644
--- a/code/modules/projectiles/projectile/arc.dm
+++ b/code/modules/projectiles/projectile/arc.dm
@@ -110,6 +110,11 @@
/obj/item/projectile/arc/fragmentation/on_impact(turf/T)
fragmentate(T, fragment_amount, spread_range, fragment_types)
+/obj/item/projectile/arc/fragmentation/mortar
+ icon_state = "mortar"
+ fragment_amount = 10
+ spread_range = 3
+
// EMP arc shot
/obj/item/projectile/arc/emp_blast
name = "emp blast"
diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm
index 0cd8e69013..ee2ccc437c 100644
--- a/code/modules/projectiles/projectile/beams.dm
+++ b/code/modules/projectiles/projectile/beams.dm
@@ -58,6 +58,16 @@
tracer_type = /obj/effect/projectile/laser_heavy/tracer
impact_type = /obj/effect/projectile/laser_heavy/impact
+/obj/item/projectile/beam/heavylaser/fakeemitter
+ name = "emitter beam"
+ icon_state = "emitter"
+ fire_sound = 'sound/weapons/emitter.ogg'
+ light_color = "#00CC33"
+
+ muzzle_type = /obj/effect/projectile/emitter/muzzle
+ tracer_type = /obj/effect/projectile/emitter/tracer
+ impact_type = /obj/effect/projectile/emitter/impact
+
/obj/item/projectile/beam/heavylaser/cannon
damage = 80
armor_penetration = 50
diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm
index 36a93a89b0..1e1d8b5413 100644
--- a/code/modules/projectiles/projectile/bullets.dm
+++ b/code/modules/projectiles/projectile/bullets.dm
@@ -189,6 +189,11 @@
range_step = 1
spread_step = 10
+/obj/item/projectile/bullet/pellet/shotgun/flak
+ damage = 2 //The main weapon using these fires four at a time, usually with different destinations. Usually.
+ range_step = 2
+ spread_step = 30
+ armor_penetration = 10
//EMP shotgun 'slug', it's basically a beanbag that pops a tiny emp when it hits. //Not currently used
/obj/item/projectile/bullet/shotgun/ion
diff --git a/code/modules/research/mechfab_designs.dm b/code/modules/research/mechfab_designs.dm
index 8464c3efc3..17ae15f7be 100644
--- a/code/modules/research/mechfab_designs.dm
+++ b/code/modules/research/mechfab_designs.dm
@@ -291,6 +291,11 @@
id = "mech_taser"
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/taser
+/datum/design/item/mecha/rigged_taser
+ name = "Jury-Rigged Taser"
+ id = "mech_taser-r"
+ build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/taser/rigged
+
/datum/design/item/mecha/shocker
name = "Exosuit Electrifier"
desc = "A device to electrify the external portions of a mecha in order to increase its defensive capabilities."
@@ -304,6 +309,11 @@
id = "mech_lmg"
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg
+/datum/design/item/mecha/rigged_lmg
+ name = "Jury-Rigged Machinegun"
+ id = "mech_lmg-r"
+ build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg/rigged
+
/datum/design/item/mecha/weapon
req_tech = list(TECH_COMBAT = 3)
materials = list(DEFAULT_WALL_MATERIAL = 8000, "glass" = 2000)
@@ -316,6 +326,13 @@
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot
materials = list(DEFAULT_WALL_MATERIAL = 8000, "glass" = 3000, "plastic" = 2000, "silver" = 2500)
+/datum/design/item/mecha/weapon/rigged_scattershot
+ name = "Jury-Rigged Shrapnel Cannon"
+ id = "mech_scattershot-r"
+ req_tech = list(TECH_COMBAT = 4)
+ build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot/rigged
+ materials = list(DEFAULT_WALL_MATERIAL = 7000, "glass" = 2000, "plastic" = 2000, "silver" = 2000)
+
/datum/design/item/mecha/weapon/laser
name = "CH-PS \"Immolator\" Laser"
id = "mech_laser"
@@ -337,6 +354,34 @@
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy
materials = list(DEFAULT_WALL_MATERIAL = 10000, "glass" = 3000, "diamond" = 2000, "osmium" = 5000, "plastic" = 2000)
+/datum/design/item/mecha/weapon/rigged_laser_heavy
+ name = "Jury-Rigged Emitter Cannon"
+ id = "mech_laser_heavy-r"
+ req_tech = list(TECH_COMBAT = 4, TECH_MAGNET = 4, TECH_PHORON = 3, TECH_ILLEGAL = 1)
+ build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/rigged
+ materials = list(DEFAULT_WALL_MATERIAL = 8000, "glass" = 4000, "diamond" = 1500, "osmium" = 4000, "plastic" = 2000)
+
+/datum/design/item/mecha/weapon/laser_xray
+ name = "CH-XS \"Penetrator\" Laser"
+ id = "mech_laser_xray"
+ req_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 3, TECH_PHORON = 3, TECH_POWER = 4)
+ build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/xray
+ materials = list(DEFAULT_WALL_MATERIAL = 9000, "glass" = 3000, "phoron" = 1000, "silver" = 1500, "gold" = 2500, "plastic" = 2000)
+
+/datum/design/item/mecha/weapon/rigged_laser_xray
+ name = "Jury-Rigged Xray Rifle"
+ id = "mech_laser_xray-r"
+ req_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 3, TECH_PHORON = 3, TECH_POWER = 4)
+ build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/xray/rigged
+ materials = list(DEFAULT_WALL_MATERIAL = 8500, "glass" = 2500, "phoron" = 1000, "silver" = 1250, "gold" = 2000, "plastic" = 2000)
+
+/datum/design/item/mecha/weapon/phase
+ name = "NT-PE \"Scorpio\" Phase-Emitter"
+ id = "mech_phase"
+ req_tech = list(TECH_MATERIAL = 1, TECH_COMBAT = 2, TECH_MAGNET = 2)
+ build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/phase
+ materials = list(DEFAULT_WALL_MATERIAL = 6000, "glass" = 3000, "plastic" = 3000)
+
/datum/design/item/mecha/weapon/ion
name = "MK-IV Ion Heavy Cannon"
id = "mech_ion"
@@ -344,20 +389,48 @@
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/ion
materials = list(DEFAULT_WALL_MATERIAL = 15000, "uranium" = 2000, "silver" = 2000, "osmium" = 4500, "plastic" = 2000)
+/datum/design/item/mecha/weapon/rigged_ion
+ name = "Jury-Rigged Ion Cannon"
+ id = "mech_ion-r"
+ req_tech = list(TECH_COMBAT = 4, TECH_MAGNET = 4)
+ build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/ion/rigged
+ materials = list(DEFAULT_WALL_MATERIAL = 13000, "uranium" = 1000, "silver" = 1000, "osmium" = 3000, "plastic" = 2000)
+
/datum/design/item/mecha/weapon/grenade_launcher
name = "SGL-6 Grenade Launcher"
id = "mech_grenade_launcher"
req_tech = list(TECH_COMBAT = 3)
- build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang
+ build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade
materials = list(DEFAULT_WALL_MATERIAL = 7000, "gold" = 2000, "plastic" = 3000)
+/datum/design/item/mecha/weapon/rigged_grenade_launcher
+ name = "Jury-Rigged Pneumatic Flashlauncher"
+ id = "mech_grenade_launcher-rig"
+ req_tech = list(TECH_COMBAT = 3)
+ build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/rigged
+ materials = list(DEFAULT_WALL_MATERIAL = 5000, "gold" = 2000, "plastic" = 2000)
+
/datum/design/item/mecha/weapon/clusterbang_launcher
name = "SOP-6 Grenade Launcher"
desc = "A weapon that violates the Geneva Convention at 6 rounds per minute."
id = "clusterbang_launcher"
req_tech = list(TECH_COMBAT= 5, TECH_MATERIAL = 5, TECH_ILLEGAL = 3)
materials = list(DEFAULT_WALL_MATERIAL = 15000, "gold" = 4500, "uranium" = 4500)
- build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang/clusterbang/limited
+ build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/clusterbang/limited
+
+/datum/design/item/mecha/weapon/conc_grenade_launcher
+ name = "SGL-9 Grenade Launcher"
+ id = "mech_grenade_launcher_conc"
+ req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 4, TECH_ILLEGAL = 1)
+ build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/concussion
+ materials = list(DEFAULT_WALL_MATERIAL = 9000, "gold" = 1000, "osmium" = 1000, "plastic" = 3000)
+
+/datum/design/item/mecha/weapon/frag_grenade_launcher
+ name = "HEP-MI 6 Grenade Launcher"
+ id = "mech_grenade_launcher_frag"
+ req_tech = list(TECH_COMBAT = 4, TECH_ENGINEERING = 2, TECH_MATERIAL = 3, TECH_ILLEGAL = 2)
+ build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/frag/mini
+ materials = list(DEFAULT_WALL_MATERIAL = 10000, "gold" = 2500, "uranium" = 3000, "osmium" = 3000, "plastic" = 3000)
/datum/design/item/mecha/weapon/flamer
name = "CR-3 Mark 8 Flamethrower"
@@ -422,6 +495,14 @@
materials = list(DEFAULT_WALL_MATERIAL = 7500, "gold" = 750, "silver" = 1500, "glass" = 3750)
build_path = /obj/item/mecha_parts/mecha_equipment/repair_droid
+/datum/design/item/mecha/shield_drone
+ name = "Shield Drone"
+ desc = "Manual shield drone. Deploys a large, familiar, and rectangular shield in one direction at a time."
+ id = "mech_shield_droid"
+ req_tech = list(TECH_PHORON = 3, TECH_MAGNET = 6, TECH_ILLEGAL = 4)
+ materials = list(DEFAULT_WALL_MATERIAL = 8000, "gold" = 2000, "silver" = 3000, "phoron" = 5000, "glass" = 3750)
+ build_path = /obj/item/mecha_parts/mecha_equipment/combat_shield
+
/datum/design/item/mecha/jetpack
name = "Ion Jetpack"
desc = "Using directed ion bursts and cunning solar wind reflection technique, this device enables controlled space flight."
diff --git a/code/modules/shieldgen/directional_shield.dm b/code/modules/shieldgen/directional_shield.dm
index 1892a3f3ad..4f49aa8890 100644
--- a/code/modules/shieldgen/directional_shield.dm
+++ b/code/modules/shieldgen/directional_shield.dm
@@ -344,4 +344,49 @@
create_shield(temp_T, i == length_to_build ? turn(dir, -45) : dir)
// Finished.
update_shield_colors()
- return TRUE
\ No newline at end of file
+ return TRUE
+
+/obj/item/shield_projector/line/exosuit //Variant for Exosuit design.
+ name = "linear exosuit shield projector"
+ offset_from_center = 1 //Snug against the exosuit.
+ max_shield_health = 200
+
+ var/obj/mecha/my_mecha = null
+ var/obj/item/mecha_parts/mecha_equipment/combat_shield/my_tool = null
+
+/obj/item/shield_projector/line/exosuit/process()
+ ..()
+ if((my_tool && loc != my_tool) && (my_mecha && loc != my_mecha))
+ forceMove(my_tool)
+ if(active)
+ my_tool.set_ready_state(0)
+ if(my_mecha.has_charge(my_tool.energy_drain * 100)) //Stops at around 2000 charge.
+ my_mecha.use_power(my_tool.energy_drain)
+ else
+ destroy_shields()
+ my_tool.set_ready_state(1)
+ my_tool.log_message("Power lost.")
+ else
+ my_tool.set_ready_state(1)
+
+/obj/item/shield_projector/line/exosuit/attack_self(var/mob/living/user)
+ if(active)
+ if(always_on)
+ to_chat(user, "You can't seem to deactivate \the [src].")
+ return
+
+ destroy_shields()
+ else
+ if(istype(user.loc, /obj/mecha))
+ set_dir(user.loc.dir)
+ else
+ set_dir(user.dir)
+ create_shields()
+ visible_message("\The [user] [!active ? "de":""]activates \the [src].")
+
+/obj/item/shield_projector/line/exosuit/adjust_health(amount)
+ ..()
+ my_mecha.use_power(my_tool.energy_drain)
+ if(!active && shield_health < shield_regen_amount)
+ my_tool.log_message("Shield overloaded.")
+ my_mecha.use_power(my_tool.energy_drain * 4)
diff --git a/html/changelogs/Mechoid - MechaWeapons.yml b/html/changelogs/Mechoid - MechaWeapons.yml
new file mode 100644
index 0000000000..15d0abc8f7
--- /dev/null
+++ b/html/changelogs/Mechoid - MechaWeapons.yml
@@ -0,0 +1,7 @@
+
+author: Mechoid
+
+delete-after: True
+
+changes:
+ - rscadd: "A large number of Mech weapon modules and their jury rigged versions."
diff --git a/icons/mecha/mecha_equipment.dmi b/icons/mecha/mecha_equipment.dmi
index 3215773403..2b96c7d492 100644
Binary files a/icons/mecha/mecha_equipment.dmi and b/icons/mecha/mecha_equipment.dmi differ
diff --git a/icons/obj/grenade.dmi b/icons/obj/grenade.dmi
index bcd64a33fe..e312da52b9 100644
Binary files a/icons/obj/grenade.dmi and b/icons/obj/grenade.dmi differ
diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi
index efc1184dd5..74d2c0a9f8 100644
Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ
diff --git a/polaris.dme b/polaris.dme
index bbe642cdd1..fc5e08e9ec 100644
--- a/polaris.dme
+++ b/polaris.dme
@@ -977,6 +977,7 @@
#include "code\game\objects\items\weapons\circuitboards\machinery\unary_atmos.dm"
#include "code\game\objects\items\weapons\grenades\anti_photon_grenade.dm"
#include "code\game\objects\items\weapons\grenades\chem_grenade.dm"
+#include "code\game\objects\items\weapons\grenades\concussion.dm"
#include "code\game\objects\items\weapons\grenades\emgrenade.dm"
#include "code\game\objects\items\weapons\grenades\explosive.dm"
#include "code\game\objects\items\weapons\grenades\flashbang.dm"