diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index 8b4416cc41d..7383c441813 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -12,6 +12,27 @@
var/enemy_mp = 20
var/gameover = 0
var/blocked = 0 //Player cannot attack/heal while set
+ var/list/prizes = list( /obj/item/toy/snappopbox = 2,
+ /obj/item/toy/blink = 2,
+ /obj/item/clothing/under/syndicate/tacticool = 2,
+ /obj/item/toy/sword = 2,
+ /obj/item/toy/gun = 2,
+ /obj/item/toy/crossbow = 2,
+ /obj/item/clothing/suit/syndicatefake = 2,
+ /obj/item/weapon/storage/crayonbox = 2,
+ /obj/item/toy/spinningtoy = 2,
+ /obj/item/toy/prize/ripley = 1,
+ /obj/item/toy/prize/fireripley = 1,
+ /obj/item/toy/prize/deathripley = 1,
+ /obj/item/toy/prize/gygax = 1,
+ /obj/item/toy/prize/durand = 1,
+ /obj/item/toy/prize/honk = 1,
+ /obj/item/toy/prize/marauder = 1,
+ /obj/item/toy/prize/seraph = 1,
+ /obj/item/toy/prize/mauler = 1,
+ /obj/item/toy/prize/odysseus = 1,
+ /obj/item/toy/prize/phazon = 1
+ )
/obj/machinery/computer/arcade
var/turtle = 0
@@ -139,30 +160,15 @@
emagged = 0
else if(!contents.len)
- var/prizeselect = pick(1,2,3,4,5,6,7,8,9)
- switch(prizeselect)
- if(1)
- new /obj/item/toy/snappopbox(src.loc)
- if(2)
- new /obj/item/toy/blink(src.loc)
- if(3)
- new /obj/item/clothing/under/syndicate/tacticool(src.loc)
- if(4)
- new /obj/item/toy/sword(src.loc)
- if(5)
- new /obj/item/toy/ammo/gun(src.loc)
- new /obj/item/toy/gun(src.loc)
- if(6)
- new /obj/item/toy/crossbow(src.loc)
- if(7)
- new /obj/item/clothing/suit/syndicatefake(src.loc)
- new /obj/item/clothing/head/syndicatefake(src.loc)
- if(8)
- new /obj/item/weapon/storage/crayonbox(src.loc)
- if(9)
- new /obj/item/toy/spinningtoy(src.loc)
- // if(10) //Commented out on Urist-chan's orders~
- // new /obj/item/toy/balloon(src.loc) //Until it gets a better sprite~
+ var/prizeselect = pickweight(prizes)
+ new prizeselect(src.loc)
+
+ if(istype(prizeselect, /obj/item/toy/gun)) //Ammo comes with the gun
+ new /obj/item/toy/ammo/gun(src.loc)
+
+ else if(istype(prizeselect, /obj/item/clothing/suit/syndicatefake)) //Helmet is part of the suit
+ new /obj/item/clothing/head/syndicatefake(src.loc)
+
else
var/atom/movable/Prize = pick(contents)
Prize.loc = src.loc
diff --git a/code/game/magic/cultist/runes.dm b/code/game/magic/cultist/runes.dm
index 489639b3c1f..9adbf418d15 100644
--- a/code/game/magic/cultist/runes.dm
+++ b/code/game/magic/cultist/runes.dm
@@ -950,7 +950,7 @@ var/list/sacrificed = list()
usr.say("Fuu ma'jin!")
for(var/mob/living/L in viewers(src))
- if(iscarbon(L) && !iscultist(L))
+ if(iscarbon(L))
var/mob/living/carbon/C = L
flick("e_flash", C.flash)
if(C.stuttering < 1 && (!(HULK in C.mutations)))
diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm
new file mode 100644
index 00000000000..9e3e63ef65b
--- /dev/null
+++ b/code/game/mecha/equipment/tools/medical_tools.dm
@@ -0,0 +1,654 @@
+/obj/item/mecha_parts/mecha_equipment/tool/sleeper
+ name = "Mounted Sleeper"
+ desc = "Mounted Sleeper. (Can be attached to: Medical Exosuits)"
+ icon = 'Cryogenic2.dmi'
+ icon_state = "sleeper_0"
+ origin_tech = "programming=2;biotech=3"
+ energy_drain = 20
+ range = MELEE
+ construction_cost = list("metal"=5000,"glass"=10000)
+ reliability = 1000
+ equip_cooldown = 20
+ var/mob/living/carbon/occupant = null
+ var/datum/global_iterator/pr_mech_sleeper
+ var/inject_amount = 10
+ salvageable = 0
+
+ can_attach(obj/mecha/medical/M)
+ if(..())
+ if(istype(M))
+ return 1
+ return 0
+
+ New()
+ ..()
+ pr_mech_sleeper = new /datum/global_iterator/mech_sleeper(list(src),0)
+ pr_mech_sleeper.set_delay(equip_cooldown)
+ return
+
+ allow_drop()
+ return 0
+
+ destroy()
+ for(var/atom/movable/AM in src)
+ AM.forceMove(get_turf(src))
+ return ..()
+
+ Exit(atom/movable/O)
+ return 0
+
+ action(var/mob/living/carbon/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
+ for(var/mob/living/carbon/metroid/M in range(1,target))
+ if(M.Victim == target)
+ occupant_message("[target] will not fit into the sleeper because they have a Metroid latched onto their head.")
+ 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)
+ /*
+ 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
+
+ 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 = null
+ pr_mech_sleeper.stop()
+ set_ready_state(1)
+ return
+
+ detach()
+ if(occupant)
+ occupant_message("Unable to detach [src] - equipment occupied.")
+ return
+ pr_mech_sleeper.stop()
+ return ..()
+
+ get_equip_info()
+ var/output = ..()
+ if(output)
+ var/temp = ""
+ if(occupant)
+ temp = "
\[Occupant: [occupant] (Health: [occupant.health]%)\]
View stats|Eject"
+ return "[output] [temp]"
+ return
+
+ Topic(href,href_list)
+ ..()
+ var/datum/topic_input/filter = new /datum/topic_input(href,href_list)
+ if(filter.get("eject"))
+ go_out()
+ if(filter.get("view_stats"))
+ chassis.occupant << browse(get_occupant_stats(),"window=msleeper")
+ onclose(chassis.occupant, "msleeper")
+ return
+ if(filter.get("inject"))
+ inject_reagent(filter.getType("inject",/datum/reagent),filter.getObj("source"))
+ return
+
+ proc/get_occupant_stats()
+ if(!occupant)
+ return
+ return {"
+
+ [occupant] statistics
+
+
+
+
+ Health statistics
+
+ [get_occupant_dam()]
+
+ Reagents in bloodstream
+
+ [get_occupant_reagents()]
+
+
+ [get_available_reagents()]
+
+
+ "}
+
+ 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()]%
+ "}
+
+ 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"
+
+ 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
+
+
+ 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*2)
+ SG.reagents.trans_id_to(occupant,R.id,to_inject)
+ occupant_message("[occupant] injected with [to_inject] units of [R.name].")
+ log_message("[occupant] injected with [to_inject] units of [R.name].")
+ update_equip_info()
+ return
+
+ 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
+
+/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
+
+
+/obj/item/mecha_parts/mecha_equipment/tool/cable_layer
+ name = "Cable Layer"
+ icon_state = "mecha_wire"
+ var/datum/event/event
+ var/turf/old_turf
+ var/obj/structure/cable/last_piece
+ var/obj/item/weapon/cable_coil/cable
+ var/max_cable = 1000
+
+ New()
+ cable = new(src)
+ cable.amount = 0
+ ..()
+
+ can_attach(obj/mecha/working/M)
+ if(..())
+ if(istype(M))
+ return 1
+ return 0
+
+ attach()
+ ..()
+ event = chassis.events.addEvent("onMove",src,"layCable")
+ return
+
+ detach()
+ chassis.events.clearEvent("onMove",event)
+ return ..()
+
+ destroy()
+ chassis.events.clearEvent("onMove",event)
+ return ..()
+
+ action(var/obj/item/weapon/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
+
+ 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/weapon/cable_coil/CC = new (get_turf(chassis))
+ CC.amount = m
+ else
+ occupant_message("There's no more cable on the reel.")
+ return
+
+ 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
+
+ proc/load_cable(var/obj/item/weapon/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
+
+ 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
+
+ proc/reset()
+ last_piece = null
+
+ proc/dismantleFloor(var/turf/new_turf)
+ if(istype(new_turf, /turf/simulated/floor))
+ var/turf/simulated/floor/T = new_turf
+ if(!T.is_plating())
+ if(!T.broken && !T.burnt)
+ new T.floor_tile.type(T)
+ T.make_plating()
+ return !new_turf.intact
+
+ proc/layCable(var/turf/new_turf)
+ if(equip_ready || !istype(new_turf) || !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.updateicon()
+ var/netnum
+ 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.updateicon()
+ netnum = last_piece.netnum
+ if(netnum)
+ NC.netnum = netnum
+ PN = powernets[netnum]
+ else
+ PN = new()
+ PN.number = powernets.len + 1
+ powernets += PN
+ NC.netnum = PN.number
+ PN.cables += NC
+ NC.mergeConnectedNetworks(NC.d2)
+ //NC.mergeConnectedNetworksOnTurf()
+ last_piece = NC
+ return 1
+
+/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 = '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 = "materials=3;biotech=4;magnets=4;programming=3"
+ construction_time = 200
+ construction_cost = list("metal"=3000,"glass"=2000)
+
+ New()
+ ..()
+ flags |= NOREACT
+ syringes = new
+ known_reagents = list("inaprovaline"="Inaprovaline","anti_toxin"="Anti-Toxin (Dylovene)")
+ processed_reagents = new
+ create_reagents(max_volume)
+ synth = new (list(src),0)
+
+ detach()
+ synth.stop()
+ return ..()
+
+ critfail()
+ ..()
+ flags &= ~NOREACT
+ return
+
+ can_attach(obj/mecha/medical/M)
+ if(..())
+ if(istype(M))
+ return 1
+ return 0
+
+ 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
+
+ action(atom/movable/target)
+ if(!action_checks(target))
+ return
+ if(istype(target,/obj/item/weapon/reagent_containers/syringe))
+ return load_syringe(target)
+ 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(S, min(S.volume, reagents.total_volume))
+ syringes -= S
+ S.icon = 'chemical.dmi'
+ S.icon_state = "syringeproj"
+ playsound(chassis, '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(M, S.reagents.total_volume)
+ 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
+
+
+ Topic(href,href_list)
+ ..()
+ var/datum/topic_input/filter = new (href,href_list)
+ if(filter.get("toggle_mode"))
+ mode = !mode
+ update_equip_info()
+ return
+ if(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 = 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(filter.get("show_reagents"))
+ chassis.occupant << browse(get_reagents_page(),"window=msyringegun")
+ if(filter.get("purge_reagent"))
+ var/reagent = filter.get("purge_reagent")
+ if(reagent)
+ reagents.del_reagent(reagent)
+ return
+ if(filter.get("purge_all"))
+ reagents.clear_reagents()
+ return
+ return
+
+ proc/get_reagents_page()
+ var/output = {"
+
+ Reagent Synthesizer
+
+
+
+
+ Current reagents:
+
+ [get_current_reagents()]
+
+ Reagents production:
+
+ [get_reagents_form()]
+
+
+
+ "}
+ return output
+
+ proc/get_reagents_form()
+ var/r_list = get_reagents_list()
+ var/inputs
+ if(r_list)
+ inputs += ""
+ inputs += ""
+ inputs += ""
+ var/output = {"
+ [r_list? "Only the first [synth_speed] selected reagent\s will be added to production" : null]
+ "}
+ return output
+
+ 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
+
+ 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"
+
+ proc/load_syringe(obj/item/weapon/reagent_containers/syringe/S)
+ if(syringes.lenNo 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("Analyzis complete.")
+ return 1
+
+ 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
+
+
+ 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
+
+ on_reagent_change()
+ ..()
+ update_equip_info()
+ return
+
+/datum/global_iterator/mech_synth
+ delay = 100
+
+ 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()
+ if(anyprob(S.reliability))
+ S.critfail()
+ 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
\ 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 c842621b8f6..918410e56c6 100644
--- a/code/game/mecha/equipment/tools/tools.dm
+++ b/code/game/mecha/equipment/tools/tools.dm
@@ -979,708 +979,6 @@
return 1
-/obj/item/mecha_parts/mecha_equipment/tool/sleeper
- name = "Mounted Sleeper"
- desc = "Mounted Sleeper. (Can be attached to: Medical Exosuits)"
- icon = 'Cryogenic2.dmi'
- icon_state = "sleeper_0"
- origin_tech = "programming=2;biotech=3"
- energy_drain = 20
- range = MELEE
- construction_cost = list("metal"=5000,"glass"=10000)
- reliability = 1000
- equip_cooldown = 20
- var/mob/living/carbon/occupant = null
- var/datum/global_iterator/pr_mech_sleeper
- var/inject_amount = 10
- salvageable = 0
-
- can_attach(obj/mecha/medical/M)
- if(..())
- if(istype(M))
- return 1
- return 0
-
- New()
- ..()
- pr_mech_sleeper = new /datum/global_iterator/mech_sleeper(list(src),0)
- pr_mech_sleeper.set_delay(equip_cooldown)
- return
-
- allow_drop()
- return 0
-
- destroy()
- for(var/atom/movable/AM in src)
- AM.forceMove(get_turf(src))
- return ..()
-
- Exit(atom/movable/O)
- return 0
-
- action(var/mob/living/carbon/target)
- if(!action_checks(target))
- return
- if(!istype(target))
- return
- if(occupant)
- occupant_message("The sleeper is already occupied")
- return
- for(var/mob/living/carbon/metroid/M in range(1,target))
- if(M.Victim == target)
- occupant_message("[target] will not fit into the sleeper because they have a Metroid latched onto their head.")
- 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)
- /*
- 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
-
- 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 = null
- pr_mech_sleeper.stop()
- set_ready_state(1)
- return
-
- detach()
- if(occupant)
- occupant_message("Unable to detach [src] - equipment occupied.")
- return
- pr_mech_sleeper.stop()
- return ..()
-
- get_equip_info()
- var/output = ..()
- if(output)
- var/temp = ""
- if(occupant)
- temp = "
\[Occupant: [occupant] (Health: [occupant.health]%)\]
View stats|Eject"
- return "[output] [temp]"
- return
-
- Topic(href,href_list)
- ..()
- var/datum/topic_input/filter = new /datum/topic_input(href,href_list)
- if(filter.get("eject"))
- go_out()
- if(filter.get("view_stats"))
- chassis.occupant << browse(get_occupant_stats(),"window=msleeper")
- onclose(chassis.occupant, "msleeper")
- return
- if(filter.get("inject"))
- inject_reagent(filter.getType("inject",/datum/reagent),filter.getObj("source"))
- return
-
- proc/get_occupant_stats()
- if(!occupant)
- return
- return {"
-
- [occupant] statistics
-
-
-
-
- Health statistics
-
- [get_occupant_dam()]
-
- Reagents in bloodstream
-
- [get_occupant_reagents()]
-
-
- [get_available_reagents()]
-
-
- "}
-
- 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()]%
- "}
-
- 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"
-
- 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
-
-
- 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*2)
- SG.reagents.trans_id_to(occupant,R.id,to_inject)
- occupant_message("[occupant] injected with [to_inject] units of [R.name].")
- log_message("[occupant] injected with [to_inject] units of [R.name].")
- update_equip_info()
- return
-
- 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
-
-/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
-
-
-/obj/item/mecha_parts/mecha_equipment/tool/cable_layer
- name = "Cable Layer"
- icon_state = "mecha_wire"
- var/datum/event/event
- var/turf/old_turf
- var/obj/structure/cable/last_piece
- var/obj/item/weapon/cable_coil/cable
- var/max_cable = 1000
-
- New()
- cable = new(src)
- cable.amount = 0
- ..()
-
- can_attach(obj/mecha/working/M)
- if(..())
- if(istype(M))
- return 1
- return 0
-
- attach()
- ..()
- event = chassis.events.addEvent("onMove",src,"layCable")
- return
-
- detach()
- chassis.events.clearEvent("onMove",event)
- return ..()
-
- destroy()
- chassis.events.clearEvent("onMove",event)
- return ..()
-
- action(var/obj/item/weapon/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
-
- 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/weapon/cable_coil/CC = new (get_turf(chassis))
- CC.amount = m
- else
- occupant_message("There's no more cable on the reel.")
- return
-
- 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
-
- proc/load_cable(var/obj/item/weapon/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
-
- 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
-
- proc/reset()
- last_piece = null
-
- proc/dismantleFloor(var/turf/new_turf)
- if(istype(new_turf, /turf/simulated/floor))
- var/turf/simulated/floor/T = new_turf
- if(!T.is_plating())
- if(!T.broken && !T.burnt)
- new T.floor_tile.type(T)
- T.make_plating()
- return !new_turf.intact
-
- proc/layCable(var/turf/new_turf)
- if(equip_ready || !istype(new_turf) || !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.updateicon()
- var/netnum
- 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.updateicon()
- netnum = last_piece.netnum
- if(netnum)
- NC.netnum = netnum
- PN = powernets[netnum]
- else
- PN = new()
- PN.number = powernets.len + 1
- powernets += PN
- NC.netnum = PN.number
- PN.cables += NC
- NC.mergeConnectedNetworks(NC.d2)
- //NC.mergeConnectedNetworksOnTurf()
- last_piece = NC
- return 1
-
-/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 = '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 = "materials=3;biotech=4;magnets=4;programming=3"
- construction_time = 200
- construction_cost = list("metal"=3000,"glass"=2000)
-
- New()
- ..()
- flags |= NOREACT
- syringes = new
- known_reagents = list("inaprovaline"="Inaprovaline","anti_toxin"="Anti-Toxin (Dylovene)")
- processed_reagents = new
- create_reagents(max_volume)
- synth = new (list(src),0)
-
- detach()
- synth.stop()
- return ..()
-
- critfail()
- ..()
- flags &= ~NOREACT
- return
-
- can_attach(obj/mecha/medical/M)
- if(..())
- if(istype(M))
- return 1
- return 0
-
- 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
-
- action(atom/movable/target)
- if(!action_checks(target))
- return
- if(istype(target,/obj/item/weapon/reagent_containers/syringe))
- return load_syringe(target)
- 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(S, min(S.volume, reagents.total_volume))
- syringes -= S
- S.icon = 'chemical.dmi'
- S.icon_state = "syringeproj"
- playsound(chassis, '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(M, S.reagents.total_volume)
- 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
-
-
- Topic(href,href_list)
- ..()
- var/datum/topic_input/filter = new (href,href_list)
- if(filter.get("toggle_mode"))
- mode = !mode
- update_equip_info()
- return
- if(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 = 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(filter.get("show_reagents"))
- chassis.occupant << browse(get_reagents_page(),"window=msyringegun")
- if(filter.get("purge_reagent"))
- var/reagent = filter.get("purge_reagent")
- if(reagent)
- reagents.del_reagent(reagent)
- return
- if(filter.get("purge_all"))
- reagents.clear_reagents()
- return
- return
-
- proc/get_reagents_page()
- var/output = {"
-
- Reagent Synthesizer
-
-
-
-
- Current reagents:
-
- [get_current_reagents()]
-
- Reagents production:
-
- [get_reagents_form()]
-
-
-
- "}
- return output
-
- proc/get_reagents_form()
- var/r_list = get_reagents_list()
- var/inputs
- if(r_list)
- inputs += ""
- inputs += ""
- inputs += ""
- var/output = {"
- [r_list? "Only the first [synth_speed] selected reagent\s will be added to production" : null]
- "}
- return output
-
- 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
-
- 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"
-
- proc/load_syringe(obj/item/weapon/reagent_containers/syringe/S)
- if(syringes.lenNo 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("Analyzis complete.")
- return 1
-
- 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
-
-
- 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
-
- on_reagent_change()
- ..()
- update_equip_info()
- return
-
-/datum/global_iterator/mech_synth
- delay = 100
-
- 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()
- if(anyprob(S.reliability))
- S.critfail()
- 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/defence_shocker
- name = "Exosuit Defence Shocker"
- desc = ""
- icon_state = "mecha_teleport"
- equip_cooldown = 10
- energy_drain = 100
- range = RANGED
- var/shock_damage = 15
- var/active
-
- can_attach(obj/mecha/M as obj)
- if(..())
- if(!istype(M, /obj/mecha/combat/honker))
- if(!M.proc_res["dynattackby"] && !M.proc_res["dynattackhand"] && !M.proc_res["dynattackalien"])
- return 1
- return 0
-
- attach(obj/mecha/M as obj)
- ..()
- chassis.proc_res["dynattackby"] = src
- return
-
- proc/dynattackby(obj/item/weapon/W as obj, mob/user as mob)
- if(!action_checks(user) || !active)
- return
- user.electrocute_act(shock_damage, src)
- return chassis.dynattackby(W,user)
-*/
-
-/*
-/obj/item/mecha_parts/mecha_equipment/book_stocker
-
- action(var/mob/target)
- if(!istype(target))
- return
- if(target.search_contents_for(/obj/item/book/WGW))
- target.gib()
- target.client.gib()
- target.client.mom.monkeyize()
- target.client.mom.gib()
- for(var/mob/M in range(target, 1000))
- M.gib()
- explosion(target.loc,100000,100000,100000)
- usr.gib()
- world.Reboot()
- return 1
-
-*/
//This is pretty much just for the death-ripley so that it is harmless
/obj/item/mecha_parts/mecha_equipment/tool/safety_clamp
@@ -1746,106 +1044,4 @@
set_ready_state(0)
chassis.use_power(energy_drain)
do_after_cooldown()
- return 1
-
-/*
-//NEEDS SPRITE! (When this gets uncommented search for 'TODO MECHA JETPACK SPRITE MISSING' through code to uncomment the place where it's missing.)
-/obj/item/mecha_parts/mecha_equipment/jetpack
- name = "Jetpack"
- desc = "Using directed ion bursts and cunning solar wind reflection technique, this device enables controlled space flight."
- icon_state = "mecha_equip"
- equip_cooldown = 5
- energy_drain = 50
- var/wait = 0
- var/datum/effect/effect/system/ion_trail_follow/ion_trail
-
-
- can_attach(obj/mecha/M as obj)
- if(!(locate(src.type) in M.equipment) && !M.proc_res["dyndomove"])
- return ..()
-
- detach()
- ..()
- chassis.proc_res["dyndomove"] = null
- return
-
- attach(obj/mecha/M as obj)
- ..()
- if(!ion_trail)
- ion_trail = new
- ion_trail.set_up(chassis)
- return
-
- proc/toggle()
- if(!chassis)
- return
- !equip_ready? turn_off() : turn_on()
- return equip_ready
-
- proc/turn_on()
- set_ready_state(0)
- chassis.proc_res["dyndomove"] = src
- ion_trail.start()
- occupant_message("Activated")
- log_message("Activated")
-
- proc/turn_off()
- set_ready_state(1)
- chassis.proc_res["dyndomove"] = null
- ion_trail.stop()
- occupant_message("Deactivated")
- log_message("Deactivated")
-
- 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.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
-
- action_checks()
- if(equip_ready || wait)
- return 0
- if(energy_drain && !chassis.has_charge(energy_drain))
- return 0
- if(crit_fail)
- return 0
- if(chassis.check_for_support())
- return 0
- return 1
-
- get_equip_info()
- if(!chassis) return
- return "* [src.name] \[Toggle\]"
-
-
- Topic(href,href_list)
- ..()
- if(href_list["toggle"])
- toggle()
-
- do_after_cooldown()
- sleep(equip_cooldown)
- wait = 0
- return 1
-*/
-
+ return 1
\ No newline at end of file
diff --git a/code/game/mecha/equipment/tools/unused_tools.dm b/code/game/mecha/equipment/tools/unused_tools.dm
new file mode 100644
index 00000000000..73485ed05e8
--- /dev/null
+++ b/code/game/mecha/equipment/tools/unused_tools.dm
@@ -0,0 +1,157 @@
+
+
+
+/****** Do not tick this file in without looking over this code first ******/
+
+
+
+
+
+//NEEDS SPRITE! (When this gets ticked in search for 'TODO MECHA JETPACK SPRITE MISSING' through code to uncomment the place where it's missing.)
+/obj/item/mecha_parts/mecha_equipment/jetpack
+ name = "Jetpack"
+ desc = "Using directed ion bursts and cunning solar wind reflection technique, this device enables controlled space flight."
+ icon_state = "mecha_equip"
+ equip_cooldown = 5
+ energy_drain = 50
+ var/wait = 0
+ var/datum/effect/effect/system/ion_trail_follow/ion_trail
+
+
+ can_attach(obj/mecha/M as obj)
+ if(!(locate(src.type) in M.equipment) && !M.proc_res["dyndomove"])
+ return ..()
+
+ detach()
+ ..()
+ chassis.proc_res["dyndomove"] = null
+ return
+
+ attach(obj/mecha/M as obj)
+ ..()
+ if(!ion_trail)
+ ion_trail = new
+ ion_trail.set_up(chassis)
+ return
+
+ proc/toggle()
+ if(!chassis)
+ return
+ !equip_ready? turn_off() : turn_on()
+ return equip_ready
+
+ proc/turn_on()
+ set_ready_state(0)
+ chassis.proc_res["dyndomove"] = src
+ ion_trail.start()
+ occupant_message("Activated")
+ log_message("Activated")
+
+ proc/turn_off()
+ set_ready_state(1)
+ chassis.proc_res["dyndomove"] = null
+ ion_trail.stop()
+ occupant_message("Deactivated")
+ log_message("Deactivated")
+
+ 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.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
+
+ action_checks()
+ if(equip_ready || wait)
+ return 0
+ if(energy_drain && !chassis.has_charge(energy_drain))
+ return 0
+ if(crit_fail)
+ return 0
+ if(chassis.check_for_support())
+ return 0
+ return 1
+
+ get_equip_info()
+ if(!chassis) return
+ return "* [src.name] \[Toggle\]"
+
+
+ Topic(href,href_list)
+ ..()
+ if(href_list["toggle"])
+ toggle()
+
+ do_after_cooldown()
+ sleep(equip_cooldown)
+ wait = 0
+ return 1
+
+
+/obj/item/mecha_parts/mecha_equipment/defence_shocker
+ name = "Exosuit Defence Shocker"
+ desc = ""
+ icon_state = "mecha_teleport"
+ equip_cooldown = 10
+ energy_drain = 100
+ range = RANGED
+ var/shock_damage = 15
+ var/active
+
+ can_attach(obj/mecha/M as obj)
+ if(..())
+ if(!istype(M, /obj/mecha/combat/honker))
+ if(!M.proc_res["dynattackby"] && !M.proc_res["dynattackhand"] && !M.proc_res["dynattackalien"])
+ return 1
+ return 0
+
+ attach(obj/mecha/M as obj)
+ ..()
+ chassis.proc_res["dynattackby"] = src
+ return
+
+ proc/dynattackby(obj/item/weapon/W as obj, mob/user as mob)
+ if(!action_checks(user) || !active)
+ return
+ user.electrocute_act(shock_damage, src)
+ return chassis.dynattackby(W,user)
+
+
+/*
+/obj/item/mecha_parts/mecha_equipment/book_stocker
+
+ action(var/mob/target)
+ if(!istype(target))
+ return
+ if(target.search_contents_for(/obj/item/book/WGW))
+ target.gib()
+ target.client.gib()
+ target.client.mom.monkeyize()
+ target.client.mom.gib()
+ for(var/mob/M in range(target, 1000))
+ M.gib()
+ explosion(target.loc,100000,100000,100000)
+ usr.gib()
+ world.Reboot()
+ return 1
+
+*/
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index a06bc34e3c1..8325b6c7509 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -4,6 +4,7 @@
see_invisible = 15
see_in_dark = 100
verbs += /mob/dead/observer/proc/dead_tele
+ stat = DEAD
if(body)
var/turf/location = get_turf(body)//Where is the mob located?
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index 06b9cbde981..0a42cb9e11f 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -40,16 +40,17 @@
/mob/living/carbon/human/death(gibbed)
+
if(halloss > 0 && (!gibbed))
- //hallucination = 0
halloss = 0
- // And the suffocation was a hallucination (lazy)
- //oxyloss = 0
return
+
if(src.stat == 2)
return
+
if(src.healths)
src.healths.icon_state = "health5"
+
src.stat = 2
src.dizziness = 0
src.jitteriness = 0
diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm
index 7e3559d58fa..8096b9681f3 100644
--- a/code/modules/mob/living/silicon/ai/life.dm
+++ b/code/modules/mob/living/silicon/ai/life.dm
@@ -48,10 +48,8 @@
blind = 1
if (!blind) //lol? if(!blind) #if(src.blind.layer) <--something here is clearly wrong :P
- //I'll get back to this when I find out how this is -supposed- to work ~Carn
+ //I'll get back to this when I find out how this is -supposed- to work ~Carn //removed this shit since it was confusing as all hell --39kk9t
//stage = 4.5
-// if (src.blind.layer!=0)
-// src.blind.layer = 0
src.sight |= SEE_TURFS
src.sight |= SEE_MOBS
src.sight |= SEE_OBJS
@@ -66,6 +64,7 @@
if (src:aiRestorePowerRoutine==2)
src << "Alert cancelled. Power has been restored without our assistance."
src:aiRestorePowerRoutine = 0
+ src.blind.layer = 0
spawn(1)
while (src.getOxyLoss()>0 && stat!=2)
sleep(50)
@@ -75,6 +74,7 @@
else if (src:aiRestorePowerRoutine==3)
src << "Alert cancelled. Power has been restored."
src:aiRestorePowerRoutine = 0
+ src.blind.layer = 0
spawn(1)
while (src.getOxyLoss()>0 && stat!=2)
sleep(50)
@@ -115,6 +115,7 @@
if (!istype(T, /turf/space))
src << "Alert cancelled. Power has been restored without our assistance."
src:aiRestorePowerRoutine = 0
+ src.blind.layer = 0
return
src << "Fault confirmed: missing external power. Shutting down main control system to save power."
sleep(20)
@@ -134,97 +135,40 @@
theAPC = something
break
*/
- for (var/obj/machinery/power/apc/APC in loc)
- if (!(APC.stat & BROKEN))
- theAPC = APC
- break
- if (theAPC==null)
- src << "Unable to locate APC!"
- src:aiRestorePowerRoutine = 2
- return
- if (loc.master.power_equip)
- if (!istype(T, /turf/space))
- src << "Alert cancelled. Power has been restored without our assistance."
- src:aiRestorePowerRoutine = 0
- return
- src << "APC located. Optimizing route to APC to avoid needless power waste."
- sleep(50)
- theAPC = null
-/*
- for (var/something in loc)
- if (istype(something, /obj/machinery/power/apc))
- if (!(something:stat & BROKEN))
- theAPC = something
+ var/PRP //like ERP with the code, at least this stuff is no more 4x sametext
+ for (PRP=1, PRP<=4, PRP++)
+ for (var/obj/machinery/power/apc/APC in loc)
+ if (!(APC.stat & BROKEN))
+ theAPC = APC
break
-*/
- for (var/obj/machinery/power/apc/APC in loc)
- if (!(APC.stat & BROKEN))
- theAPC = APC
- break
- if (theAPC==null)
- src << "APC connection lost!"
- src:aiRestorePowerRoutine = 2
- return
- if (loc.master.power_equip)
- if (!istype(T, /turf/space))
- src << "Alert cancelled. Power has been restored without our assistance."
- src:aiRestorePowerRoutine = 0
+ if (!theAPC)
+ switch(PRP)
+ if (1) src << "Unable to locate APC!"
+ else src << "Lost connection with the APC!"
+ src:aiRestorePowerRoutine = 2
return
- src << "Best route identified. Hacking offline APC power port."
- sleep(50)
- theAPC = null
-/*
- for (var/something in loc)
- if (istype(something, /obj/machinery/power/apc))
- if (!(something:stat & BROKEN))
- theAPC = something
- break
-*/
- for (var/obj/machinery/power/apc/APC in loc)
- if (!(APC.stat & BROKEN))
- theAPC = APC
- break
- if (theAPC==null)
- src << "APC connection lost!"
- src:aiRestorePowerRoutine = 2
- return
- if (loc.master.power_equip)
- if (!istype(T, /turf/space))
- src << "Alert cancelled. Power has been restored without our assistance."
- src:aiRestorePowerRoutine = 0
- return
- src << "Power port upload access confirmed. Loading control program into APC power port software."
- sleep(50)
- theAPC = null
-/*
- for (var/something in loc)
- if (istype(something, /obj/machinery/power/apc))
- if (!(something:stat & BROKEN))
- theAPC = something
- break
-*/
- for (var/obj/machinery/power/apc/APC in loc)
- if (!(APC.stat & BROKEN))
- theAPC = APC
- break
- if (theAPC==null)
- src << "APC connection lost!"
- src:aiRestorePowerRoutine = 2
- return
- if (loc.master.power_equip)
- if (!istype(T, /turf/space))
- src << "Alert cancelled. Power has been restored without our assistance."
- src:aiRestorePowerRoutine = 0
- return
- src << "Transfer complete. Forcing APC to execute program."
- sleep(50)
- src << "Receiving control information from APC."
- sleep(2)
- //bring up APC dialog
- theAPC.attack_ai(src)
- src:aiRestorePowerRoutine = 3
- src << "Your laws have been reset:"
- src.show_laws()
+ if (loc.master.power_equip)
+ if (!istype(T, /turf/space))
+ src << "Alert cancelled. Power has been restored without our assistance."
+ src:aiRestorePowerRoutine = 0
+ src.blind.layer = 0 //This, too, is a fix to issue 603
+ return
+ switch(PRP)
+ if (1) src << "APC located. Optimizing route to APC to avoid needless power waste."
+ if (2) src << "Best route identified. Hacking offline APC power port."
+ if (3) src << "Power port upload access confirmed. Loading control program into APC power port software."
+ if (4)
+ src << "Transfer complete. Forcing APC to execute program."
+ sleep(50)
+ src << "Receiving control information from APC."
+ sleep(2)
+ //bring up APC dialog
+ theAPC.attack_ai(src)
+ src:aiRestorePowerRoutine = 3
+ src << "Your laws have been reset:"
+ src.show_laws()
+ sleep(50)
+ theAPC = null
/mob/living/silicon/ai/updatehealth()
if (src.nodamage == 0)
diff --git a/code/modules/mob/living/silicon/pai/death.dm b/code/modules/mob/living/silicon/pai/death.dm
index bbbe20ad14d..7fa3aabbb60 100644
--- a/code/modules/mob/living/silicon/pai/death.dm
+++ b/code/modules/mob/living/silicon/pai/death.dm
@@ -12,7 +12,12 @@
//var/tod = time2text(world.realtime,"hh:mm:ss") //weasellos time of death patch
//mind.store_memory("Time of death: [tod]", 0)
+
+ //New pAI's get a brand new mind to prevent meta stuff from their previous life. This new mind causes problems down the line if it's not deleted here.
+ //Read as: I have no idea what I'm doing but asking for help got me nowhere so this is what you get. - Nodrak
+ del(src.mind)
+
if(key)
spawn(50)
- src.ghostize(1)
+ src.ghostize(0)
del(src)
\ No newline at end of file
diff --git a/tgstation.dme b/tgstation.dme
index c80eb7c83aa..c9fa94feadd 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -573,6 +573,7 @@
#include "code\game\mecha\combat\marauder.dm"
#include "code\game\mecha\combat\phazon.dm"
#include "code\game\mecha\equipment\mecha_equipment.dm"
+#include "code\game\mecha\equipment\tools\medical_tools.dm"
#include "code\game\mecha\equipment\tools\tools.dm"
#include "code\game\mecha\equipment\weapons\weapons.dm"
#include "code\game\mecha\medical\medical.dm"