From 188b4875423153e0592b4f9b0c32d78134e42ffd Mon Sep 17 00:00:00 2001 From: "johnsonmt88@gmail.com" Date: Wed, 4 Jul 2012 19:52:45 +0000 Subject: [PATCH] AI's are no longer permanently blinded by power loss. Fixes issue 603 - Thanks to Zekkeit/39kk9t for this fix! Cultists now get stunned by their own stun rune again. - Apparently this would have been game-breakingly spammable Added WJohnston's mech toys as arcade prizes! Made mech tool code less of a nightmare to navigate: - Moved mech medical tools into their own .dm file - Moved unused mech tools into their own .dm file Fixed a major pAI exploit. Fixed the odysseus picking up people who were buckled, causing the person to be unable to move. git-svn-id: http://tgstation13.googlecode.com/svn/trunk@3982 316c924e-a436-60f5-8080-3fe189b3f50e --- code/game/machinery/computer/arcade.dm | 54 +- code/game/magic/cultist/runes.dm | 2 +- .../mecha/equipment/tools/medical_tools.dm | 654 ++++++++++++++ code/game/mecha/equipment/tools/tools.dm | 806 +----------------- .../mecha/equipment/tools/unused_tools.dm | 157 ++++ code/modules/mob/dead/observer/observer.dm | 1 + code/modules/mob/living/carbon/human/death.dm | 7 +- code/modules/mob/living/silicon/ai/life.dm | 128 +-- code/modules/mob/living/silicon/pai/death.dm | 7 +- tgstation.dme | 1 + 10 files changed, 891 insertions(+), 926 deletions(-) create mode 100644 code/game/mecha/equipment/tools/medical_tools.dm create mode 100644 code/game/mecha/equipment/tools/unused_tools.dm diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 8b4416cc41..7383c44181 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 489639b3c1..9adbf418d1 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 0000000000..9e3e63ef65 --- /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 || "No known reagents"] + [inputs] +
+ [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 c842621b8f..918410e56c 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 || "No known reagents"] - [inputs] -
- [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 0000000000..73485ed05e --- /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 a06bc34e3c..8325b6c750 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 06b9cbde98..0a42cb9e11 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 7e3559d58f..8096b9681f 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 bbbe20ad14..7fa3aabbb6 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 c80eb7c83a..c9fa94fead 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"