Hardsuit and Pickaxe Bugfixes (#9594)

This commit is contained in:
Geeves
2020-08-11 12:17:33 +02:00
committed by GitHub
parent d5df1f998e
commit 08964ec3f3
18 changed files with 597 additions and 597 deletions
@@ -18,10 +18,9 @@
category = MODULE_LIGHT_COMBAT
/obj/item/rig_module/grenade_launcher
name = "mounted grenade launcher"
desc = "A shoulder-mounted micro-explosive dispenser."
selectable = 1
selectable = TRUE
icon_state = "grenade"
interface_name = "integrated grenade launcher"
@@ -39,9 +38,8 @@
)
/obj/item/rig_module/grenade_launcher/accepts_item(var/obj/item/input_device, var/mob/living/user)
if(!istype(input_device) || !istype(user))
return 0
return FALSE
var/datum/rig_charge/accepted_item
for(var/charge in charges)
@@ -51,58 +49,54 @@
break
if(!accepted_item)
return 0
return FALSE
if(accepted_item.charges >= 5)
to_chat(user, "<span class='danger'>Another grenade of that type will not fit into the module.</span>")
return 0
to_chat(user, SPAN_WARNING("Another grenade of that type will not fit into the module."))
return FALSE
to_chat(user, "<font color='blue'><b>You slot \the [input_device] into the suit module.</b></font>")
to_chat(user, SPAN_NOTICE("You slot \the [input_device] into the suit module."))
qdel(input_device)
accepted_item.charges++
return 1
/obj/item/rig_module/grenade_launcher/engage(atom/target)
return TRUE
/obj/item/rig_module/grenade_launcher/engage(atom/target, mob/user)
if(!..())
return 0
return FALSE
if(!target)
return 0
var/mob/living/carbon/human/H = holder.wearer
return FALSE
if(!charge_selected)
to_chat(H, "<span class='danger'>You have not selected a grenade type.</span>")
return 0
to_chat(user, SPAN_WARNING("You have not selected a grenade type."))
return FALSE
var/datum/rig_charge/charge = charges[charge_selected]
if(!charge)
return 0
return FALSE
if(charge.charges <= 0)
to_chat(H, "<span class='danger'>Insufficient grenades!</span>")
return 0
to_chat(user, SPAN_WARNING("Insufficient grenades!"))
return FALSE
charge.charges--
var/obj/item/grenade/new_grenade = new charge.product_type(get_turf(H))
H.visible_message("<span class='danger'>[H] launches \a [new_grenade]!</span>")
new_grenade.activate(H)
new_grenade.throw_at(target,fire_force,fire_distance)
var/obj/item/grenade/new_grenade = new charge.product_type(get_turf(holder.wearer))
holder.wearer.visible_message(SPAN_DANGER("[user] launches \a [new_grenade]!"))
new_grenade.activate(user)
new_grenade.throw_at(target, fire_force, fire_distance)
/obj/item/rig_module/grenade_launcher/frag
name = "mounted frag grenade launcher"
desc = "A shoulder-mounted fragmentation explosives dispenser."
selectable = 1
selectable = TRUE
icon_state = "grenade"
interface_name = "integrated frag grenade launcher"
interface_desc = "Discharges loaded frag grenades against the wearer's location."
charges = list(
list("frag grenade", "frag grenade", /obj/item/grenade/frag, 3)
list("frag grenade", "frag grenade", /obj/item/grenade/frag, 3)
)
/obj/item/rig_module/grenade_launcher/cleaner
@@ -112,15 +106,14 @@
category = MODULE_GENERAL
charges = list(
list("cleaning grenade", "cleaning grenade", /obj/item/grenade/chem_grenade/cleaner, 9)
list("cleaning grenade", "cleaning grenade", /obj/item/grenade/chem_grenade/cleaner, 9)
)
/obj/item/rig_module/mounted
name = "mounted laser cannon"
desc = "A shoulder-mounted battery-powered laser cannon mount."
selectable = 1
usable = 1
selectable = TRUE
usable = TRUE
module_cooldown = 0
icon_state = "lcannon"
@@ -140,24 +133,25 @@
if(istype(gun, /obj/item/gun))
gun.has_safety = FALSE
/obj/item/rig_module/mounted/engage(atom/target)
/obj/item/rig_module/mounted/engage(atom/target, mob/user)
if(!..())
return 0
return FALSE
if(!target)
gun.attack_self(holder.wearer)
return 1
var/list/extra_mobs = list()
if(holder.wearer != user)
extra_mobs += holder.wearer
gun.attack_self(user, extra_mobs)
return TRUE
gun.Fire(target,holder.wearer)
return 1
gun.Fire(target, user)
return TRUE
/obj/item/rig_module/mounted/egun
name = "mounted energy gun"
desc = "A forearm-mounted energy projector."
icon_state = "egun"
construction_cost= list(DEFAULT_WALL_MATERIAL=7000, MATERIAL_GLASS = 2250, MATERIAL_URANIUM = 3250, MATERIAL_GOLD = 2500)
construction_cost= list(DEFAULT_WALL_MATERIAL = 7000, MATERIAL_GLASS = 2250, MATERIAL_URANIUM = 3250, MATERIAL_GOLD = 2500)
construction_time = 300
interface_name = "mounted energy gun"
@@ -168,14 +162,13 @@
category = MODULE_LIGHT_COMBAT
/obj/item/rig_module/mounted/taser
name = "mounted taser"
desc = "A palm-mounted nonlethal energy projector."
icon_state = "taser"
construction_cost = list(DEFAULT_WALL_MATERIAL = 7000, MATERIAL_GLASS = 5250)
construction_time = 300
usable = 0
usable = FALSE
suit_overlay_active = "mounted-taser"
suit_overlay_inactive = "mounted-taser"
@@ -188,7 +181,6 @@
category = MODULE_LIGHT_COMBAT
/obj/item/rig_module/mounted/pulse
name = "mounted pulse rifle"
desc = "A shoulder-mounted battery-powered pulse rifle mount."
icon_state = "pulse"
@@ -210,7 +202,6 @@
gun_type = /obj/item/gun/energy/mountedplasma
/obj/item/rig_module/mounted/smg
name = "mounted submachine gun"
desc = "A forearm-mounted suit-powered ballistic submachine gun."
icon_state = "smg"
@@ -221,7 +212,6 @@
gun_type = /obj/item/gun/energy/mountedsmg
/obj/item/rig_module/mounted/xray
name = "mounted xray laser gun"
desc = "A forearm-mounted suit-powered xray laser gun."
icon_state = "xray"
@@ -232,7 +222,6 @@
gun_type = /obj/item/gun/energy/xray/mounted
/obj/item/rig_module/mounted/ion
name = "mounted ion rifle"
desc = "A shoulder-mounted battery-powered ion rifle mount."
icon_state = "ion"
@@ -243,7 +232,6 @@
gun_type = /obj/item/gun/energy/rifle/ionrifle/mounted
/obj/item/rig_module/mounted/tesla
name = "mounted tesla carbine"
desc = "A shoulder-mounted battery-powered tesla carbine mount."
icon_state = "tesla"
@@ -280,7 +268,6 @@
category = MODULE_UTILITY
/obj/item/rig_module/mounted/energy_blade
name = "energy blade projector"
desc = "A powerful cutting beam projector."
icon_state = "eblade"
@@ -291,9 +278,9 @@
interface_name = "spider fang blade"
interface_desc = "A lethal energy projector that can shape a blade projected from the hand of the wearer or launch radioactive darts."
usable = 0
selectable = 1
toggleable = 1
usable = FALSE
selectable = TRUE
toggleable = TRUE
use_power_cost = 50
active_power_cost = 10
passive_power_cost = 0
@@ -303,22 +290,23 @@
category = MODULE_SPECIAL
/obj/item/rig_module/mounted/energy_blade/process()
if(holder && holder.wearer)
if(!(locate(/obj/item/melee/energy/blade) in holder.wearer))
deactivate()
return 0
deactivate(holder.wearer)
return FALSE
return ..()
/obj/item/rig_module/mounted/energy_blade/activate()
/obj/item/rig_module/mounted/energy_blade/activate(mob/user)
..()
var/mob/living/M = holder.wearer
if(M.l_hand && M.r_hand)
to_chat(M, "<span class='danger'>Your hands are full.</span>")
if(M == user)
to_chat(M, SPAN_WARNING("Your hands are full."))
else
to_chat(user, SPAN_WARNING("[M]'s hands are full."))
deactivate()
return
@@ -327,7 +315,6 @@
M.put_in_hands(blade)
/obj/item/rig_module/mounted/energy_blade/deactivate()
..()
var/mob/living/M = holder.wearer
@@ -339,11 +326,10 @@
qdel(blade)
/obj/item/rig_module/fabricator
name = "matter fabricator"
desc = "A self-contained microfactory system for hardsuit integration."
selectable = 1
usable = 1
selectable = TRUE
usable = TRUE
use_power_cost = 10
icon_state = "enet"
@@ -358,28 +344,28 @@
category = MODULE_SPECIAL
/obj/item/rig_module/fabricator/engage(atom/target)
/obj/item/rig_module/fabricator/engage(atom/target, mob/user)
if(!..())
return 0
return FALSE
var/mob/living/H = holder.wearer
if(target)
var/obj/item/firing = new fabrication_type()
firing.forceMove(get_turf(src))
H.visible_message("<span class='danger'>[H] launches \a [firing]!</span>")
firing.throw_at(target,fire_force,fire_distance)
var/obj/item/firing = new fabrication_type(get_turf(src))
holder.wearer.visible_message(SPAN_DANGER("[user] launches \a [firing]!"))
firing.throw_at(target, fire_force, fire_distance)
else
if(H.l_hand && H.r_hand)
to_chat(H, "<span class='danger'>Your hands are full.</span>")
if(H == user)
to_chat(H, SPAN_WARNING("Your hands are full."))
else
to_chat(user, SPAN_WARNING("[H]'s hands are full."))
else
var/obj/item/new_weapon = new fabrication_type()
new_weapon.forceMove(H)
to_chat(H, "<font color='blue'><b>You quickly fabricate \a [new_weapon].</b></font>")
var/obj/item/new_weapon = new fabrication_type(H)
message_user(user, SPAN_NOTICE("You quickly fabricate \a [new_weapon]."), SPAN_NOTICE("\The [user] fabricates \a [new_weapon]."))
H.put_in_hands(new_weapon)
return 1
return TRUE
/obj/item/rig_module/fabricator/sign
name = "wet floor sign fabricator"
@@ -392,7 +378,6 @@
category = MODULE_GENERAL
/obj/item/rig_module/tesla_coil
name = "mounted tesla coil"
desc = "A mounted tesla coil that discharges a powerful lightning strike around the user."
@@ -403,17 +388,17 @@
use_power_cost = 30
module_cooldown = 100
usable = 1
usable = TRUE
category = MODULE_LIGHT_COMBAT
/obj/item/rig_module/tesla_coil/engage()
/obj/item/rig_module/tesla_coil/engage(atom/target, mob/user)
if(!..())
return 0
return FALSE
var/mob/living/carbon/human/H = holder.wearer
H.visible_message("<span class='danger'>\The [H] crackles with energy!</span>")
H.visible_message(SPAN_DANGER("\The [H] crackles with energy!"))
playsound(H, 'sound/magic/LightningShock.ogg', 75, 1)
tesla_zap(H, 5, 5000)
return 1
return TRUE
@@ -15,12 +15,12 @@
set src in usr
if(!usr.loc || !usr.loc.loc || !istype(usr.loc.loc, /obj/item/rig_module))
to_chat(usr, "You are not loaded into a hardsuit.")
to_chat(usr, SPAN_WARNING("You are not loaded into a hardsuit."))
return
var/obj/item/rig_module/module = usr.loc.loc
if(!module.holder)
to_chat(usr, "Your module is not installed in a hardsuit.")
to_chat(usr, SPAN_WARNING("Your module is not installed in a hardsuit."))
return
module.holder.ui_interact(usr, nano_state = contained_state)
@@ -32,11 +32,11 @@
name = "IIS module"
desc = "An integrated intelligence system module suitable for most hardsuits."
icon_state = "IIS"
toggleable = 1
usable = 1
disruptive = 0
activates_on_touch = 1
confined_use = 1
toggleable = TRUE
usable = TRUE
disruptive = FALSE
activates_on_touch = TRUE
confined_use = TRUE
construction_cost = list(DEFAULT_WALL_MATERIAL = 5000, MATERIAL_GLASS = 7500)
construction_time = 300
@@ -83,7 +83,6 @@
verb_holder.forceMove(src)
/obj/item/rig_module/ai_container/accepts_item(var/obj/item/input_device, var/mob/living/user)
// Check if there's actually an AI to deal with.
var/mob/living/silicon/ai/target_ai
if(istype(input_device, /mob/living/silicon/ai))
@@ -102,7 +101,7 @@
// Terminal interaction only works with an intellicarded AI.
if(!istype(card))
return 0
return FALSE
// Since we've explicitly checked for three types, this should be safe.
input_device.attackby(card,user)
@@ -114,7 +113,7 @@
else
eject_ai()
update_verb_holder()
return 1
return TRUE
if(istype(input_device,/obj/item/aicard))
// We are carding the AI in our suit.
@@ -127,9 +126,9 @@
else
// You're using an empty card on an empty suit, idiot.
if(!target_ai)
return 0
return FALSE
integrate_ai(input_device,user)
return 1
return TRUE
// Okay, it wasn't a terminal being touched, check for all the simple insertions.
if(input_device.type in list(/obj/item/device/paicard, /obj/item/device/mmi, /obj/item/device/mmi/digital/posibrain))
@@ -141,51 +140,47 @@
eject_ai()
else
integrate_ai(input_device,user)
return 1
return TRUE
return 0
/obj/item/rig_module/ai_container/engage(atom/target)
return FALSE
/obj/item/rig_module/ai_container/engage(atom/target, mob/user)
if(!..())
return 0
return FALSE
var/mob/living/carbon/human/H = holder.wearer
if(!target)
if(ai_card)
if(istype(ai_card,/obj/item/aicard))
if(istype(ai_card, /obj/item/aicard))
ai_card.ui_interact(H, state = deep_inventory_state)
else
eject_ai(H)
update_verb_holder()
return 1
return TRUE
if(accepts_item(target,H))
return 1
return TRUE
return 0
return FALSE
/obj/item/rig_module/ai_container/removed()
eject_ai()
..()
/obj/item/rig_module/ai_container/proc/eject_ai(var/mob/user)
if(ai_card)
if(istype(ai_card, /obj/item/aicard))
if(integrated_ai && !integrated_ai.stat)
if(user)
to_chat(user, "<span class='danger'>You cannot eject your currently stored AI. Purge it manually.</span>")
return 0
to_chat(user, "<span class='danger'>You purge the remaining scraps of data from your previous AI, freeing it for use.</span>")
to_chat(user, SPAN_WARNING("You cannot eject your currently stored AI. Purge it manually."))
return FALSE
message_user(user, SPAN_NOTICE("You purge the remaining scraps of data from your previous AI, freeing it for use."), SPAN_NOTICE("\The [user] purges \the [integrated_ai]."))
if(integrated_ai)
integrated_ai.ghostize()
qdel(integrated_ai)
integrated_ai = null
QDEL_NULL(integrated_ai)
if(ai_card)
qdel(ai_card)
ai_card = null
QDEL_NULL(ai_card)
else if(user)
user.put_in_hands(ai_card)
else
@@ -195,16 +190,16 @@
update_verb_holder()
/obj/item/rig_module/ai_container/proc/integrate_ai(var/obj/item/ai,var/mob/user)
if(!ai) return
if(!ai)
return
// The ONLY THING all the different AI systems have in common is that they all store the mob inside an item.
var/mob/living/ai_mob = locate(/mob/living) in ai.contents
if(ai_mob)
ai_mob.resting = FALSE
ai_mob.canmove = TRUE
if(ai_mob.key && ai_mob.client)
if(istype(ai, /obj/item/aicard))
if(!ai_card)
ai_card = new /obj/item/aicard(src)
@@ -214,9 +209,9 @@
if(target_card.grab_ai(ai_mob, user))
source_card.clear()
else
return 0
return FALSE
else
return 0
return FALSE
else
user.drop_from_inventory(ai,src)
ai_card = ai
@@ -229,20 +224,19 @@
integrated_ai = null
eject_ai()
else
to_chat(user, "<span class='warning'>There is no active AI within \the [ai].</span>")
to_chat(user, SPAN_WARNING("There is no active AI within \the [ai]."))
else
to_chat(user, "<span class='warning'>There is no active AI within \the [ai].</span>")
to_chat(user, SPAN_WARNING("There is no active AI within \the [ai]."))
update_verb_holder()
return
/obj/item/rig_module/datajack
name = "datajack module"
desc = "A simple induction datalink module."
icon_state = "datajack"
toggleable = 1
activates_on_touch = 1
usable = 0
toggleable = TRUE
activates_on_touch = TRUE
usable = FALSE
activate_string = "Enable Datajack"
deactivate_string = "Disable Datajack"
@@ -257,31 +251,29 @@
..()
stored_research = list()
/obj/item/rig_module/datajack/engage(atom/target)
/obj/item/rig_module/datajack/engage(atom/target, mob/user)
if(!..())
return 0
return FALSE
if(target)
var/mob/living/carbon/human/H = holder.wearer
if(!accepts_item(target,H))
return 0
return 1
return FALSE
return TRUE
/obj/item/rig_module/datajack/accepts_item(var/obj/item/input_device, var/mob/living/user)
if(istype(input_device,/obj/item/disk/tech_disk))
to_chat(user, "You slot the disk into [src].")
if(istype(input_device, /obj/item/disk/tech_disk))
to_chat(user, SPAN_NOTICE("You slot the disk into [src]."))
var/obj/item/disk/tech_disk/disk = input_device
if(disk.stored)
if(load_data(disk.stored))
to_chat(user, "<font color='blue'>Download successful; disk erased.</font>")
to_chat(user, SPAN_NOTICE("Download successful; disk erased."))
disk.stored = null
else
to_chat(user, "<span class='warning'>The disk is corrupt. It is useless to you.</span>")
to_chat(user, SPAN_WARNING("The disk is corrupt. It is useless to you."))
else
to_chat(user, "<span class='warning'>The disk is blank. It is useless to you.</span>")
return 1
to_chat(user, SPAN_WARNING("The disk is blank. It is useless to you."))
return TRUE
// I fucking hate R&D code. This typecheck spam would be totally unnecessary in a sane setup.
else if(istype(input_device,/obj/machinery))
@@ -297,22 +289,22 @@
incoming_files = input_machine.files
if(!incoming_files || !incoming_files.known_tech || !incoming_files.known_tech.len)
to_chat(user, "<span class='warning'>Memory failure. There is nothing accessible stored on this terminal.</span>")
to_chat(user, SPAN_WARNING("Memory failure. There is nothing accessible stored on this terminal."))
else
// Maybe consider a way to drop all your data into a target repo in the future.
if(load_data(incoming_files.known_tech))
to_chat(user, "<font color='blue'>Download successful; local and remote repositories synchronized.</font>")
to_chat(user, SPAN_NOTICE("Download successful; local and remote repositories synchronized."))
else
to_chat(user, "<span class='warning'>Scan complete. There is nothing useful stored on this terminal.</span>")
return 1
return 0
to_chat(user, SPAN_WARNING("Scan complete. There is nothing useful stored on this terminal."))
return TRUE
return FALSE
/obj/item/rig_module/datajack/proc/load_data(var/incoming_data)
if(islist(incoming_data))
for(var/entry in incoming_data)
load_data(entry)
return 1
return TRUE
if(istype(incoming_data, /datum/tech))
var/data_found
@@ -325,17 +317,17 @@
break
if(!data_found)
stored_research += incoming_data
return 1
return 0
return TRUE
return FALSE
/obj/item/rig_module/electrowarfare_suite
name = "electrowarfare module"
desc = "A bewilderingly complex bundle of fiber optics and chips."
icon_state = "ewar"
toggleable = 1
usable = 0
confined_use = 1
toggleable = TRUE
usable = FALSE
confined_use = TRUE
activate_string = "Enable Countermeasures"
deactivate_string = "Disable Countermeasures"
@@ -367,9 +359,9 @@
name = "hardsuit power sink"
desc = "An heavy-duty power sink."
icon_state = "powersink"
toggleable = 1
activates_on_touch = 1
disruptive = 0
toggleable = TRUE
activates_on_touch = TRUE
disruptive = FALSE
construction_cost = list(DEFAULT_WALL_MATERIAL=10000, MATERIAL_GOLD =2000, MATERIAL_SILVER =3000, MATERIAL_GLASS =2000)
construction_time = 500
@@ -389,8 +381,8 @@
/obj/item/rig_module/power_sink/deactivate()
if(interfaced_with)
if(holder && holder.wearer)
to_chat(holder.wearer, "<span class = 'warning'>Your power sink retracts as the module deactivates.</span>")
if(holder?.wearer)
to_chat(holder.wearer, SPAN_WARNING("Your power sink retracts as the module deactivates."))
drain_complete()
interfaced_with = null
total_power_drained = 0
@@ -401,45 +393,43 @@
total_power_drained = 0
return ..()
/obj/item/rig_module/power_sink/engage(atom/target)
/obj/item/rig_module/power_sink/engage(atom/target, mob/user)
if(!..())
return 0
return FALSE
//Target wasn't supplied or we're already draining.
if(interfaced_with)
return 0
return FALSE
if(!target)
return 1
return TRUE
// Are we close enough?
var/mob/living/carbon/human/H = holder.wearer
if(!target.Adjacent(H))
return 0
return FALSE
// Is it a valid power source?
if(target.drain_power(1) <= 0)
return 0
return FALSE
to_chat(H, "<span class = 'danger'>You begin draining power from [target]!</span>")
message_user(user, SPAN_NOTICE("You begin draining power from \the [target]!"), SPAN_NOTICE("[user] begins draining power from \the [target]!"))
interfaced_with = target
drain_loc = interfaced_with.loc
holder.spark_system.queue()
playsound(H.loc, 'sound/effects/sparks2.ogg', 50, 1)
return 1
return TRUE
/obj/item/rig_module/power_sink/accepts_item(var/obj/item/input_device, var/mob/living/user)
var/can_drain = input_device.drain_power(1)
if(can_drain > 0)
engage(input_device)
return 1
return 0
engage(input_device, user)
return TRUE
return FALSE
/obj/item/rig_module/power_sink/process()
if(!interfaced_with)
return ..()
@@ -448,23 +438,23 @@
H = holder.wearer
if(!H || !istype(H))
return 0
return FALSE
holder.spark_system.queue()
playsound(H.loc, 'sound/effects/sparks2.ogg', 50, 1)
if(!holder.cell)
to_chat(H, "<span class = 'danger'>Your power sink flashes an error; there is no cell in your hardsuit.</span>")
to_chat(H, SPAN_WARNING("Your power sink flashes an error; there is no cell in your hardsuit."))
drain_complete(H)
return
if(!interfaced_with || !interfaced_with.Adjacent(H) || !(interfaced_with.loc == drain_loc))
to_chat(H, "<span class = 'warning'>Your power sink retracts into its casing.</span>")
to_chat(H, SPAN_WARNING("Your power sink retracts into its casing."))
drain_complete(H)
return
if(holder.cell.fully_charged())
to_chat(H, "<span class = 'warning'>Your power sink flashes an amber light; your hardsuit cell is full.</span>")
to_chat(H, SPAN_WARNING("Your power sink flashes an amber light; your hardsuit cell is full."))
drain_complete(H)
return
@@ -472,23 +462,22 @@
var/to_drain = min(80000, ((holder.cell.maxcharge - holder.cell.charge) / CELLRATE))
var/target_drained = interfaced_with.drain_power(0,0,to_drain)
if(target_drained <= 0)
to_chat(H, "<span class = 'danger'>Your power sink flashes a red light; there is no power left in [interfaced_with].</span>")
to_chat(H, SPAN_WARNING("Your power sink flashes a red light; there is no power left in \the [interfaced_with]."))
drain_complete(H)
return
holder.cell.give(target_drained * CELLRATE * 2)
total_power_drained += target_drained
return 1
return TRUE
/obj/item/rig_module/power_sink/proc/drain_complete(var/mob/living/M)
if(!interfaced_with)
if(M) to_chat(M, "<font color='blue'><b>Total power drained:</b> [round(total_power_drained/500)]kJ.</font>")
if(M) to_chat(M, SPAN_NOTICE("<b>Total power drained:</b> [round(total_power_drained/500)]kJ."))
else
if(M) to_chat(M, "<font color='blue'><b>Total power drained from [interfaced_with]:</b> [round(total_power_drained/500)]kJ.</font>")
interfaced_with.drain_power(0,1,0) // Damage the victim.
if(M) to_chat(M, SPAN_NOTICE("<b>Total power drained from [interfaced_with]:</b> [round(total_power_drained/500)]kJ."))
interfaced_with.drain_power(0, 1, 0) // Damage the victim.
drain_loc = null
interfaced_with = null
total_power_drained = 0
total_power_drained = 0
@@ -24,6 +24,7 @@
var/module_cooldown = 10
var/next_use = 0
var/engage_on_activate = TRUE // Whether the rig should call engage() in its activate() proc
var/toggleable // Set to 1 for the device to show up as an active effect.
var/usable // Set to 1 for the device to have an on-use effect.
var/selectable // Set to 1 to be able to assign the device as primary system.
@@ -31,7 +32,7 @@
var/permanent // If set, the module can't be removed.
var/disruptive = 1 // Can disrupt by other effects.
var/activates_on_touch // If set, unarmed attacks will call engage() on the target.
var/confined_use = 0 // If set, can be used inside mechs and other vehicles.
var/confined_use = FALSE // If set, can be used inside mechs and other vehicles.
var/active // Basic module status
var/disruptable // Will deactivate if some other powers are used.
@@ -60,56 +61,52 @@
var/list/stat_rig_module/stat_modules = new()
var/category // Use for restricting modules for specific suits, to specialize
/obj/item/rig_module/examine()
/obj/item/rig_module/examine(mob/user)
..()
switch(damage)
if(0)
to_chat(usr, "It is undamaged.")
to_chat(user, SPAN_NOTICE("It is undamaged."))
if(1)
to_chat(usr, "It is badly damaged.")
to_chat(user, SPAN_WARNING("It is badly damaged."))
if(2)
to_chat(usr, "It is almost completely destroyed.")
/obj/item/rig_module/attackby(obj/item/W as obj, mob/user as mob)
if(istype(W,/obj/item/stack/nanopaste))
to_chat(user, SPAN_DANGER("It is almost completely destroyed."))
/obj/item/rig_module/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/stack/nanopaste))
if(damage == 0)
to_chat(user, "There is no damage to mend.")
to_chat(user, SPAN_WARNING("There is no damage to mend."))
return
to_chat(user, "You start mending the damaged portions of \the [src]...")
to_chat(user, SPAN_NOTICE("You start mending the damaged portions of \the [src]..."))
if(!do_after(user,30) || !W || !src)
return
var/obj/item/stack/nanopaste/paste = W
damage = 0
to_chat(user, "You mend the damage to [src] with [W].")
to_chat(user, SPAN_NOTICE("You mend the damage to \the [src] with \the [W]."))
paste.use(1)
return
else if(W.iscoil())
switch(damage)
if(0)
to_chat(user, "There is no damage to mend.")
to_chat(user, SPAN_WARNING("There is no damage to mend."))
return
if(2)
to_chat(user, "There is no damage that you are capable of mending with such crude tools.")
to_chat(user, SPAN_WARNING("\The [src] is too damaged to repair with cable coil, it needs nanopaste."))
return
var/obj/item/stack/cable_coil/cable = W
if(!cable.amount >= 5)
to_chat(user, "You need five units of cable to repair \the [src].")
to_chat(user, SPAN_WARNING("You need five units of cable to repair \the [src]."))
return
to_chat(user, "You start mending the damaged portions of \the [src]...")
if(!do_after(user,30) || !W || !src)
to_chat(user, SPAN_NOTICE("You start mending the damaged portions of \the [src]..."))
if(!do_after(user, 30) || !W || !src)
return
damage = 1
to_chat(user, "You mend some of damage to [src] with [W], but you will need more advanced tools to fix it completely.")
to_chat(user, SPAN_NOTICE("You mend some of damage to \the [src] with \the [W], but you will need more advanced tools to fix it completely."))
cable.use(5)
return
..()
@@ -134,11 +131,11 @@
charges = processed_charges
stat_modules += new/stat_rig_module/activate(src)
stat_modules += new/stat_rig_module/deactivate(src)
stat_modules += new/stat_rig_module/engage(src)
stat_modules += new/stat_rig_module/select(src)
stat_modules += new/stat_rig_module/charge(src)
stat_modules += new /stat_rig_module/activate(src)
stat_modules += new /stat_rig_module/deactivate(src)
stat_modules += new /stat_rig_module/engage(src)
stat_modules += new /stat_rig_module/select(src)
stat_modules += new /stat_rig_module/charge(src)
/obj/item/rig_module/Destroy()
@@ -154,50 +151,50 @@
return
//Proc for one-use abilities like teleport.
/obj/item/rig_module/proc/engage()
/obj/item/rig_module/proc/engage(atom/target, mob/user)
if(damage >= 2)
to_chat(usr, "<span class='warning'>The [interface_name] is damaged beyond use!</span>")
return 0
to_chat(user, SPAN_WARNING("\The [interface_name] is damaged beyond use!"))
return FALSE
if(world.time < next_use)
to_chat(usr, "<span class='warning'>You cannot use the [interface_name] again so soon.</span>")
return 0
to_chat(user, SPAN_WARNING("You cannot use \the [interface_name] again so soon."))
return FALSE
if(!holder || holder.canremove)
to_chat(usr, "<span class='warning'>The suit is not initialized.</span>")
return 0
to_chat(user, SPAN_WARNING("The suit is not initialized."))
return FALSE
if(usr.lying || usr.stat || usr.stunned || usr.paralysis || usr.weakened)
to_chat(usr, "<span class='warning'>You cannot use the suit in this state.</span>")
return 0
if(user.lying || user.stat || user.stunned || user.paralysis || user.weakened)
to_chat(user, SPAN_WARNING("You cannot use the suit in this state."))
return FALSE
if(holder.wearer && holder.wearer.lying)
to_chat(usr, "<span class='warning'>The suit cannot function while the wearer is prone.</span>")
return 0
to_chat(user, SPAN_WARNING("The suit cannot function while the wearer is prone."))
return FALSE
if(holder.security_check_enabled && !holder.check_suit_access(usr))
to_chat(usr, "<span class='danger'>Access denied.</span>")
return 0
if(holder.security_check_enabled && !holder.check_suit_access(user))
to_chat(user, SPAN_DANGER("Access denied."))
return FALSE
if(!holder.check_power_cost(usr, use_power_cost, 0, src, (istype(usr,/mob/living/silicon ? 1 : 0) ) ) )
return 0
if(!holder.check_power_cost(user, use_power_cost, 0, src, (istype(user,/mob/living/silicon ? 1 : 0) ) ) )
return FALSE
if(!confined_use && istype(usr.loc, /mob/living/heavy_vehicle))
to_chat(usr, "<span class='danger'>You cannot use the suit in the confined space.</span>")
return 0
if(!confined_use && istype(user.loc, /mob/living/heavy_vehicle))
to_chat(user, SPAN_DANGER("You cannot use the suit in the confined space."))
return FALSE
next_use = world.time + module_cooldown
return 1
return TRUE
// Proc for toggling on active abilities.
/obj/item/rig_module/proc/activate()
/obj/item/rig_module/proc/activate(mob/user)
if(active)
return FALSE
if(engage_on_activate && !engage(null, user))
return FALSE
if(active || !engage())
return 0
active = 1
active = TRUE
spawn(1)
if(suit_overlay_active)
@@ -206,15 +203,14 @@
suit_overlay = null
holder.update_icon()
return 1
return TRUE
// Proc for toggling off active abilities.
/obj/item/rig_module/proc/deactivate()
/obj/item/rig_module/proc/deactivate(mob/user)
if(!active)
return 0
return FALSE
active = 0
active = FALSE
spawn(1)
if(suit_overlay_inactive)
@@ -224,7 +220,7 @@
if(holder)
holder.update_icon()
return 1
return TRUE
// Called when the module is uninstalled from a suit.
/obj/item/rig_module/proc/removed()
@@ -242,7 +238,14 @@
// Called by holder rigsuit attackby()
// Checks if an item is usable with this module and handles it if it is
/obj/item/rig_module/proc/accepts_item(var/obj/item/input_device)
return 0
return FALSE
/obj/item/rig_module/proc/message_user(mob/user, var/user_text, var/wearer_text)
to_chat(user, user_text)
if(holder.wearer && user != holder.wearer)
to_chat(holder.wearer, wearer_text)
return
/mob/living/carbon/human/Stat()
. = ..()
@@ -277,7 +280,7 @@
return
/stat_rig_module/proc/CanUse()
return 0
return FALSE
/stat_rig_module/Click()
if(CanUse())
@@ -331,8 +334,8 @@
/stat_rig_module/select/CanUse()
if(module.selectable)
name = module.holder.selected_module == module ? "Selected" : "Select"
return 1
return 0
return TRUE
return FALSE
/stat_rig_module/charge/New()
..()
@@ -352,8 +355,8 @@
if(module.charges && module.charges.len)
var/datum/rig_charge/charge = module.charges[module.charge_selected]
name = "[charge.display_name] ([charge.charges]C) - Change"
return 1
return 0
return TRUE
return FALSE
/mob/living/carbon/human/ClickOn(atom/A, params)
. = ..()
@@ -10,16 +10,15 @@
*/
/obj/item/rig_module/stealth_field
name = "active camouflage module"
desc = "A robust hardsuit-integrated stealth module."
icon_state = "cloak"
toggleable = 1
disruptable = 1
disruptive = 0
attackdisrupts = 1
confined_use = 1
toggleable = TRUE
disruptable = TRUE
disruptive = FALSE
attackdisrupts = TRUE
confined_use = TRUE
use_power_cost = 75
active_power_cost = 5
@@ -38,45 +37,40 @@
category = MODULE_SPECIAL
/obj/item/rig_module/stealth_field/activate()
if(!..())
return 0
return FALSE
var/mob/living/carbon/human/H = holder.wearer
to_chat(H, "<font color='blue'><b>You are now invisible to normal detection.</b></font>")
to_chat(H, SPAN_NOTICE("<b>You are now invisible to normal detection.</b>"))
H.invisibility = INVISIBILITY_LEVEL_TWO
anim(get_turf(H), H, 'icons/effects/effects.dmi', "electricity",null,20,null)
anim(get_turf(H), H, 'icons/effects/effects.dmi', "electricity", null, 20, null)
H.visible_message("<span class='notice'>[H] vanishes into thin air!</span>", "<span class='notice'>You vanish into thin air!</span>")
H.visible_message(SPAN_NOTICE("[H] vanishes into thin air!"), SPAN_NOTICE("You vanish into thin air!"))
/obj/item/rig_module/stealth_field/deactivate()
if(!..())
return 0
return FALSE
var/mob/living/carbon/human/H = holder.wearer
to_chat(H, "<span class='danger'>You are now visible.</span>")
H.invisibility = 0
to_chat(H, SPAN_NOTICE("<b>You are now visible.</b>"))
H.invisibility = FALSE
anim(get_turf(H), H,'icons/mob/mob.dmi',,"uncloak",,H.dir)
anim(get_turf(H), H, 'icons/effects/effects.dmi', "electricity",null,20,null)
anim(get_turf(H), H, 'icons/mob/mob.dmi', ,"uncloak", , H.dir)
anim(get_turf(H), H, 'icons/effects/effects.dmi', "electricity", null, 20, null)
for(var/mob/O in oviewers(H))
O.show_message("[H.name] appears from thin air!",1)
H.visible_message(SPAN_NOTICE("[H] appears from thin air!"), SPAN_NOTICE("You appear from thin air!"))
playsound(get_turf(H), 'sound/effects/stealthoff.ogg', 10, 1)
/obj/item/rig_module/teleporter
name = "bluespace teleportation module"
desc = "A complex, sleek-looking, hardsuit-integrated teleportation module that exploits bluespace energy to phase from one location to another instantaneously."
icon_state = "teleporter"
use_power_cost = 40
redundant = 1
usable = 1
usable = TRUE
selectable = 1
var/lastteleport
@@ -87,36 +81,34 @@
category = MODULE_SPECIAL
/obj/item/rig_module/teleporter/proc/phase_in(var/mob/M,var/turf/T)
/obj/item/rig_module/teleporter/proc/phase_in(var/mob/M, var/turf/T)
if(!M || !T)
return
holder.spark_system.queue()
playsound(T, 'sound/effects/phasein.ogg', 25, 1)
playsound(T, 'sound/effects/sparks2.ogg', 50, 1)
anim(T,M,'icons/mob/mob.dmi',,"phasein",,M.dir)
/obj/item/rig_module/teleporter/proc/phase_out(var/mob/M,var/turf/T)
anim(T, M, 'icons/mob/mob.dmi', ,"phasein", , M.dir)
/obj/item/rig_module/teleporter/proc/phase_out(var/mob/M, var/turf/T)
if(!M || !T)
return
playsound(T, "sparks", 50, 1)
anim(T,M,'icons/mob/mob.dmi',,"phaseout",,M.dir)
anim(T, M, 'icons/mob/mob.dmi', ,"phaseout", ,M.dir)
/obj/item/rig_module/teleporter/engage(var/atom/target, var/notify_ai)
if(!..()) return FALSE
/obj/item/rig_module/teleporter/engage(atom/target, mob/user, var/notify_ai)
if(!..())
return FALSE
var/mob/living/carbon/human/H = holder.wearer
if(lastteleport + (5 SECONDS) > world.time)
to_chat(H, SPAN_WARNING("The teleporter needs time to cool down!"))
to_chat(user, SPAN_WARNING("The teleporter needs time to cool down!"))
return FALSE
if(!istype(H.loc, /turf))
to_chat(H, "<span class='warning'>You cannot teleport out of your current location.</span>")
to_chat(user, SPAN_WARNING("You cannot teleport out of your current location."))
return FALSE
var/turf/T
@@ -126,19 +118,19 @@
T = get_teleport_loc(get_turf(H), H, rand(5, 9))
if(!T || T.density)
to_chat(H, "<span class='warning'>You cannot teleport into solid walls.</span>")
to_chat(user, SPAN_WARNING("You cannot teleport into solid walls."))
return FALSE
if(isAdminLevel(T.z))
to_chat(H, "<span class='warning'>You cannot use your teleporter on this Z-level.</span>")
to_chat(user, SPAN_WARNING("You cannot use your teleporter on this Z-level."))
return FALSE
if(T.contains_dense_objects())
to_chat(H, "<span class='warning'>You cannot teleport to a location with solid objects.</span>")
to_chat(user, SPAN_WARNING("You cannot teleport to a location with solid objects."))
return FALSE
if((T.z != H.z || get_dist(T, get_turf(H)) > world.view) && target)
to_chat(H, "<span class='warning'>You cannot teleport to such a distant object.</span>")
to_chat(user, SPAN_WARNING("You cannot teleport to such a distant object."))
return FALSE
phase_out(H,get_turf(H))
@@ -146,7 +138,7 @@
phase_in(H,get_turf(H))
if(T != get_turf(H))
to_chat(H, SPAN_WARNING("Something interferes with your [src]!"))
to_chat(user, SPAN_WARNING("Something interferes with your [src]!"))
for(var/obj/item/grab/G in H.contents)
if(G.affecting)
@@ -158,7 +150,6 @@
return TRUE
/obj/item/rig_module/fabricator/energy_net
name = "net projector"
desc = "Some kind of complex energy projector with a hardsuit mount."
icon_state = "enet"
@@ -173,33 +164,31 @@
category = MODULE_SPECIAL
/obj/item/rig_module/fabricator/energy_net/engage(atom/target)
/obj/item/rig_module/fabricator/energy_net/engage(atom/target, mob/user)
if(holder && holder.wearer)
if(..(target) && target)
holder.wearer.Beam(target,"n_beam",,10)
return 1
return 0
holder.wearer.Beam(target, "n_beam", , 10)
return TRUE
return FALSE
/obj/item/rig_module/self_destruct
name = "self-destruct module"
desc = "Oh my God, Captain. A bomb."
icon_state = "deadman"
usable = 1
active = 1
permanent = 1
usable = TRUE
active = TRUE
permanent = TRUE
engage_string = "Detonate"
interface_name = "dead man's switch"
interface_desc = "An integrated self-destruct module. When the wearer dies, so does the surrounding area. Do not press this button."
var/list/explosion_values = list(3,4,5,6)
var/list/explosion_values = list(3, 4, 5, 6)
category = MODULE_SPECIAL
/obj/item/rig_module/self_destruct/small
explosion_values = list(1,2,3,4)
explosion_values = list(1, 2, 3, 4)
/obj/item/rig_module/self_destruct/activate()
return
@@ -208,13 +197,12 @@
return
/obj/item/rig_module/self_destruct/process()
// Not being worn, leave it alone.
if(!holder || !holder.wearer || !holder.wearer.wear_suit == holder)
return 0
return FALSE
//OH SHIT.
if(holder.wearer.stat == 2)
if(holder.wearer.stat == DEAD)
engage(1)
/obj/item/rig_module/self_destruct/engage(var/skip_check)
@@ -231,8 +219,8 @@
name = "EMP dissipation module"
desc = "A bewilderingly complex bundle of fiber optics and chips. Seems like it uses a good deal of power."
active_power_cost = 10
toggleable = 1
usable = 0
toggleable = TRUE
usable = FALSE
use_power_cost = 70
module_cooldown = 30
@@ -255,36 +243,36 @@
if(!..())
return
holder.emp_protection = max(0,(holder.emp_protection - protection_amount))
holder.emp_protection = max(0, (holder.emp_protection - protection_amount))
/obj/item/rig_module/emergency_powergenerator
name = "emergency power generator"
desc = "A high yield power generating device that takes a long time to recharge."
active_power_cost = 0
toggleable = 0
usable = 1
confined_use = 1
toggleable = FALSE
usable = TRUE
confined_use = TRUE
var/cooldown = 0
engage_string = "Use Emergency Power"
interface_name = "emergency power generator"
interface_desc = "A high yield power generating device that takes a long time to recharge."
var/generation_ammount = 3500
var/generation_amount = 3500
category = MODULE_SPECIAL
/obj/item/rig_module/emergency_powergenerator/engage()
/obj/item/rig_module/emergency_powergenerator/engage(atom/target, mob/user)
if(!..())
return
var/mob/living/carbon/human/H = holder.wearer
if(cooldown)
to_chat(H, "<span class='danger'>There isn't enough power stored up yet!</span>")
return 0
to_chat(user, SPAN_DANGER("There isn't enough power stored up yet!"))
return FALSE
else
to_chat(H, "<span class='danger'>Your suit emits a loud sound as power is rapidly injected into your suits battery!</span>")
message_user(user, SPAN_NOTICE("You inject a burst of power into \the [holder]."), SPAN_NOTICE("Your suit emits a loud sound as power is rapidly injected into your suit's battery!"))
playsound(H.loc, 'sound/effects/sparks2.ogg', 50, 1)
holder.cell.give(generation_ammount)
holder.cell.give(generation_amount)
cooldown = 1
addtimer(CALLBACK(src, /obj/item/rig_module/emergency_powergenerator/proc/reset_cooldown), 2 MINUTES)
@@ -320,9 +308,9 @@
use_power_cost = 10
module_cooldown = 5
usable = 0
usable = FALSE
selectable = 0
toggleable = 1
toggleable = TRUE
interface_name = "advanced door hacking tool"
interface_desc = "An advanced door hacking tool that sports a low power cost and incredibly quick door hacking time. The device also supports hacking several signals at once remotely, and the last 10 doors hacked can be instantly accessed."
@@ -330,22 +318,23 @@
category = MODULE_SPECIAL
/obj/item/rig_module/device/door_hack/process()
if(holder && holder.wearer)
if(!(locate(/obj/item/device/multitool/hacktool/rig) in holder.wearer))
deactivate()
return 0
return FALSE
return ..()
/obj/item/rig_module/device/door_hack/activate()
/obj/item/rig_module/device/door_hack/activate(mob/user)
..()
var/mob/living/M = holder.wearer
if(M.l_hand && M.r_hand)
to_chat(M, "<span class='danger'>Your hands are full.</span>")
if(M == user)
to_chat(M, SPAN_WARNING("Your hands are full."))
else
to_chat(user, SPAN_WARNING("[M]'s hands are full."))
deactivate()
return
@@ -354,7 +343,6 @@
M.put_in_hands(hacktool)
/obj/item/rig_module/device/door_hack/deactivate()
..()
var/mob/living/M = holder.wearer
@@ -22,10 +22,10 @@
/obj/item/rig_module/device
name = "mounted device"
desc = "Some kind of hardsuit mount."
usable = 0
usable = FALSE
selectable = 1
toggleable = 0
disruptive = 0
toggleable = FALSE
disruptive = FALSE
var/device_type
var/obj/item/device
@@ -49,7 +49,7 @@
interface_name = "vitals tracker"
interface_desc = "Shows an informative health readout of the user."
usable = 1
usable = TRUE
selectable = 0
category = MODULE_GENERAL
@@ -92,7 +92,7 @@
interface_name = "Alden-Saraspova counter"
interface_desc = "An exotic particle detector commonly used by xenoarchaeologists."
engage_string = "Begin Scan"
usable = 1
usable = TRUE
selectable = 0
device_type = /obj/item/device/ano_scanner
@@ -105,7 +105,7 @@
interface_name = "ore detector"
interface_desc = "A sonar system for detecting large masses of ore."
engage_string = "Begin Scan"
usable = 1
usable = TRUE
selectable = 0
device_type = /obj/item/mining_scanner
@@ -117,9 +117,9 @@
icon_state = "rcd"
interface_name = "mounted RFD-C"
interface_desc = "A device for building or removing walls. Cell-powered."
usable = 1
usable = TRUE
engage_string = "Configure RFD-C"
construction_cost = list(DEFAULT_WALL_MATERIAL=30000,"phoron"=12500, MATERIAL_SILVER =10000, MATERIAL_GOLD =10000)
construction_cost = list(DEFAULT_WALL_MATERIAL = 30000, MATERIAL_PHORON = 12500, MATERIAL_SILVER = 10000, MATERIAL_GOLD = 10000)
construction_time = 1000
device_type = /obj/item/rfd/construction/mounted
@@ -131,12 +131,12 @@
if(device_type)
device = new device_type(src)
/obj/item/rig_module/device/engage(atom/target)
/obj/item/rig_module/device/engage(atom/target, mob/user)
if(!..() || !device)
return FALSE
if(!target)
device.attack_self(holder.wearer)
device.attack_self(user)
return TRUE
var/turf/T = get_turf(target)
@@ -147,20 +147,20 @@
if(istype(target, /obj/machinery/disposal))
return FALSE
var/resolved = target.attackby(device)
var/resolved = target.attackby(device, user)
if(!resolved && device && target)
device.afterattack(target, holder.wearer, TRUE)
device.afterattack(target, user, TRUE)
return TRUE
/obj/item/rig_module/chem_dispenser
name = "mounted chemical dispenser"
desc = "A complex web of tubing and needles suitable for hardsuit use."
icon_state = "injector"
usable = 1
selectable = 0
toggleable = 0
disruptive = 0
confined_use = 1
usable = TRUE
selectable = FALSE
toggleable = FALSE
disruptive = FALSE
confined_use = TRUE
construction_cost = list(DEFAULT_WALL_MATERIAL=10000, MATERIAL_GLASS =9250, MATERIAL_GOLD =2500, MATERIAL_SILVER =4250,"phoron"=5500)
construction_time = 400
@@ -170,15 +170,15 @@
interface_desc = "Dispenses loaded chemicals directly into the wearer's bloodstream."
charges = list(
list("tricordrazine", "tricordrazine",/datum/reagent/tricordrazine, 80),
list("tricordrazine", "tricordrazine", /datum/reagent/tricordrazine, 80),
list("mortaphenyl", "mortaphenyl", /datum/reagent/mortaphenyl, 80),
list("dexalin plus", "dexalinp", /datum/reagent/dexalin/plus, 80),
list("antibiotics", "thetamycin", /datum/reagent/thetamycin, 80),
list("antitoxins", "dylovene", /datum/reagent/dylovene, 80),
list("nutrients", "glucose", /datum/reagent/nutriment/glucose, 80),
list("saline", "saline", /datum/reagent/saline, 80),
list("hyronalin", "hyronalin", /datum/reagent/hyronalin, 80),
list("radium", "radium", /datum/reagent/radium, 80)
list("dexalin plus", "dexalinp", /datum/reagent/dexalin/plus, 80),
list("antibiotics", "thetamycin", /datum/reagent/thetamycin, 80),
list("antitoxins", "dylovene", /datum/reagent/dylovene, 80),
list("nutrients", "glucose", /datum/reagent/nutriment/glucose, 80),
list("saline", "saline", /datum/reagent/saline, 80),
list("hyronalin", "hyronalin", /datum/reagent/hyronalin, 80),
list("radium", "radium", /datum/reagent/radium, 80)
)
var/max_reagent_volume = 80 //Used when refilling.
@@ -190,27 +190,26 @@
//just over a syringe worth of each. Want more? Go refill. Gives the ninja another reason to have to show their face.
charges = list(
list("tricordrazine", "tricordrazine",/datum/reagent/tricordrazine, 20),
list("tricordrazine", "tricordrazine", /datum/reagent/tricordrazine, 20),
list("mortaphenyl", "mortaphenyl", /datum/reagent/mortaphenyl, 20),
list("dexalin plus", "dexalinp", /datum/reagent/dexalin/plus, 20),
list("antibiotics", "thetamycin", /datum/reagent/thetamycin, 20),
list("antitoxins", "dylovene", /datum/reagent/dylovene, 20),
list("nutrients", "glucose", /datum/reagent/nutriment/glucose, 80),
list("saline", "saline", /datum/reagent/saline, 80),
list("hyronalin", "hyronalin", /datum/reagent/hyronalin, 20),
list("radium", "radium", /datum/reagent/radium, 20)
list("dexalin plus", "dexalinp", /datum/reagent/dexalin/plus, 20),
list("antibiotics", "thetamycin", /datum/reagent/thetamycin, 20),
list("antitoxins", "dylovene", /datum/reagent/dylovene, 20),
list("nutrients", "glucose", /datum/reagent/nutriment/glucose, 80),
list("saline", "saline", /datum/reagent/saline, 80),
list("hyronalin", "hyronalin", /datum/reagent/hyronalin, 20),
list("radium", "radium", /datum/reagent/radium, 20)
)
category = MODULE_UTILITY
/obj/item/rig_module/chem_dispenser/accepts_item(var/obj/item/input_item, var/mob/living/user)
if(!input_item.is_open_container())
return 0
return FALSE
if(!input_item.reagents || !input_item.reagents.total_volume)
to_chat(user, "\The [input_item] is empty.")
return 0
to_chat(user, SPAN_WARNING("\The [input_item] is empty."))
return FALSE
// Magical chemical filtration system, do not question it.
var/total_transferred = 0
@@ -231,31 +230,30 @@
break
if(total_transferred)
to_chat(user, "<font color='blue'>You transfer [total_transferred] units into the suit reservoir.</font>")
to_chat(user, SPAN_NOTICE("You transfer [total_transferred] units into the suit reservoir."))
else
to_chat(user, "<span class='danger'>None of the reagents seem suitable.</span>")
return 1
/obj/item/rig_module/chem_dispenser/engage(atom/target)
to_chat(user, SPAN_WARNING("None of the reagents seem suitable."))
return TRUE
/obj/item/rig_module/chem_dispenser/engage(atom/target, mob/user)
if(!..())
return 0
return FALSE
var/mob/living/carbon/human/H = holder.wearer
if(!charge_selected)
to_chat(H, "<span class='danger'>You have not selected a chemical type.</span>")
return 0
to_chat(user, SPAN_WARNING("You have not selected a chemical type."))
return FALSE
var/datum/rig_charge/charge = charges[charge_selected]
if(!charge)
return 0
return FALSE
var/chems_to_use = 10
if(charge.charges <= 0)
to_chat(H, "<span class='danger'>Insufficient chems!</span>")
return 0
to_chat(user, SPAN_WARNING("Insufficient chems!"))
return FALSE
else if(charge.charges < chems_to_use)
chems_to_use = charge.charges
@@ -264,37 +262,37 @@
if(istype(target,/mob/living/carbon))
target_mob = target
else
return 0
return FALSE
else
target_mob = H
if(!H.Adjacent(target_mob))
to_chat(H, "<span class='danger'>You are not close enough to inject them!</span>")
return 0
to_chat(user, SPAN_WARNING("You are not close enough to inject them!"))
return FALSE
if(target_mob != H)
to_chat(H, "<span class='danger'>You inject [target_mob] with [chems_to_use] unit\s of [charge.display_name].</span>")
if(target_mob != user)
to_chat(user, SPAN_NOTICE("You inject [target_mob] with [chems_to_use] unit\s of [charge.display_name]."))
if(!target_mob.is_physically_disabled())
to_chat(target_mob, "<span class='danger'>You feel a rushing in your veins as [chems_to_use] unit\s of [charge.display_name] [chems_to_use == 1 ? "is" : "are"] injected.</span>")
to_chat(target_mob, SPAN_NOTICE("<b>You feel a rushing in your veins as [chems_to_use] unit\s of [charge.display_name] [chems_to_use == 1 ? "is" : "are"] injected.</b>"))
target_mob.reagents.add_reagent(charge.product_type, chems_to_use)
charge.charges -= chems_to_use
if(charge.charges < 0) charge.charges = 0
if(charge.charges < 0)
charge.charges = 0
return 1
return TRUE
/obj/item/rig_module/chem_dispenser/combat
name = "combat chemical injector"
desc = "A complex web of tubing and needles suitable for hardsuit use."
charges = list(
list("synaptizine", "synaptizine", /datum/reagent/synaptizine, 30),
list("hyperzine", "hyperzine", /datum/reagent/hyperzine, 30),
list("oxycomorphine", "oxycomorphine", /datum/reagent/oxycomorphine, 30),
list("nutrients", "glucose", /datum/reagent/nutriment/glucose, 80),
list("saline", "saline", /datum/reagent/saline, 80)
list("synaptizine", "synaptizine", /datum/reagent/synaptizine, 30),
list("hyperzine", "hyperzine", /datum/reagent/hyperzine, 30),
list("oxycomorphine", "oxycomorphine", /datum/reagent/oxycomorphine, 30),
list("nutrients", "glucose", /datum/reagent/nutriment/glucose, 80),
list("saline", "saline", /datum/reagent/saline, 80)
)
interface_name = "combat chem dispenser"
@@ -303,33 +301,30 @@
category = MODULE_LIGHT_COMBAT
/obj/item/rig_module/chem_dispenser/vaurca
name = "vaurca combat chemical injector"
desc = "A complex web of tubing and needles suitable for vaurcan hardsuit use."
charges = list(
list("synaptizine", "synaptizine", /datum/reagent/synaptizine, 30),
list("hyperzine", "hyperzine", /datum/reagent/hyperzine, 30),
list("synaptizine", "synaptizine", /datum/reagent/synaptizine, 30),
list("hyperzine", "hyperzine", /datum/reagent/hyperzine, 30),
list("oxycomorphine", "oxycomorphine", /datum/reagent/oxycomorphine, 30),
list("phoron", "phoron", /datum/reagent/toxin/phoron,60),
list("kois", "k'ois paste", /datum/reagent/kois, 80),
list("saline", "saline", /datum/reagent/saline, 80)
list("phoron", "phoron", /datum/reagent/toxin/phoron, 60),
list("kois", "k'ois paste", /datum/reagent/kois, 80),
list("saline", "saline", /datum/reagent/saline, 80)
)
interface_name = "vaurca combat chem dispenser"
interface_desc = "Dispenses loaded chemicals directly into the bloodstream."
category = MODULE_VAURCA
/obj/item/rig_module/chem_dispenser/offworlder
name = "chemical injector"
desc = "A complex web of tubing and needles suitable for hardsuit use."
charges = list(
list("dexalin", "dexalin", /datum/reagent/dexalin, 5),
list("inaprovaline", "inaprovaline", /datum/reagent/inaprovaline, 5)
list("dexalin", "dexalin", /datum/reagent/dexalin, 5),
list("inaprovaline", "inaprovaline", /datum/reagent/inaprovaline, 5)
)
interface_name = "chem dispenser"
@@ -337,15 +332,13 @@
category = MODULE_GENERAL
/obj/item/rig_module/chem_dispenser/injector
name = "mounted chemical injector"
desc = "A complex web of tubing and a large needle suitable for hardsuit use."
usable = 0
usable = FALSE
selectable = 1
disruptive = 1
construction_cost = list(DEFAULT_WALL_MATERIAL=10000, MATERIAL_GLASS =9250, MATERIAL_GOLD =2500, MATERIAL_SILVER =4250,"phoron"=5500)
construction_cost = list(DEFAULT_WALL_MATERIAL = 10000, MATERIAL_GLASS = 9250, MATERIAL_GOLD = 2500, MATERIAL_SILVER = 4250, MATERIAL_PHORON = 5500)
construction_time = 400
interface_name = "mounted chem injector"
@@ -354,24 +347,22 @@
category = MODULE_MEDICAL
/obj/item/rig_module/chem_dispenser/injector/paramedic //downgraded version
charges = list(
list("tricordrazine", "tricordrazine", /datum/reagent/tricordrazine, 40),
list("mortaphenyl", "mortaphenyl", /datum/reagent/mortaphenyl, 40),
list("mortaphenyl", "mortaphenyl", /datum/reagent/mortaphenyl, 40),
list("dexalin", "dexalin", /datum/reagent/dexalin, 40),
list("inaprovaline", "inaprovaline", /datum/reagent/inaprovaline, 40)
list("inaprovaline", "inaprovaline", /datum/reagent/inaprovaline, 40)
)
/obj/item/rig_module/voice
name = "hardsuit voice synthesiser"
desc = "A speaker box and sound processor."
icon_state = "megaphone"
usable = 1
usable = TRUE
selectable = 0
toggleable = 0
disruptive = 0
confined_use = 1
toggleable = FALSE
disruptive = FALSE
confined_use = TRUE
engage_string = "Configure Synthesiser"
@@ -391,47 +382,46 @@
..()
holder.speech = src
/obj/item/rig_module/voice/engage()
/obj/item/rig_module/voice/engage(atom/target, mob/user)
if(!..())
return 0
return FALSE
var/choice= input("Would you like to toggle the synthesiser, set the name or set an accent?") as null|anything in list("Enable","Disable","Set Name", "Set Accent")
if(!choice)
return 0
return FALSE
switch(choice)
if("Enable")
active = 1
voice_holder.active = 1
to_chat(usr, "<font color='blue'>You enable the speech synthesiser.</font>")
active = TRUE
voice_holder.active = TRUE
message_user(user, SPAN_NOTICE("You enable the speech synthesiser."), SPAN_NOTICE("\The [user] enables the speech synthesiser."))
if("Disable")
active = 0
voice_holder.active = 0
to_chat(usr, "<font color='blue'>You disable the speech synthesiser.</font>")
active = FALSE
voice_holder.active = FALSE
message_user(user, SPAN_NOTICE("You disable the speech synthesiser."), SPAN_NOTICE("\The [user] disables the speech synthesiser."))
if("Set Name")
var/raw_choice = sanitize(input(usr, "Please enter a new name.") as text|null, MAX_NAME_LEN)
var/raw_choice = sanitize(input(user, "Please enter a new name.") as text|null, MAX_NAME_LEN)
if(!raw_choice)
return 0
return FALSE
voice_holder.voice = raw_choice
to_chat(usr, "<font color='blue'>You are now mimicking <B>[voice_holder.voice]</B>.</font>")
message_user(user, SPAN_NOTICE("You set the synthesizer to mimic <b>[voice_holder.voice]</b>."), SPAN_NOTICE("\The [user] set the speech synthesizer to mimic <b>[voice_holder.voice]</b>."))
if("Set Accent")
var/raw_choice = input(usr, "Please choose an accent to mimick.") as null|anything in SSrecords.accents
var/raw_choice = input(user, "Please choose an accent to mimick.") as null|anything in SSrecords.accents
if(!raw_choice)
return 0
return FALSE
voice_holder.current_accent = raw_choice
to_chat(usr, SPAN_NOTICE("You are now mimicking the [raw_choice] accent."))
return 1
message_user(user, SPAN_NOTICE("You set the synthesizer to mimic the [raw_choice] accent."), SPAN_NOTICE("\The [user] set the speech synthesizer the [raw_choice] accent."))
return TRUE
/obj/item/rig_module/maneuvering_jets
name = "hardsuit maneuvering jets"
desc = "A compact gas thruster system for a hardsuit."
icon_state = "thrusters"
usable = 1
toggleable = 1
usable = TRUE
toggleable = TRUE
selectable = 0
disruptive = 0
disruptive = FALSE
construction_cost = list(DEFAULT_WALL_MATERIAL = 15000, MATERIAL_GLASS = 4250, MATERIAL_SILVER = 4250, MATERIAL_URANIUM = 5250)
construction_time = 300
@@ -449,18 +439,20 @@
category = MODULE_GENERAL
/obj/item/rig_module/maneuvering_jets/engage()
/obj/item/rig_module/maneuvering_jets/engage(atom/target, mob/user)
if(!..())
return 0
jets.toggle_rockets()
return 1
/obj/item/rig_module/maneuvering_jets/activate()
return FALSE
var/list/extra_mobs = list()
if(user != holder.wearer)
extra_mobs += holder.wearer
jets.toggle_rockets_stabilization(user, extra_mobs)
return TRUE
/obj/item/rig_module/maneuvering_jets/activate(mob/user)
if(active)
return 0
return FALSE
active = 1
active = TRUE
spawn(1)
if(suit_overlay_active)
@@ -470,15 +462,21 @@
holder.update_icon()
if(!jets.on)
jets.toggle()
return 1
var/list/extra_mobs = list()
if(user != holder.wearer)
extra_mobs += holder.wearer
jets.toggle_jetpack(user, extra_mobs)
return TRUE
/obj/item/rig_module/maneuvering_jets/deactivate()
/obj/item/rig_module/maneuvering_jets/deactivate(mob/user)
if(!..())
return 0
return FALSE
if(jets.on)
jets.toggle()
return 1
var/list/extra_mobs = list()
if(user != holder.wearer)
extra_mobs += holder.wearer
jets.toggle_jetpack(user, extra_mobs)
return TRUE
/obj/item/rig_module/maneuvering_jets/New()
..()
@@ -503,20 +501,19 @@
interface_name = "paper dispenser"
interface_desc = "Dispenses warm, clean, and crisp sheets of paper."
engage_string = "Dispense"
usable = 1
usable = TRUE
selectable = 0
device_type = /obj/item/paper_bin
category = MODULE_GENERAL
/obj/item/rig_module/device/paperdispenser/engage(atom/target)
/obj/item/rig_module/device/paperdispenser/engage(atom/target, mob/user)
if(!..() || !device)
return 0
return FALSE
if(!target)
device.attack_hand(holder.wearer)
return 1
device.attack_hand(user)
return TRUE
/obj/item/rig_module/device/pen
name = "mounted pen"
@@ -525,7 +522,7 @@
interface_name = "mounted pen"
interface_desc = "Signatures with style(tm)."
engage_string = "Change color"
usable = 1
usable = TRUE
device_type = /obj/item/pen/multi
category = MODULE_GENERAL
@@ -537,7 +534,7 @@
interface_name = "mounted stamp"
interface_desc = "Leave your mark."
engage_string = "Toggle stamp type"
usable = 1
usable = TRUE
var/iastamp
var/deniedstamp
@@ -549,18 +546,18 @@
deniedstamp = new /obj/item/stamp/denied(src)
device = iastamp
/obj/item/rig_module/device/stamp/engage(atom/target)
/obj/item/rig_module/device/stamp/engage(atom/target, mob/user)
if(!..() || !device)
return 0
return FALSE
if(!target)
if(device == iastamp)
device = deniedstamp
to_chat(holder.wearer, "<span class='notice'>Switched to denied stamp.</span>")
message_user(user, SPAN_NOTICE("You set \the [src] to the denied stamp."), SPAN_NOTICE("\The [user] set \the [src] to the denied stamp."))
else if(device == deniedstamp)
device = iastamp
to_chat(holder.wearer, "<span class='notice'>Switched to internal affairs stamp.</span>")
return 1
message_user(user, SPAN_NOTICE("You set \the [src] to the internal affairs stamp."), SPAN_NOTICE("\The [user] set \the [src] to the internal affairs stamp."))
return TRUE
/obj/item/rig_module/device/decompiler
name = "mounted matter decompiler"
@@ -583,7 +580,7 @@
construction_cost = list(DEFAULT_WALL_MATERIAL=15000, MATERIAL_GLASS = 1250, MATERIAL_SILVER =5250)
construction_time = 300
disruptive = 0
disruptive = FALSE
use_power_cost = 5
module_cooldown = 25
@@ -592,9 +589,9 @@
* TOGGLE - dampens fall, on or off.
* SELECTABLE - Jump forward or up!
*/
toggleable = 1
selectable = 1
usable = 0
toggleable = TRUE
selectable = TRUE
usable = FALSE
engage_string = "Toggle Leg Actuators"
activate_string = "Enable Leg Actuators"
@@ -618,26 +615,42 @@
category = MODULE_LIGHT_COMBAT
/obj/item/rig_module/actuators/engage(var/atom/target)
/obj/item/rig_module/actuators/proc/is_valid_turf(var/turf/T)
if(!T || istype(T, /turf/space) || T.density || T.contains_dense_objects())
return null
if(isopenturf(T))
var/obj/structure/lattice/L = locate() in T
if(L)
return L.name
var/turf/leapBelow = GetBelow(T)
if(leapBelow.density)
return leapBelow.name
else if(T.contains_dense_objects())
return "structure"
else
return null
return T.name
/obj/item/rig_module/actuators/engage(atom/target, mob/user)
if (!..())
return 0
return FALSE
// This is for when you toggle it on or off. Why do they both run the same
// proc chain ...? :l
if (!target)
return 1
return TRUE
var/mob/living/carbon/human/H = holder.wearer
if (!isturf(H.loc))
to_chat(H, "<span class='warning'>You cannot leap out of your current location!</span>")
return 0
to_chat(user, SPAN_WARNING("You cannot leap out of your current location!"))
return FALSE
var/turf/T = get_turf(target)
if (!T || T.density)
to_chat(H, "<span class='warning'>You cannot leap at solid walls!</span>")
return 0
to_chat(user, SPAN_WARNING("You cannot leap at solid walls!"))
return FALSE
// Saved, we need it more than 1 place.
var/dist = max(get_dist(T, get_turf(H)), 0)
@@ -649,46 +662,45 @@
continue
if (aa.density)
to_chat(H, "<span class='warning'>You cannot leap at a location with solid objects on it!</span>")
return 0
to_chat(user, SPAN_WARNING("You cannot leap at a location with solid objects on it!"))
return FALSE
if (T.z != H.z || dist > leapDistance)
to_chat(H, "<span class='warning'>You cannot leap at such a distant object!</span>")
return 0
to_chat(user, SPAN_WARNING("You cannot leap at such a distant object!"))
return FALSE
// Handle leaping at targets with a combat capable version here.
if (combatType && dist && (ismob(target) || (locate(/mob/living) in T)))
H.do_leap(target, leapDistance, FALSE)
return 1
return TRUE
// If dist -> horizontal leap. Otherwise, the user clicked the turf that they're
// currently on. Which means they want to do a vertical leap upwards!
if (dist)
H.visible_message("<span class='warning'>\The [H] leaps horizontally at \the [T]!</span>",
"<span class='warning'>You leap horizontally at \the [T]!</span>",
"<span class='warning'>You hear an electric <i>whirr</i> followed by a weighty thump!</span>")
H.visible_message(SPAN_WARNING("\The [H] leaps horizontally at \the [T]!"),
SPAN_WARNING("You leap horizontally at \the [T]!"),
SPAN_WARNING("You hear an electric <i>whirr</i> followed by a weighty thump!"))
H.face_atom(T)
H.throw_at(T, leapDistance, 1, src, do_throw_animation = FALSE)
return 1
return TRUE
else
var/turf/simulated/open/TA = GetAbove(src)
if (!istype(TA))
to_chat(H, "<span class='warning'>There is a ceiling above you that stop you from leaping upwards!</span>")
return 0
to_chat(user, SPAN_WARNING("There is a ceiling above you that stop you from leaping upwards!"))
return FALSE
for (var/atom/A in TA)
if (!A.CanPass(src, TA, 1.5, 0))
to_chat(H, "<span class='warning'>\The [A] blocks you!</span>")
return 0
to_chat(user, SPAN_WARNING("\The [A] blocks you!"))
return FALSE
var/turf/leapEnd = get_step(TA, H.dir)
if (!leapEnd || isopenturf(leapEnd) || istype(leapEnd, /turf/space)\
|| leapEnd.density || leapEnd.contains_dense_objects())
to_chat(H, "<span class='warning'>There is no valid ledge to scale ahead of you!</span>")
return 0
var/valid_climbable = is_valid_turf(leapEnd)
if(!valid_climbable)
to_chat(user, SPAN_WARNING("There is no valid ledge to scale ahead of you!"))
return
H.visible_message("<span class='notice'>\The [H] leaps up, out of view!</span>",
"<span class='notice'>You leap up!</span>")
H.visible_message(SPAN_NOTICE("\The [H] leaps up, out of view!"), SPAN_NOTICE("You leap up!"))
// This setting is necessary even for combat type, to stop you from moving onto
// the turf, falling back down, and then getting forcemoved to the final destination.
@@ -699,11 +711,9 @@
// Combat type actuators are better, they allow you to jump instantly onto
// a ledge. Regular actuators make you have to climb the rest of the way.
if (!combatType)
H.visible_message("<span class='notice'>\The [H] starts pulling \himself up onto \the [leapEnd].</span>",
"<span class='notice'>You start pulling yourself up onto \the [leapEnd].</span>")
H.visible_message(SPAN_NOTICE("\The [H] starts pulling \himself up onto the [valid_climbable]."), SPAN_NOTICE("You start pulling yourself up onto \the [valid_climbable]."))
if (!do_after(H, 4 SECONDS, use_user_turf = TRUE))
H.visible_message("<span class='warning'>\The [H] is interrupted and falls!</span>",
"<span class='danger'>You are interrupted and fall back down!</span>")
H.visible_message(SPAN_WARNING("\The [H] is interrupted and falls!"), SPAN_DANGER("You are interrupted and fall back down!"))
// Climbers will auto-fall if they exit the turf. This is for in case
// something else interrupts them.
@@ -711,23 +721,20 @@
TA.remove_climber(H)
ADD_FALLING_ATOM(H)
return 1
return TRUE
H.visible_message("<span class='notice'>\The [H] finishes climbing onto \the [leapEnd].</span>",
"<span class='notice'>You finish climbing onto \the [leapEnd].</span>")
H.visible_message(SPAN_NOTICE("\The [H] finishes climbing onto \the [valid_climbable]."), SPAN_NOTICE("You finish climbing onto \the [valid_climbable]."))
else
H.visible_message("<span class='warning'>\The [H] lands on \the [leapEnd] with a heavy slam!</span>",
"<span class='warning'>You land on \the [leapEnd] with a heavy thud!</span>")
H.visible_message(SPAN_WARNING("\The [H] lands on \the [valid_climbable] with a heavy slam!"), SPAN_WARNING("You land on \the [valid_climbable] with a heavy thud!"))
// open/Exited() removes from climbers.
H.forceMove(leapEnd)
return 1
return TRUE
/obj/item/rig_module/cooling_unit
name = "mounted cooling unit"
toggleable = 1
toggleable = TRUE
origin_tech = list(TECH_MAGNET = 2, TECH_MATERIAL = 2, TECH_ENGINEERING = 3)
interface_name = "mounted cooling unit"
interface_desc = "A heat sink with liquid cooled radiator."
@@ -765,13 +772,13 @@
use_power_cost = 5
module_cooldown = 25
usable = 1
usable = TRUE
category = MODULE_VAURCA
/obj/item/rig_module/boring/engage()
/obj/item/rig_module/boring/engage(atom/target, mob/user)
if (!..())
return 0
return FALSE
playsound(src,'sound/magic/lightningbolt.ogg',60,1)
var/turf/T = get_turf(holder.wearer)
@@ -781,8 +788,6 @@
else
T.ChangeTurf(/turf/space)
var/global/list/lattice_users = list()
/obj/item/rig_module/lattice
@@ -792,25 +797,25 @@ var/global/list/lattice_users = list()
interface_name = "neural lattice"
interface_desc = "Synchronize neural lattice to reduce pain."
disruptive = 0
disruptive = FALSE
toggleable = 1
confined_use = 1
toggleable = TRUE
confined_use = TRUE
category = MODULE_VAURCA
/obj/item/rig_module/lattice/activate()
if (!..())
return 0
return FALSE
var/mob/living/carbon/human/H = holder.wearer
to_chat(H, "<span class='notice'>Neural lattice engaged. Pain receptors altered.</span>")
to_chat(H, SPAN_NOTICE("Neural lattice engaged. Pain receptors altered."))
lattice_users.Add(H)
/obj/item/rig_module/lattice/deactivate()
if (!..())
return 0
return FALSE
var/mob/living/carbon/human/H = holder.wearer
to_chat(H, "<span class='notice'>Neural lattice disengaged. Pain receptors restored.</span>")
lattice_users.Remove(H)
to_chat(H, SPAN_NOTICE("Neural lattice disengaged. Pain receptors restored."))
lattice_users.Remove(H)
@@ -50,7 +50,6 @@
glasses = new /obj/item/clothing/glasses/hud/health
/obj/item/rig_module/vision
name = "hardsuit visor"
desc = "A layered, translucent visor system for a hardsuit."
icon_state = "optics"
@@ -58,10 +57,11 @@
interface_name = "optical scanners"
interface_desc = "An integrated multi-mode vision system."
usable = 1
toggleable = 1
disruptive = 0
confined_use = 1
engage_on_activate = FALSE
usable = TRUE
toggleable = TRUE
disruptive = FALSE
confined_use = TRUE
engage_string = "Cycle Visor Mode"
activate_string = "Enable Visor"
@@ -79,30 +79,29 @@
category = MODULE_GENERAL
/obj/item/rig_module/vision/multi
name = "hardsuit optical package"
desc = "A complete visor system of optical scanners and vision modes."
icon_state = "fulloptics"
interface_name = "multi optical visor"
interface_desc = "An integrated multi-mode vision system."
vision_modes = list(/datum/rig_vision/meson,
/datum/rig_vision/nvg,
/datum/rig_vision/thermal,
/datum/rig_vision/sechud,
/datum/rig_vision/medhud)
vision_modes = list(
/datum/rig_vision/meson,
/datum/rig_vision/nvg,
/datum/rig_vision/thermal,
/datum/rig_vision/sechud,
/datum/rig_vision/medhud
)
category = MODULE_SPECIAL
/obj/item/rig_module/vision/meson
name = "hardsuit meson/material scanner"
desc = "A layered, translucent visor system for a hardsuit."
icon_state = "meson"
usable = 0
usable = FALSE
construction_cost = list(DEFAULT_WALL_MATERIAL = 1500, MATERIAL_GLASS = 5000)
construction_time = 300
@@ -110,16 +109,17 @@
interface_name = "meson/material scanner"
interface_desc = "An integrated meson/material scanner."
vision_modes = list(/datum/rig_vision/meson,
/datum/rig_vision/material)
vision_modes = list(
/datum/rig_vision/meson,
/datum/rig_vision/material
)
/obj/item/rig_module/vision/thermal
name = "hardsuit thermal scanner"
desc = "A layered, translucent visor system for a hardsuit."
icon_state = "thermal"
usable = 0
usable = FALSE
interface_name = "thermal scanner"
interface_desc = "An integrated thermal scanner."
@@ -129,12 +129,11 @@
category = MODULE_LIGHT_COMBAT
/obj/item/rig_module/vision/nvg
name = "hardsuit night vision interface"
desc = "A multi input night vision system for a hardsuit."
icon_state = "night"
usable = 0
usable = FALSE
construction_cost = list(DEFAULT_WALL_MATERIAL = 1500, MATERIAL_GLASS = 5000, MATERIAL_URANIUM = 5000)
construction_time = 300
@@ -147,12 +146,11 @@
category = MODULE_LIGHT_COMBAT
/obj/item/rig_module/vision/sechud
name = "hardsuit security hud"
desc = "A simple tactical information system for a hardsuit."
icon_state = "securityhud"
usable = 0
usable = FALSE
construction_cost = list(DEFAULT_WALL_MATERIAL = 1500, MATERIAL_GLASS = 5000)
construction_time = 300
@@ -165,12 +163,11 @@
category = MODULE_LIGHT_COMBAT
/obj/item/rig_module/vision/medhud
name = "hardsuit medical hud"
desc = "A simple medical status indicator for a hardsuit."
icon_state = "healthhud"
usable = 0
usable = FALSE
construction_cost = list(DEFAULT_WALL_MATERIAL = 1500, MATERIAL_GLASS = 5000)
construction_time = 300
@@ -187,17 +184,12 @@
..()
holder.visor = src
/obj/item/rig_module/vision/engage()
var/starting_up = !active
/obj/item/rig_module/vision/engage(atom/target, mob/user)
if(!..() || !vision_modes)
return 0
// Don't cycle if this engage() is being called by activate().
if(starting_up)
to_chat(holder.wearer, "<font color='blue'>You activate your visual sensors.</font>")
return 1
return FALSE
if(!active)
to_chat(user, SPAN_WARNING("\The [src] isn't activated!"))
return FALSE
if(vision_modes.len > 1)
vision_index++
@@ -205,10 +197,10 @@
vision_index = 1
vision = vision_modes[vision_index]
to_chat(holder.wearer, "<font color='blue'>You cycle your sensors to <b>[vision.mode]</b> mode.</font>")
message_user(user, SPAN_NOTICE("You cycle \the [src] to <b>[vision.mode]</b> mode."), SPAN_NOTICE("\The [user] cycles \the [src] to <b>[vision.mode]</b> mode."))
else
to_chat(holder.wearer, "<font color='blue'>Your sensors only have one mode.</font>")
return 1
to_chat(user, SPAN_WARNING("\The [src] only has one mode."))
return TRUE
/obj/item/rig_module/vision/New()
..()
@@ -224,4 +216,4 @@
if(!vision) vision = vision_datum
processed_vision += vision_datum
vision_modes = processed_vision
vision_modes = processed_vision
+22 -14
View File
@@ -319,7 +319,7 @@
if(canremove)
for(var/obj/item/rig_module/module in installed_modules)
module.deactivate()
module.deactivate(initiator)
if(airtight)
update_component_sealed()
update_icon(1)
@@ -555,15 +555,21 @@
//TODO: Fix Topic vulnerabilities for malfunction and AI override.
/obj/item/rig/Topic(href,href_list)
if(!check_suit_access(usr))
if(ismob(href))
do_rig_thing(href, href_list)
return
do_rig_thing(usr, href_list)
/obj/item/rig/proc/do_rig_thing(mob/user, var/list/href_list)
if(!check_suit_access(user))
return 0
if(href_list["toggle_piece"])
if(ishuman(usr) && (usr.stat || usr.stunned || usr.lying))
return 0
toggle_piece(href_list["toggle_piece"], usr)
if(ishuman(user) && (user.stat || user.stunned || user.lying))
return FALSE
toggle_piece(href_list["toggle_piece"], user)
else if(href_list["toggle_seals"])
toggle_seals(usr)
toggle_seals(user)
else if(href_list["interact_module"])
var/module_index = text2num(href_list["interact_module"])
@@ -572,11 +578,11 @@
var/obj/item/rig_module/module = installed_modules[module_index]
switch(href_list["module_mode"])
if("activate")
module.activate()
module.activate(user)
if("deactivate")
module.deactivate()
module.deactivate(user)
if("engage")
module.engage()
module.engage(null, user)
if("select")
selected_module = module
if("select_charge_type")
@@ -587,9 +593,9 @@
else if(href_list["toggle_suit_lock"])
locked = !locked
usr.set_machine(src)
src.add_fingerprint(usr)
return 0
user.set_machine(src)
src.add_fingerprint(user)
return FALSE
/obj/item/rig/proc/notify_ai(var/message)
for(var/obj/item/rig_module/ai_container/module in installed_modules)
@@ -858,7 +864,6 @@
to_chat(user, "<span class='notice'>\The [wearer] is now [wearer.resting ? "resting" : "getting up"].</span>")
/obj/item/rig/proc/forced_move(var/direction, var/mob/user)
// Why is all this shit in client/Move()? Who knows?
if(world.time < wearer_move_delay)
return
@@ -866,6 +871,9 @@
if(!wearer || !wearer.loc || !ai_can_move_suit(user, check_user_module = 1))
return
if(!wearer.stat) // don't force move if our wearer is awake
return
//This is sota the goto stop mobs from moving var
if(wearer.transforming || !wearer.canmove)
return
@@ -936,7 +944,7 @@
wearer_move_delay += 2
return wearer.buckled.relaymove(wearer,direction)
cell.use(200) //Arbitrary, TODO
cell.use(10)
wearer.Move(get_step(get_turf(wearer),direction),direction)
// This returns the rig if you are contained inside one, but not if you are wearing it
@@ -95,7 +95,7 @@
for(var/obj/item/rig_module/module in suit.installed_modules)
if(module.active && module.activates_on_touch)
if(module.engage(A))
if(module.engage(A, H))
return 1
return 0
@@ -35,9 +35,9 @@
return
if(!visor.active)
visor.activate()
visor.activate(usr)
else
visor.deactivate()
visor.deactivate(usr)
/obj/item/rig/proc/toggle_helmet()
@@ -156,13 +156,13 @@
return
if(!visor.active)
visor.activate()
visor.activate(usr)
if(!visor.active)
to_chat(usr, "<span class='warning'>The visor is suffering a hardware fault and cannot be configured.</span>")
return
visor.engage()
visor.engage(null, usr)
/obj/item/rig/verb/alter_voice()
@@ -186,7 +186,7 @@
to_chat(usr, "<span class='warning'>The hardsuit does not have a speech synthesiser.</span>")
return
speech.engage()
speech.engage(null, usr)
/obj/item/rig/verb/select_module()
@@ -257,10 +257,10 @@
if(module.active)
to_chat(usr, "<font color='blue'><b>You attempt to deactivate \the [module.interface_name].</b></font>")
module.deactivate()
module.deactivate(usr)
else
to_chat(usr, "<font color='blue'><b>You attempt to activate \the [module.interface_name].</b></font>")
module.activate()
module.activate(usr)
/obj/item/rig/verb/engage_module()
@@ -294,4 +294,4 @@
return
to_chat(usr, "<font color='blue'><b>You attempt to engage the [module.interface_name].</b></font>")
module.engage()
module.engage(null, usr)
+1
View File
@@ -68,6 +68,7 @@
var/digspeed //moving the delay to an item var so R&D can make improved picks. --NEO
origin_tech = list(TECH_MATERIAL = 1, TECH_ENGINEERING = 1)
attack_verb = list("hit", "pierced", "sliced", "attacked")
hitsound = 'sound/weapons/rapidslice.ogg'
var/drill_sound = "pickaxe"
var/drill_verb = "excavating"
var/autodrill = 0 //pickaxes must be manually swung to mine, drills can mine rocks via bump
+10 -7
View File
@@ -176,18 +176,21 @@ note dizziness decrements automatically in the mob's Life() proc.
animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, time = 2)
animate(pixel_x = pixel_x - pixel_x_diff, pixel_y = pixel_y - pixel_y_diff, time = 2)
/mob/do_attack_animation(atom/A)
/mob/do_attack_animation(atom/A, var/atom/attack_item)
..()
is_floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
// What icon do we use for the attack?
var/image/I
if(hand && l_hand) // Attacked with item in left hand.
I = image(l_hand.icon, A, l_hand.icon_state, A.layer + 1)
else if (!hand && r_hand) // Attacked with item in right hand.
I = image(r_hand.icon, A, r_hand.icon_state, A.layer + 1)
else // Attacked with a fist?
return
if(attack_item)
I = image(attack_item.icon, A, attack_item.icon_state, A.layer + 1)
else
if(hand && l_hand) // Attacked with item in left hand.
I = image(l_hand.icon, A, l_hand.icon_state, A.layer + 1)
else if (!hand && r_hand) // Attacked with item in right hand.
I = image(r_hand.icon, A, r_hand.icon_state, A.layer + 1)
else // Attacked with a fist?
return
// Who can see the attack?
var/list/viewing = list()
+1 -2
View File
@@ -107,7 +107,7 @@
if(M.a_intent != I_HELP)
var/action
switch(a_intent)
switch(M.a_intent)
if(I_GRAB)
action = "grabbed"
if(I_DISARM)
@@ -133,7 +133,6 @@
visible_message(SPAN_NOTICE("[M] [action] [src] waking [t_him] up!"))
sleeping = 0
willfully_sleeping = FALSE
return
/mob/living/carbon/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/def_zone = null, var/tesla_shock = 0, var/ground_zero)
if(status_flags & GODMODE)
+5 -2
View File
@@ -320,7 +320,8 @@
if(pointblank)
process_point_blank(projectile, user, target)
if(process_projectile(projectile, user, target, user.zone_sel.selecting, clickparams))
var/selected_zone = user.zone_sel ? user.zone_sel.selecting : BP_CHEST
if(process_projectile(projectile, user, target, selected_zone, clickparams))
var/show_emote = TRUE
if(i > 1 && burst_delay < 3 && burst < 5)
show_emote = FALSE
@@ -626,10 +627,12 @@
return new_mode
/obj/item/gun/attack_self(mob/user)
/obj/item/gun/attack_self(mob/user, var/list/message_mobs)
var/datum/firemode/new_mode = switch_firemodes(user)
if(new_mode)
to_chat(user, SPAN_NOTICE("\The [src] is now set to [new_mode.name]."))
for(var/M in message_mobs)
to_chat(M, SPAN_NOTICE("[user] has set \the [src] to [new_mode.name]."))
// Safety Procs