From eeb8310aa250221fc84a5d8b94d5a45d33d992ce Mon Sep 17 00:00:00 2001 From: Atermonera Date: Sat, 21 Dec 2019 20:56:24 -0800 Subject: [PATCH] Fixes mech projectile armor thinking test projectiles are dangerous --- .../game/mecha/equipment/tools/armor_melee.dm | 49 + .../mecha/equipment/tools/armor_ranged.dm | 72 + .../game/mecha/equipment/tools/cable_layer.dm | 128 ++ code/game/mecha/equipment/tools/catapult.dm | 76 + code/game/mecha/equipment/tools/clamp.dm | 175 ++ code/game/mecha/equipment/tools/drill.dm | 142 ++ .../mecha/equipment/tools/energy_relay.dm | 115 ++ .../mecha/equipment/tools/extinguisher.dm | 69 + code/game/mecha/equipment/tools/generator.dm | 166 ++ code/game/mecha/equipment/tools/jetpack.dm | 94 + code/game/mecha/equipment/tools/orescanner.dm | 41 + code/game/mecha/equipment/tools/passenger.dm | 151 ++ code/game/mecha/equipment/tools/rcd.dm | 45 + .../mecha/equipment/tools/repair_droid.dm | 94 + code/game/mecha/equipment/tools/shield.dm | 82 + code/game/mecha/equipment/tools/sleeper.dm | 247 +++ code/game/mecha/equipment/tools/speedboost.dm | 21 + .../{medical_tools.dm => syringe_gun.dm} | 507 +++++ code/game/mecha/equipment/tools/teleporter.dm | 20 + code/game/mecha/equipment/tools/tools.dm | 1668 +---------------- code/game/mecha/equipment/tools/wormhole.dm | 50 + code/game/mecha/equipment/tools/wrench.dm | 41 + .../equipment/weapons/ballistic/automatic.dm | 22 + .../equipment/weapons/ballistic/ballistic.dm | 23 + .../equipment/weapons/ballistic/mortar.dm | 22 + .../equipment/weapons/ballistic/shotgun.dm | 25 + .../equipment/weapons/defense/shocker.dm | 33 + .../mecha/equipment/weapons/energy/energy.dm | 3 + .../mecha/equipment/weapons/energy/ion.dm | 20 + .../mecha/equipment/weapons/energy/laser.dm | 68 + .../mecha/equipment/weapons/energy/phased.dm | 13 + .../mecha/equipment/weapons/energy/pulse.dm | 21 + .../mecha/equipment/weapons/energy/stun.dm | 17 + .../equipment/weapons/explosive/grenade.dm | 70 + .../equipment/weapons/explosive/missile.dm | 80 + .../equipment/weapons/fire/flamethrower.dm | 27 + .../equipment/weapons/fire/incendiary.dm | 18 + code/game/mecha/equipment/weapons/honk.dm | 37 + code/game/mecha/equipment/weapons/weapons.dm | 517 +---- code/game/mecha/working/ripley.dm | 2 +- code/game/objects/structures/loot_piles.dm | 2 +- vorestation.dme | 40 + 42 files changed, 2928 insertions(+), 2185 deletions(-) create mode 100644 code/game/mecha/equipment/tools/armor_melee.dm create mode 100644 code/game/mecha/equipment/tools/armor_ranged.dm create mode 100644 code/game/mecha/equipment/tools/cable_layer.dm create mode 100644 code/game/mecha/equipment/tools/catapult.dm create mode 100644 code/game/mecha/equipment/tools/clamp.dm create mode 100644 code/game/mecha/equipment/tools/drill.dm create mode 100644 code/game/mecha/equipment/tools/energy_relay.dm create mode 100644 code/game/mecha/equipment/tools/extinguisher.dm create mode 100644 code/game/mecha/equipment/tools/generator.dm create mode 100644 code/game/mecha/equipment/tools/jetpack.dm create mode 100644 code/game/mecha/equipment/tools/orescanner.dm create mode 100644 code/game/mecha/equipment/tools/passenger.dm create mode 100644 code/game/mecha/equipment/tools/rcd.dm create mode 100644 code/game/mecha/equipment/tools/repair_droid.dm create mode 100644 code/game/mecha/equipment/tools/shield.dm create mode 100644 code/game/mecha/equipment/tools/sleeper.dm create mode 100644 code/game/mecha/equipment/tools/speedboost.dm rename code/game/mecha/equipment/tools/{medical_tools.dm => syringe_gun.dm} (60%) create mode 100644 code/game/mecha/equipment/tools/teleporter.dm create mode 100644 code/game/mecha/equipment/tools/wormhole.dm create mode 100644 code/game/mecha/equipment/tools/wrench.dm create mode 100644 code/game/mecha/equipment/weapons/ballistic/automatic.dm create mode 100644 code/game/mecha/equipment/weapons/ballistic/ballistic.dm create mode 100644 code/game/mecha/equipment/weapons/ballistic/mortar.dm create mode 100644 code/game/mecha/equipment/weapons/ballistic/shotgun.dm create mode 100644 code/game/mecha/equipment/weapons/defense/shocker.dm create mode 100644 code/game/mecha/equipment/weapons/energy/energy.dm create mode 100644 code/game/mecha/equipment/weapons/energy/ion.dm create mode 100644 code/game/mecha/equipment/weapons/energy/laser.dm create mode 100644 code/game/mecha/equipment/weapons/energy/phased.dm create mode 100644 code/game/mecha/equipment/weapons/energy/pulse.dm create mode 100644 code/game/mecha/equipment/weapons/energy/stun.dm create mode 100644 code/game/mecha/equipment/weapons/explosive/grenade.dm create mode 100644 code/game/mecha/equipment/weapons/explosive/missile.dm create mode 100644 code/game/mecha/equipment/weapons/fire/flamethrower.dm create mode 100644 code/game/mecha/equipment/weapons/fire/incendiary.dm create mode 100644 code/game/mecha/equipment/weapons/honk.dm diff --git a/code/game/mecha/equipment/tools/armor_melee.dm b/code/game/mecha/equipment/tools/armor_melee.dm new file mode 100644 index 0000000000..83c8228131 --- /dev/null +++ b/code/game/mecha/equipment/tools/armor_melee.dm @@ -0,0 +1,49 @@ +/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster //what is that noise? A BAWWW from TK mutants. + name = "\improper CCW armor booster" + desc = "Close-combat armor booster. Boosts exosuit armor against armed melee attacks. Requires energy to operate." + icon_state = "mecha_abooster_ccw" + origin_tech = list(TECH_MATERIAL = 3) + equip_cooldown = 10 + energy_drain = 50 + range = 0 + var/deflect_coeff = 1.15 + var/damage_coeff = 0.8 + + equip_type = EQUIP_HULL + +/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/can_attach(obj/mecha/M as obj) + if(..()) + if(!M.proc_res["dynattackby"]) + return 1 + return 0 + +/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/attach(obj/mecha/M as obj) + ..() + chassis.proc_res["dynattackby"] = src + return + +/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/detach() + chassis.proc_res["dynattackby"] = null + ..() + return + +/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/get_equip_info() + if(!chassis) return + return "* [src.name]" + +/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/proc/dynattackby(obj/item/weapon/W as obj, mob/user as mob) + if(!action_checks(user)) + return chassis.dynattackby(W,user) + chassis.log_message("Attacked by [W]. Attacker - [user]") + if(prob(chassis.deflect_chance*deflect_coeff)) + user << "\The [W] bounces off [chassis] armor." + chassis.log_append_to_last("Armor saved.") + else + chassis.occupant_message("\The [user] hits [chassis] with [W].") + user.visible_message("\The [user] hits [chassis] with [W].", "You hit [src] with [W].") + chassis.take_damage(round(W.force*damage_coeff),W.damtype) + chassis.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) + set_ready_state(0) + chassis.use_power(energy_drain) + do_after_cooldown() + return \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/armor_ranged.dm b/code/game/mecha/equipment/tools/armor_ranged.dm new file mode 100644 index 0000000000..2e3523275f --- /dev/null +++ b/code/game/mecha/equipment/tools/armor_ranged.dm @@ -0,0 +1,72 @@ +/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster + name = "\improper RW armor booster" + desc = "Ranged-weaponry armor booster. Boosts exosuit armor against ranged attacks. Completely blocks taser shots, but requires energy to operate." + icon_state = "mecha_abooster_proj" + origin_tech = list(TECH_MATERIAL = 4) + equip_cooldown = 10 + energy_drain = 50 + range = 0 + var/deflect_coeff = 1.15 + var/damage_coeff = 0.8 + + equip_type = EQUIP_HULL + +/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/can_attach(obj/mecha/M as obj) + if(..()) + if(!M.proc_res["dynbulletdamage"] && !M.proc_res["dynhitby"]) + return 1 + return 0 + +/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/attach(obj/mecha/M as obj) + ..() + chassis.proc_res["dynbulletdamage"] = src + chassis.proc_res["dynhitby"] = src + return + +/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/detach() + chassis.proc_res["dynbulletdamage"] = null + chassis.proc_res["dynhitby"] = null + ..() + return + +/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/get_equip_info() + if(!chassis) return + return "* [src.name]" + +/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/proc/dynbulletdamage(var/obj/item/projectile/Proj) + if(istype(Proj, /obj/item/projectile/test)) + return // Don't care about test projectiles, just what comes after them + if(!action_checks(src)) + return chassis.dynbulletdamage(Proj) + if(prob(chassis.deflect_chance*deflect_coeff)) + chassis.occupant_message("The armor deflects incoming projectile.") + chassis.visible_message("The [chassis.name] armor deflects the projectile") + chassis.log_append_to_last("Armor saved.") + else + chassis.take_damage(round(Proj.damage*src.damage_coeff),Proj.check_armour) + chassis.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) + Proj.on_hit(chassis) + set_ready_state(0) + chassis.use_power(energy_drain) + do_after_cooldown() + return + +/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/proc/dynhitby(atom/movable/A) + if(!action_checks(A)) + return chassis.dynhitby(A) + if(prob(chassis.deflect_chance*deflect_coeff) || istype(A, /mob/living) || istype(A, /obj/item/mecha_parts/mecha_tracking)) + chassis.occupant_message("The [A] bounces off the armor.") + chassis.visible_message("The [A] bounces off the [chassis] armor") + chassis.log_append_to_last("Armor saved.") + if(istype(A, /mob/living)) + var/mob/living/M = A + M.take_organ_damage(10) + else if(istype(A, /obj)) + var/obj/O = A + if(O.throwforce) + chassis.take_damage(round(O.throwforce*damage_coeff)) + chassis.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) + set_ready_state(0) + chassis.use_power(energy_drain) + do_after_cooldown() + return \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/cable_layer.dm b/code/game/mecha/equipment/tools/cable_layer.dm new file mode 100644 index 0000000000..5fbb7b70db --- /dev/null +++ b/code/game/mecha/equipment/tools/cable_layer.dm @@ -0,0 +1,128 @@ +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer + name = "Cable Layer" + icon_state = "mecha_wire" + var/turf/old_turf + var/obj/structure/cable/last_piece + var/obj/item/stack/cable_coil/cable + var/max_cable = 1000 + required_type = list(/obj/mecha/working) + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/New() + cable = new(src) + cable.amount = 0 + ..() + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/MoveAction() + layCable() + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/action(var/obj/item/stack/cable_coil/target) + if(!action_checks(target)) + return + var/result = load_cable(target) + var/message + if(isnull(result)) + message = "Unable to load [target] - no cable found." + else if(!result) + message = "Reel is full." + else + message = "[result] meters of cable successfully loaded." + send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) + occupant_message(message) + return + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/Topic(href,href_list) + ..() + if(href_list["toggle"]) + set_ready_state(!equip_ready) + occupant_message("[src] [equip_ready?"dea":"a"]ctivated.") + log_message("[equip_ready?"Dea":"A"]ctivated.") + return + if(href_list["cut"]) + if(cable && cable.amount) + var/m = round(input(chassis.occupant,"Please specify the length of cable to cut","Cut cable",min(cable.amount,30)) as num, 1) + m = min(m, cable.amount) + if(m) + use_cable(m) + var/obj/item/stack/cable_coil/CC = new (get_turf(chassis)) + CC.amount = m + else + occupant_message("There's no more cable on the reel.") + return + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/get_equip_info() + var/output = ..() + if(output) + return "[output] \[Cable: [cable ? cable.amount : 0] m\][(cable && cable.amount) ? "- [!equip_ready?"Dea":"A"]ctivate|Cut" : null]" + return + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/load_cable(var/obj/item/stack/cable_coil/CC) + if(istype(CC) && CC.amount) + var/cur_amount = cable? cable.amount : 0 + var/to_load = max(max_cable - cur_amount,0) + if(to_load) + to_load = min(CC.amount, to_load) + if(!cable) + cable = new(src) + cable.amount = 0 + cable.amount += to_load + CC.use(to_load) + return to_load + else + return 0 + return + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/use_cable(amount) + if(!cable || cable.amount<1) + set_ready_state(1) + occupant_message("Cable depleted, [src] deactivated.") + log_message("Cable depleted, [src] deactivated.") + return + if(cable.amount < amount) + occupant_message("No enough cable to finish the task.") + return + cable.use(amount) + update_equip_info() + return 1 + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/reset() + last_piece = null + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/dismantleFloor(var/turf/new_turf) + new_turf = get_turf(chassis) + if(istype(new_turf, /turf/simulated/floor)) + var/turf/simulated/floor/T = new_turf + if(!T.is_plating()) + T.make_plating(!(T.broken || T.burnt)) + return new_turf.is_plating() + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/layCable(var/turf/new_turf) + new_turf = get_turf(chassis) + if(equip_ready || !istype(new_turf, /turf/simulated/floor) || !dismantleFloor(new_turf)) + return reset() + var/fdirn = turn(chassis.dir,180) + for(var/obj/structure/cable/LC in new_turf) // check to make sure there's not a cable there already + if(LC.d1 == fdirn || LC.d2 == fdirn) + return reset() + if(!use_cable(1)) + return reset() + var/obj/structure/cable/NC = new(new_turf) + NC.cableColor("red") + NC.d1 = 0 + NC.d2 = fdirn + NC.update_icon() + + var/datum/powernet/PN + if(last_piece && last_piece.d2 != chassis.dir) + last_piece.d1 = min(last_piece.d2, chassis.dir) + last_piece.d2 = max(last_piece.d2, chassis.dir) + last_piece.update_icon() + PN = last_piece.powernet + + if(!PN) + PN = new() + PN.add_cable(NC) + NC.mergeConnectedNetworks(NC.d2) + + //NC.mergeConnectedNetworksOnTurf() + last_piece = NC + return 1 \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/catapult.dm b/code/game/mecha/equipment/tools/catapult.dm new file mode 100644 index 0000000000..7d9162823d --- /dev/null +++ b/code/game/mecha/equipment/tools/catapult.dm @@ -0,0 +1,76 @@ +/obj/item/mecha_parts/mecha_equipment/gravcatapult + name = "gravitational catapult" + desc = "An exosuit mounted gravitational catapult." + icon_state = "mecha_teleport" + origin_tech = list(TECH_BLUESPACE = 2, TECH_MAGNET = 3) + equip_cooldown = 10 + energy_drain = 100 + range = MELEE|RANGED + var/atom/movable/locked + var/mode = 1 //1 - gravsling 2 - gravpush + + var/last_fired = 0 //Concept stolen from guns. + var/fire_delay = 10 //Used to prevent spam-brute against humans. + + equip_type = EQUIP_UTILITY + +/obj/item/mecha_parts/mecha_equipment/gravcatapult/action(atom/movable/target) + + if(world.time >= last_fired + fire_delay) + last_fired = world.time + else + if (world.time % 3) + occupant_message("[src] is not ready to fire again!") + return 0 + + switch(mode) + if(1) + if(!action_checks(target) && !locked) return + if(!locked) + if(!istype(target) || target.anchored) + occupant_message("Unable to lock on [target]") + return + locked = target + occupant_message("Locked on [target]") + send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) + return + else if(target!=locked) + if(locked in view(chassis)) + locked.throw_at(target, 14, 1.5, chassis) + locked = null + send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) + set_ready_state(0) + chassis.use_power(energy_drain) + do_after_cooldown() + else + locked = null + occupant_message("Lock on [locked] disengaged.") + send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) + if(2) + if(!action_checks(target)) return + var/list/atoms = list() + if(isturf(target)) + atoms = range(target,3) + else + atoms = orange(target,3) + for(var/atom/movable/A in atoms) + if(A.anchored) continue + spawn(0) + var/iter = 5-get_dist(A,target) + for(var/i=0 to iter) + step_away(A,target) + sleep(2) + set_ready_state(0) + chassis.use_power(energy_drain) + do_after_cooldown() + return + +/obj/item/mecha_parts/mecha_equipment/gravcatapult/get_equip_info() + return "[..()] [mode==1?"([locked||"Nothing"])":null] \[S|P\]" + +/obj/item/mecha_parts/mecha_equipment/gravcatapult/Topic(href, href_list) + ..() + if(href_list["mode"]) + mode = text2num(href_list["mode"]) + send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) + return \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/clamp.dm b/code/game/mecha/equipment/tools/clamp.dm new file mode 100644 index 0000000000..a587d89568 --- /dev/null +++ b/code/game/mecha/equipment/tools/clamp.dm @@ -0,0 +1,175 @@ +/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp + name = "hydraulic clamp" + icon_state = "mecha_clamp" + equip_cooldown = 15 + energy_drain = 10 + var/dam_force = 20 + var/obj/mecha/working/ripley/cargo_holder + required_type = list(/obj/mecha/working) + ready_sound = 'sound/mecha/gasdisconnected.ogg' + +/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp/attach(obj/mecha/M as obj) + ..() + cargo_holder = M + + return + +/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp/action(atom/target) + if(!action_checks(target)) return + if(!cargo_holder) return + + //loading + if(istype(target,/obj)) + var/obj/O = target + if(O.has_buckled_mobs()) + return + if(locate(/mob/living) in O) + occupant_message("You can't load living things into the cargo compartment.") + return + if(O.anchored) + if(enable_special) + if(istype(O, /obj/machinery/door/firedoor)) // I love doors. + var/obj/machinery/door/firedoor/FD = O + if(FD.blocked) + FD.visible_message("\The [chassis] begins prying on \the [FD]!") + if(do_after(chassis.occupant,10 SECONDS,FD)) + playsound(FD.loc, 'sound/machines/airlock_creaking.ogg', 100, 1) + FD.blocked = 0 + FD.update_icon() + FD.open(1) + FD.visible_message("\The [chassis] tears \the [FD] open!") + else if(FD.density) + FD.visible_message("\The [chassis] begins forcing \the [FD] open!") + if(do_after(chassis.occupant, 5 SECONDS,FD)) + playsound(FD.loc, 'sound/machines/airlock_creaking.ogg', 100, 1) + FD.visible_message("\The [chassis] forces \the [FD] open!") + FD.open(1) + else + FD.visible_message("\The [chassis] forces \the [FD] closed!") + FD.close(1) + else if(istype(O, /obj/machinery/door/airlock)) // D o o r s. + var/obj/machinery/door/airlock/AD = O + if(AD.locked) + occupant_message("The airlock's bolts prevent it from being forced.") + else if(!AD.operating) + if(AD.welded) + AD.visible_message("\The [chassis] begins prying on \the [AD]!") + if(do_after(chassis.occupant, 15 SECONDS,AD) && chassis.Adjacent(AD)) + AD.welded = FALSE + AD.update_icon() + playsound(AD.loc, 'sound/machines/airlock_creaking.ogg', 100, 1) + AD.visible_message("\The [chassis] tears \the [AD] open!") + if(!AD.welded) + if(density) + spawn(0) + AD.open(1) + else + spawn(0) + AD.close(1) + return + else + occupant_message("[target] is firmly secured.") + return + if(cargo_holder.cargo.len >= cargo_holder.cargo_capacity) + occupant_message("Not enough room in cargo compartment.") + return + + occupant_message("You lift [target] and start to load it into cargo compartment.") + chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.") + set_ready_state(0) + chassis.use_power(energy_drain) + O.anchored = 1 + var/T = chassis.loc + if(do_after_cooldown(target)) + if(T == chassis.loc && src == chassis.selected) + cargo_holder.cargo += O + O.loc = chassis + O.anchored = 0 + occupant_message("[target] succesfully loaded.") + log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") + else + occupant_message("You must hold still while handling objects.") + O.anchored = initial(O.anchored) + + //attacking + else if(istype(target,/mob/living)) + var/mob/living/M = target + if(M.stat>1) return + if(chassis.occupant.a_intent == I_HURT || istype(chassis.occupant,/mob/living/carbon/brain)) //No tactile feedback for brains + M.take_overall_damage(dam_force) + M.adjustOxyLoss(round(dam_force/2)) + M.updatehealth() + occupant_message("You squeeze [target] with [src.name]. Something cracks.") + playsound(src.loc, "fracture", 5, 1, -2) //CRACK + chassis.visible_message("[chassis] squeezes [target].") + else if(chassis.occupant.a_intent == I_DISARM && enable_special) + playsound(src.loc, 'sound/mecha/hydraulic.ogg', 10, 1, -2) + M.take_overall_damage(dam_force/2) + M.adjustOxyLoss(round(dam_force/3)) + M.updatehealth() + occupant_message("You slam [target] with [src.name]. Something cracks.") + playsound(src.loc, "fracture", 3, 1, -2) //CRACK 2 + chassis.visible_message("[chassis] slams [target].") + M.throw_at(get_step(M,get_dir(src, M)), 14, 1.5, chassis) + else + step_away(M,chassis) + occupant_message("You push [target] out of the way.") + chassis.visible_message("[chassis] pushes [target] out of the way.") + set_ready_state(0) + chassis.use_power(energy_drain) + do_after_cooldown() + return 1 + + +//This is pretty much just for the death-ripley so that it is harmless +/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp/safety + name = "\improper KILL CLAMP" + equip_cooldown = 15 + energy_drain = 0 + dam_force = 0 + +/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp/safety/action(atom/target) + if(!action_checks(target)) return + if(!cargo_holder) return + if(istype(target,/obj)) + var/obj/O = target + if(!O.anchored) + if(cargo_holder.cargo.len < cargo_holder.cargo_capacity) + chassis.occupant_message("You lift [target] and start to load it into cargo compartment.") + chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.") + set_ready_state(0) + chassis.use_power(energy_drain) + O.anchored = 1 + var/T = chassis.loc + if(do_after_cooldown(target)) + if(T == chassis.loc && src == chassis.selected) + cargo_holder.cargo += O + O.loc = chassis + O.anchored = 0 + chassis.occupant_message("[target] succesfully loaded.") + chassis.log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") + else + chassis.occupant_message("You must hold still while handling objects.") + O.anchored = initial(O.anchored) + else + chassis.occupant_message("Not enough room in cargo compartment.") + else + chassis.occupant_message("[target] is firmly secured.") + + else if(istype(target,/mob/living)) + var/mob/living/M = target + if(M.stat>1) return + if(chassis.occupant.a_intent == I_HURT) + chassis.occupant_message("You obliterate [target] with [src.name], leaving blood and guts everywhere.") + chassis.visible_message("[chassis] destroys [target] in an unholy fury.") + if(chassis.occupant.a_intent == I_DISARM) + chassis.occupant_message("You tear [target]'s limbs off with [src.name].") + chassis.visible_message("[chassis] rips [target]'s arms off.") + else + step_away(M,chassis) + chassis.occupant_message("You smash into [target], sending them flying.") + chassis.visible_message("[chassis] tosses [target] like a piece of paper.") + set_ready_state(0) + chassis.use_power(energy_drain) + do_after_cooldown() + return 1 \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/drill.dm b/code/game/mecha/equipment/tools/drill.dm new file mode 100644 index 0000000000..6f44c92d5f --- /dev/null +++ b/code/game/mecha/equipment/tools/drill.dm @@ -0,0 +1,142 @@ +/obj/item/mecha_parts/mecha_equipment/tool/drill + name = "drill" + desc = "This is the drill that'll pierce the heavens!" + icon_state = "mecha_drill" + equip_cooldown = 30 + energy_drain = 10 + force = 15 + required_type = list(/obj/mecha/working/ripley) + +/obj/item/mecha_parts/mecha_equipment/tool/drill/action(atom/target) + if(!action_checks(target)) return + if(isobj(target)) + var/obj/target_obj = target + if(!target_obj.vars.Find("unacidable") || target_obj.unacidable) return + set_ready_state(0) + chassis.use_power(energy_drain) + chassis.visible_message("[chassis] starts to drill [target]", "You hear the drill.") + occupant_message("You start to drill [target]") + var/T = chassis.loc + var/C = target.loc //why are these backwards? we may never know -Pete + if(do_after_cooldown(target)) + if(T == chassis.loc && src == chassis.selected) + if(istype(target, /turf/simulated/wall)) + var/turf/simulated/wall/W = target + if(W.reinf_material) + occupant_message("[target] is too durable to drill through.") + else + log_message("Drilled through [target]") + target.ex_act(2) + else if(istype(target, /turf/simulated/mineral)) + if(enable_special) + for(var/turf/simulated/mineral/M in range(chassis,1)) + if(get_dir(chassis,M)&chassis.dir) + M.GetDrilled() + else + var/turf/simulated/mineral/M1 = target + M1.GetDrilled() + log_message("Drilled through [target]") + if(locate(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp) in chassis.equipment) + var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo + if(ore_box) + for(var/obj/item/weapon/ore/ore in range(chassis,1)) + if(get_dir(chassis,ore)&chassis.dir) + ore.forceMove(ore_box) + else if(target.loc == C) + log_message("Drilled through [target]") + target.ex_act(2) + return 1 + +/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill + name = "diamond drill" + desc = "This is an upgraded version of the drill that'll pierce the heavens!" + icon_state = "mecha_diamond_drill" + origin_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3) + equip_cooldown = 10 + force = 15 + +/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill/action(atom/target) + if(!action_checks(target)) return + if(isobj(target)) + var/obj/target_obj = target + if(target_obj.unacidable) return + set_ready_state(0) + chassis.use_power(energy_drain) + chassis.visible_message("[chassis] starts to drill [target]", "You hear the drill.") + occupant_message("You start to drill [target]") + var/T = chassis.loc + var/C = target.loc //why are these backwards? we may never know -Pete + if(do_after_cooldown(target)) + if(T == chassis.loc && src == chassis.selected) + if(istype(target, /turf/simulated/wall)) + var/turf/simulated/wall/W = target + if(!W.reinf_material || do_after_cooldown(target))//To slow down how fast mechs can drill through the station + log_message("Drilled through [target]") + target.ex_act(3) + else if(istype(target, /turf/simulated/mineral)) + if(enable_special) + for(var/turf/simulated/mineral/M in range(chassis,1)) + if(get_dir(chassis,M)&chassis.dir) + M.GetDrilled() + else + var/turf/simulated/mineral/M1 = target + M1.GetDrilled() + log_message("Drilled through [target]") + if(locate(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp) in chassis.equipment) + var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo + if(ore_box) + for(var/obj/item/weapon/ore/ore in range(chassis,1)) + if(get_dir(chassis,ore)&chassis.dir) + ore.forceMove(ore_box) + else if(target.loc == C) + log_message("Drilled through [target]") + target.ex_act(2) + return 1 + +/obj/item/mecha_parts/mecha_equipment/tool/drill/bore + name = "depth bore" + desc = "This is the drill that'll pierce the depths!" + icon_state = "mecha_bore" + equip_cooldown = 5 SECONDS + energy_drain = 30 + force = 20 + required_type = list(/obj/mecha/working/ripley) + +/obj/item/mecha_parts/mecha_equipment/tool/drill/bore/action(atom/target) + if(!action_checks(target)) return + if(isobj(target)) + var/obj/target_obj = target + if(target_obj.unacidable) return + set_ready_state(0) + chassis.use_power(energy_drain) + chassis.visible_message("[chassis] starts to bore into \the [target]", "You hear the bore.") + occupant_message("You start to bore into \the [target]") + var/T = chassis.loc + var/C = target.loc + if(do_after_cooldown(target)) + if(T == chassis.loc && src == chassis.selected) + if(istype(target, /turf/simulated/wall)) + var/turf/simulated/wall/W = target + if(W.reinf_material) + occupant_message("[target] is too durable to bore through.") + else + log_message("Bored through [target]") + target.ex_act(2) + else if(istype(target, /turf/simulated/mineral)) + var/turf/simulated/mineral/M = target + if(enable_special && !M.density) + M.ex_act(2) + log_message("Bored into [target]") + else + M.GetDrilled() + log_message("Bored through [target]") + if(locate(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp) in chassis.equipment) + var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo + if(ore_box) + for(var/obj/item/weapon/ore/ore in range(chassis,1)) + if(get_dir(chassis,ore)&chassis.dir) + ore.forceMove(ore_box) + else if(target.loc == C) + log_message("Drilled through [target]") + target.ex_act(2) + return 1 \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/energy_relay.dm b/code/game/mecha/equipment/tools/energy_relay.dm new file mode 100644 index 0000000000..d6917a0de1 --- /dev/null +++ b/code/game/mecha/equipment/tools/energy_relay.dm @@ -0,0 +1,115 @@ +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay + name = "energy relay" + desc = "Wirelessly drains energy from any available power channel in area. The performance index is quite low." + icon_state = "tesla" + origin_tech = list(TECH_MAGNET = 4, TECH_ILLEGAL = 2) + equip_cooldown = 10 + energy_drain = 0 + range = 0 + var/datum/global_iterator/pr_energy_relay + var/coeff = 100 + var/list/use_channels = list(EQUIP,ENVIRON,LIGHT) + + equip_type = EQUIP_UTILITY + +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/New() + ..() + pr_energy_relay = new /datum/global_iterator/mecha_energy_relay(list(src),0) + pr_energy_relay.set_delay(equip_cooldown) + return + +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/Destroy() + qdel(pr_energy_relay) + pr_energy_relay = null + ..() + +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/detach() + pr_energy_relay.stop() +// chassis.proc_res["dynusepower"] = null + chassis.proc_res["dyngetcharge"] = null + ..() + return + +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/attach(obj/mecha/M) + ..() + chassis.proc_res["dyngetcharge"] = src +// chassis.proc_res["dynusepower"] = src + return + +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/can_attach(obj/mecha/M) + if(..()) + if(!M.proc_res["dyngetcharge"])// && !M.proc_res["dynusepower"]) + return 1 + return 0 + +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/dyngetcharge() + if(equip_ready) //disabled + return chassis.dyngetcharge() + var/area/A = get_area(chassis) + var/pow_chan = get_power_channel(A) + var/charge = 0 + if(pow_chan) + charge = 1000 //making magic + else + return chassis.dyngetcharge() + return charge + +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/get_power_channel(var/area/A) + var/pow_chan + if(A) + for(var/c in use_channels) + if(A.powered(c)) + pow_chan = c + break + return pow_chan + +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/Topic(href, href_list) + ..() + if(href_list["toggle_relay"]) + if(pr_energy_relay.toggle()) + set_ready_state(0) + log_message("Activated.") + else + set_ready_state(1) + log_message("Deactivated.") + return + +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/get_equip_info() + if(!chassis) return + return "* [src.name] - [pr_energy_relay.active()?"Dea":"A"]ctivate" + +/* proc/dynusepower(amount) + if(!equip_ready) //enabled + var/area/A = get_area(chassis) + var/pow_chan = get_power_channel(A) + if(pow_chan) + A.master.use_power(amount*coeff, pow_chan) + return 1 + return chassis.dynusepower(amount)*/ + +/datum/global_iterator/mecha_energy_relay + +/datum/global_iterator/mecha_energy_relay/process(var/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/ER) + if(!ER.chassis || ER.chassis.hasInternalDamage(MECHA_INT_SHORT_CIRCUIT)) + stop() + ER.set_ready_state(1) + return + var/cur_charge = ER.chassis.get_charge() + if(isnull(cur_charge) || !ER.chassis.cell) + stop() + ER.set_ready_state(1) + ER.occupant_message("No powercell detected.") + return + if(cur_charge3) return + if(get_dist(chassis, target)>2) return + set_ready_state(0) + if(do_after_cooldown(target)) + if( istype(target, /obj/structure/reagent_dispensers/watertank) && get_dist(chassis,target) <= 1) + var/obj/o = target + var/amount = o.reagents.trans_to_obj(src, 200) + occupant_message("[amount] units transferred into internal tank.") + playsound(chassis, 'sound/effects/refill.ogg', 50, 1, -6) + return + + if (src.reagents.total_volume < 1) + occupant_message("\The [src] is empty.") + return + + playsound(chassis, 'sound/effects/extinguish.ogg', 75, 1, -3) + + var/direction = get_dir(chassis,target) + + var/turf/T = get_turf(target) + var/turf/T1 = get_step(T,turn(direction, 90)) + var/turf/T2 = get_step(T,turn(direction, -90)) + + var/list/the_targets = list(T,T1,T2) + + for(var/a = 1 to 5) + spawn(0) + var/obj/effect/effect/water/W = new /obj/effect/effect/water(get_turf(chassis)) + var/turf/my_target + if(a == 1) + my_target = T + else if(a == 2) + my_target = T1 + else if(a == 3) + my_target = T2 + else + my_target = pick(the_targets) + W.create_reagents(5) + if(!W || !src) + return + reagents.trans_to_obj(W, spray_amount) + W.set_color() + W.set_up(my_target) + return 1 + +/obj/item/mecha_parts/mecha_equipment/tool/extinguisher/get_equip_info() + return "[..()] \[[src.reagents.total_volume]\]" + +/obj/item/mecha_parts/mecha_equipment/tool/extinguisher/on_reagent_change() + return \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/generator.dm b/code/game/mecha/equipment/tools/generator.dm new file mode 100644 index 0000000000..b4896045c5 --- /dev/null +++ b/code/game/mecha/equipment/tools/generator.dm @@ -0,0 +1,166 @@ +/obj/item/mecha_parts/mecha_equipment/generator + name = "phoron generator" + desc = "Generates power using solid phoron as fuel. Pollutes the environment." + icon_state = "tesla" + origin_tech = list(TECH_PHORON = 2, TECH_POWER = 2, TECH_ENGINEERING = 1) + equip_cooldown = 10 + energy_drain = 0 + range = MELEE + var/datum/global_iterator/pr_mech_generator + var/coeff = 100 + var/obj/item/stack/material/fuel + var/max_fuel = 150000 + var/fuel_per_cycle_idle = 100 + var/fuel_per_cycle_active = 500 + var/power_per_cycle = 20 + + equip_type = EQUIP_UTILITY + +/obj/item/mecha_parts/mecha_equipment/generator/New() + ..() + init() + return + +/obj/item/mecha_parts/mecha_equipment/generator/Destroy() + qdel(pr_mech_generator) + pr_mech_generator = null + ..() + +/obj/item/mecha_parts/mecha_equipment/generator/proc/init() + fuel = new /obj/item/stack/material/phoron(src) + fuel.amount = 0 + pr_mech_generator = new /datum/global_iterator/mecha_generator(list(src),0) + pr_mech_generator.set_delay(equip_cooldown) + return + +/obj/item/mecha_parts/mecha_equipment/generator/detach() + pr_mech_generator.stop() + ..() + return + + +/obj/item/mecha_parts/mecha_equipment/generator/Topic(href, href_list) + ..() + if(href_list["toggle"]) + if(pr_mech_generator.toggle()) + set_ready_state(0) + log_message("Activated.") + else + set_ready_state(1) + log_message("Deactivated.") + return + +/obj/item/mecha_parts/mecha_equipment/generator/get_equip_info() + var/output = ..() + if(output) + return "[output] \[[fuel]: [round(fuel.amount*fuel.perunit,0.1)] cm3\] - [pr_mech_generator.active()?"Dea":"A"]ctivate" + return + +/obj/item/mecha_parts/mecha_equipment/generator/action(target) + if(chassis) + var/result = load_fuel(target) + var/message + if(isnull(result)) + message = "[fuel] traces in target minimal. [target] cannot be used as fuel." + else if(!result) + message = "Unit is full." + else + message = "[result] unit\s of [fuel] successfully loaded." + send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) + occupant_message(message) + return + +/obj/item/mecha_parts/mecha_equipment/generator/proc/load_fuel(var/obj/item/stack/material/P) + if(P.type == fuel.type && P.amount) + var/to_load = max(max_fuel - fuel.amount*fuel.perunit,0) + if(to_load) + var/units = min(max(round(to_load / P.perunit),1),P.amount) + if(units) + fuel.amount += units + P.use(units) + return units + else + return 0 + return + +/obj/item/mecha_parts/mecha_equipment/generator/attackby(weapon,mob/user) + var/result = load_fuel(weapon) + if(isnull(result)) + user.visible_message("[user] tries to shove [weapon] into [src]. What a dumb-ass.","[fuel] traces minimal. [weapon] cannot be used as fuel.") + else if(!result) + user << "Unit is full." + else + user.visible_message("[user] loads [src] with [fuel].","[result] unit\s of [fuel] successfully loaded.") + return + +/obj/item/mecha_parts/mecha_equipment/generator/critfail() + ..() + var/turf/simulated/T = get_turf(src) + if(!T) + return + var/datum/gas_mixture/GM = new + if(prob(10)) + T.assume_gas("phoron", 100, 1500+T0C) + T.visible_message("The [src] suddenly disgorges a cloud of heated phoron.") + destroy() + else + T.assume_gas("phoron", 5, istype(T) ? T.air.temperature : T20C) + T.visible_message("The [src] suddenly disgorges a cloud of phoron.") + T.assume_air(GM) + return + +/datum/global_iterator/mecha_generator + +/datum/global_iterator/mecha_generator/process(var/obj/item/mecha_parts/mecha_equipment/generator/EG) + if(!EG.chassis) + stop() + EG.set_ready_state(1) + return 0 + if(EG.fuel.amount<=0) + stop() + EG.log_message("Deactivated - no fuel.") + EG.set_ready_state(1) + return 0 + var/cur_charge = EG.chassis.get_charge() + if(isnull(cur_charge)) + EG.set_ready_state(1) + EG.occupant_message("No powercell detected.") + EG.log_message("Deactivated.") + stop() + return 0 + var/use_fuel = EG.fuel_per_cycle_idle + if(cur_charge* [src.name] \[Toggle\]" + +/obj/item/mecha_parts/mecha_equipment/tool/jetpack/Topic(href,href_list) + ..() + if(href_list["toggle"]) + toggle() + +/obj/item/mecha_parts/mecha_equipment/tool/jetpack/do_after_cooldown() + sleep(equip_cooldown) + wait = 0 + return 1 \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/orescanner.dm b/code/game/mecha/equipment/tools/orescanner.dm new file mode 100644 index 0000000000..91027bd264 --- /dev/null +++ b/code/game/mecha/equipment/tools/orescanner.dm @@ -0,0 +1,41 @@ +/obj/item/mecha_parts/mecha_equipment/tool/orescanner + name = "mounted ore scanner" + desc = "An exosuit-mounted ore scanner." + icon_state = "mecha_analyzer" + origin_tech = list(TECH_MATERIAL = 2, TECH_MAGNET = 2, TECH_POWER = 2) + equip_cooldown = 5 + energy_drain = 30 + range = MELEE|RANGED + equip_type = EQUIP_SPECIAL + ready_sound = 'sound/items/goggles_charge.ogg' + required_type = list(/obj/mecha/working/ripley) + + var/obj/item/weapon/mining_scanner/my_scanner = null + var/exact_scan = FALSE + +/obj/item/mecha_parts/mecha_equipment/tool/orescanner/Initialize() + my_scanner = new(src) + return ..() + +/obj/item/mecha_parts/mecha_equipment/tool/orescanner/Destroy() + QDEL_NULL(my_scanner) + return ..() + +/obj/item/mecha_parts/mecha_equipment/tool/orescanner/action(var/atom/target) + if(!action_checks(target) || get_dist(chassis, target) > 5) + return FALSE + + if(!enable_special) + target = get_turf(chassis) + + var/datum/beam/ScanBeam = chassis.Beam(target,"g_beam",'icons/effects/beam.dmi',time=2 SECONDS,10,/obj/effect/ebeam,2) + + if(do_after(chassis.occupant, 2 SECONDS)) + my_scanner.ScanTurf(target, chassis.occupant, exact_scan) + + QDEL_NULL(ScanBeam) + +/obj/item/mecha_parts/mecha_equipment/tool/orescanner/advanced + name = "advanced ore scanner" + icon_state = "mecha_analyzer_adv" + exact_scan = TRUE \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/passenger.dm b/code/game/mecha/equipment/tools/passenger.dm new file mode 100644 index 0000000000..1e40da2f30 --- /dev/null +++ b/code/game/mecha/equipment/tools/passenger.dm @@ -0,0 +1,151 @@ +/obj/item/mecha_parts/mecha_equipment/tool/passenger + name = "passenger compartment" + desc = "A mountable passenger compartment for exosuits. Rather cramped." + icon_state = "mecha_abooster_ccw" + origin_tech = list(TECH_ENGINEERING = 1, TECH_BIO = 1) + energy_drain = 10 + range = MELEE + equip_cooldown = 20 + var/mob/living/carbon/occupant = null + var/door_locked = 1 + salvageable = 0 + allow_duplicate = TRUE + + equip_type = EQUIP_HULL + +/obj/item/mecha_parts/mecha_equipment/tool/passenger/destroy() + for(var/atom/movable/AM in src) + AM.forceMove(get_turf(src)) + AM << "You tumble out of the destroyed [src.name]!" + return ..() + +/obj/item/mecha_parts/mecha_equipment/tool/passenger/Exit(atom/movable/O) + return 0 + +/obj/item/mecha_parts/mecha_equipment/tool/passenger/proc/move_inside(var/mob/user) + if (chassis) + chassis.visible_message("[user] starts to climb into [chassis].") + + if(do_after(user, 40, needhand=0)) + if(!src.occupant) + user.forceMove(src) + occupant = user + log_message("[user] boarded.") + occupant_message("[user] boarded.") + else if(src.occupant != user) + to_chat(user, "[src.occupant] was faster. Try harder next time, loser.") + else + to_chat(user, "You stop entering the exosuit.") + +/obj/item/mecha_parts/mecha_equipment/tool/passenger/verb/eject() + set name = "Eject" + set category = "Exosuit Interface" + set src = usr.loc + set popup_menu = 0 + + if(usr != occupant) + return + to_chat(occupant, "You climb out from \the [src].") + go_out() + occupant_message("[occupant] disembarked.") + log_message("[occupant] disembarked.") + add_fingerprint(usr) + +/obj/item/mecha_parts/mecha_equipment/tool/passenger/proc/go_out() + if(!occupant) + return + occupant.forceMove(get_turf(src)) + occupant.reset_view() + /* + if(occupant.client) + occupant.client.eye = occupant.client.mob + occupant.client.perspective = MOB_PERSPECTIVE + */ + occupant = null + return + +/obj/item/mecha_parts/mecha_equipment/tool/passenger/attach() + ..() + if (chassis) + chassis.verbs |= /obj/mecha/proc/move_inside_passenger + +/obj/item/mecha_parts/mecha_equipment/tool/passenger/detach() + if(occupant) + occupant_message("Unable to detach [src] - equipment occupied.") + return + + var/obj/mecha/M = chassis + ..() + if (M && !(locate(/obj/item/mecha_parts/mecha_equipment/tool/passenger) in M)) + M.verbs -= /obj/mecha/proc/move_inside_passenger + +/obj/item/mecha_parts/mecha_equipment/tool/passenger/get_equip_info() + return "[..()]
[occupant? "\[Occupant: [occupant]\]|" : ""]Exterior Hatch: Toggle Lock" + +/obj/item/mecha_parts/mecha_equipment/tool/passenger/Topic(href,href_list) + ..() + if (href_list["toggle_lock"]) + door_locked = !door_locked + occupant_message("Passenger compartment hatch [door_locked? "locked" : "unlocked"].") + if (chassis) + chassis.visible_message("The hatch on \the [chassis] [door_locked? "locks" : "unlocks"].", "You hear something latching.") + + +#define LOCKED 1 +#define OCCUPIED 2 + +/obj/mecha/proc/move_inside_passenger() + set category = "Object" + set name = "Enter Passenger Compartment" + set src in oview(1) + + //check that usr can climb in + if (usr.stat || !ishuman(usr)) + return + + if (!usr.Adjacent(src)) + return + + if (!isturf(usr.loc)) + usr << "You can't reach the passenger compartment from here." + return + + if(iscarbon(usr)) + var/mob/living/carbon/C = usr + if(C.handcuffed) + usr << "Kinda hard to climb in while handcuffed don't you think?" + return + + if(isliving(usr)) + var/mob/living/L = usr + if(L.has_buckled_mobs()) + to_chat(L, span("warning", "You have other entities attached to yourself. Remove them first.")) + return + + //search for a valid passenger compartment + var/feedback = 0 //for nicer user feedback + for(var/obj/item/mecha_parts/mecha_equipment/tool/passenger/P in src) + if (P.occupant) + feedback |= OCCUPIED + continue + if (P.door_locked) + feedback |= LOCKED + continue + + //found a boardable compartment + P.move_inside(usr) + return + + //didn't find anything + switch (feedback) + if (OCCUPIED) + usr << "The passenger compartment is already occupied!" + if (LOCKED) + usr << "The passenger compartment hatch is locked!" + if (OCCUPIED|LOCKED) + usr << "All of the passenger compartments are already occupied or locked!" + if (0) + usr << "\The [src] doesn't have a passenger compartment." + +#undef LOCKED +#undef OCCUPIED \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/rcd.dm b/code/game/mecha/equipment/tools/rcd.dm new file mode 100644 index 0000000000..9aa9a8bb40 --- /dev/null +++ b/code/game/mecha/equipment/tools/rcd.dm @@ -0,0 +1,45 @@ +/obj/item/mecha_parts/mecha_equipment/tool/rcd + name = "mounted RCD" + desc = "An exosuit-mounted Rapid Construction Device. (Can be attached to: Any exosuit)" + icon_state = "mecha_rcd" + origin_tech = list(TECH_MATERIAL = 4, TECH_BLUESPACE = 3, TECH_MAGNET = 4, TECH_POWER = 4) + equip_cooldown = 10 + energy_drain = 250 + range = MELEE|RANGED + equip_type = EQUIP_SPECIAL + var/obj/item/weapon/rcd/electric/mounted/mecha/my_rcd = null + +/obj/item/mecha_parts/mecha_equipment/tool/rcd/Initialize() + my_rcd = new(src) + return ..() + +/obj/item/mecha_parts/mecha_equipment/tool/rcd/Destroy() + QDEL_NULL(my_rcd) + return ..() + +/obj/item/mecha_parts/mecha_equipment/tool/rcd/action(atom/target) + if(!action_checks(target) || get_dist(chassis, target) > 3) + return FALSE + + my_rcd.use_rcd(target, chassis.occupant) + +/obj/item/mecha_parts/mecha_equipment/tool/rcd/Topic(href,href_list) + ..() + if(href_list["mode"]) + my_rcd.mode_index = text2num(href_list["mode"]) + occupant_message("RCD reconfigured to '[my_rcd.modes[my_rcd.mode_index]]'.") +/* +/obj/item/mecha_parts/mecha_equipment/tool/rcd/get_equip_info() + return "[..()] \[D|C|A\]" +*/ +/obj/item/mecha_parts/mecha_equipment/tool/rcd/get_equip_info() + var/list/content = list(..()) // This is all for one line, in the interest of string tree conservation. + var/i = 1 + content += "
" + for(var/mode in my_rcd.modes) + content += " [mode]" + if(i < my_rcd.modes.len) + content += "
" + i++ + + return content.Join() \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/repair_droid.dm b/code/game/mecha/equipment/tools/repair_droid.dm new file mode 100644 index 0000000000..f76eeed6f0 --- /dev/null +++ b/code/game/mecha/equipment/tools/repair_droid.dm @@ -0,0 +1,94 @@ +/obj/item/mecha_parts/mecha_equipment/repair_droid + name = "repair droid" + desc = "Automated repair droid. Scans exosuit for damage and repairs it. Can fix almost any type of external or internal damage." + icon_state = "repair_droid" + origin_tech = list(TECH_MAGNET = 3, TECH_DATA = 3) + equip_cooldown = 20 + energy_drain = 100 + range = 0 + var/health_boost = 2 + var/datum/global_iterator/pr_repair_droid + var/icon/droid_overlay + var/list/repairable_damage = list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH) + + equip_type = EQUIP_HULL + +/obj/item/mecha_parts/mecha_equipment/repair_droid/New() + ..() + pr_repair_droid = new /datum/global_iterator/mecha_repair_droid(list(src),0) + pr_repair_droid.set_delay(equip_cooldown) + return + +/obj/item/mecha_parts/mecha_equipment/repair_droid/Destroy() + qdel(pr_repair_droid) + pr_repair_droid = null + ..() + +/obj/item/mecha_parts/mecha_equipment/repair_droid/attach(obj/mecha/M as obj) + ..() + droid_overlay = new(src.icon, icon_state = "repair_droid") + M.overlays += droid_overlay + return + +/obj/item/mecha_parts/mecha_equipment/repair_droid/destroy() + chassis.overlays -= droid_overlay + ..() + return + +/obj/item/mecha_parts/mecha_equipment/repair_droid/detach() + chassis.overlays -= droid_overlay + pr_repair_droid.stop() + ..() + return + +/obj/item/mecha_parts/mecha_equipment/repair_droid/get_equip_info() + if(!chassis) return + return "* [src.name] - [pr_repair_droid.active()?"Dea":"A"]ctivate" + + +/obj/item/mecha_parts/mecha_equipment/repair_droid/Topic(href, href_list) + ..() + if(href_list["toggle_repairs"]) + chassis.overlays -= droid_overlay + if(pr_repair_droid.toggle()) + droid_overlay = new(src.icon, icon_state = "repair_droid_a") + log_message("Activated.") + else + droid_overlay = new(src.icon, icon_state = "repair_droid") + log_message("Deactivated.") + set_ready_state(1) + chassis.overlays += droid_overlay + send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) + return + + +/datum/global_iterator/mecha_repair_droid + +/datum/global_iterator/mecha_repair_droid/process(var/obj/item/mecha_parts/mecha_equipment/repair_droid/RD as obj) + if(!RD.chassis) + stop() + RD.set_ready_state(1) + return + var/health_boost = RD.health_boost + var/repaired = 0 + if(RD.chassis.hasInternalDamage(MECHA_INT_SHORT_CIRCUIT)) + health_boost *= -2 + else if(RD.chassis.hasInternalDamage() && prob(15)) + for(var/int_dam_flag in RD.repairable_damage) + if(RD.chassis.hasInternalDamage(int_dam_flag)) + RD.chassis.clearInternalDamage(int_dam_flag) + repaired = 1 + break + if(health_boost<0 || RD.chassis.health < initial(RD.chassis.health)) + RD.chassis.health += min(health_boost, initial(RD.chassis.health)-RD.chassis.health) + repaired = 1 + if(repaired) + if(RD.chassis.use_power(RD.energy_drain)) + RD.set_ready_state(0) + else + stop() + RD.set_ready_state(1) + return + else + RD.set_ready_state(1) + return \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/shield.dm b/code/game/mecha/equipment/tools/shield.dm new file mode 100644 index 0000000000..1ceab07945 --- /dev/null +++ b/code/game/mecha/equipment/tools/shield.dm @@ -0,0 +1,82 @@ +/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 = 0 + 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" \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/sleeper.dm b/code/game/mecha/equipment/tools/sleeper.dm new file mode 100644 index 0000000000..861471b6ce --- /dev/null +++ b/code/game/mecha/equipment/tools/sleeper.dm @@ -0,0 +1,247 @@ +/obj/item/mecha_parts/mecha_equipment/tool/sleeper + name = "mounted sleeper" + desc = "A sleeper. Mountable to an exosuit. (Can be attached to: Medical Exosuits)" + icon = 'icons/obj/Cryogenic2.dmi' + icon_state = "sleeper_0" + origin_tech = list(TECH_DATA = 2, TECH_BIO = 3) + energy_drain = 20 + range = MELEE + equip_cooldown = 30 + var/mob/living/carbon/human/occupant = null + var/datum/global_iterator/pr_mech_sleeper + var/inject_amount = 5 + required_type = list(/obj/mecha/medical) + salvageable = 0 + allow_duplicate = TRUE + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/New() + ..() + pr_mech_sleeper = new /datum/global_iterator/mech_sleeper(list(src),0) + pr_mech_sleeper.set_delay(equip_cooldown) + return + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/Destroy() + qdel(pr_mech_sleeper) + for(var/atom/movable/AM in src) + AM.forceMove(get_turf(src)) + return ..() + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/Exit(atom/movable/O) + return 0 + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/action(var/mob/living/carbon/human/target) + if(!action_checks(target)) + return + if(!istype(target)) + return + if(target.buckled) + occupant_message("[target] will not fit into the sleeper because they are buckled to [target.buckled].") + return + if(occupant) + occupant_message("The sleeper is already occupied") + return + if(target.has_buckled_mobs()) + occupant_message(span("warning", "\The [target] has other entities attached to it. Remove them first.")) + return + occupant_message("You start putting [target] into [src].") + chassis.visible_message("[chassis] starts putting [target] into the [src].") + var/C = chassis.loc + var/T = target.loc + if(do_after_cooldown(target)) + if(chassis.loc!=C || target.loc!=T) + return + if(occupant) + occupant_message("The sleeper is already occupied!") + return + target.forceMove(src) + occupant = target + target.reset_view(src) + occupant.Stasis(3) + /* + if(target.client) + target.client.perspective = EYE_PERSPECTIVE + target.client.eye = chassis + */ + set_ready_state(0) + pr_mech_sleeper.start() + occupant_message("[target] successfully loaded into [src]. Life support functions engaged.") + chassis.visible_message("[chassis] loads [target] into [src].") + log_message("[target] loaded. Life support functions engaged.") + return + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/proc/go_out() + if(!occupant) + return + occupant.forceMove(get_turf(src)) + occupant_message("[occupant] ejected. Life support functions disabled.") + log_message("[occupant] ejected. Life support functions disabled.") + occupant.reset_view() + /* + if(occupant.client) + occupant.client.eye = occupant.client.mob + occupant.client.perspective = MOB_PERSPECTIVE + */ + occupant.Stasis(0) + occupant = null + pr_mech_sleeper.stop() + set_ready_state(1) + return + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/detach() + if(occupant) + occupant_message("Unable to detach [src] - equipment occupied.") + return + pr_mech_sleeper.stop() + return ..() + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/get_equip_info() + var/output = ..() + if(output) + var/temp = "" + if(occupant) + temp = "
\[Occupant: [occupant] (Health: [occupant.health]%)\]
View stats|Eject" + return "[output] [temp]" + return + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/Topic(href,href_list) + ..() + var/datum/topic_input/top_filter = new /datum/topic_input(href,href_list) + if(top_filter.get("eject")) + go_out() + if(top_filter.get("view_stats")) + chassis.occupant << browse(get_occupant_stats(),"window=msleeper") + onclose(chassis.occupant, "msleeper") + return + if(top_filter.get("inject")) + inject_reagent(top_filter.getType("inject",/datum/reagent),top_filter.getObj("source")) + return + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/proc/get_occupant_stats() + if(!occupant) + return + return {" + + [occupant] statistics + + + + +

Health statistics

+
+ [get_occupant_dam()] +
+

Reagents in bloodstream

+
+ [get_occupant_reagents()] +
+
+ [get_available_reagents()] +
+ + "} + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/proc/get_occupant_dam() + var/t1 + switch(occupant.stat) + if(0) + t1 = "Conscious" + if(1) + t1 = "Unconscious" + if(2) + t1 = "*dead*" + else + t1 = "Unknown" + return {"Health: [occupant.health]% ([t1])
+ Core Temperature: [src.occupant.bodytemperature-T0C]°C ([src.occupant.bodytemperature*1.8-459.67]°F)
+ Brute Damage: [occupant.getBruteLoss()]%
+ Respiratory Damage: [occupant.getOxyLoss()]%
+ Toxin Content: [occupant.getToxLoss()]%
+ Burn Severity: [occupant.getFireLoss()]%
+ "} + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/proc/get_occupant_reagents() + if(occupant.reagents) + for(var/datum/reagent/R in occupant.reagents.reagent_list) + if(R.volume > 0) + . += "[R]: [round(R.volume,0.01)]
" + return . || "None" + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/proc/get_available_reagents() + var/output + var/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/SG = locate(/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun) in chassis + if(SG && SG.reagents && islist(SG.reagents.reagent_list)) + for(var/datum/reagent/R in SG.reagents.reagent_list) + if(R.volume > 0) + output += "Inject [R.name]
" + return output + + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/proc/inject_reagent(var/datum/reagent/R,var/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/SG) + if(!R || !occupant || !SG || !(SG in chassis.equipment)) + return 0 + var/to_inject = min(R.volume, inject_amount) + if(to_inject && occupant.reagents.get_reagent_amount(R.id) + to_inject > inject_amount*4) + occupant_message("Sleeper safeties prohibit you from injecting more than [inject_amount*4] units of [R.name].") + else + occupant_message("Injecting [occupant] with [to_inject] units of [R.name].") + log_message("Injecting [occupant] with [to_inject] units of [R.name].") + //SG.reagents.trans_id_to(occupant,R.id,to_inject) + SG.reagents.remove_reagent(R.id,to_inject) + occupant.reagents.add_reagent(R.id,to_inject) + update_equip_info() + return + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/update_equip_info() + if(..()) + send_byjax(chassis.occupant,"msleeper.browser","lossinfo",get_occupant_dam()) + send_byjax(chassis.occupant,"msleeper.browser","reagents",get_occupant_reagents()) + send_byjax(chassis.occupant,"msleeper.browser","injectwith",get_available_reagents()) + return 1 + return + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/verb/eject() + set name = "Sleeper Eject" + set category = "Exosuit Interface" + set src = usr.loc + set popup_menu = 0 + if(usr!=src.occupant || usr.stat == 2) + return + to_chat(usr,"Release sequence activated. This will take one minute.") + sleep(600) + if(!src || !usr || !occupant || (occupant != usr)) //Check if someone's released/replaced/bombed him already + return + go_out()//and release him from the eternal prison. + +/datum/global_iterator/mech_sleeper + +/datum/global_iterator/mech_sleeper/process(var/obj/item/mecha_parts/mecha_equipment/tool/sleeper/S) + if(!S.chassis) + S.set_ready_state(1) + return stop() + if(!S.chassis.has_charge(S.energy_drain)) + S.set_ready_state(1) + S.log_message("Deactivated.") + S.occupant_message("[src] deactivated - no power.") + return stop() + var/mob/living/carbon/M = S.occupant + if(!M) + return + if(M.health > 0) + M.adjustOxyLoss(-1) + M.updatehealth() + M.AdjustStunned(-4) + M.AdjustWeakened(-4) + M.AdjustStunned(-4) + M.Paralyse(2) + M.Weaken(2) + M.Stun(2) + if(M.reagents.get_reagent_amount("inaprovaline") < 5) + M.reagents.add_reagent("inaprovaline", 5) + S.chassis.use_power(S.energy_drain) + S.update_equip_info() + return \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/speedboost.dm b/code/game/mecha/equipment/tools/speedboost.dm new file mode 100644 index 0000000000..1cb0df9469 --- /dev/null +++ b/code/game/mecha/equipment/tools/speedboost.dm @@ -0,0 +1,21 @@ +/obj/item/mecha_parts/mecha_equipment/speedboost + name = "ripley leg actuator overdrive" + desc = "System enhancements and overdrives to make a ripley's legs move faster." + icon_state = "tesla" + origin_tech = list( TECH_POWER = 5, TECH_MATERIAL = 4, TECH_ENGINEERING = 4) + required_type = list(/obj/mecha/working/ripley) + + equip_type = EQUIP_HULL + +/obj/item/mecha_parts/mecha_equipment/speedboost/attach(obj/mecha/M as obj) + ..() + if(enable_special) + chassis.step_in = (chassis.step_in-2) // Make the ripley as fast as a durand + else + chassis.step_in = (chassis.step_in+1) // Improper parts slow the mech down + return + +/obj/item/mecha_parts/mecha_equipment/speedboost/detach() + chassis.step_in = initial(chassis.step_in) + ..() + return \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/syringe_gun.dm similarity index 60% rename from code/game/mecha/equipment/tools/medical_tools.dm rename to code/game/mecha/equipment/tools/syringe_gun.dm index 9f1e522733..31206d7640 100644 --- a/code/game/mecha/equipment/tools/medical_tools.dm +++ b/code/game/mecha/equipment/tools/syringe_gun.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD:code/game/mecha/equipment/tools/medical_tools.dm /obj/item/mecha_parts/mecha_equipment/tool/sleeper name = "mounted sleeper" desc = "A sleeper. Mountable to an exosuit. (Can be attached to: Medical Exosuits)" @@ -803,3 +804,509 @@ required_type = list(/obj/mecha/medical) tooltype = /obj/item/device/healthanalyzer/advanced +======= +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun + name = "syringe gun" + desc = "Exosuit-mounted chem synthesizer with syringe gun. Reagents inside are held in stasis, so no reactions will occur. (Can be attached to: Medical Exosuits)" + icon = 'icons/obj/gun.dmi' + icon_state = "syringegun" + var/list/syringes + var/list/known_reagents + var/list/processed_reagents + var/max_syringes = 10 + var/max_volume = 75 //max reagent volume + var/synth_speed = 5 //[num] reagent units per cycle + energy_drain = 10 + var/mode = 0 //0 - fire syringe, 1 - analyze reagents. + var/datum/global_iterator/mech_synth/synth + range = MELEE|RANGED + equip_cooldown = 10 + origin_tech = list(TECH_MATERIAL = 3, TECH_BIO = 4, TECH_MAGNET = 4, TECH_DATA = 3) + required_type = list(/obj/mecha/medical) + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/New() + ..() + flags |= NOREACT + syringes = new + known_reagents = list("inaprovaline"="Inaprovaline","anti_toxin"="Dylovene") + processed_reagents = new + create_reagents(max_volume) + synth = new (list(src),0) + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/detach() + synth.stop() + return ..() + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/critfail() + ..() + flags &= ~NOREACT + return + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/get_equip_info() + var/output = ..() + if(output) + return "[output] \[[mode? "Analyze" : "Launch"]\]
\[Syringes: [syringes.len]/[max_syringes] | Reagents: [reagents.total_volume]/[reagents.maximum_volume]\]
Reagents list" + return + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/action(atom/movable/target) + if(!action_checks(target)) + return + if(istype(target,/obj/item/weapon/reagent_containers/syringe)) + return load_syringe(target) + if(istype(target,/obj/item/weapon/storage))//Loads syringes from boxes + for(var/obj/item/weapon/reagent_containers/syringe/S in target.contents) + load_syringe(S) + return + if(mode) + return analyze_reagents(target) + if(!syringes.len) + occupant_message("No syringes loaded.") + return + if(reagents.total_volume<=0) + occupant_message("No available reagents to load syringe with.") + return + set_ready_state(0) + chassis.use_power(energy_drain) + var/turf/trg = get_turf(target) + var/obj/item/weapon/reagent_containers/syringe/S = syringes[1] + S.forceMove(get_turf(chassis)) + reagents.trans_to_obj(S, min(S.volume, reagents.total_volume)) + syringes -= S + S.icon = 'icons/obj/chemical.dmi' + S.icon_state = "syringeproj" + playsound(chassis, 'sound/items/syringeproj.ogg', 50, 1) + log_message("Launched [S] from [src], targeting [target].") + spawn(-1) + src = null //if src is deleted, still process the syringe + for(var/i=0, i<6, i++) + if(!S) + break + if(step_towards(S,trg)) + var/list/mobs = new + for(var/mob/living/carbon/M in S.loc) + mobs += M + var/mob/living/carbon/M = safepick(mobs) + if(M) + S.icon_state = initial(S.icon_state) + S.icon = initial(S.icon) + S.reagents.trans_to_mob(M, S.reagents.total_volume, CHEM_BLOOD) + M.take_organ_damage(2) + S.visible_message(" [M] was hit by the syringe!") + break + else if(S.loc == trg) + S.icon_state = initial(S.icon_state) + S.icon = initial(S.icon) + S.update_icon() + break + else + S.icon_state = initial(S.icon_state) + S.icon = initial(S.icon) + S.update_icon() + break + sleep(1) + do_after_cooldown() + return 1 + + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/Topic(href,href_list) + ..() + var/datum/topic_input/top_filter = new (href,href_list) + if(top_filter.get("toggle_mode")) + mode = !mode + update_equip_info() + return + if(top_filter.get("select_reagents")) + processed_reagents.len = 0 + var/m = 0 + var/message + for(var/i=1 to known_reagents.len) + if(m>=synth_speed) + break + var/reagent = top_filter.get("reagent_[i]") + if(reagent && (reagent in known_reagents)) + message = "[m ? ", " : null][known_reagents[reagent]]" + processed_reagents += reagent + m++ + if(processed_reagents.len) + message += " added to production" + synth.start() + occupant_message(message) + occupant_message("Reagent processing started.") + log_message("Reagent processing started.") + return + if(top_filter.get("show_reagents")) + chassis.occupant << browse(get_reagents_page(),"window=msyringegun") + if(top_filter.get("purge_reagent")) + var/reagent = top_filter.get("purge_reagent") + if(reagent) + reagents.del_reagent(reagent) + return + if(top_filter.get("purge_all")) + reagents.clear_reagents() + return + return + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/proc/get_reagents_page() + var/output = {" + + Reagent Synthesizer + + + + +

Current reagents:

+
+ [get_current_reagents()] +
+

Reagents production:

+
+ [get_reagents_form()] +
+ + + "} + return output + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/proc/get_reagents_form() + var/r_list = get_reagents_list() + var/inputs + if(r_list) + inputs += "" + inputs += "" + inputs += "" + var/output = {"
+ [r_list || "No known reagents"] + [inputs] +
+ [r_list? "Only the first [synth_speed] selected reagent\s will be added to production" : null] + "} + return output + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/proc/get_reagents_list() + var/output + for(var/i=1 to known_reagents.len) + var/reagent_id = known_reagents[i] + output += {" [known_reagents[reagent_id]]
"} + return output + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/proc/get_current_reagents() + var/output + for(var/datum/reagent/R in reagents.reagent_list) + if(R.volume > 0) + output += "[R]: [round(R.volume,0.001)] - Purge Reagent
" + if(output) + output += "Total: [round(reagents.total_volume,0.001)]/[reagents.maximum_volume] - Purge All" + return output || "None" + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/proc/load_syringe(obj/item/weapon/reagent_containers/syringe/S) + if(syringes.len= 2) + occupant_message("The syringe is too far away.") + return 0 + for(var/obj/structure/D in S.loc)//Basic level check for structures in the way (Like grilles and windows) + if(!(D.CanPass(S,src.loc))) + occupant_message("Unable to load syringe.") + return 0 + for(var/obj/machinery/door/D in S.loc)//Checks for doors + if(!(D.CanPass(S,src.loc))) + occupant_message("Unable to load syringe.") + return 0 + S.reagents.trans_to_obj(src, S.reagents.total_volume) + S.forceMove(src) + syringes += S + occupant_message("Syringe loaded.") + update_equip_info() + return 1 + occupant_message("The [src] syringe chamber is full.") + return 0 + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/proc/analyze_reagents(atom/A) + if(get_dist(src,A) >= 4) + occupant_message("The object is too far away.") + return 0 + if(!A.reagents || istype(A,/mob)) + occupant_message("No reagent info gained from [A].") + return 0 + occupant_message("Analyzing reagents...") + for(var/datum/reagent/R in A.reagents.reagent_list) + if(R.reagent_state == 2 && add_known_reagent(R.id,R.name)) + occupant_message("Reagent analyzed, identified as [R.name] and added to database.") + send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form()) + occupant_message("Analysis complete.") + return 1 + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/proc/add_known_reagent(r_id,r_name) + set_ready_state(0) + do_after_cooldown() + if(!(r_id in known_reagents)) + known_reagents += r_id + known_reagents[r_id] = r_name + return 1 + return 0 + + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/update_equip_info() + if(..()) + send_byjax(chassis.occupant,"msyringegun.browser","reagents",get_current_reagents()) + send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form()) + return 1 + return + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/on_reagent_change() + ..() + update_equip_info() + return + +/datum/global_iterator/mech_synth + delay = 100 + +/datum/global_iterator/mech_synth/process(var/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/S) + if(!S.chassis) + return stop() + var/energy_drain = S.energy_drain*10 + if(!S.processed_reagents.len || S.reagents.total_volume >= S.reagents.maximum_volume || !S.chassis.has_charge(energy_drain)) + S.occupant_message("Reagent processing stopped.") + S.log_message("Reagent processing stopped.") + return stop() + var/amount = S.synth_speed / S.processed_reagents.len + for(var/reagent in S.processed_reagents) + S.reagents.add_reagent(reagent,amount) + S.chassis.use_power(energy_drain) + return 1 + +/obj/item/mecha_parts/mecha_equipment/crisis_drone + name = "crisis dronebay" + desc = "A small shoulder-mounted dronebay containing a rapid response drone capable of moderately stabilizing a patient near the exosuit." + icon_state = "mecha_dronebay" + origin_tech = list(TECH_PHORON = 3, TECH_MAGNET = 6, TECH_BIO = 5, TECH_DATA = 4) + range = MELEE|RANGED + equip_cooldown = 3 SECONDS + required_type = list(/obj/mecha/medical) + + var/droid_state = "med_droid" + + var/beam_state = "medbeam" + + var/enabled = FALSE + + var/icon/drone_overlay + + var/max_distance = 3 + + var/damcap = 60 + var/heal_dead = FALSE // Does this device heal the dead? + + var/brute_heal = 0.5 // Amount of bruteloss healed. + var/burn_heal = 0.5 // Amount of fireloss healed. + var/tox_heal = 0.5 // Amount of toxloss healed. + var/oxy_heal = 1 // Amount of oxyloss healed. + var/rad_heal = 0 // Amount of radiation healed. + var/clone_heal = 0 // Amount of cloneloss healed. + var/hal_heal = 0.2 // Amount of halloss healed. + var/bone_heal = 0 // Percent chance it will heal a broken bone. this does not mean 'make it not instantly re-break'. + + var/mob/living/Target = null + var/datum/beam/MyBeam = null + + equip_type = EQUIP_HULL + +/obj/item/mecha_parts/mecha_equipment/crisis_drone/Initialize() + ..() + drone_overlay = new(src.icon, icon_state = droid_state) + +/obj/item/mecha_parts/mecha_equipment/crisis_drone/Destroy() + STOP_PROCESSING(SSobj, src) + ..() + +/obj/item/mecha_parts/mecha_equipment/crisis_drone/attach(obj/mecha/M as obj) + . = ..(M) + if(chassis) + START_PROCESSING(SSobj, src) + +/obj/item/mecha_parts/mecha_equipment/crisis_drone/detach(atom/moveto=null) + shut_down() + . = ..(moveto) + STOP_PROCESSING(SSobj, src) + +/obj/item/mecha_parts/mecha_equipment/crisis_drone/critfail() + . = ..() + STOP_PROCESSING(SSobj, src) + shut_down() + if(chassis && chassis.occupant) + to_chat(chassis.occupant, "\The [chassis] shudders as something jams!") + log_message("[src.name] has malfunctioned. Maintenance required.") + +/obj/item/mecha_parts/mecha_equipment/crisis_drone/process() // Will continually try to find the nearest person above the threshold that is a valid target, and try to heal them. + if(chassis && enabled && chassis.has_charge(energy_drain) && (chassis.occupant || enable_special)) + var/mob/living/Targ = Target + var/TargDamage = 0 + + if(!valid_target(Target)) + Target = null + + if(Target) + TargDamage = (Targ.getOxyLoss() + Targ.getFireLoss() + Targ.getBruteLoss() + Targ.getToxLoss()) + + for(var/mob/living/Potential in viewers(max_distance, chassis)) + if(!valid_target(Potential)) + continue + + var/tallydamage = 0 + if(oxy_heal) + tallydamage += Potential.getOxyLoss() + if(burn_heal) + tallydamage += Potential.getFireLoss() + if(brute_heal) + tallydamage += Potential.getBruteLoss() + if(tox_heal) + tallydamage += Potential.getToxLoss() + if(hal_heal) + tallydamage += Potential.getHalLoss() + if(clone_heal) + tallydamage += Potential.getCloneLoss() + if(rad_heal) + tallydamage += Potential.radiation / 2 + + if(tallydamage > TargDamage) + Target = Potential + + if(MyBeam && !valid_target(MyBeam.target)) + QDEL_NULL(MyBeam) + + if(Target) + if(MyBeam && MyBeam.target != Target) + QDEL_NULL(MyBeam) + + if(valid_target(Target)) + if(!MyBeam) + MyBeam = chassis.Beam(Target,icon='icons/effects/beam.dmi',icon_state=beam_state,time=3 SECONDS,maxdistance=max_distance,beam_type = /obj/effect/ebeam,beam_sleep_time=2) + heal_target(Target) + + else + shut_down() + +/obj/item/mecha_parts/mecha_equipment/crisis_drone/proc/valid_target(var/mob/living/L) + . = TRUE + + if(!L || !istype(L)) + return FALSE + + if(get_dist(L, src) > max_distance) + return FALSE + + if(!(L in viewers(max_distance, chassis))) + return FALSE + + if(!unique_patient_checks(L)) + return FALSE + + if(L.stat == DEAD && !heal_dead) + return FALSE + + var/tallydamage = 0 + if(oxy_heal) + tallydamage += L.getOxyLoss() + if(burn_heal) + tallydamage += L.getFireLoss() + if(brute_heal) + tallydamage += L.getBruteLoss() + if(tox_heal) + tallydamage += L.getToxLoss() + if(hal_heal) + tallydamage += L.getHalLoss() + if(clone_heal) + tallydamage += L.getCloneLoss() + if(rad_heal) + tallydamage += L.radiation / 2 + + if(tallydamage < damcap) + return FALSE + +/obj/item/mecha_parts/mecha_equipment/crisis_drone/proc/shut_down() + if(enabled) + chassis.visible_message("\The [chassis]'s [src] buzzes as its drone returns to port.") + toggle_drone() + if(!isnull(Target)) + Target = null + if(MyBeam) + QDEL_NULL(MyBeam) + +/obj/item/mecha_parts/mecha_equipment/crisis_drone/proc/unique_patient_checks(var/mob/living/L) // Anything special for subtypes. Does it only work on Robots? Fleshies? A species? + . = TRUE + +/obj/item/mecha_parts/mecha_equipment/crisis_drone/proc/heal_target(var/mob/living/L) // We've done all our special checks, just get to fixing damage. + chassis.use_power(energy_drain) + if(istype(L)) + L.adjustBruteLoss(brute_heal * -1) + L.adjustFireLoss(burn_heal * -1) + L.adjustToxLoss(tox_heal * -1) + L.adjustOxyLoss(oxy_heal * -1) + L.adjustCloneLoss(clone_heal * -1) + L.adjustHalLoss(hal_heal * -1) + L.radiation = max(0, L.radiation - rad_heal) + + if(ishuman(L) && bone_heal) + var/mob/living/carbon/human/H = L + + if(H.bad_external_organs.len) + for(var/obj/item/organ/external/E in H.bad_external_organs) + if(prob(bone_heal)) + E.status &= ~ORGAN_BROKEN + +/obj/item/mecha_parts/mecha_equipment/crisis_drone/proc/toggle_drone() + ..() + if(chassis) + enabled = !enabled + if(enabled) + set_ready_state(0) + log_message("Activated.") + chassis.overlays += drone_overlay + else + set_ready_state(1) + log_message("Deactivated.") + chassis.overlays -= drone_overlay + +/obj/item/mecha_parts/mecha_equipment/crisis_drone/Topic(href, href_list) + ..() + if(href_list["toggle_drone"]) + toggle_drone() + return + +/obj/item/mecha_parts/mecha_equipment/crisis_drone/get_equip_info() + if(!chassis) return + return "* [src.name] - [enabled?"Dea":"A"]ctivate" + +/obj/item/mecha_parts/mecha_equipment/crisis_drone/rad + name = "hazmat dronebay" + desc = "A small shoulder-mounted dronebay containing a rapid response drone capable of purging a patient near the exosuit of radiation damage." + icon_state = "mecha_dronebay_rad" + + droid_state = "rad_drone" + beam_state = "g_beam" + + tox_heal = 0.5 + rad_heal = 5 + clone_heal = 0.2 + hal_heal = 0.2 + +/obj/item/mecha_parts/mecha_equipment/tool/powertool/medanalyzer + name = "mounted humanoid scanner" + desc = "An exosuit-mounted scanning device." + icon_state = "mecha_analyzer_health" + origin_tech = list(TECH_MATERIAL = 5, TECH_MAGNET = 5, TECH_BIO = 5) + equip_cooldown = 5 SECONDS + energy_drain = 100 + range = MELEE + equip_type = EQUIP_UTILITY + ready_sound = 'sound/weapons/flash.ogg' + required_type = list(/obj/mecha/medical) + + tooltype = /obj/item/device/healthanalyzer/advanced +>>>>>>> e749b79... Fixes mech projectile armor thinking test projectiles are dangerous (#6480):code/game/mecha/equipment/tools/syringe_gun.dm diff --git a/code/game/mecha/equipment/tools/teleporter.dm b/code/game/mecha/equipment/tools/teleporter.dm new file mode 100644 index 0000000000..b77b1c3fdc --- /dev/null +++ b/code/game/mecha/equipment/tools/teleporter.dm @@ -0,0 +1,20 @@ +/obj/item/mecha_parts/mecha_equipment/teleporter + name = "teleporter" + desc = "An exosuit module that allows exosuits to teleport to any position in view." + icon_state = "mecha_teleport" + origin_tech = list(TECH_BLUESPACE = 10) + equip_cooldown = 150 + energy_drain = 1000 + range = RANGED + + equip_type = EQUIP_SPECIAL + +/obj/item/mecha_parts/mecha_equipment/teleporter/action(atom/target) + if(!action_checks(target) || src.loc.z == 2) return + var/turf/T = get_turf(target) + if(T) + set_ready_state(0) + chassis.use_power(energy_drain) + do_teleport(chassis, T, 4) + do_after_cooldown() + return \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm index 73f7356ade..01aeca691d 100644 --- a/code/game/mecha/equipment/tools/tools.dm +++ b/code/game/mecha/equipment/tools/tools.dm @@ -1,1668 +1,2 @@ /obj/item/mecha_parts/mecha_equipment/tool - equip_type = EQUIP_UTILITY - -/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp - name = "hydraulic clamp" - icon_state = "mecha_clamp" - equip_cooldown = 15 - energy_drain = 10 - var/dam_force = 20 - var/obj/mecha/working/ripley/cargo_holder - required_type = list(/obj/mecha/working) - ready_sound = 'sound/mecha/gasdisconnected.ogg' - -/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp/attach(obj/mecha/M as obj) - ..() - cargo_holder = M - - return - -/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp/action(atom/target) - if(!action_checks(target)) return - if(!cargo_holder) return - - //loading - if(istype(target,/obj)) - var/obj/O = target - if(O.has_buckled_mobs()) - return - if(locate(/mob/living) in O) - occupant_message("You can't load living things into the cargo compartment.") - return - if(O.anchored) - if(enable_special) - if(istype(O, /obj/machinery/door/firedoor)) // I love doors. - var/obj/machinery/door/firedoor/FD = O - if(FD.blocked) - FD.visible_message("\The [chassis] begins prying on \the [FD]!") - if(do_after(chassis.occupant,10 SECONDS,FD)) - playsound(FD.loc, 'sound/machines/airlock_creaking.ogg', 100, 1) - FD.blocked = 0 - FD.update_icon() - FD.open(1) - FD.visible_message("\The [chassis] tears \the [FD] open!") - else if(FD.density) - FD.visible_message("\The [chassis] begins forcing \the [FD] open!") - if(do_after(chassis.occupant, 5 SECONDS,FD)) - playsound(FD.loc, 'sound/machines/airlock_creaking.ogg', 100, 1) - FD.visible_message("\The [chassis] forces \the [FD] open!") - FD.open(1) - else - FD.visible_message("\The [chassis] forces \the [FD] closed!") - FD.close(1) - else if(istype(O, /obj/machinery/door/airlock)) // D o o r s. - var/obj/machinery/door/airlock/AD = O - if(AD.locked) - occupant_message("The airlock's bolts prevent it from being forced.") - else if(!AD.operating) - if(AD.welded) - AD.visible_message("\The [chassis] begins prying on \the [AD]!") - if(do_after(chassis.occupant, 15 SECONDS,AD) && chassis.Adjacent(AD)) - AD.welded = FALSE - AD.update_icon() - playsound(AD.loc, 'sound/machines/airlock_creaking.ogg', 100, 1) - AD.visible_message("\The [chassis] tears \the [AD] open!") - if(!AD.welded) - if(density) - spawn(0) - AD.open(1) - else - spawn(0) - AD.close(1) - return - else - occupant_message("[target] is firmly secured.") - return - if(cargo_holder.cargo.len >= cargo_holder.cargo_capacity) - occupant_message("Not enough room in cargo compartment.") - return - - occupant_message("You lift [target] and start to load it into cargo compartment.") - chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.") - set_ready_state(0) - chassis.use_power(energy_drain) - O.anchored = 1 - var/T = chassis.loc - if(do_after_cooldown(target)) - if(T == chassis.loc && src == chassis.selected) - cargo_holder.cargo += O - O.loc = chassis - O.anchored = 0 - occupant_message("[target] succesfully loaded.") - log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") - else - occupant_message("You must hold still while handling objects.") - O.anchored = initial(O.anchored) - - //attacking - else if(istype(target,/mob/living)) - var/mob/living/M = target - if(M.stat>1) return - if(chassis.occupant.a_intent == I_HURT || istype(chassis.occupant,/mob/living/carbon/brain)) //No tactile feedback for brains - M.take_overall_damage(dam_force) - M.adjustOxyLoss(round(dam_force/2)) - M.updatehealth() - occupant_message("You squeeze [target] with [src.name]. Something cracks.") - playsound(src.loc, "fracture", 5, 1, -2) //CRACK - chassis.visible_message("[chassis] squeezes [target].") - else if(chassis.occupant.a_intent == I_DISARM && enable_special) - playsound(src.loc, 'sound/mecha/hydraulic.ogg', 10, 1, -2) - M.take_overall_damage(dam_force/2) - M.adjustOxyLoss(round(dam_force/3)) - M.updatehealth() - occupant_message("You slam [target] with [src.name]. Something cracks.") - playsound(src.loc, "fracture", 3, 1, -2) //CRACK 2 - chassis.visible_message("[chassis] slams [target].") - M.throw_at(get_step(M,get_dir(src, M)), 14, 1.5, chassis) - else - step_away(M,chassis) - occupant_message("You push [target] out of the way.") - chassis.visible_message("[chassis] pushes [target] out of the way.") - set_ready_state(0) - chassis.use_power(energy_drain) - do_after_cooldown() - return 1 - -/obj/item/mecha_parts/mecha_equipment/tool/drill - name = "drill" - desc = "This is the drill that'll pierce the heavens!" - icon_state = "mecha_drill" - equip_cooldown = 30 - energy_drain = 10 - force = 15 - required_type = list(/obj/mecha/working/ripley) - -/obj/item/mecha_parts/mecha_equipment/tool/drill/action(atom/target) - if(!action_checks(target)) return - if(isobj(target)) - var/obj/target_obj = target - if(!target_obj.vars.Find("unacidable") || target_obj.unacidable) return - set_ready_state(0) - chassis.use_power(energy_drain) - chassis.visible_message("[chassis] starts to drill [target]", "You hear the drill.") - occupant_message("You start to drill [target]") - var/T = chassis.loc - var/C = target.loc //why are these backwards? we may never know -Pete - if(do_after_cooldown(target)) - if(T == chassis.loc && src == chassis.selected) - if(istype(target, /turf/simulated/wall)) - var/turf/simulated/wall/W = target - if(W.reinf_material) - occupant_message("[target] is too durable to drill through.") - else - log_message("Drilled through [target]") - target.ex_act(2) - else if(istype(target, /turf/simulated/mineral)) - if(enable_special) - for(var/turf/simulated/mineral/M in range(chassis,1)) - if(get_dir(chassis,M)&chassis.dir) - M.GetDrilled() - else - var/turf/simulated/mineral/M1 = target - M1.GetDrilled() - log_message("Drilled through [target]") - if(locate(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp) in chassis.equipment) - var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo - if(ore_box) - for(var/obj/item/weapon/ore/ore in range(chassis,1)) - if(get_dir(chassis,ore)&chassis.dir) - ore.forceMove(ore_box) - else if(target.loc == C) - log_message("Drilled through [target]") - target.ex_act(2) - return 1 - -/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill - name = "diamond drill" - desc = "This is an upgraded version of the drill that'll pierce the heavens!" - icon_state = "mecha_diamond_drill" - origin_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3) - equip_cooldown = 10 - force = 15 - -/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill/action(atom/target) - if(!action_checks(target)) return - if(isobj(target)) - var/obj/target_obj = target - if(target_obj.unacidable) return - set_ready_state(0) - chassis.use_power(energy_drain) - chassis.visible_message("[chassis] starts to drill [target]", "You hear the drill.") - occupant_message("You start to drill [target]") - var/T = chassis.loc - var/C = target.loc //why are these backwards? we may never know -Pete - if(do_after_cooldown(target)) - if(T == chassis.loc && src == chassis.selected) - if(istype(target, /turf/simulated/wall)) - var/turf/simulated/wall/W = target - if(!W.reinf_material || do_after_cooldown(target))//To slow down how fast mechs can drill through the station - log_message("Drilled through [target]") - target.ex_act(3) - else if(istype(target, /turf/simulated/mineral)) - if(enable_special) - for(var/turf/simulated/mineral/M in range(chassis,1)) - if(get_dir(chassis,M)&chassis.dir) - M.GetDrilled() - else - var/turf/simulated/mineral/M1 = target - M1.GetDrilled() - log_message("Drilled through [target]") - if(locate(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp) in chassis.equipment) - var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo - if(ore_box) - for(var/obj/item/weapon/ore/ore in range(chassis,1)) - if(get_dir(chassis,ore)&chassis.dir) - ore.forceMove(ore_box) - else if(target.loc == C) - log_message("Drilled through [target]") - target.ex_act(2) - return 1 - -/obj/item/mecha_parts/mecha_equipment/tool/drill/bore - name = "depth bore" - desc = "This is the drill that'll pierce the depths!" - icon_state = "mecha_bore" - equip_cooldown = 5 SECONDS - energy_drain = 30 - force = 20 - required_type = list(/obj/mecha/working/ripley) - -/obj/item/mecha_parts/mecha_equipment/tool/drill/bore/action(atom/target) - if(!action_checks(target)) return - if(isobj(target)) - var/obj/target_obj = target - if(target_obj.unacidable) return - set_ready_state(0) - chassis.use_power(energy_drain) - chassis.visible_message("[chassis] starts to bore into \the [target]", "You hear the bore.") - occupant_message("You start to bore into \the [target]") - var/T = chassis.loc - var/C = target.loc - if(do_after_cooldown(target)) - if(T == chassis.loc && src == chassis.selected) - if(istype(target, /turf/simulated/wall)) - var/turf/simulated/wall/W = target - if(W.reinf_material) - occupant_message("[target] is too durable to bore through.") - else - log_message("Bored through [target]") - target.ex_act(2) - else if(istype(target, /turf/simulated/mineral)) - var/turf/simulated/mineral/M = target - if(enable_special && !M.density) - M.ex_act(2) - log_message("Bored into [target]") - else - M.GetDrilled() - log_message("Bored through [target]") - if(locate(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp) in chassis.equipment) - var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo - if(ore_box) - for(var/obj/item/weapon/ore/ore in range(chassis,1)) - if(get_dir(chassis,ore)&chassis.dir) - ore.forceMove(ore_box) - else if(target.loc == C) - log_message("Drilled through [target]") - target.ex_act(2) - return 1 - -/obj/item/mecha_parts/mecha_equipment/tool/orescanner - name = "mounted ore scanner" - desc = "An exosuit-mounted ore scanner." - icon_state = "mecha_analyzer" - origin_tech = list(TECH_MATERIAL = 2, TECH_MAGNET = 2, TECH_POWER = 2) - equip_cooldown = 5 - energy_drain = 30 - range = MELEE|RANGED - equip_type = EQUIP_SPECIAL - ready_sound = 'sound/items/goggles_charge.ogg' - required_type = list(/obj/mecha/working/ripley) - - var/obj/item/weapon/mining_scanner/my_scanner = null - var/exact_scan = FALSE - -/obj/item/mecha_parts/mecha_equipment/tool/orescanner/Initialize() - my_scanner = new(src) - return ..() - -/obj/item/mecha_parts/mecha_equipment/tool/orescanner/Destroy() - QDEL_NULL(my_scanner) - return ..() - -/obj/item/mecha_parts/mecha_equipment/tool/orescanner/action(var/atom/target) - if(!action_checks(target) || get_dist(chassis, target) > 5) - return FALSE - - if(!enable_special) - target = get_turf(chassis) - - var/datum/beam/ScanBeam = chassis.Beam(target,"g_beam",'icons/effects/beam.dmi',time=2 SECONDS,10,/obj/effect/ebeam,2) - - if(do_after(chassis.occupant, 2 SECONDS)) - my_scanner.ScanTurf(target, chassis.occupant, exact_scan) - - QDEL_NULL(ScanBeam) - -/obj/item/mecha_parts/mecha_equipment/tool/orescanner/advanced - name = "advanced ore scanner" - icon_state = "mecha_analyzer_adv" - exact_scan = TRUE - -/obj/item/mecha_parts/mecha_equipment/tool/extinguisher - name = "extinguisher" - desc = "Exosuit-mounted extinguisher (Can be attached to: Engineering exosuits)" - icon_state = "mecha_exting" - equip_cooldown = 5 - energy_drain = 0 - range = MELEE|RANGED - required_type = list(/obj/mecha/working) - var/spray_particles = 5 - var/spray_amount = 5 //units of liquid per particle. 5 is enough to wet the floor - it's a big fire extinguisher, so should be fine - var/max_water = 1000 - -/obj/item/mecha_parts/mecha_equipment/tool/extinguisher/Initialize() - . = ..() - reagents = new/datum/reagents(max_water) - reagents.my_atom = src - reagents.add_reagent("water", max_water) - -/obj/item/mecha_parts/mecha_equipment/tool/extinguisher/action(atom/target) //copypasted from extinguisher. TODO: Rewrite from scratch. - if(!action_checks(target) || get_dist(chassis, target)>3) return - if(get_dist(chassis, target)>2) return - set_ready_state(0) - if(do_after_cooldown(target)) - if( istype(target, /obj/structure/reagent_dispensers/watertank) && get_dist(chassis,target) <= 1) - var/obj/o = target - var/amount = o.reagents.trans_to_obj(src, 200) - occupant_message("[amount] units transferred into internal tank.") - playsound(chassis, 'sound/effects/refill.ogg', 50, 1, -6) - return - - if (src.reagents.total_volume < 1) - occupant_message("\The [src] is empty.") - return - - playsound(chassis, 'sound/effects/extinguish.ogg', 75, 1, -3) - - var/direction = get_dir(chassis,target) - - var/turf/T = get_turf(target) - var/turf/T1 = get_step(T,turn(direction, 90)) - var/turf/T2 = get_step(T,turn(direction, -90)) - - var/list/the_targets = list(T,T1,T2) - - for(var/a = 1 to 5) - spawn(0) - var/obj/effect/effect/water/W = new /obj/effect/effect/water(get_turf(chassis)) - var/turf/my_target - if(a == 1) - my_target = T - else if(a == 2) - my_target = T1 - else if(a == 3) - my_target = T2 - else - my_target = pick(the_targets) - W.create_reagents(5) - if(!W || !src) - return - reagents.trans_to_obj(W, spray_amount) - W.set_color() - W.set_up(my_target) - return 1 - -/obj/item/mecha_parts/mecha_equipment/tool/extinguisher/get_equip_info() - return "[..()] \[[src.reagents.total_volume]\]" - -/obj/item/mecha_parts/mecha_equipment/tool/extinguisher/on_reagent_change() - return - -/obj/item/mecha_parts/mecha_equipment/tool/powertool - name = "pneumatic wrench" - desc = "An exosuit-mounted hydraulic wrench." - icon_state = "mecha_wrench" - origin_tech = list(TECH_MATERIAL = 2, TECH_MAGNET = 2, TECH_POWER = 2) - equip_cooldown = 3 - energy_drain = 15 - range = MELEE - equip_type = EQUIP_UTILITY - ready_sound = 'sound/items/Ratchet.ogg' - required_type = list(/obj/mecha/working/ripley) - - var/obj/item/my_tool = null - var/tooltype = /obj/item/weapon/tool/wrench/power - -/obj/item/mecha_parts/mecha_equipment/tool/powertool/Initialize() - my_tool = new tooltype(src) - my_tool.name = name - my_tool.anchored = TRUE - my_tool.canremove = FALSE - return ..() - -/obj/item/mecha_parts/mecha_equipment/tool/powertool/Destroy() - QDEL_NULL(my_tool) - return ..() - -/obj/item/mecha_parts/mecha_equipment/tool/powertool/action(var/atom/target) - if(!action_checks(target)) - return FALSE - - if(isliving(target)) - my_tool.attack(target, chassis.occupant, BP_TORSO) - - target.attackby(my_tool,chassis.occupant) - -/obj/item/mecha_parts/mecha_equipment/tool/powertool/prybar - name = "pneumatic prybar" - desc = "An exosuit-mounted pneumatic prybar." - icon_state = "mecha_crowbar" - tooltype = /obj/item/weapon/tool/crowbar/power - ready_sound = 'sound/mecha/gasdisconnected.ogg' - -/obj/item/mecha_parts/mecha_equipment/tool/rcd - name = "mounted RCD" - desc = "An exosuit-mounted Rapid Construction Device. (Can be attached to: Any exosuit)" - icon_state = "mecha_rcd" - origin_tech = list(TECH_MATERIAL = 4, TECH_BLUESPACE = 3, TECH_MAGNET = 4, TECH_POWER = 4) - equip_cooldown = 10 - energy_drain = 250 - range = MELEE|RANGED - equip_type = EQUIP_SPECIAL - var/obj/item/weapon/rcd/electric/mounted/mecha/my_rcd = null - -/obj/item/mecha_parts/mecha_equipment/tool/rcd/Initialize() - my_rcd = new(src) - return ..() - -/obj/item/mecha_parts/mecha_equipment/tool/rcd/Destroy() - QDEL_NULL(my_rcd) - return ..() - -/obj/item/mecha_parts/mecha_equipment/tool/rcd/action(atom/target) - if(!action_checks(target) || get_dist(chassis, target) > 3) - return FALSE - - my_rcd.use_rcd(target, chassis.occupant) - -/obj/item/mecha_parts/mecha_equipment/tool/rcd/Topic(href,href_list) - ..() - if(href_list["mode"]) - my_rcd.mode_index = text2num(href_list["mode"]) - occupant_message("RCD reconfigured to '[my_rcd.modes[my_rcd.mode_index]]'.") -/* -/obj/item/mecha_parts/mecha_equipment/tool/rcd/get_equip_info() - return "[..()] \[D|C|A\]" -*/ -/obj/item/mecha_parts/mecha_equipment/tool/rcd/get_equip_info() - var/list/content = list(..()) // This is all for one line, in the interest of string tree conservation. - var/i = 1 - content += "
" - for(var/mode in my_rcd.modes) - content += " [mode]" - if(i < my_rcd.modes.len) - content += "
" - i++ - - return content.Join() - - -/obj/item/mecha_parts/mecha_equipment/teleporter - name = "teleporter" - desc = "An exosuit module that allows exosuits to teleport to any position in view." - icon_state = "mecha_teleport" - origin_tech = list(TECH_BLUESPACE = 10) - equip_cooldown = 150 - energy_drain = 1000 - range = RANGED - - equip_type = EQUIP_SPECIAL - -/obj/item/mecha_parts/mecha_equipment/teleporter/action(atom/target) - if(!action_checks(target) || src.loc.z == 2) return - var/turf/T = get_turf(target) - if(T) - set_ready_state(0) - chassis.use_power(energy_drain) - do_teleport(chassis, T, 4) - do_after_cooldown() - return - - -/obj/item/mecha_parts/mecha_equipment/wormhole_generator - name = "wormhole generator" - desc = "An exosuit module that allows generating of small quasi-stable wormholes." - icon_state = "mecha_wholegen" - origin_tech = list(TECH_BLUESPACE = 3) - equip_cooldown = 50 - energy_drain = 300 - range = RANGED - - equip_type = EQUIP_SPECIAL - -/obj/item/mecha_parts/mecha_equipment/wormhole_generator/action(atom/target) - if(!action_checks(target) || src.loc.z == 2) return - var/list/theareas = list() - for(var/area/AR in orange(100, chassis)) - if(AR in theareas) continue - theareas += AR - if(!theareas.len) - return - var/area/thearea = pick(theareas) - var/list/L = list() - var/turf/pos = get_turf(src) - for(var/turf/T in get_area_turfs(thearea.type)) - if(!T.density && pos.z == T.z) - var/clear = 1 - for(var/obj/O in T) - if(O.density) - clear = 0 - break - if(clear) - L+=T - if(!L.len) - return - var/turf/target_turf = pick(L) - if(!target_turf) - return - chassis.use_power(energy_drain) - set_ready_state(0) - var/obj/effect/portal/P = new /obj/effect/portal(get_turf(target)) - P.target = target_turf - P.creator = null - P.icon = 'icons/obj/objects.dmi' - P.failchance = 0 - P.icon_state = "anom" - P.name = "wormhole" - do_after_cooldown() - src = null - spawn(rand(150,300)) - qdel(P) - return - -/obj/item/mecha_parts/mecha_equipment/gravcatapult - name = "gravitational catapult" - desc = "An exosuit mounted gravitational catapult." - icon_state = "mecha_teleport" - origin_tech = list(TECH_BLUESPACE = 2, TECH_MAGNET = 3) - equip_cooldown = 10 - energy_drain = 100 - range = MELEE|RANGED - var/atom/movable/locked - var/mode = 1 //1 - gravsling 2 - gravpush - - var/last_fired = 0 //Concept stolen from guns. - var/fire_delay = 10 //Used to prevent spam-brute against humans. - - equip_type = EQUIP_UTILITY - -/obj/item/mecha_parts/mecha_equipment/gravcatapult/action(atom/movable/target) - - if(world.time >= last_fired + fire_delay) - last_fired = world.time - else - if (world.time % 3) - occupant_message("[src] is not ready to fire again!") - return 0 - - switch(mode) - if(1) - if(!action_checks(target) && !locked) return - if(!locked) - if(!istype(target) || target.anchored) - occupant_message("Unable to lock on [target]") - return - locked = target - occupant_message("Locked on [target]") - send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) - return - else if(target!=locked) - if(locked in view(chassis)) - locked.throw_at(target, 14, 1.5, chassis) - locked = null - send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) - set_ready_state(0) - chassis.use_power(energy_drain) - do_after_cooldown() - else - locked = null - occupant_message("Lock on [locked] disengaged.") - send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) - if(2) - if(!action_checks(target)) return - var/list/atoms = list() - if(isturf(target)) - atoms = range(target,3) - else - atoms = orange(target,3) - for(var/atom/movable/A in atoms) - if(A.anchored) continue - spawn(0) - var/iter = 5-get_dist(A,target) - for(var/i=0 to iter) - step_away(A,target) - sleep(2) - set_ready_state(0) - chassis.use_power(energy_drain) - do_after_cooldown() - return - -/obj/item/mecha_parts/mecha_equipment/gravcatapult/get_equip_info() - return "[..()] [mode==1?"([locked||"Nothing"])":null] \[S|P\]" - -/obj/item/mecha_parts/mecha_equipment/gravcatapult/Topic(href, href_list) - ..() - if(href_list["mode"]) - mode = text2num(href_list["mode"]) - send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) - return - - -/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster //what is that noise? A BAWWW from TK mutants. - name = "\improper CCW armor booster" - desc = "Close-combat armor booster. Boosts exosuit armor against armed melee attacks. Requires energy to operate." - icon_state = "mecha_abooster_ccw" - origin_tech = list(TECH_MATERIAL = 3) - equip_cooldown = 10 - energy_drain = 50 - range = 0 - var/deflect_coeff = 1.15 - var/damage_coeff = 0.8 - - equip_type = EQUIP_HULL - -/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/can_attach(obj/mecha/M as obj) - if(..()) - if(!M.proc_res["dynattackby"]) - return 1 - return 0 - -/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/attach(obj/mecha/M as obj) - ..() - chassis.proc_res["dynattackby"] = src - return - -/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/detach() - chassis.proc_res["dynattackby"] = null - ..() - return - -/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/get_equip_info() - if(!chassis) return - return "* [src.name]" - -/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/proc/dynattackby(obj/item/weapon/W as obj, mob/user as mob) - if(!action_checks(user)) - return chassis.dynattackby(W,user) - chassis.log_message("Attacked by [W]. Attacker - [user]") - if(prob(chassis.deflect_chance*deflect_coeff)) - user << "\The [W] bounces off [chassis] armor." - chassis.log_append_to_last("Armor saved.") - else - chassis.occupant_message("\The [user] hits [chassis] with [W].") - user.visible_message("\The [user] hits [chassis] with [W].", "You hit [src] with [W].") - chassis.take_damage(round(W.force*damage_coeff),W.damtype) - chassis.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) - set_ready_state(0) - chassis.use_power(energy_drain) - do_after_cooldown() - return - - -/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster - name = "\improper RW armor booster" - desc = "Ranged-weaponry armor booster. Boosts exosuit armor against ranged attacks. Completely blocks taser shots, but requires energy to operate." - icon_state = "mecha_abooster_proj" - origin_tech = list(TECH_MATERIAL = 4) - equip_cooldown = 10 - energy_drain = 50 - range = 0 - var/deflect_coeff = 1.15 - var/damage_coeff = 0.8 - - equip_type = EQUIP_HULL - -/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/can_attach(obj/mecha/M as obj) - if(..()) - if(!M.proc_res["dynbulletdamage"] && !M.proc_res["dynhitby"]) - return 1 - return 0 - -/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/attach(obj/mecha/M as obj) - ..() - chassis.proc_res["dynbulletdamage"] = src - chassis.proc_res["dynhitby"] = src - return - -/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/detach() - chassis.proc_res["dynbulletdamage"] = null - chassis.proc_res["dynhitby"] = null - ..() - return - -/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/get_equip_info() - if(!chassis) return - return "* [src.name]" - -/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/proc/dynbulletdamage(var/obj/item/projectile/Proj) - if(!action_checks(src)) - return chassis.dynbulletdamage(Proj) - if(prob(chassis.deflect_chance*deflect_coeff)) - chassis.occupant_message("The armor deflects incoming projectile.") - chassis.visible_message("The [chassis.name] armor deflects the projectile") - chassis.log_append_to_last("Armor saved.") - else - chassis.take_damage(round(Proj.damage*src.damage_coeff),Proj.check_armour) - chassis.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) - Proj.on_hit(chassis) - set_ready_state(0) - chassis.use_power(energy_drain) - do_after_cooldown() - return - -/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/proc/dynhitby(atom/movable/A) - if(!action_checks(A)) - return chassis.dynhitby(A) - if(prob(chassis.deflect_chance*deflect_coeff) || istype(A, /mob/living) || istype(A, /obj/item/mecha_parts/mecha_tracking)) - chassis.occupant_message("The [A] bounces off the armor.") - chassis.visible_message("The [A] bounces off the [chassis] armor") - chassis.log_append_to_last("Armor saved.") - if(istype(A, /mob/living)) - var/mob/living/M = A - M.take_organ_damage(10) - else if(istype(A, /obj)) - var/obj/O = A - if(O.throwforce) - chassis.take_damage(round(O.throwforce*damage_coeff)) - chassis.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) - set_ready_state(0) - chassis.use_power(energy_drain) - do_after_cooldown() - return - - -/obj/item/mecha_parts/mecha_equipment/repair_droid - name = "repair droid" - desc = "Automated repair droid. Scans exosuit for damage and repairs it. Can fix almost any type of external or internal damage." - icon_state = "repair_droid" - origin_tech = list(TECH_MAGNET = 3, TECH_DATA = 3) - equip_cooldown = 20 - energy_drain = 100 - range = 0 - var/health_boost = 2 - var/datum/global_iterator/pr_repair_droid - var/icon/droid_overlay - var/list/repairable_damage = list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH) - - equip_type = EQUIP_HULL - -/obj/item/mecha_parts/mecha_equipment/repair_droid/New() - ..() - pr_repair_droid = new /datum/global_iterator/mecha_repair_droid(list(src),0) - pr_repair_droid.set_delay(equip_cooldown) - return - -/obj/item/mecha_parts/mecha_equipment/repair_droid/Destroy() - qdel(pr_repair_droid) - pr_repair_droid = null - ..() - -/obj/item/mecha_parts/mecha_equipment/repair_droid/attach(obj/mecha/M as obj) - ..() - droid_overlay = new(src.icon, icon_state = "repair_droid") - M.overlays += droid_overlay - return - -/obj/item/mecha_parts/mecha_equipment/repair_droid/destroy() - chassis.overlays -= droid_overlay - ..() - return - -/obj/item/mecha_parts/mecha_equipment/repair_droid/detach() - chassis.overlays -= droid_overlay - pr_repair_droid.stop() - ..() - return - -/obj/item/mecha_parts/mecha_equipment/repair_droid/get_equip_info() - if(!chassis) return - return "* [src.name] - [pr_repair_droid.active()?"Dea":"A"]ctivate" - - -/obj/item/mecha_parts/mecha_equipment/repair_droid/Topic(href, href_list) - ..() - if(href_list["toggle_repairs"]) - chassis.overlays -= droid_overlay - if(pr_repair_droid.toggle()) - droid_overlay = new(src.icon, icon_state = "repair_droid_a") - log_message("Activated.") - else - droid_overlay = new(src.icon, icon_state = "repair_droid") - log_message("Deactivated.") - set_ready_state(1) - chassis.overlays += droid_overlay - send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) - return - - -/datum/global_iterator/mecha_repair_droid - -/datum/global_iterator/mecha_repair_droid/process(var/obj/item/mecha_parts/mecha_equipment/repair_droid/RD as obj) - if(!RD.chassis) - stop() - RD.set_ready_state(1) - return - var/health_boost = RD.health_boost - var/repaired = 0 - if(RD.chassis.hasInternalDamage(MECHA_INT_SHORT_CIRCUIT)) - health_boost *= -2 - else if(RD.chassis.hasInternalDamage() && prob(15)) - for(var/int_dam_flag in RD.repairable_damage) - if(RD.chassis.hasInternalDamage(int_dam_flag)) - RD.chassis.clearInternalDamage(int_dam_flag) - repaired = 1 - break - if(health_boost<0 || RD.chassis.health < initial(RD.chassis.health)) - RD.chassis.health += min(health_boost, initial(RD.chassis.health)-RD.chassis.health) - repaired = 1 - if(repaired) - if(RD.chassis.use_power(RD.energy_drain)) - RD.set_ready_state(0) - else - stop() - RD.set_ready_state(1) - return - else - RD.set_ready_state(1) - return - - -/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay - name = "energy relay" - desc = "Wirelessly drains energy from any available power channel in area. The performance index is quite low." - icon_state = "tesla" - origin_tech = list(TECH_MAGNET = 4, TECH_ILLEGAL = 2) - equip_cooldown = 10 - energy_drain = 0 - range = 0 - var/datum/global_iterator/pr_energy_relay - var/coeff = 100 - var/list/use_channels = list(EQUIP,ENVIRON,LIGHT) - - equip_type = EQUIP_UTILITY - -/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/New() - ..() - pr_energy_relay = new /datum/global_iterator/mecha_energy_relay(list(src),0) - pr_energy_relay.set_delay(equip_cooldown) - return - -/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/Destroy() - qdel(pr_energy_relay) - pr_energy_relay = null - ..() - -/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/detach() - pr_energy_relay.stop() -// chassis.proc_res["dynusepower"] = null - chassis.proc_res["dyngetcharge"] = null - ..() - return - -/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/attach(obj/mecha/M) - ..() - chassis.proc_res["dyngetcharge"] = src -// chassis.proc_res["dynusepower"] = src - return - -/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/can_attach(obj/mecha/M) - if(..()) - if(!M.proc_res["dyngetcharge"])// && !M.proc_res["dynusepower"]) - return 1 - return 0 - -/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/dyngetcharge() - if(equip_ready) //disabled - return chassis.dyngetcharge() - var/area/A = get_area(chassis) - var/pow_chan = get_power_channel(A) - var/charge = 0 - if(pow_chan) - charge = 1000 //making magic - else - return chassis.dyngetcharge() - return charge - -/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/get_power_channel(var/area/A) - var/pow_chan - if(A) - for(var/c in use_channels) - if(A.powered(c)) - pow_chan = c - break - return pow_chan - -/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/Topic(href, href_list) - ..() - if(href_list["toggle_relay"]) - if(pr_energy_relay.toggle()) - set_ready_state(0) - log_message("Activated.") - else - set_ready_state(1) - log_message("Deactivated.") - return - -/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/get_equip_info() - if(!chassis) return - return "* [src.name] - [pr_energy_relay.active()?"Dea":"A"]ctivate" - -/* proc/dynusepower(amount) - if(!equip_ready) //enabled - var/area/A = get_area(chassis) - var/pow_chan = get_power_channel(A) - if(pow_chan) - A.master.use_power(amount*coeff, pow_chan) - return 1 - return chassis.dynusepower(amount)*/ - -/datum/global_iterator/mecha_energy_relay - -/datum/global_iterator/mecha_energy_relay/process(var/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/ER) - if(!ER.chassis || ER.chassis.hasInternalDamage(MECHA_INT_SHORT_CIRCUIT)) - stop() - ER.set_ready_state(1) - return - var/cur_charge = ER.chassis.get_charge() - if(isnull(cur_charge) || !ER.chassis.cell) - stop() - ER.set_ready_state(1) - ER.occupant_message("No powercell detected.") - return - if(cur_charge* [src.name] - [my_shield.active?"Dea":"A"]ctivate" - - -/obj/item/mecha_parts/mecha_equipment/generator - name = "phoron generator" - desc = "Generates power using solid phoron as fuel. Pollutes the environment." - icon_state = "tesla" - origin_tech = list(TECH_PHORON = 2, TECH_POWER = 2, TECH_ENGINEERING = 1) - equip_cooldown = 10 - energy_drain = 0 - range = MELEE - var/datum/global_iterator/pr_mech_generator - var/coeff = 100 - var/obj/item/stack/material/fuel - var/max_fuel = 150000 - var/fuel_per_cycle_idle = 100 - var/fuel_per_cycle_active = 500 - var/power_per_cycle = 20 - - equip_type = EQUIP_UTILITY - -/obj/item/mecha_parts/mecha_equipment/generator/New() - ..() - init() - return - -/obj/item/mecha_parts/mecha_equipment/generator/Destroy() - qdel(pr_mech_generator) - pr_mech_generator = null - ..() - -/obj/item/mecha_parts/mecha_equipment/generator/proc/init() - fuel = new /obj/item/stack/material/phoron(src) - fuel.amount = 0 - pr_mech_generator = new /datum/global_iterator/mecha_generator(list(src),0) - pr_mech_generator.set_delay(equip_cooldown) - return - -/obj/item/mecha_parts/mecha_equipment/generator/detach() - pr_mech_generator.stop() - ..() - return - - -/obj/item/mecha_parts/mecha_equipment/generator/Topic(href, href_list) - ..() - if(href_list["toggle"]) - if(pr_mech_generator.toggle()) - set_ready_state(0) - log_message("Activated.") - else - set_ready_state(1) - log_message("Deactivated.") - return - -/obj/item/mecha_parts/mecha_equipment/generator/get_equip_info() - var/output = ..() - if(output) - return "[output] \[[fuel]: [round(fuel.amount*fuel.perunit,0.1)] cm3\] - [pr_mech_generator.active()?"Dea":"A"]ctivate" - return - -/obj/item/mecha_parts/mecha_equipment/generator/action(target) - if(chassis) - var/result = load_fuel(target) - var/message - if(isnull(result)) - message = "[fuel] traces in target minimal. [target] cannot be used as fuel." - else if(!result) - message = "Unit is full." - else - message = "[result] unit\s of [fuel] successfully loaded." - send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) - occupant_message(message) - return - -/obj/item/mecha_parts/mecha_equipment/generator/proc/load_fuel(var/obj/item/stack/material/P) - if(P.type == fuel.type && P.amount) - var/to_load = max(max_fuel - fuel.amount*fuel.perunit,0) - if(to_load) - var/units = min(max(round(to_load / P.perunit),1),P.amount) - if(units) - fuel.amount += units - P.use(units) - return units - else - return 0 - return - -/obj/item/mecha_parts/mecha_equipment/generator/attackby(weapon,mob/user) - var/result = load_fuel(weapon) - if(isnull(result)) - user.visible_message("[user] tries to shove [weapon] into [src]. What a dumb-ass.","[fuel] traces minimal. [weapon] cannot be used as fuel.") - else if(!result) - user << "Unit is full." - else - user.visible_message("[user] loads [src] with [fuel].","[result] unit\s of [fuel] successfully loaded.") - return - -/obj/item/mecha_parts/mecha_equipment/generator/critfail() - ..() - var/turf/simulated/T = get_turf(src) - if(!T) - return - var/datum/gas_mixture/GM = new - if(prob(10)) - T.assume_gas("phoron", 100, 1500+T0C) - T.visible_message("The [src] suddenly disgorges a cloud of heated phoron.") - destroy() - else - T.assume_gas("phoron", 5, istype(T) ? T.air.temperature : T20C) - T.visible_message("The [src] suddenly disgorges a cloud of phoron.") - T.assume_air(GM) - return - -/datum/global_iterator/mecha_generator - -/datum/global_iterator/mecha_generator/process(var/obj/item/mecha_parts/mecha_equipment/generator/EG) - if(!EG.chassis) - stop() - EG.set_ready_state(1) - return 0 - if(EG.fuel.amount<=0) - stop() - EG.log_message("Deactivated - no fuel.") - EG.set_ready_state(1) - return 0 - var/cur_charge = EG.chassis.get_charge() - if(isnull(cur_charge)) - EG.set_ready_state(1) - EG.occupant_message("No powercell detected.") - EG.log_message("Deactivated.") - stop() - return 0 - var/use_fuel = EG.fuel_per_cycle_idle - if(cur_charge[target] succesfully loaded.") - chassis.log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") - else - chassis.occupant_message("You must hold still while handling objects.") - O.anchored = initial(O.anchored) - else - chassis.occupant_message("Not enough room in cargo compartment.") - else - chassis.occupant_message("[target] is firmly secured.") - - else if(istype(target,/mob/living)) - var/mob/living/M = target - if(M.stat>1) return - if(chassis.occupant.a_intent == I_HURT) - chassis.occupant_message("You obliterate [target] with [src.name], leaving blood and guts everywhere.") - chassis.visible_message("[chassis] destroys [target] in an unholy fury.") - if(chassis.occupant.a_intent == I_DISARM) - chassis.occupant_message("You tear [target]'s limbs off with [src.name].") - chassis.visible_message("[chassis] rips [target]'s arms off.") - else - step_away(M,chassis) - chassis.occupant_message("You smash into [target], sending them flying.") - chassis.visible_message("[chassis] tosses [target] like a piece of paper.") - set_ready_state(0) - chassis.use_power(energy_drain) - do_after_cooldown() - return 1 - -/obj/item/mecha_parts/mecha_equipment/tool/passenger - name = "passenger compartment" - desc = "A mountable passenger compartment for exosuits. Rather cramped." - icon_state = "mecha_abooster_ccw" - origin_tech = list(TECH_ENGINEERING = 1, TECH_BIO = 1) - energy_drain = 10 - range = MELEE - equip_cooldown = 20 - var/mob/living/carbon/occupant = null - var/door_locked = 1 - salvageable = 0 - allow_duplicate = TRUE - - equip_type = EQUIP_HULL - -/obj/item/mecha_parts/mecha_equipment/tool/passenger/destroy() - for(var/atom/movable/AM in src) - AM.forceMove(get_turf(src)) - AM << "You tumble out of the destroyed [src.name]!" - return ..() - -/obj/item/mecha_parts/mecha_equipment/tool/passenger/Exit(atom/movable/O) - return 0 - -/obj/item/mecha_parts/mecha_equipment/tool/passenger/proc/move_inside(var/mob/user) - if (chassis) - chassis.visible_message("[user] starts to climb into [chassis].") - - if(do_after(user, 40, needhand=0)) - if(!src.occupant) - user.forceMove(src) - occupant = user - log_message("[user] boarded.") - occupant_message("[user] boarded.") - else if(src.occupant != user) - to_chat(user, "[src.occupant] was faster. Try harder next time, loser.") - else - to_chat(user, "You stop entering the exosuit.") - -/obj/item/mecha_parts/mecha_equipment/tool/passenger/verb/eject() - set name = "Eject" - set category = "Exosuit Interface" - set src = usr.loc - set popup_menu = 0 - - if(usr != occupant) - return - to_chat(occupant, "You climb out from \the [src].") - go_out() - occupant_message("[occupant] disembarked.") - log_message("[occupant] disembarked.") - add_fingerprint(usr) - -/obj/item/mecha_parts/mecha_equipment/tool/passenger/proc/go_out() - if(!occupant) - return - occupant.forceMove(get_turf(src)) - occupant.reset_view() - /* - if(occupant.client) - occupant.client.eye = occupant.client.mob - occupant.client.perspective = MOB_PERSPECTIVE - */ - occupant = null - return - -/obj/item/mecha_parts/mecha_equipment/tool/passenger/attach() - ..() - if (chassis) - chassis.verbs |= /obj/mecha/proc/move_inside_passenger - -/obj/item/mecha_parts/mecha_equipment/tool/passenger/detach() - if(occupant) - occupant_message("Unable to detach [src] - equipment occupied.") - return - - var/obj/mecha/M = chassis - ..() - if (M && !(locate(/obj/item/mecha_parts/mecha_equipment/tool/passenger) in M)) - M.verbs -= /obj/mecha/proc/move_inside_passenger - -/obj/item/mecha_parts/mecha_equipment/tool/passenger/get_equip_info() - return "[..()]
[occupant? "\[Occupant: [occupant]\]|" : ""]Exterior Hatch: Toggle Lock" - -/obj/item/mecha_parts/mecha_equipment/tool/passenger/Topic(href,href_list) - ..() - if (href_list["toggle_lock"]) - door_locked = !door_locked - occupant_message("Passenger compartment hatch [door_locked? "locked" : "unlocked"].") - if (chassis) - chassis.visible_message("The hatch on \the [chassis] [door_locked? "locks" : "unlocks"].", "You hear something latching.") - - -#define LOCKED 1 -#define OCCUPIED 2 - -/obj/mecha/proc/move_inside_passenger() - set category = "Object" - set name = "Enter Passenger Compartment" - set src in oview(1) - - //check that usr can climb in - if (usr.stat || !ishuman(usr)) - return - - if (!usr.Adjacent(src)) - return - - if (!isturf(usr.loc)) - usr << "You can't reach the passenger compartment from here." - return - - if(iscarbon(usr)) - var/mob/living/carbon/C = usr - if(C.handcuffed) - usr << "Kinda hard to climb in while handcuffed don't you think?" - return - - if(isliving(usr)) - var/mob/living/L = usr - if(L.has_buckled_mobs()) - to_chat(L, span("warning", "You have other entities attached to yourself. Remove them first.")) - return - - //search for a valid passenger compartment - var/feedback = 0 //for nicer user feedback - for(var/obj/item/mecha_parts/mecha_equipment/tool/passenger/P in src) - if (P.occupant) - feedback |= OCCUPIED - continue - if (P.door_locked) - feedback |= LOCKED - continue - - //found a boardable compartment - P.move_inside(usr) - return - - //didn't find anything - switch (feedback) - if (OCCUPIED) - usr << "The passenger compartment is already occupied!" - if (LOCKED) - usr << "The passenger compartment hatch is locked!" - if (OCCUPIED|LOCKED) - usr << "All of the passenger compartments are already occupied or locked!" - if (0) - usr << "\The [src] doesn't have a passenger compartment." - -#undef LOCKED -#undef OCCUPIED - -/obj/item/mecha_parts/mecha_equipment/tool/jetpack - name = "ion jetpack" - desc = "Using directed ion bursts and cunning solar wind reflection technique, this device enables controlled space flight." - icon_state = "mecha_jetpack" - equip_cooldown = 5 - energy_drain = 50 - var/wait = 0 - var/datum/effect/effect/system/ion_trail_follow/ion_trail - - -/obj/item/mecha_parts/mecha_equipment/tool/jetpack/can_attach(obj/mecha/M as obj) - if(!(locate(src.type) in M.equipment) && !M.proc_res["dyndomove"]) - return ..() - -/obj/item/mecha_parts/mecha_equipment/tool/jetpack/detach() - ..() - chassis.proc_res["dyndomove"] = null - return - -/obj/item/mecha_parts/mecha_equipment/tool/jetpack/attach(obj/mecha/M as obj) - ..() - if(!ion_trail) - ion_trail = new - ion_trail.set_up(chassis) - return - -/obj/item/mecha_parts/mecha_equipment/tool/jetpack/proc/toggle() - if(!chassis) - return - !equip_ready? turn_off() : turn_on() - return equip_ready - -/obj/item/mecha_parts/mecha_equipment/tool/jetpack/proc/turn_on() - set_ready_state(0) - chassis.proc_res["dyndomove"] = src - ion_trail.start() - occupant_message("Activated") - log_message("Activated") - -/obj/item/mecha_parts/mecha_equipment/tool/jetpack/proc/turn_off() - set_ready_state(1) - chassis.proc_res["dyndomove"] = null - ion_trail.stop() - occupant_message("Deactivated") - log_message("Deactivated") - -/obj/item/mecha_parts/mecha_equipment/tool/jetpack/proc/dyndomove(direction) - if(!action_checks()) - return chassis.dyndomove(direction) - var/move_result = 0 - if(chassis.hasInternalDamage(MECHA_INT_CONTROL_LOST)) - move_result = step_rand(chassis) - else if(chassis.dir!=direction) - chassis.set_dir(direction) - move_result = 1 - else - move_result = step(chassis,direction) - if(chassis.occupant) - for(var/obj/effect/speech_bubble/B in range(1, chassis)) - if(B.parent == chassis.occupant) - B.loc = chassis.loc - if(move_result) - wait = 1 - chassis.use_power(energy_drain) - if(!chassis.pr_inertial_movement.active()) - chassis.pr_inertial_movement.start(list(chassis,direction)) - else - chassis.pr_inertial_movement.set_process_args(list(chassis,direction)) - do_after_cooldown() - return 1 - return 0 - -/obj/item/mecha_parts/mecha_equipment/tool/jetpack/action_checks() - if(equip_ready || wait) - return 0 - if(energy_drain && !chassis.has_charge(energy_drain)) - return 0 - if(chassis.check_for_support()) - return 0 - return 1 - -/obj/item/mecha_parts/mecha_equipment/tool/jetpack/get_equip_info() - if(!chassis) return - return "* [src.name] \[Toggle\]" - -/obj/item/mecha_parts/mecha_equipment/tool/jetpack/Topic(href,href_list) - ..() - if(href_list["toggle"]) - toggle() - -/obj/item/mecha_parts/mecha_equipment/tool/jetpack/do_after_cooldown() - sleep(equip_cooldown) - wait = 0 - return 1 - -/obj/item/mecha_parts/mecha_equipment/speedboost - name = "ripley leg actuator overdrive" - desc = "System enhancements and overdrives to make a ripley's legs move faster." - icon_state = "tesla" - origin_tech = list( TECH_POWER = 5, TECH_MATERIAL = 4, TECH_ENGINEERING = 4) - required_type = list(/obj/mecha/working/ripley) - - equip_type = EQUIP_HULL - -/obj/item/mecha_parts/mecha_equipment/speedboost/attach(obj/mecha/M as obj) - ..() - if(enable_special) - chassis.step_in = (chassis.step_in-2) // Make the ripley as fast as a durand - else - chassis.step_in = (chassis.step_in+1) // Improper parts slow the mech down - return - -/obj/item/mecha_parts/mecha_equipment/speedboost/detach() - chassis.step_in = initial(chassis.step_in) - ..() - return - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer - name = "Cable Layer" - icon_state = "mecha_wire" - var/turf/old_turf - var/obj/structure/cable/last_piece - var/obj/item/stack/cable_coil/cable - var/max_cable = 1000 - required_type = list(/obj/mecha/working) - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/New() - cable = new(src) - cable.amount = 0 - ..() - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/MoveAction() - layCable() - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/action(var/obj/item/stack/cable_coil/target) - if(!action_checks(target)) - return - var/result = load_cable(target) - var/message - if(isnull(result)) - message = "Unable to load [target] - no cable found." - else if(!result) - message = "Reel is full." - else - message = "[result] meters of cable successfully loaded." - send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) - occupant_message(message) - return - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/Topic(href,href_list) - ..() - if(href_list["toggle"]) - set_ready_state(!equip_ready) - occupant_message("[src] [equip_ready?"dea":"a"]ctivated.") - log_message("[equip_ready?"Dea":"A"]ctivated.") - return - if(href_list["cut"]) - if(cable && cable.amount) - var/m = round(input(chassis.occupant,"Please specify the length of cable to cut","Cut cable",min(cable.amount,30)) as num, 1) - m = min(m, cable.amount) - if(m) - use_cable(m) - var/obj/item/stack/cable_coil/CC = new (get_turf(chassis)) - CC.amount = m - else - occupant_message("There's no more cable on the reel.") - return - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/get_equip_info() - var/output = ..() - if(output) - return "[output] \[Cable: [cable ? cable.amount : 0] m\][(cable && cable.amount) ? "- [!equip_ready?"Dea":"A"]ctivate|Cut" : null]" - return - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/load_cable(var/obj/item/stack/cable_coil/CC) - if(istype(CC) && CC.amount) - var/cur_amount = cable? cable.amount : 0 - var/to_load = max(max_cable - cur_amount,0) - if(to_load) - to_load = min(CC.amount, to_load) - if(!cable) - cable = new(src) - cable.amount = 0 - cable.amount += to_load - CC.use(to_load) - return to_load - else - return 0 - return - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/use_cable(amount) - if(!cable || cable.amount<1) - set_ready_state(1) - occupant_message("Cable depleted, [src] deactivated.") - log_message("Cable depleted, [src] deactivated.") - return - if(cable.amount < amount) - occupant_message("No enough cable to finish the task.") - return - cable.use(amount) - update_equip_info() - return 1 - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/reset() - last_piece = null - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/dismantleFloor(var/turf/new_turf) - new_turf = get_turf(chassis) - if(istype(new_turf, /turf/simulated/floor)) - var/turf/simulated/floor/T = new_turf - if(!T.is_plating()) - T.make_plating(!(T.broken || T.burnt)) - return new_turf.is_plating() - -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/layCable(var/turf/new_turf) - new_turf = get_turf(chassis) - if(equip_ready || !istype(new_turf, /turf/simulated/floor) || !dismantleFloor(new_turf)) - return reset() - var/fdirn = turn(chassis.dir,180) - for(var/obj/structure/cable/LC in new_turf) // check to make sure there's not a cable there already - if(LC.d1 == fdirn || LC.d2 == fdirn) - return reset() - if(!use_cable(1)) - return reset() - var/obj/structure/cable/NC = new(new_turf) - NC.cableColor("red") - NC.d1 = 0 - NC.d2 = fdirn - NC.update_icon() - - var/datum/powernet/PN - if(last_piece && last_piece.d2 != chassis.dir) - last_piece.d1 = min(last_piece.d2, chassis.dir) - last_piece.d2 = max(last_piece.d2, chassis.dir) - last_piece.update_icon() - PN = last_piece.powernet - - if(!PN) - PN = new() - PN.add_cable(NC) - NC.mergeConnectedNetworks(NC.d2) - - //NC.mergeConnectedNetworksOnTurf() - last_piece = NC - return 1 \ No newline at end of file + equip_type = EQUIP_UTILITY \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/wormhole.dm b/code/game/mecha/equipment/tools/wormhole.dm new file mode 100644 index 0000000000..eef3c6a52a --- /dev/null +++ b/code/game/mecha/equipment/tools/wormhole.dm @@ -0,0 +1,50 @@ +/obj/item/mecha_parts/mecha_equipment/wormhole_generator + name = "wormhole generator" + desc = "An exosuit module that allows generating of small quasi-stable wormholes." + icon_state = "mecha_wholegen" + origin_tech = list(TECH_BLUESPACE = 3) + equip_cooldown = 50 + energy_drain = 300 + range = RANGED + + equip_type = EQUIP_SPECIAL + +/obj/item/mecha_parts/mecha_equipment/wormhole_generator/action(atom/target) + if(!action_checks(target) || src.loc.z == 2) return + var/list/theareas = list() + for(var/area/AR in orange(100, chassis)) + if(AR in theareas) continue + theareas += AR + if(!theareas.len) + return + var/area/thearea = pick(theareas) + var/list/L = list() + var/turf/pos = get_turf(src) + for(var/turf/T in get_area_turfs(thearea.type)) + if(!T.density && pos.z == T.z) + var/clear = 1 + for(var/obj/O in T) + if(O.density) + clear = 0 + break + if(clear) + L+=T + if(!L.len) + return + var/turf/target_turf = pick(L) + if(!target_turf) + return + chassis.use_power(energy_drain) + set_ready_state(0) + var/obj/effect/portal/P = new /obj/effect/portal(get_turf(target)) + P.target = target_turf + P.creator = null + P.icon = 'icons/obj/objects.dmi' + P.failchance = 0 + P.icon_state = "anom" + P.name = "wormhole" + do_after_cooldown() + src = null + spawn(rand(150,300)) + qdel(P) + return \ No newline at end of file diff --git a/code/game/mecha/equipment/tools/wrench.dm b/code/game/mecha/equipment/tools/wrench.dm new file mode 100644 index 0000000000..605c2ee33d --- /dev/null +++ b/code/game/mecha/equipment/tools/wrench.dm @@ -0,0 +1,41 @@ +/obj/item/mecha_parts/mecha_equipment/tool/powertool + name = "pneumatic wrench" + desc = "An exosuit-mounted hydraulic wrench." + icon_state = "mecha_wrench" + origin_tech = list(TECH_MATERIAL = 2, TECH_MAGNET = 2, TECH_POWER = 2) + equip_cooldown = 3 + energy_drain = 15 + range = MELEE + equip_type = EQUIP_UTILITY + ready_sound = 'sound/items/Ratchet.ogg' + required_type = list(/obj/mecha/working/ripley) + + var/obj/item/my_tool = null + var/tooltype = /obj/item/weapon/tool/wrench/power + +/obj/item/mecha_parts/mecha_equipment/tool/powertool/Initialize() + my_tool = new tooltype(src) + my_tool.name = name + my_tool.anchored = TRUE + my_tool.canremove = FALSE + return ..() + +/obj/item/mecha_parts/mecha_equipment/tool/powertool/Destroy() + QDEL_NULL(my_tool) + return ..() + +/obj/item/mecha_parts/mecha_equipment/tool/powertool/action(var/atom/target) + if(!action_checks(target)) + return FALSE + + if(isliving(target)) + my_tool.attack(target, chassis.occupant, BP_TORSO) + + target.attackby(my_tool,chassis.occupant) + +/obj/item/mecha_parts/mecha_equipment/tool/powertool/prybar + name = "pneumatic prybar" + desc = "An exosuit-mounted pneumatic prybar." + icon_state = "mecha_crowbar" + tooltype = /obj/item/weapon/tool/crowbar/power + ready_sound = 'sound/mecha/gasdisconnected.ogg' \ No newline at end of file diff --git a/code/game/mecha/equipment/weapons/ballistic/automatic.dm b/code/game/mecha/equipment/weapons/ballistic/automatic.dm new file mode 100644 index 0000000000..3578592511 --- /dev/null +++ b/code/game/mecha/equipment/weapons/ballistic/automatic.dm @@ -0,0 +1,22 @@ +/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 + fire_sound = 'sound/weapons/Gunshot_machinegun.ogg' + projectiles = 30 //10 bursts, matching the Scattershot's 10. Also, conveniently, doesn't eat your powercell when reloading like 300 bullets does. + projectiles_per_shot = 3 + deviation = 0.3 + 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 diff --git a/code/game/mecha/equipment/weapons/ballistic/ballistic.dm b/code/game/mecha/equipment/weapons/ballistic/ballistic.dm new file mode 100644 index 0000000000..99ef24aab7 --- /dev/null +++ b/code/game/mecha/equipment/weapons/ballistic/ballistic.dm @@ -0,0 +1,23 @@ +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic + name = "general ballisic weapon" + var/projectile_energy_cost + +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/get_equip_info() + return "[..()]\[[src.projectiles]\][(src.projectiles < initial(src.projectiles))?" - Rearm":null]" + +/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 + +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/Topic(href, href_list) + ..() + if (href_list["rearm"]) + src.rearm() + return \ No newline at end of file diff --git a/code/game/mecha/equipment/weapons/ballistic/mortar.dm b/code/game/mecha/equipment/weapons/ballistic/mortar.dm new file mode 100644 index 0000000000..86928c9da5 --- /dev/null +++ b/code/game/mecha/equipment/weapons/ballistic/mortar.dm @@ -0,0 +1,22 @@ +/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/Gunshot_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 ..() \ No newline at end of file diff --git a/code/game/mecha/equipment/weapons/ballistic/shotgun.dm b/code/game/mecha/equipment/weapons/ballistic/shotgun.dm new file mode 100644 index 0000000000..d2232d0004 --- /dev/null +++ b/code/game/mecha/equipment/weapons/ballistic/shotgun.dm @@ -0,0 +1,25 @@ +/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/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 \ No newline at end of file diff --git a/code/game/mecha/equipment/weapons/defense/shocker.dm b/code/game/mecha/equipment/weapons/defense/shocker.dm new file mode 100644 index 0000000000..af120167d2 --- /dev/null +++ b/code/game/mecha/equipment/weapons/defense/shocker.dm @@ -0,0 +1,33 @@ +////////////// +//Defensive// +////////////// + +/obj/item/mecha_parts/mecha_equipment/shocker + name = "exosuit electrifier" + desc = "A device to electrify the external portions of a mecha in order to increase its defensive capabilities." + icon_state = "mecha_coil" + equip_cooldown = 10 + energy_drain = 100 + range = RANGED + origin_tech = list(TECH_COMBAT = 3, TECH_POWER = 6) + var/shock_damage = 15 + var/active + + equip_type = EQUIP_HULL + +/obj/item/mecha_parts/mecha_equipment/shocker/can_attach(obj/mecha/M as obj) + if(..()) + if(!M.proc_res["dynattackby"] && !M.proc_res["dynattackhand"] && !M.proc_res["dynattackalien"]) + return 1 + return 0 + +/obj/item/mecha_parts/mecha_equipment/shocker/attach(obj/mecha/M as obj) + ..() + chassis.proc_res["dynattackby"] = src + return + +/obj/item/mecha_parts/mecha_equipment/shocker/proc/dynattackby(obj/item/weapon/W, mob/living/user) + if(!action_checks(user) || !active) + return + user.electrocute_act(shock_damage, src) + return chassis.dynattackby(W,user) diff --git a/code/game/mecha/equipment/weapons/energy/energy.dm b/code/game/mecha/equipment/weapons/energy/energy.dm new file mode 100644 index 0000000000..091e8dcc7b --- /dev/null +++ b/code/game/mecha/equipment/weapons/energy/energy.dm @@ -0,0 +1,3 @@ +/obj/item/mecha_parts/mecha_equipment/weapon/energy + name = "general energy weapon" + auto_rearm = 1 \ No newline at end of file diff --git a/code/game/mecha/equipment/weapons/energy/ion.dm b/code/game/mecha/equipment/weapons/energy/ion.dm new file mode 100644 index 0000000000..7d5be8ef2c --- /dev/null +++ b/code/game/mecha/equipment/weapons/energy/ion.dm @@ -0,0 +1,20 @@ +/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 \ No newline at end of file diff --git a/code/game/mecha/equipment/weapons/energy/laser.dm b/code/game/mecha/equipment/weapons/energy/laser.dm new file mode 100644 index 0000000000..8bdcbcf71f --- /dev/null +++ b/code/game/mecha/equipment/weapons/energy/laser.dm @@ -0,0 +1,68 @@ +/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 = 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 = 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) \ No newline at end of file diff --git a/code/game/mecha/equipment/weapons/energy/phased.dm b/code/game/mecha/equipment/weapons/energy/phased.dm new file mode 100644 index 0000000000..423755705f --- /dev/null +++ b/code/game/mecha/equipment/weapons/energy/phased.dm @@ -0,0 +1,13 @@ +/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/heavy + fire_sound = 'sound/weapons/Taser.ogg' + + equip_type = EQUIP_UTILITY + + origin_tech = list(TECH_MATERIAL = 1, TECH_COMBAT = 2, TECH_MAGNET = 2) \ No newline at end of file diff --git a/code/game/mecha/equipment/weapons/energy/pulse.dm b/code/game/mecha/equipment/weapons/energy/pulse.dm new file mode 100644 index 0000000000..99f7f1d0ce --- /dev/null +++ b/code/game/mecha/equipment/weapons/energy/pulse.dm @@ -0,0 +1,21 @@ +/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) + projectile = /obj/item/projectile/beam/pulse/heavy + fire_sound = 'sound/weapons/gauss_shoot.ogg' + +/obj/item/projectile/beam/pulse/heavy + name = "heavy pulse laser" + icon_state = "pulse1_bl" + var/life = 20 + +/obj/item/projectile/beam/pulse/heavy/Bump(atom/A) + A.bullet_act(src, def_zone) + src.life -= 10 + if(life <= 0) + qdel(src) + return \ No newline at end of file diff --git a/code/game/mecha/equipment/weapons/energy/stun.dm b/code/game/mecha/equipment/weapons/energy/stun.dm new file mode 100644 index 0000000000..f73e439249 --- /dev/null +++ b/code/game/mecha/equipment/weapons/energy/stun.dm @@ -0,0 +1,17 @@ +/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 \ No newline at end of file diff --git a/code/game/mecha/equipment/weapons/explosive/grenade.dm b/code/game/mecha/equipment/weapons/explosive/grenade.dm new file mode 100644 index 0000000000..930000fe3a --- /dev/null +++ b/code/game/mecha/equipment/weapons/explosive/grenade.dm @@ -0,0 +1,70 @@ +/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' + projectiles = 6 + missile_speed = 1.5 + projectile_energy_cost = 800 + equip_cooldown = 60 + var/det_time = 20 + +/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/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. + AM.throw_at(target,missile_range, missile_speed, chassis) + +/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 + + 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/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) diff --git a/code/game/mecha/equipment/weapons/explosive/missile.dm b/code/game/mecha/equipment/weapons/explosive/missile.dm new file mode 100644 index 0000000000..1c14a8c1dd --- /dev/null +++ b/code/game/mecha/equipment/weapons/explosive/missile.dm @@ -0,0 +1,80 @@ +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack + var/missile_speed = 2 + var/missile_range = 30 + +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/Fire(atom/movable/AM, atom/target, turf/aimloc) + AM.throw_at(target,missile_range, missile_speed, chassis) + +/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' + auto_rearm = 1 + fire_cooldown = 20 + projectiles_per_shot = 1 + projectile_energy_cost = 20 + missile_speed = 1 + missile_range = 15 + required_type = /obj/mecha //Why restrict it to just mining or combat mechs? + + equip_type = EQUIP_UTILITY + +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flare/Fire(atom/movable/AM, atom/target, turf/aimloc) + var/obj/item/device/flashlight/flare/fired = AM + fired.ignite() + ..() + +/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' + projectiles = 8 + projectile_energy_cost = 1000 + equip_cooldown = 60 + +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive/Fire(atom/movable/AM, atom/target) + var/obj/item/missile/M = AM + M.primed = 1 + ..() + +/obj/item/missile + icon = 'icons/obj/grenade.dmi' + icon_state = "missile" + var/primed = null + throwforce = 15 + catchable = 0 + var/devastation = 0 + var/heavy_blast = 1 + var/light_blast = 2 + var/flash_blast = 4 + does_spin = FALSE // No fun corkscrew missiles. + +/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) + warhead_special(hit_atom) + qdel(src) + else + ..() + return + +/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 \ No newline at end of file diff --git a/code/game/mecha/equipment/weapons/fire/flamethrower.dm b/code/game/mecha/equipment/weapons/fire/flamethrower.dm new file mode 100644 index 0000000000..f97f598e24 --- /dev/null +++ b/code/game/mecha/equipment/weapons/fire/flamethrower.dm @@ -0,0 +1,27 @@ +/obj/item/mecha_parts/mecha_equipment/weapon/energy/flamer + equip_cooldown = 30 + name = "\improper CR-3 Mark 8" + desc = "An imposing device, this weapon hurls balls of fire." + description_fluff = "A weapon designed by Hephaestus for anti-infantry combat, the CR-3 is capable of outputting a large volume of synthesized fuel. Initially designed by a small company, later purchased by Aether, on Earth as a device made for clearing underbrush and co-operating with firefighting operations. Obviously, Hephaestus has found an 'improved' use for the Aether designs." + icon_state = "mecha_cremate" + + energy_drain = 30 + + projectile = /obj/item/projectile/bullet/incendiary/flamethrower/large + fire_sound = 'sound/weapons/towelwipe.ogg' + + origin_tech = list(TECH_MATERIAL = 4, TECH_COMBAT = 6, TECH_PHORON = 4, TECH_ILLEGAL = 4) + +/obj/item/mecha_parts/mecha_equipment/weapon/energy/flamer/rigged + name = "\improper AA-CR-1 Mark 4" + description_fluff = "A firefighting tool maintained by Aether Atmospherics, whose initial design originated from a small Earth company. This one seems to have been jury rigged." + icon_state = "mecha_cremate-rig" + + energy_drain = 50 + required_type = list(/obj/mecha/combat, /obj/mecha/working) + + projectile = /obj/item/projectile/bullet/incendiary/flamethrower + + origin_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 3, TECH_PHORON = 3, TECH_ILLEGAL = 2) + + equip_type = EQUIP_UTILITY diff --git a/code/game/mecha/equipment/weapons/fire/incendiary.dm b/code/game/mecha/equipment/weapons/fire/incendiary.dm new file mode 100644 index 0000000000..3d3c174839 --- /dev/null +++ b/code/game/mecha/equipment/weapons/fire/incendiary.dm @@ -0,0 +1,18 @@ +////////////// +//Fire-based// +////////////// + +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/incendiary + name = "\improper DR-AC 3" + desc = "Dual-barrel rotary machinegun that fires small, incendiary rounds. Ages ten and up." + description_fluff = "A weapon designed by Hephaestus Industries, the DR-AC 3's design was plagued by prototype faults including but not limited to: Spontaneous combustion, spontaneous detonation, and excessive collateral conflagration." + icon_state = "mecha_drac3" + equip_cooldown = 20 + projectile = /obj/item/projectile/bullet/incendiary + fire_sound = 'sound/weapons/Gunshot_machinegun.ogg' + projectiles = 30 + projectiles_per_shot = 2 + deviation = 0.4 + projectile_energy_cost = 40 + fire_cooldown = 3 + origin_tech = list(TECH_MATERIAL = 4, TECH_COMBAT = 5, TECH_PHORON = 2, TECH_ILLEGAL = 1) diff --git a/code/game/mecha/equipment/weapons/honk.dm b/code/game/mecha/equipment/weapons/honk.dm new file mode 100644 index 0000000000..921111a6cd --- /dev/null +++ b/code/game/mecha/equipment/weapons/honk.dm @@ -0,0 +1,37 @@ +/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 + origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 4, TECH_ILLEGAL = 1) + + equip_type = EQUIP_SPECIAL + +/obj/item/mecha_parts/mecha_equipment/weapon/honker/action(target) + if(!chassis) + return 0 + if(energy_drain && chassis.get_charge() < energy_drain) + return 0 + if(!equip_ready) + return 0 + + playsound(chassis, 'sound/effects/bang.ogg', 30, 1, 30) + chassis.occupant_message("You emit a high-pitched noise from the mech.") + for(var/mob/living/carbon/M in ohearers(6, chassis)) + if(istype(M, /mob/living/carbon/human)) + var/ear_safety = 0 + ear_safety = M.get_ear_protection() + if(ear_safety > 0) + return + to_chat(M, "Your ears feel like they're bleeding!") + playsound(M, 'sound/effects/bang.ogg', 70, 1, 30) + M.sleeping = 0 + M.ear_deaf += 30 + M.ear_damage += rand(5, 20) + M.Weaken(3) + M.Stun(5) + chassis.use_power(energy_drain) + log_message("Used a sound emission device.") + do_after_cooldown() + return \ No newline at end of file diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index 5df2c54d10..cbbc702adf 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -89,519 +89,4 @@ 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 - -/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 = 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 = 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/heavy - 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) - projectile = /obj/item/projectile/beam/pulse/heavy - fire_sound = 'sound/weapons/gauss_shoot.ogg' - -/obj/item/projectile/beam/pulse/heavy - name = "heavy pulse laser" - icon_state = "pulse1_bl" - var/life = 20 - -/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 - origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 4, TECH_ILLEGAL = 1) - - equip_type = EQUIP_SPECIAL - -/obj/item/mecha_parts/mecha_equipment/weapon/honker/action(target) - if(!chassis) - return 0 - if(energy_drain && chassis.get_charge() < energy_drain) - return 0 - if(!equip_ready) - return 0 - - playsound(chassis, 'sound/effects/bang.ogg', 30, 1, 30) - chassis.occupant_message("You emit a high-pitched noise from the mech.") - for(var/mob/living/carbon/M in ohearers(6, chassis)) - if(istype(M, /mob/living/carbon/human)) - var/ear_safety = 0 - ear_safety = M.get_ear_protection() - if(ear_safety > 0) - return - to_chat(M, "Your ears feel like they're bleeding!") - playsound(M, 'sound/effects/bang.ogg', 70, 1, 30) - M.sleeping = 0 - M.ear_deaf += 30 - M.ear_damage += rand(5, 20) - M.Weaken(3) - M.Stun(5) - chassis.use_power(energy_drain) - log_message("Used a sound emission device.") - do_after_cooldown() - return - -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic - name = "general ballisic weapon" - var/projectile_energy_cost - -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/get_equip_info() - return "[..()]\[[src.projectiles]\][(src.projectiles < initial(src.projectiles))?" - Rearm":null]" - -/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 - -/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/Gunshot_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/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 - fire_sound = 'sound/weapons/Gunshot_machinegun.ogg' - projectiles = 30 //10 bursts, matching the Scattershot's 10. Also, conveniently, doesn't eat your powercell when reloading like 300 bullets does. - projectiles_per_shot = 3 - deviation = 0.3 - 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 - -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/Fire(atom/movable/AM, atom/target, turf/aimloc) - AM.throw_at(target,missile_range, missile_speed, chassis) - -/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' - auto_rearm = 1 - fire_cooldown = 20 - projectiles_per_shot = 1 - projectile_energy_cost = 20 - missile_speed = 1 - missile_range = 15 - required_type = /obj/mecha //Why restrict it to just mining or combat mechs? - - equip_type = EQUIP_UTILITY - -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flare/Fire(atom/movable/AM, atom/target, turf/aimloc) - var/obj/item/device/flashlight/flare/fired = AM - fired.ignite() - ..() - -/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' - projectiles = 8 - projectile_energy_cost = 1000 - equip_cooldown = 60 - -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive/Fire(atom/movable/AM, atom/target) - var/obj/item/missile/M = AM - M.primed = 1 - ..() - -/obj/item/missile - icon = 'icons/obj/grenade.dmi' - icon_state = "missile" - var/primed = null - throwforce = 15 - catchable = 0 - var/devastation = 0 - var/heavy_blast = 1 - var/light_blast = 2 - var/flash_blast = 4 - does_spin = FALSE // No fun corkscrew missiles. - -/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) - warhead_special(hit_atom) - qdel(src) - else - ..() - return - -/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' - projectiles = 6 - missile_speed = 1.5 - projectile_energy_cost = 800 - equip_cooldown = 60 - var/det_time = 20 - -/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/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. - AM.throw_at(target,missile_range, missile_speed, chassis) - -/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 - - 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/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// -////////////// - -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/incendiary - name = "\improper DR-AC 3" - desc = "Dual-barrel rotary machinegun that fires small, incendiary rounds. Ages ten and up." - description_fluff = "A weapon designed by Hephaestus Industries, the DR-AC 3's design was plagued by prototype faults including but not limited to: Spontaneous combustion, spontaneous detonation, and excessive collateral conflagration." - icon_state = "mecha_drac3" - equip_cooldown = 20 - projectile = /obj/item/projectile/bullet/incendiary - fire_sound = 'sound/weapons/Gunshot_machinegun.ogg' - projectiles = 30 - projectiles_per_shot = 2 - deviation = 0.4 - projectile_energy_cost = 40 - fire_cooldown = 3 - origin_tech = list(TECH_MATERIAL = 4, TECH_COMBAT = 5, TECH_PHORON = 2, TECH_ILLEGAL = 1) - -/obj/item/mecha_parts/mecha_equipment/weapon/energy/flamer - equip_cooldown = 30 - name = "\improper CR-3 Mark 8" - desc = "An imposing device, this weapon hurls balls of fire." - description_fluff = "A weapon designed by Hephaestus for anti-infantry combat, the CR-3 is capable of outputting a large volume of synthesized fuel. Initially designed by a small company, later purchased by Aether, on Earth as a device made for clearing underbrush and co-operating with firefighting operations. Obviously, Hephaestus has found an 'improved' use for the Aether designs." - icon_state = "mecha_cremate" - - energy_drain = 30 - - projectile = /obj/item/projectile/bullet/incendiary/flamethrower/large - fire_sound = 'sound/weapons/towelwipe.ogg' - - origin_tech = list(TECH_MATERIAL = 4, TECH_COMBAT = 6, TECH_PHORON = 4, TECH_ILLEGAL = 4) - -/obj/item/mecha_parts/mecha_equipment/weapon/energy/flamer/rigged - name = "\improper AA-CR-1 Mark 4" - description_fluff = "A firefighting tool maintained by Aether Atmospherics, whose initial design originated from a small Earth company. This one seems to have been jury rigged." - icon_state = "mecha_cremate-rig" - - energy_drain = 50 - required_type = list(/obj/mecha/combat, /obj/mecha/working) - - projectile = /obj/item/projectile/bullet/incendiary/flamethrower - - origin_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 3, TECH_PHORON = 3, TECH_ILLEGAL = 2) - - equip_type = EQUIP_UTILITY - -////////////// -//Defensive// -////////////// - -/obj/item/mecha_parts/mecha_equipment/shocker - name = "exosuit electrifier" - desc = "A device to electrify the external portions of a mecha in order to increase its defensive capabilities." - icon_state = "mecha_coil" - equip_cooldown = 10 - energy_drain = 100 - range = RANGED - origin_tech = list(TECH_COMBAT = 3, TECH_POWER = 6) - var/shock_damage = 15 - var/active - - equip_type = EQUIP_HULL - -/obj/item/mecha_parts/mecha_equipment/shocker/can_attach(obj/mecha/M as obj) - if(..()) - if(!M.proc_res["dynattackby"] && !M.proc_res["dynattackhand"] && !M.proc_res["dynattackalien"]) - return 1 - return 0 - -/obj/item/mecha_parts/mecha_equipment/shocker/attach(obj/mecha/M as obj) - ..() - chassis.proc_res["dynattackby"] = src - return - -/obj/item/mecha_parts/mecha_equipment/shocker/proc/dynattackby(obj/item/weapon/W, mob/living/user) - if(!action_checks(user) || !active) - return - user.electrocute_act(shock_damage, src) - return chassis.dynattackby(W,user) + P.dispersion = max(P.dispersion + M.accuracy_dispersion, 0) \ No newline at end of file diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm index 5dd88eb7e7..938a720c4f 100644 --- a/code/game/mecha/working/ripley.dm +++ b/code/game/mecha/working/ripley.dm @@ -56,7 +56,7 @@ /obj/mecha/working/ripley/deathripley/Initialize() ..() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/tool/safety_clamp + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp/safety ME.attach(src) return diff --git a/code/game/objects/structures/loot_piles.dm b/code/game/objects/structures/loot_piles.dm index f74770664b..e3607fdeea 100644 --- a/code/game/objects/structures/loot_piles.dm +++ b/code/game/objects/structures/loot_piles.dm @@ -680,7 +680,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/tool/safety_clamp, + /obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp/safety, /obj/item/mecha_parts/mecha_equipment/weapon/energy/riggedlaser, /obj/item/mecha_parts/mecha_equipment/repair_droid, /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay diff --git a/vorestation.dme b/vorestation.dme index e54bf5a45c..61c330d021 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -882,10 +882,50 @@ #include "code\game\mecha\combat\marauder.dm" #include "code\game\mecha\combat\phazon.dm" #include "code\game\mecha\equipment\mecha_equipment.dm" +<<<<<<< HEAD:vorestation.dme #include "code\game\mecha\equipment\tools\medical_tools.dm" #include "code\game\mecha\equipment\tools\medical_tools_vr.dm" +======= +#include "code\game\mecha\equipment\tools\armor_melee.dm" +#include "code\game\mecha\equipment\tools\armor_ranged.dm" +#include "code\game\mecha\equipment\tools\cable_layer.dm" +#include "code\game\mecha\equipment\tools\catapult.dm" +#include "code\game\mecha\equipment\tools\clamp.dm" +#include "code\game\mecha\equipment\tools\drill.dm" +#include "code\game\mecha\equipment\tools\energy_relay.dm" +#include "code\game\mecha\equipment\tools\extinguisher.dm" +#include "code\game\mecha\equipment\tools\generator.dm" +#include "code\game\mecha\equipment\tools\jetpack.dm" +#include "code\game\mecha\equipment\tools\orescanner.dm" +#include "code\game\mecha\equipment\tools\passenger.dm" +#include "code\game\mecha\equipment\tools\rcd.dm" +#include "code\game\mecha\equipment\tools\repair_droid.dm" +#include "code\game\mecha\equipment\tools\shield.dm" +#include "code\game\mecha\equipment\tools\sleeper.dm" +#include "code\game\mecha\equipment\tools\speedboost.dm" +#include "code\game\mecha\equipment\tools\syringe_gun.dm" +#include "code\game\mecha\equipment\tools\teleporter.dm" +>>>>>>> e749b79... Fixes mech projectile armor thinking test projectiles are dangerous (#6480):polaris.dme #include "code\game\mecha\equipment\tools\tools.dm" +#include "code\game\mecha\equipment\tools\wormhole.dm" +#include "code\game\mecha\equipment\tools\wrench.dm" +#include "code\game\mecha\equipment\weapons\honk.dm" #include "code\game\mecha\equipment\weapons\weapons.dm" +#include "code\game\mecha\equipment\weapons\ballistic\automatic.dm" +#include "code\game\mecha\equipment\weapons\ballistic\ballistic.dm" +#include "code\game\mecha\equipment\weapons\ballistic\mortar.dm" +#include "code\game\mecha\equipment\weapons\ballistic\shotgun.dm" +#include "code\game\mecha\equipment\weapons\defense\shocker.dm" +#include "code\game\mecha\equipment\weapons\energy\energy.dm" +#include "code\game\mecha\equipment\weapons\energy\ion.dm" +#include "code\game\mecha\equipment\weapons\energy\laser.dm" +#include "code\game\mecha\equipment\weapons\energy\phased.dm" +#include "code\game\mecha\equipment\weapons\energy\pulse.dm" +#include "code\game\mecha\equipment\weapons\energy\stun.dm" +#include "code\game\mecha\equipment\weapons\explosive\grenade.dm" +#include "code\game\mecha\equipment\weapons\explosive\missile.dm" +#include "code\game\mecha\equipment\weapons\fire\flamethrower.dm" +#include "code\game\mecha\equipment\weapons\fire\incendiary.dm" #include "code\game\mecha\medical\medical.dm" #include "code\game\mecha\medical\odysseus.dm" #include "code\game\mecha\micro\mecha_construction_paths_vr.dm"