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"