From eec262a5e1b449f4c4defe84c713ab6255c8c46f Mon Sep 17 00:00:00 2001 From: Atlantiscze Date: Sat, 29 Nov 2014 22:49:06 +0100 Subject: [PATCH 01/94] Emitters can now damage and eventually break walls --- code/game/turfs/simulated/walls.dm | 16 ++++++++++++++++ code/game/turfs/simulated/walls_reinforced.dm | 1 + 2 files changed, 17 insertions(+) diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index d8f91582b6c..fda5083d868 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -7,6 +7,7 @@ var/damage = 0 var/damage_cap = 100 //Wall will break down to girders if damage reaches this point + var/armor = 0.5 // Damage is multiplied by this var/damage_overlay var/global/damage_overlays[8] @@ -22,6 +23,21 @@ var/walltype = "metal" +/turf/simulated/wall/bullet_act(var/obj/item/projectile/Proj) + + // Tasers and stuff? No thanks. + if(Proj.damage_type == HALLOSS) + return + + // Emitter blasts are somewhat weaker as emitters have large rate of fire and don't require limited power cell to run + if(istype(Proj, /obj/item/projectile/beam/emitter)) + Proj.damage /= 4 + + take_damage(Proj.damage * armor) + return + + + /turf/simulated/wall/Del() for(var/obj/effect/E in src) if(E.name == "Wallrot") del E ..() diff --git a/code/game/turfs/simulated/walls_reinforced.dm b/code/game/turfs/simulated/walls_reinforced.dm index 10c7a2cbceb..33e048fc159 100644 --- a/code/game/turfs/simulated/walls_reinforced.dm +++ b/code/game/turfs/simulated/walls_reinforced.dm @@ -7,6 +7,7 @@ damage_cap = 200 max_temperature = 6000 + armor = 0.1 // Only 10% damage from gunfire, it's made from strong alloys and stuff. walltype = "rwall" From 45eb8f37dd2f44a291d5ed99af9d72eef717f13a Mon Sep 17 00:00:00 2001 From: Atlantiscze Date: Sat, 29 Nov 2014 22:52:02 +0100 Subject: [PATCH 02/94] Emitters can now completely destroy doors, given enough time. Amount of shots per door varies depending on type. Regular airlocks are quite weak. Secure bolt-when-destroyed airlocks can take some punishment, and blast doors will take serious bombardment to destroy. --- code/game/machinery/doors/airlock.dm | 4 ++++ code/game/machinery/doors/door.dm | 15 +++++++++++++++ code/game/machinery/doors/poddoor.dm | 1 + 3 files changed, 20 insertions(+) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index bb23176478c..9ba81bb79c0 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1069,6 +1069,10 @@ About the new airlock wires panel: /obj/machinery/door/airlock/New() ..() + //High-sec airlocks are much harder to completely break by emitters. + if(security_bolts) + emitter_resistance *= 3 + //wires if (secured_wires) wires = new/datum/wires/airlock/secure(src) diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 37966deea69..02d48f4c036 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -25,6 +25,8 @@ var/air_properties_vary_with_direction = 0 var/maxhealth = 300 var/health + var/emitter_hits = 0 // For use when tracking amount of emitter hits taken. + var/emitter_resistance = 10 // Amount of emitter hits doors whistand var/min_force = 10 //minimum amount of force needed to damage the door with a melee weapon var/hitsound = 'sound/weapons/smash.ogg' //sound door makes when hit with a weapon @@ -133,9 +135,22 @@ if(Proj.damage_type == HALLOSS) return + // Emitter Blasts - these will eventually completely destroy the door, given enough time. + if (istype(Proj, /obj/item/projectile/beam/emitter)) + if(health > 0) + Proj.damage /= 4 + else + emitter_hits ++ + if(emitter_hits >= emitter_resistance) + visible_message("\red [src.name] breaks apart!", 1) + new /obj/effect/decal/cleanable/ash(src.loc) // Turn it to ashes! + del(src) + if(Proj.damage) take_damage(Proj.damage) + + /obj/machinery/door/hitby(AM as mob|obj) ..() diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm index aeccacd45ce..8fc8e767ef5 100644 --- a/code/game/machinery/doors/poddoor.dm +++ b/code/game/machinery/doors/poddoor.dm @@ -6,6 +6,7 @@ var/id = 1.0 dir = 1 explosion_resistance = 25 + emitter_resistance = 50 // Lots of emitter blasts, it's blast door after all. /obj/machinery/door/poddoor/New() . = ..() From d074292da95484f92996183c85860c3bab439a12 Mon Sep 17 00:00:00 2001 From: Atlantiscze Date: Sat, 29 Nov 2014 22:52:39 +0100 Subject: [PATCH 03/94] Fixes blast doors losing icon when being hit by emitter or similar weapon. --- code/game/machinery/doors/poddoor.dm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm index 8fc8e767ef5..9ab7dabb2d1 100644 --- a/code/game/machinery/doors/poddoor.dm +++ b/code/game/machinery/doors/poddoor.dm @@ -22,6 +22,14 @@ else return 0 +/obj/machinery/door/poddoor/update_icon() + if(density) + icon_state = "pdoor1" + else + icon_state = "pdoor0" + return + + /obj/machinery/door/poddoor/attackby(obj/item/weapon/C as obj, mob/user as mob) src.add_fingerprint(user) if (!( istype(C, /obj/item/weapon/crowbar) || (istype(C, /obj/item/weapon/twohanded/fireaxe) && C:wielded == 1) )) From 682164335a268f1a6e62c18fc1c3044176e38ee6 Mon Sep 17 00:00:00 2001 From: Atlantiscze Date: Sat, 29 Nov 2014 22:54:16 +0100 Subject: [PATCH 04/94] EMITTER MINING! Yes! You can now mine using emitters. Each rock takes 3 blasts to break. This method will also yield less ore than other conventional methods. But using big lasers for mining is cool, right? Who cares about productivity. --- code/modules/mining/mine_turfs.dm | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index c556990e815..de933e4cf3b 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -14,6 +14,7 @@ var/mineral/mineral var/mined_ore = 0 var/last_act = 0 + var/emitter_blasts_taken = 0 // EMITTER MINING! Muhehe. var/datum/geosample/geologic_data var/excavation_level = 0 @@ -52,6 +53,16 @@ mined_ore = 2 //some of the stuff gets blown up GetDrilled() +/turf/simulated/mineral/bullet_act(var/obj/item/projectile/Proj) + + // Emitter blasts + if(istype(Proj, /obj/item/projectile/beam/emitter)) + emitter_blasts_taken++ + + if(emitter_blasts_taken > 2) // 3 blasts per tile + mined_ore = 1 + GetDrilled() + /turf/simulated/mineral/Bumped(AM) . = ..() if(istype(AM,/mob/living/carbon/human)) From bf213e6889f909958978228e2c5b8a6b8ef8db74 Mon Sep 17 00:00:00 2001 From: Atlantiscze Date: Sun, 7 Dec 2014 04:43:00 +0100 Subject: [PATCH 05/94] Resolves compilation errors caused by previous merge --- code/game/machinery/doors/airlock.dm | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index d0634f81cc0..49252eaac64 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -913,9 +913,9 @@ About the new airlock wires panel: if(operating == -1) new /obj/item/weapon/circuitboard/broken(src.loc) operating = 0 - else + else if (!electronics) create_electronics() - + electronics.loc = src.loc electronics = null @@ -1059,18 +1059,17 @@ About the new airlock wires panel: /obj/machinery/door/airlock/New(var/newloc, var/obj/structure/door_assembly/assembly=null) ..() -<<<<<<< HEAD //High-sec airlocks are much harder to completely break by emitters. - if(security_bolts) + if(secured_wires) emitter_resistance *= 3 -======= + //if assembly is given, create the new door from the assembly if (assembly) assembly_type = assembly.type - + electronics = assembly.electronics electronics.loc = src - + //update the door's access to match the electronics' secured_wires = electronics.secure if(electronics.one_access) @@ -1078,13 +1077,12 @@ About the new airlock wires panel: req_one_access = src.electronics.conf_access else req_access = src.electronics.conf_access - + //get the name from the assembly if(assembly.created_name) name = assembly.created_name else name = "[istext(assembly.glass) ? "[assembly.glass] airlock" : assembly.base_name]" ->>>>>>> 2d7ea3028f36259d189674c209b727029da4ecc6 //wires if (secured_wires) @@ -1099,8 +1097,8 @@ About the new airlock wires panel: src.closeOther = A break -// Most doors will never be deconstructed over the course of a round, -// so as an optimization defer the creation of electronics until +// Most doors will never be deconstructed over the course of a round, +// so as an optimization defer the creation of electronics until // the airlock is deconstructed /obj/machinery/door/airlock/proc/create_electronics() //create new electronics @@ -1108,7 +1106,7 @@ About the new airlock wires panel: src.electronics = new/obj/item/weapon/airlock_electronics/secure( src.loc ) else src.electronics = new/obj/item/weapon/airlock_electronics( src.loc ) - + //update the electronics to match the door's access if(!src.req_access) src.check_access() From 52152166b386507b20b1914cc07fdb53b042423d Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Wed, 10 Dec 2014 18:49:32 +1030 Subject: [PATCH 06/94] Wip fixing suit spints. --- code/modules/clothing/spacesuits/rig/rig.dm | 6 ++++-- code/modules/clothing/spacesuits/spacesuits.dm | 12 +++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index 1c10aa36ac5..b3e8ea68167 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -595,6 +595,8 @@ H << "Your [use_obj.name] [use_obj.gender == PLURAL ? "retract" : "retracts"] swiftly." use_obj.canremove = 1 holder.drop_from_inventory(use_obj) + use_obj.loc = get_turf(src) + use_obj.dropped() use_obj.canremove = 0 use_obj.loc = src @@ -648,10 +650,10 @@ for(var/piece in list("helmet","gauntlets","chest","boots")) toggle_piece(piece, H, ONLY_DEPLOY) -/obj/item/weapon/rig/dropped() +/obj/item/weapon/rig/dropped(var/mob/user) ..() for(var/piece in list("helmet","gauntlets","chest","boots")) - toggle_piece(piece, wearer, ONLY_RETRACT) + toggle_piece(piece, user, ONLY_RETRACT) wearer = null //Todo diff --git a/code/modules/clothing/spacesuits/spacesuits.dm b/code/modules/clothing/spacesuits/spacesuits.dm index d3b354fe521..535ab47f813 100644 --- a/code/modules/clothing/spacesuits/spacesuits.dm +++ b/code/modules/clothing/spacesuits/spacesuits.dm @@ -70,27 +70,25 @@ check_limb_support() ..() -/obj/item/clothing/suit/space/dropped() - check_limb_support() +/obj/item/clothing/suit/space/dropped(var/mob/user) + check_limb_support(user) ..() // Some space suits are equipped with reactive membranes that support // broken limbs - at the time of writing, only the ninja suit, but // I can see it being useful for other suits as we expand them. ~ Z // The actual splinting occurs in /datum/organ/external/proc/fracture() -/obj/item/clothing/suit/space/proc/check_limb_support() +/obj/item/clothing/suit/space/proc/check_limb_support(var/mob/living/carbon/human/user) // If this isn't set, then we don't need to care. if(!supporting_limbs || !supporting_limbs.len) return - var/mob/living/carbon/human/H = src.loc - - // If the holder isn't human, or the holder IS and is wearing the suit, it keeps supporting the limbs. - if(!istype(H) || H.wear_suit == src) + if(!istype(user) || user.wear_suit == src) return // Otherwise, remove the splints. for(var/datum/organ/external/E in supporting_limbs) E.status &= ~ ORGAN_SPLINTED + user << "The suit stops supporting your [E.display_name]." supporting_limbs = list() \ No newline at end of file From 43e816895d30ce800688ee3b20e6f0f96aeb2ec4 Mon Sep 17 00:00:00 2001 From: Atlantiscze Date: Wed, 10 Dec 2014 12:32:27 +0100 Subject: [PATCH 07/94] v1.0 of NanoUI for mech bay consoles. --- code/game/mecha/mech_bay.dm | 63 +++++++++++++------------------------ 1 file changed, 22 insertions(+), 41 deletions(-) diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm index 20703363ff8..578eea01994 100644 --- a/code/game/mecha/mech_bay.dm +++ b/code/game/mecha/mech_bay.dm @@ -46,8 +46,8 @@ return // temporary fix for broken icon until somebody gets around to make these player-buildable -/turf/simulated/floor/mech_bay_recharge_floor/attackby(obj/item/C as obj, mob/user as mob) - ..() +/turf/simulated/floor/mech_bay_recharge_floor/attackby(obj/item/C as obj, mob/user as mob) + ..() if(floor_type) icon_state = "recharge_floor" else @@ -190,45 +190,26 @@ var/turf/simulated/floor/mech_bay_recharge_floor/F = locate() in range(1,src) if(F) F.init_devices() - - var/output = "[src.name]" - if(!recharge_floor) - output += "Mech Bay Recharge Station not initialized.
" - else - output += {"Mech Bay Recharge Station Data:
- Mecha: [recharge_floor.recharging_mecha||"None"]
"} - if(recharge_floor.recharging_mecha) - var/cell_charge = recharge_floor.recharging_mecha.get_charge() - output += "Cell charge: [isnull(cell_charge)?"No powercell found":"[recharge_floor.recharging_mecha.cell.charge]/[recharge_floor.recharging_mecha.cell.maxcharge]"]
" - output += "
" - if(!recharge_port) - output += "Mech Bay Power Port not initialized.
" - else - output += "Mech Bay Power Port Status: [recharge_port.active()?"Now charging":"On hold"]
" - /* - output += {"
- Settings: -
- Start sequence on succesful init: [autostart?"On":"Off"]
- Recharge Port Voltage: Low - Medium - High
-
"} - */ + var/list/data = list() - output += "" - user << browse(output, "window=mech_bay_console") - onclose(user, "mech_bay_console") - return + data["has_floor"] = recharge_floor + data["has_port"] = recharge_port + data["has_mech"] = !isnull(recharge_floor.recharging_mecha) + if(recharge_floor) + data["mecha_name"] = recharge_floor.recharging_mecha || "None" + data["mecha_charge"] = isnull(cell_charge) ? 0 : recharge_floor.recharging_mecha.cell.charge + data["mecha_maxcharge"] = isnull(cell_charge) ? 0 : recharge_floor.recharging_mecha.cell.maxcharge + data["mecha_charge_percentage"] = round(recharge_floor.recharging_mecha.cell.percent()) -// unused at the moment, also lacks any kind of exploit prevention -/* -/obj/machinery/computer/mech_bay_power_console/Topic(href, href_list) - if(href_list["autostart"]) - autostart = !autostart - if(href_list["voltage"]) - voltage = text2num(href_list["voltage"]) - if(recharge_port) - recharge_port.set_voltage(voltage) - updateUsrDialog() - return -*/ + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + // the ui does not exist, so we'll create a new() one + // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm + ui = new(user, src, ui_key, "mech_bay_console.tmpl", "Mech Bay Control Console", 300, 200) + // when the ui is first opened this is the data it will use + ui.set_initial_data(data) + // open the new ui window + ui.open() + // auto update every Master Controller tick + ui.set_auto_update(1) \ No newline at end of file From 73b04ff177085b87737d04fc29d4adfce215b849 Mon Sep 17 00:00:00 2001 From: Atlantiscze Date: Wed, 10 Dec 2014 12:34:23 +0100 Subject: [PATCH 08/94] Compile error fix --- code/game/mecha/mech_bay.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm index 578eea01994..c2103cb26be 100644 --- a/code/game/mecha/mech_bay.dm +++ b/code/game/mecha/mech_bay.dm @@ -191,7 +191,7 @@ if(F) F.init_devices() - var/list/data = list() + var/list/data = list() data["has_floor"] = recharge_floor data["has_port"] = recharge_port From 1a6d1eac2fc691f6100be4abddc909dd8d7466e0 Mon Sep 17 00:00:00 2001 From: Atlantiscze Date: Wed, 10 Dec 2014 12:42:57 +0100 Subject: [PATCH 09/94] Compile error fix --- code/game/mecha/mech_bay.dm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm index c2103cb26be..22c099b6b0f 100644 --- a/code/game/mecha/mech_bay.dm +++ b/code/game/mecha/mech_bay.dm @@ -190,16 +190,17 @@ var/turf/simulated/floor/mech_bay_recharge_floor/F = locate() in range(1,src) if(F) F.init_devices() + ui_interact(user) +/obj/machinery/computer/mech_bay_power_console/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) var/list/data = list() - data["has_floor"] = recharge_floor data["has_port"] = recharge_port data["has_mech"] = !isnull(recharge_floor.recharging_mecha) - if(recharge_floor) + if(recharge_floor && recharge_floor.recharging_mecha) data["mecha_name"] = recharge_floor.recharging_mecha || "None" - data["mecha_charge"] = isnull(cell_charge) ? 0 : recharge_floor.recharging_mecha.cell.charge - data["mecha_maxcharge"] = isnull(cell_charge) ? 0 : recharge_floor.recharging_mecha.cell.maxcharge + data["mecha_charge"] = isnull(recharge_floor.recharging_mecha) ? 0 : recharge_floor.recharging_mecha.cell.charge + data["mecha_maxcharge"] = isnull(recharge_floor.recharging_mecha) ? 0 : recharge_floor.recharging_mecha.cell.maxcharge data["mecha_charge_percentage"] = round(recharge_floor.recharging_mecha.cell.percent()) ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) From 5422e3e7c30250dbcc3cf72b5af79b35ac74d938 Mon Sep 17 00:00:00 2001 From: Neerti Date: Wed, 10 Dec 2014 07:12:30 -0500 Subject: [PATCH 10/94] Makes service drone sprite have consistent frames with the other drone sprites, which will make the eyes sync properly. --- icons/mob/robots.dmi | Bin 155563 -> 155561 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/mob/robots.dmi b/icons/mob/robots.dmi index 04202fe3134ef304cf6dfa972d319d99df312195..f83d75f3f6430d8b2909e075e4d7ef524b3ce659 100644 GIT binary patch delta 846 zcmV-U1F`(8zX_?o36LZKmysnmFwvltqTs$Xd zE}oP#7taboE46i3DhR;efDXC_hWhBBYlwG6kJ^9_3a}iO+#^2hk&!yu|1?k%I) zp1@@zc(N*@X84#Pd4Nu_Dxgc2s*cyT{A*)L?y$Eo+Jf+vp0ZnR^1soH9q+^aK5v2rQG2;^phJc;37w{{a}(7FXDk Yph^G$AOJ~3gUkbm%mV?p%mV`7TZek1WB>pF delta 846 zcmV-U1F`(6zX_|q36LZKnUN(oFfpK%q<;H7#BH5SWYL+04}%Flk`ncc6hDfmmoKkh z#q;JhIRZJ2R;;w?Oh5T`4?S4tLmdsDcBP9B9dbRvhRP z2dWG!Tc0_Qfxy9EVv^b@_F@}t0Z7{>dg2>xfmqtuXbUv|&SJkoeIV_-e<=7wSfP(% zTZ2gPTyG5`#nrSmh!oe;)*w<`QCovZaZPOvBE?m;HHZ`!jPnHYM?52EE}oJz7thI= ziznsG#j`@tN^RYh3IgyqprfvVp*}k58sc5iqc-4!0xX9mw@9zc>O||+AM?LE#nb%; z6bExqS4i>8-pZf4)y8PFe^K@yX`j%?bBM~L<0{g795A)7EfBXW z@zTQ!3>~Q?HiQ8)he^jB*>Ya2>yXh9$ z9-Y2zRusWKj(uan+BOiYT-+6l6Wg`Y?O;$fLanfW3-QF)AJGUr%-$l+7lV`T-+jDD z-=)m6JN;1_o$zlj+Zl@tMlw8)D zfCEAkFN#cy8;x();t^V~{#HwZz0}0Hg8v(Nm6E{f6rqL8d1;lTKyn9rEz^gzOdsB! z>AReq?SI{mcP-+6CujSSp3PjrogU7{eYJkq0`B(FuYau6e{yqhua90y2Wo%l3bD~W@&`*iLGWjT8zCMfR&1>=>9TXN> Y?sW`v001BWgUADi$O8el$O8i5TX*%PP5=M^ From 0bacf5492e8b36c33f7675c46b7eefb8e5c2eea9 Mon Sep 17 00:00:00 2001 From: Atlantiscze Date: Wed, 10 Dec 2014 15:19:53 +0100 Subject: [PATCH 11/94] Final version of Mech Bay Charging Console NanoUI implementation --- code/game/mecha/mech_bay.dm | 9 ++-- nano/templates/mech_bay_console.tmpl | 67 ++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 nano/templates/mech_bay_console.tmpl diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm index 22c099b6b0f..65f77c1d999 100644 --- a/code/game/mecha/mech_bay.dm +++ b/code/game/mecha/mech_bay.dm @@ -196,13 +196,14 @@ var/list/data = list() data["has_floor"] = recharge_floor data["has_port"] = recharge_port - data["has_mech"] = !isnull(recharge_floor.recharging_mecha) - if(recharge_floor && recharge_floor.recharging_mecha) + if(recharge_floor && recharge_floor.recharging_mecha && recharge_floor.recharging_mecha.cell) + data["has_mech"] = 1 data["mecha_name"] = recharge_floor.recharging_mecha || "None" data["mecha_charge"] = isnull(recharge_floor.recharging_mecha) ? 0 : recharge_floor.recharging_mecha.cell.charge data["mecha_maxcharge"] = isnull(recharge_floor.recharging_mecha) ? 0 : recharge_floor.recharging_mecha.cell.maxcharge - data["mecha_charge_percentage"] = round(recharge_floor.recharging_mecha.cell.percent()) - + data["mecha_charge_percentage"] = isnull(recharge_floor.recharging_mecha) ? 0 : round(recharge_floor.recharging_mecha.cell.percent()) + else + data["has_mech"] = 0 ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) // the ui does not exist, so we'll create a new() one diff --git a/nano/templates/mech_bay_console.tmpl b/nano/templates/mech_bay_console.tmpl new file mode 100644 index 00000000000..87e34d7b8e1 --- /dev/null +++ b/nano/templates/mech_bay_console.tmpl @@ -0,0 +1,67 @@ +

Subsystems

+
+
+ Recharge Station: +
+
+ {{if data.has_floor}} + OK + {{else}} + ERROR + {{/if}} +
+
+
+
+ Power Port: +
+
+ {{if data.has_port}} + OK + {{else}} + ERROR + {{/if}} +
+
+
+
+ Mecha: +
+
+ {{if data.has_mech}} + LOCATED ({{:data.mecha_name}}) + {{else}} + NONE + {{/if}} +
+
+{{if data.has_mech}} +

Charging

+
+
+ Charge Level: +
+
+ {{:helper.displayBar(data.mecha_charge_percentage, 0, 100)}} +
+ {{:data.mecha_charge_percentage}}%
+
+
+
+
+
+ Cell Rating: +
+
+ {{:data.mecha_maxcharge}} +
+
+
+
+ Cell Charge: +
+
+ {{:data.mecha_charge}} +
+
+{{/if}} \ No newline at end of file From 1f070cd60aeda88de5d7228780f6829faefc2fec Mon Sep 17 00:00:00 2001 From: Hubblenaut Date: Wed, 10 Dec 2014 18:04:13 +0100 Subject: [PATCH 12/94] Fixes Hotkey --- interface/interface.dm | 3 +-- interface/skin.dmf | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/interface/interface.dm b/interface/interface.dm index 47b80678751..9cf97cfd98c 100644 --- a/interface/interface.dm +++ b/interface/interface.dm @@ -46,8 +46,7 @@ Hotkey-Mode: (hotkey-mode must be on) \te = equip \tr = throw \tt = say -\ty = emote -\tx = swap-hand +\tx = swap-hand (or y) \tz = activate held object \tf = cycle-intents-left \tg = cycle-intents-right diff --git a/interface/skin.dmf b/interface/skin.dmf index 7d8485e6ec7..f8fc765e3e6 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -367,7 +367,7 @@ macro "hotkeymode" is-disabled = false elem name = "Y" - command = "me" + command = "Activate-Held-Object" is-disabled = false elem name = "CTRL+Y" From 8e5bc3a589cd2713b42f6772285394f9a62e58e5 Mon Sep 17 00:00:00 2001 From: PsiOmega Date: Wed, 10 Dec 2014 20:11:00 +0100 Subject: [PATCH 13/94] Fixes #7356. Clam now uses the proper arg name when trying to create borers. Fixes a minor issue in the event manager, where the wrong Topic arg was used. --- code/game/gamemodes/calamity/calamity.dm | 2 +- code/modules/events/event_manager.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/calamity/calamity.dm b/code/game/gamemodes/calamity/calamity.dm index 0d8b46b318e..a4e617aaf4a 100644 --- a/code/game/gamemodes/calamity/calamity.dm +++ b/code/game/gamemodes/calamity/calamity.dm @@ -91,7 +91,7 @@ // Add the cortical borer event var/list/moderate_event_list = EModerate.available_events - var/event = new /datum/event_meta(EVENT_LEVEL_MODERATE, "Borer Infestation", /datum/event/borer_infestation, 400, one_shot = 1) + var/event = new /datum/event_meta(EVENT_LEVEL_MODERATE, "Borer Infestation", /datum/event/borer_infestation, 400, is_one_shot = 1) moderate_event_list.Add(event) if(chosen_atypes) diff --git a/code/modules/events/event_manager.dm b/code/modules/events/event_manager.dm index bc42d7c19fb..22407ff2bd5 100644 --- a/code/modules/events/event_manager.dm +++ b/code/modules/events/event_manager.dm @@ -106,7 +106,7 @@ html += "[new_event.name ? new_event.name : "Enter Event"]" html += "[new_event.event_type ? new_event.event_type : "Select Type"]" html += "[new_event.weight ? new_event.weight : 0]" - html += "[new_event.one_shot]" + html += "[new_event.one_shot]" html += "" html += "" html += "Add
" From 3a2aed265b08a00ae00220a5af8ea1ecb1bc0f13 Mon Sep 17 00:00:00 2001 From: PsiOmega Date: Wed, 10 Dec 2014 20:25:03 +0100 Subject: [PATCH 14/94] Fixes #7374. Now checks the correct ringer flag when receiving a PDA message. --- code/game/objects/items/devices/PDA/PDA.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 6a25b46444f..05071c58838 100755 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -1052,7 +1052,7 @@ var/global/list/obj/item/device/pda/PDAs = list() /obj/item/device/pda/proc/new_message(var/sending_unit, var/sender, var/sender_job, var/message) var/reception_message = "\icon[src] Message from [sender] ([sender_job]), \"[message]\" (Reply)" - new_info(news_silent, newstone, reception_message) + new_info(message_silent, newstone, reception_message) log_pda("[usr] (PDA: [sending_unit]) sent \"[message]\" to [name]") new_message = 1 From 087cc1882c58516e7498dd56d564664b43e752cf Mon Sep 17 00:00:00 2001 From: PsiOmega Date: Wed, 10 Dec 2014 21:54:57 +0100 Subject: [PATCH 15/94] Fixes #7366. Kills unecessary photo datum which wasn't even used correctly anymore. Photos have a global id for ease of synth syncing. Changes how law/photo syncing is handled when pulsing the appropriate borg wire. Also ensures re-synced borgs are added/removed from the appropriate AIs. --- code/datums/wires/robot.dm | 27 +------ code/game/machinery/computer/security.dm | 4 +- .../mob/living/silicon/robot/photos.dm | 33 +++++--- .../modules/mob/living/silicon/robot/robot.dm | 7 +- code/modules/paperwork/photocopier.dm | 17 ++-- code/modules/paperwork/photography.dm | 80 +++++++++---------- code/modules/paperwork/silicon_photography.dm | 51 +++++------- 7 files changed, 100 insertions(+), 119 deletions(-) diff --git a/code/datums/wires/robot.dm b/code/datums/wires/robot.dm index f65ee6be508..73555f38899 100644 --- a/code/datums/wires/robot.dm +++ b/code/datums/wires/robot.dm @@ -51,36 +51,17 @@ var/const/BORG_WIRE_CAMERA = 16 /datum/wires/robot/UpdatePulsed(var/index) - var/mob/living/silicon/robot/R = holder switch(index) if (BORG_WIRE_AI_CONTROL) //pulse the AI wire to make the borg reselect an AI if(!R.emagged) - var/new_ai = select_active_ai(R) + var/mob/living/silicon/ai/new_ai = select_active_ai(R) if(new_ai && (new_ai != R.connected_ai)) + R.connected_ai.connected_robots -= src R.connected_ai = new_ai + new_ai.connected_robots += src R.notify_ai(1) - var/numberer = 1 // Send images the Cyborg has taken to the AI's album upon sync. - for(var/datum/picture/z in R.aiCamera.aipictures) - if(R.connected_ai.aiCamera.aipictures.len == 0) - var/datum/picture/p = new/datum/picture() - p = z - p.fields["name"] = "Uploaded Image [numberer] (synced from [R.name])" - R.connected_ai.aiCamera.aipictures += p - numberer++ - continue - for(var/datum/picture/t in R.connected_ai.aiCamera.aipictures) //Hopefully to prevent someone spamming images to silicons, by spamming this wire - if((z.fields["pixel_y"] != t.fields["pixel_y"]) && (z.fields["pixel_x"] != t.fields["pixel_x"])) //~2.26 out of 1000 chance this will stop something it shouldn't - var/datum/picture/p = new/datum/picture() - p = z - p.fields["name"] = "Uploaded Image [numberer] (synced from [R.name])" - R.connected_ai.aiCamera.aipictures += p - else - continue - numberer++ - if(R.aiCamera.aipictures.len > 0) - R << "Locally saved images synced with AI. Images were retained in local database in case of loss of connection with the AI." - + R.sync() if (BORG_WIRE_CAMERA) if(!isnull(R.camera) && R.camera.can_use() && !R.scrambledcodes) R.camera.kick_viewers() // Kick anyone watching the Cyborg's camera diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index 5aed27cc564..76c9790c5d8 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -576,9 +576,9 @@ What a mess.*/ return photo.img if(istype(user, /mob/living/silicon)) var/mob/living/silicon/tempAI = usr - var/datum/picture/selection = tempAI.GetPicture() + var/obj/item/weapon/photo/selection = tempAI.GetPicture() if (selection) - return selection.fields["img"] + return selection.img /obj/machinery/computer/secure_data/emp_act(severity) if(stat & (BROKEN|NOPOWER)) diff --git a/code/modules/mob/living/silicon/robot/photos.dm b/code/modules/mob/living/silicon/robot/photos.dm index fbcc3bf4842..7c52bd0f858 100644 --- a/code/modules/mob/living/silicon/robot/photos.dm +++ b/code/modules/mob/living/silicon/robot/photos.dm @@ -1,13 +1,20 @@ -/mob/living/silicon/robot/proc/photosync() - var/obj/item/device/camera/siliconcam/master_cam = connected_ai ? connected_ai.aiCamera : null - if (!master_cam) - return - - var/synced - synced = 0 - for(var/datum/picture/z in aiCamera.aipictures) - if (!(master_cam.aipictures.Find(z))) - aiCamera.printpicture(null, z) - synced = 1 - if(synced) - src << "Locally saved images synced with AI. Images were retained in local database in case of loss of connection with the AI." +/mob/living/silicon/robot/proc/photosync() + var/obj/item/device/camera/siliconcam/master_cam = connected_ai ? connected_ai.aiCamera : null + if (!master_cam) + return + + var/synced = 0 + // Sync borg images to the master AI. + // We don't care about syncing the other way around + for(var/obj/item/weapon/photo/borg_photo in aiCamera.aipictures) + var/copied = 0 + for(var/obj/item/weapon/photo/ai_photo in master_cam.aipictures) + if(borg_photo.id == ai_photo.id) + copied = 1 + break + if(!copied) + master_cam.injectaialbum(borg_photo.copy(1), " (synced from [name])") + synced = 1 + + if(synced) + src << "Images synced with AI. Local images will be retained in the case of loss of connection with the AI." diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 2d6685d8b21..4c0068a79d2 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -159,9 +159,8 @@ var/list/robot_verbs_default = list( connected_ai = select_active_ai_with_fewest_borgs() if(connected_ai) connected_ai.connected_robots += src - lawsync() - photosync() lawupdate = 1 + sync() else lawupdate = 0 @@ -178,6 +177,10 @@ var/list/robot_verbs_default = list( playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0) +/mob/living/silicon/robot/proc/sync() + if(lawupdate && connected_ai) + lawsync() + photosync() /mob/living/silicon/robot/drain_power(var/drain_check) diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 41e59884c72..83b27b7a2be 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -43,11 +43,11 @@ if(href_list["copy"]) if(stat & (BROKEN|NOPOWER)) return - + for(var/i = 0, i < copies, i++) if(toner <= 0) break - + if (istype(copyitem, /obj/item/weapon/paper)) copy(copyitem) sleep(15) @@ -60,7 +60,7 @@ else usr << "\The [copyitem] can't be copied by \the [src]." break - + use_power(active_power_usage) updateUsrDialog() else if(href_list["remove"]) @@ -81,19 +81,18 @@ else if(href_list["aipic"]) if(!istype(usr,/mob/living/silicon)) return if(stat & (BROKEN|NOPOWER)) return - + if(toner >= 5) var/mob/living/silicon/tempAI = usr var/obj/item/device/camera/siliconcam/camera = tempAI.aiCamera if(!camera) return - var/datum/picture/selection = camera.selectpicture() + var/obj/item/weapon/photo/selection = camera.selectpicture() if (!selection) return - var/obj/item/weapon/photo/p = new /obj/item/weapon/photo (src.loc) - p.construct(selection) + var/obj/item/weapon/photo/p = photocopy(selection) if (p.desc == "") p.desc += "Copied by [tempAI.name]" else @@ -195,6 +194,7 @@ /obj/machinery/photocopier/proc/photocopy(var/obj/item/weapon/photo/photocopy) var/obj/item/weapon/photo/p = photocopy.copy() + p.loc = src.loc var/icon/I = icon(photocopy.icon, photocopy.icon_state) if(toner > 10) //plenty of toner, go straight greyscale @@ -210,6 +210,7 @@ if(toner < 0) toner = 0 visible_message("A red light on \the [src] flashes, indicating that it is out of toner.") + return p //If need_toner is 0, the copies will still be lightened when low on toner, however it will not be prevented from printing. TODO: Implement print queues for fax machines and get rid of need_toner @@ -220,7 +221,7 @@ toner = 0 visible_message("A red light on \the [src] flashes, indicating that it is out of toner.") break - + if(istype(W, /obj/item/weapon/paper)) W = copy(W) else if(istype(W, /obj/item/weapon/photo)) diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index 5fc37334514..1a93e875398 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -21,17 +21,23 @@ /******** * photo * ********/ +var/global/photo_count = 0 + /obj/item/weapon/photo name = "photo" icon = 'icons/obj/items.dmi' icon_state = "photo" item_state = "paper" w_class = 2.0 + var/id var/icon/img //Big photo image var/scribble //Scribble on the back. var/icon/tiny var/photo_size = 3 +/obj/item/weapon/photo/New() + id = photo_count++ + /obj/item/weapon/photo/attack_self(mob/user as mob) user.examinate(src) @@ -270,8 +276,8 @@ y_c-- x_c = x_c - size - var/datum/picture/P = createpicture(target, user, turfs, mobs, flag) - printpicture(user, P) + var/obj/item/weapon/photo/p = createpicture(target, user, turfs, mobs, flag) + printpicture(user, p) /obj/item/device/camera/proc/createpicture(atom/target, mob/user, list/turfs, mobs, flag) var/icon/photoimage = get_icon(turfs, target) @@ -285,43 +291,37 @@ ic.Blend(small_img,ICON_OVERLAY, 10, 13) pc.Blend(tiny_img,ICON_OVERLAY, 12, 19) - var/datum/picture/P = new() - P.fields["name"] = "photo" - P.fields["icon"] = ic - P.fields["tiny"] = pc - P.fields["img"] = photoimage - P.fields["desc"] = mobs - P.fields["pixel_x"] = rand(-10, 10) - P.fields["pixel_y"] = rand(-10, 10) - P.fields["size"] = size - - return P - -/obj/item/device/camera/proc/printpicture(mob/user, var/datum/picture/P) - var/obj/item/weapon/photo/Photo = new/obj/item/weapon/photo() - Photo.loc = user.loc - if(!user.get_inactive_hand()) - user.put_in_inactive_hand(Photo) - Photo.construct(P) - -/obj/item/weapon/photo/proc/construct(var/datum/picture/P) - name = P.fields["name"] - icon = P.fields["icon"] - tiny = P.fields["tiny"] - img = P.fields["img"] - desc = P.fields["desc"] - pixel_x = P.fields["pixel_x"] - pixel_y = P.fields["pixel_y"] - photo_size = P.fields["size"] - -/obj/item/weapon/photo/proc/copy() - var/obj/item/weapon/photo/p = new/obj/item/weapon/photo() - - p.icon = icon(icon, icon_state) - p.img = icon(img) - p.tiny = icon(tiny) - p.name = name - p.desc = desc - p.scribble = scribble + var/obj/item/weapon/photo/p = new() + p.name = "photo" + p.icon = ic + p.tiny = pc + p.img = photoimage + p.desc = mobs + p.pixel_x = rand(-10, 10) + p.pixel_y = rand(-10, 10) + p.photo_size = size + + return p + +/obj/item/device/camera/proc/printpicture(mob/user, obj/item/weapon/photo/p) + p.loc = user.loc + if(!user.get_inactive_hand()) + user.put_in_inactive_hand(p) + +/obj/item/weapon/photo/proc/copy(var/copy_id = 0) + var/obj/item/weapon/photo/p = new/obj/item/weapon/photo() + + p.name = name + p.icon = icon + p.tiny = tiny + p.img = img + p.desc = desc + p.pixel_x = pixel_x + p.pixel_y = pixel_y + p.photo_size = photo_size + p.scribble = scribble + + if(copy_id) + p.id = id return p diff --git a/code/modules/paperwork/silicon_photography.dm b/code/modules/paperwork/silicon_photography.dm index fb321ae603f..c754909c4ca 100644 --- a/code/modules/paperwork/silicon_photography.dm +++ b/code/modules/paperwork/silicon_photography.dm @@ -1,10 +1,6 @@ /************** * AI-specific * **************/ -/datum/picture - var/name = "image" - var/list/fields = list() - /obj/item/device/camera/siliconcam var/in_camera_mode = 0 var/photos_taken = 0 @@ -19,23 +15,22 @@ /obj/item/device/camera/siliconcam/drone_camera //currently doesn't offer the verbs, thus cannot be used name = "Drone photo camera" -/obj/item/device/camera/siliconcam/proc/injectaialbum(var/datum/picture/P, var/sufix = "") //stores image information to a list similar to that of the datacore +/obj/item/device/camera/siliconcam/proc/injectaialbum(obj/item/weapon/photo/p, var/sufix = "") //stores image information to a list similar to that of the datacore + p.loc = src photos_taken++ - P.fields["name"] = "Image [photos_taken][sufix]" - var/obj/item/weapon/photo/photo = new - photo.construct(P) - aipictures += photo + p.name = "Image [photos_taken][sufix]" + aipictures += p -/obj/item/device/camera/siliconcam/proc/injectmasteralbum(var/datum/picture/P) //stores image information to a list similar to that of the datacore - var/mob/living/silicon/robot/C = src.loc +/obj/item/device/camera/siliconcam/proc/injectmasteralbum(obj/item/weapon/photo/p) //stores image information to a list similar to that of the datacore + var/mob/living/silicon/robot/C = usr if(C.connected_ai) - var/mob/A = P.fields["author"] - C.connected_ai.aiCamera.injectaialbum(P, " (taken by [A.name])") - C.connected_ai << "Image recorded and saved by [name]" - usr << "Image recorded and saved to remote database" //feedback to the Cyborg player that the picture was taken + C.connected_ai.aiCamera.injectaialbum(p.copy(1), " (synced from [C.name])") + C.connected_ai << "Image uploaded by [C.name]" + usr << "Image synced to remote database" //feedback to the Cyborg player that the picture was taken else - injectaialbum(P) usr << "Image recorded" + // Always save locally + injectaialbum(p) /obj/item/device/camera/siliconcam/proc/selectpicture(obj/item/device/camera/siliconcam/cam) if(!cam) @@ -65,14 +60,14 @@ selection.show(usr) usr << selection.desc -/obj/item/device/camera/siliconcam/proc/deletepicture() - var/selection = selectpicture() +/obj/item/device/camera/siliconcam/proc/deletepicture(obj/item/device/camera/siliconcam/cam) + var/selection = selectpicture(cam) if(!selection) return aipictures -= selection - usr << "Image deleted" + usr << "Local image deleted" /obj/item/device/camera/siliconcam/ai_camera/can_capture_turf(turf/T, mob/user) var/mob/living/silicon/ai = user @@ -92,12 +87,12 @@ src.in_camera_mode = 1 usr << "Camera Mode activated" -/obj/item/device/camera/siliconcam/ai_camera/printpicture(mob/user, datum/picture/P) - injectaialbum(P) +/obj/item/device/camera/siliconcam/ai_camera/printpicture(mob/user, obj/item/weapon/photo/p) + injectaialbum(p) usr << "Image recorded" -/obj/item/device/camera/siliconcam/robot_camera/printpicture(mob/user, datum/picture/P) - injectmasteralbum(P) +/obj/item/device/camera/siliconcam/robot_camera/printpicture(mob/user, obj/item/weapon/photo/p) + injectmasteralbum(p) /obj/item/device/camera/siliconcam/ai_camera/verb/take_image() set category = "AI Commands" @@ -145,19 +140,13 @@ set desc = "Delete a local image" set src in usr - // Explicitly only allow deletion from the local camera - var/mob/living/silicon/robot/C = src.loc - if(C.connected_ai) - C << "Not allowed to delete from the remote database." - return - - deletepicture() + deletepicture(src) obj/item/device/camera/siliconcam/proc/getsource() if(istype(src.loc, /mob/living/silicon/ai)) return src - var/mob/living/silicon/robot/C = src.loc + var/mob/living/silicon/robot/C = usr var/obj/item/device/camera/siliconcam/Cinfo if(C.connected_ai) Cinfo = C.connected_ai.aiCamera From 0cc7998197122a129aa2faa8b1ccd52dbf45579e Mon Sep 17 00:00:00 2001 From: PsiOmega Date: Wed, 10 Dec 2014 22:10:16 +0100 Subject: [PATCH 16/94] Fixes #7378. Now uses the config.wikiurl setting instead. Assumes wikiurl is in an format which can accept titles, in Bay12's case: http://wiki.baystation12.net/index.php?title= --- code/game/objects/items/weapons/manuals.dm | 25 ++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm index 99c4f960b0f..14511fdcfbe 100644 --- a/code/game/objects/items/weapons/manuals.dm +++ b/code/game/objects/items/weapons/manuals.dm @@ -13,26 +13,29 @@ author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned title = "Station Repairs and Construction" +/obj/item/weapon/book/manual/engineering_construction/New() + ..() dat = {" - + "} - /obj/item/weapon/book/manual/engineering_particle_accelerator name = "Particle Accelerator User's Guide" icon_state ="bookParticleAccelerator" author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned title = "Particle Accelerator User's Guide" +/obj/item/weapon/book/manual/engineering_particle_accelerator/New() + ..() dat = {"