From 31b7f9a074732314caa692ffb346d53b9b5ca462 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sat, 17 Jun 2017 16:54:43 -0500 Subject: [PATCH 01/15] The Hierophant is a little less chaotic and murdery on average --- .../hostile/megafauna/hierophant.dm | 95 +++++++++---------- 1 file changed, 47 insertions(+), 48 deletions(-) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm index 9675ac25b1..6336c118f4 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -7,23 +7,25 @@ The Hierophant spawns in its arena, which makes fighting it challenging but not The text this boss speaks is ROT4, use ROT22 to decode -The Hierophant's attacks are as follows, and INTENSIFY at a random chance based on Hierophant's health; -- Creates a cardinal or diagonal blast(Cross Blast) under its target, exploding after a short time. - INTENSITY EFFECT: Creates one of the cross blast types under itself instead of under the target. - INTENSITY EFFECT: The created Cross Blast fires in all directions if below half health. -- If no chasers exist, creates a chaser that will seek its target, leaving a trail of blasts. - INTENSITY EFFECT: Creates a second, slower chaser. -- Creates an expanding AoE burst. -- INTENSE ATTACKS: +The Hierophant's attacks are as follows; +- These attacks happen at a random, increasing chance: If target is at least 2 tiles away; Blinks to the target after a very brief delay, damaging everything near the start and end points. As above, but does so multiple times if below half health. - Rapidly creates Cross Blasts under a target. - If chasers are off cooldown, creates four high-speed chasers. -- IF TARGET WAS STRUCK IN MELEE: Creates a 3x3 square of blasts under the target. + Rapidly creates cardinal and diagonal Cross Blasts under a target. + If chasers are off cooldown, creates 4 chasers. -- IF TARGET IS OUTSIDE THE ARENA: Creates an arena around the target for 10 seconds, blinking to it if Hierophant is not in the arena. +- IF TARGET IS OUTSIDE THE ARENA: Creates an arena around the target for 10 seconds, blinking to the target if not in the created arena. The arena has a 20 second cooldown, giving people a small window to get the fuck out. +- If no chasers exist, creates a chaser that will seek its target, leaving a trail of blasts. + Is more likely to create a second, slower, chaser if hurt. +- If the target is at least 2 tiles away, may Blink to the target after a very brief delay, damaging everything near the start and end points. +- Creates a cardinal or diagonal blast(Cross Blast) under its target, exploding after a short time. + If below half health, the created Cross Blast may fire in all directions. +- Creates an expanding AoE burst. + +- IF TARGET WAS STRUCK IN MELEE: Creates a 3x3 square of blasts under the target. + Cross Blasts and the AoE burst gain additional range as Hierophant loses health, while Chasers gain additional speed. When Hierophant dies, it stops trying to murder you and shrinks into a small form, which, while much weaker, is still quite effective. @@ -178,17 +180,18 @@ Difficulty: Hard /mob/living/simple_animal/hostile/megafauna/hierophant/OpenFire() calculate_rage() - var/target_is_slow = FALSE + if(blinking) + return + + var/target_slowness = 0 if(isliving(target)) var/mob/living/L = target if(!blinking && L.stat == DEAD && get_dist(src, L) > 2) blink(L) return - if(L.movement_delay() > 1.5) - target_is_slow = TRUE - chaser_speed = max(1, (3 - anger_modifier * 0.04) + target_is_slow * 0.5) - if(blinking) - return + target_slowness += L.movement_delay() + target_slowness = max(target_slowness, 1) + chaser_speed = max(1, (3 - anger_modifier * 0.04) + ((target_slowness - 1) * 0.5)) arena_trap(target) ranged_cooldown = world.time + max(5, ranged_cooldown_time - anger_modifier * 0.75) //scale cooldown lower with high anger. @@ -210,18 +213,19 @@ Difficulty: Hard var/blink_counter = 1 + round(anger_modifier * 0.08) switch(pick(possibilities)) if("blink_spam") //blink either once or multiple times. - if(health < maxHealth * 0.5 && !target_is_slow && blink_counter > 1) + if(health < maxHealth * 0.5 && blink_counter > 1) visible_message("\"Mx ampp rsx iwgeti.\"") var/oldcolor = color animate(src, color = "#660099", time = 6) - while(health && target && blink_counter) + sleep(6) + while(health && !QDELETED(target) && blink_counter) if(loc == target.loc || loc == target) //we're on the same tile as them after about a second we can stop now break blink_counter-- blinking = FALSE blink(target) blinking = TRUE - sleep(5) + sleep(4 + target_slowness) animate(src, color = oldcolor, time = 8) addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 8) sleep(8) @@ -233,15 +237,14 @@ Difficulty: Hard blinking = TRUE var/oldcolor = color animate(src, color = "#660099", time = 6) - while(health && target && cross_counter) + sleep(6) + while(health && !QDELETED(target) && cross_counter) cross_counter-- - var/delay = 7 if(prob(60)) INVOKE_ASYNC(src, .proc/cardinal_blasts, target) else INVOKE_ASYNC(src, .proc/diagonal_blasts, target) - delay = 5 //this one isn't so mean, so do the next one faster(if there is one) - sleep(delay) + sleep(6 + target_slowness) animate(src, color = oldcolor, time = 8) addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 8) sleep(8) @@ -250,19 +253,22 @@ Difficulty: Hard visible_message("\"Mx gerrsx lmhi.\"") blinking = TRUE var/oldcolor = color - animate(src, color = "#660099", time = 10) + animate(src, color = "#660099", time = 6) + sleep(6) var/list/targets = ListTargets() var/list/cardinal_copy = GLOB.cardinal.Copy() while(health && targets.len && cardinal_copy.len) var/mob/living/pickedtarget = pick(targets) - if(targets.len > 4) + if(targets.len >= cardinal_copy.len) pickedtarget = pick_n_take(targets) if(!istype(pickedtarget) || pickedtarget.stat == DEAD) pickedtarget = target + if(QDELETED(pickedtarget) || (istype(pickedtarget) && pickedtarget.stat == DEAD)) + break //main target is dead and we're out of living targets, cancel out var/obj/effect/temp_visual/hierophant/chaser/C = new /obj/effect/temp_visual/hierophant/chaser(loc, src, pickedtarget, chaser_speed, FALSE) C.moving = 3 C.moving_dir = pick_n_take(cardinal_copy) - sleep(10) + sleep(8 + target_slowness) chaser_cooldown = world.time + initial(chaser_cooldown) animate(src, color = oldcolor, time = 8) addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 8) @@ -270,31 +276,24 @@ Difficulty: Hard blinking = FALSE return - if(prob(10 + (anger_modifier * 0.5)) && get_dist(src, target) > 2) - blink(target) - - else if(prob(70 - anger_modifier)) //a cross blast of some type - if(prob(anger_modifier)) //at us? - if(prob(anger_modifier * 2) && health < maxHealth * 0.5) //we're super angry do it at all dirs - INVOKE_ASYNC(src, .proc/alldir_blasts, src) - else if(prob(60)) - INVOKE_ASYNC(src, .proc/cardinal_blasts, src) - else - INVOKE_ASYNC(src, .proc/diagonal_blasts, src) - else //at them? - if(prob(anger_modifier * 2) && health < maxHealth * 0.5 && !target_is_slow) //we're super angry do it at all dirs - INVOKE_ASYNC(src, .proc/alldir_blasts, target) - else if(prob(60)) - INVOKE_ASYNC(src, .proc/cardinal_blasts, target) - else - INVOKE_ASYNC(src, .proc/diagonal_blasts, target) - else if(chaser_cooldown < world.time) //if chasers are off cooldown, fire some! + if(chaser_cooldown < world.time) //if chasers are off cooldown, fire some! var/obj/effect/temp_visual/hierophant/chaser/C = new /obj/effect/temp_visual/hierophant/chaser(loc, src, target, chaser_speed, FALSE) chaser_cooldown = world.time + initial(chaser_cooldown) if((prob(anger_modifier) || target.Adjacent(src)) && target != src) - var/obj/effect/temp_visual/hierophant/chaser/OC = new /obj/effect/temp_visual/hierophant/chaser(loc, src, target, max(1.5, 5 - anger_modifier * 0.07), FALSE) + var/obj/effect/temp_visual/hierophant/chaser/OC = new /obj/effect/temp_visual/hierophant/chaser(loc, src, target, chaser_speed * 1.5, FALSE) OC.moving = 4 OC.moving_dir = pick(GLOB.cardinal - C.moving_dir) + + else if(prob(10 + (anger_modifier * 0.5)) && get_dist(src, target) > 2) + blink(target) + + else if(prob(70 - anger_modifier)) //a cross blast of some type + if(prob(anger_modifier * (2 / target_slowness)) && health < maxHealth * 0.5) //we're super angry do it at all dirs + INVOKE_ASYNC(src, .proc/alldir_blasts, target) + else if(prob(60)) + INVOKE_ASYNC(src, .proc/cardinal_blasts, target) + else + INVOKE_ASYNC(src, .proc/diagonal_blasts, target) else //just release a burst of power INVOKE_ASYNC(src, .proc/burst, get_turf(src)) From 341a229b943ec4f3637954422d078dfa1b7ebd92 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 18 Jun 2017 20:35:08 -0500 Subject: [PATCH 02/15] Vending machines accept space cash. --- code/game/machinery/vending.dm | 84 ++++++++++++++++++++++------------ tgstation.dme.rej | 9 ++++ 2 files changed, 65 insertions(+), 28 deletions(-) create mode 100644 tgstation.dme.rej diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 3fe719c9f2..bffa2a997b 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -53,6 +53,7 @@ var/extended_inventory = 0 //can we access the hidden inventory? var/scan_id = 1 var/obj/item/weapon/coin/coin + var/obj/item/stack/spacecash/bill var/dish_quants = list() //used by the snack machine's custom compartment to count dishes. @@ -118,10 +119,9 @@ ..() /obj/machinery/vending/Destroy() - qdel(wires) - wires = null - qdel(coin) - coin = null + QDEL_NULL(wires) + QDEL_NULL(coin) + QDEL_NULL(bill) return ..() /obj/machinery/vending/snack/Destroy() @@ -311,6 +311,12 @@ attack_hand(user) return else if(istype(W, /obj/item/weapon/coin)) + if(coin) + to_chat(user, "[src] already has [coin] inserted") + return + if(bill) + to_chat(user, "[src] already has [bill] inserted") + return if(!premium.len) to_chat(user, "[src] doesn't have a coin slot.") return @@ -320,6 +326,21 @@ coin = W to_chat(user, "You insert [W] into [src].") return + else if(istype(W, /obj/item/stack/spacecash)) + if(coin) + to_chat(user, "[src] already has [coin] inserted") + return + if(bill) + to_chat(user, "[src] already has [bill] inserted") + return + var/obj/item/stack/S = W + if(!premium.len) + to_chat(user, "[src] doesn't have a bill slot.") + return + S.use(1) + bill = new S.type(src,1) + to_chat(user, "You insert [W] into [src].") + return else if(istype(W, refill_canister) && refill_canister != null) if(stat & (BROKEN|NOPOWER)) to_chat(user, "It does nothing.") @@ -386,9 +407,9 @@ var/list/display_records = product_records if(extended_inventory) display_records = product_records + hidden_records - if(coin) + if(coin || bill) display_records = product_records + coin_records - if(coin && extended_inventory) + if((coin || bill) && extended_inventory) display_records = product_records + hidden_records + coin_records dat += "" dat += "" if(premium.len > 0) - dat += "Coin slot: " - if (coin) - dat += "[coin]  Remove" + dat += "Change Return: " + if (coin || bill) + dat += "[(coin ? coin : "")][(bill ? bill : "")]  Remove" else - dat += "No coin  Remove" + dat += "No money  Remove" if(istype(src, /obj/machinery/vending/snack)) dat += "

Chef's Food Selection

" dat += "
" @@ -443,16 +464,24 @@ return if(href_list["remove_coin"]) - if(!coin) - to_chat(usr, "There is no coin in this machine.") + if(!(coin || bill)) + to_chat(usr, "There is no money in this machine.") return - - coin.loc = loc - if(!usr.get_active_held_item()) - usr.put_in_hands(coin) - to_chat(usr, "You remove [coin] from [src].") - coin = null - + if(coin) + if(!usr.get_active_held_item()) + usr.put_in_hands(coin) + else + coin.forceMove(get_turf(src)) + to_chat(usr, "You remove [coin] from [src].") + coin = null + if(bill) + if(!usr.get_active_held_item()) + usr.put_in_hands(bill) + else + bill.forceMove(get_turf(src)) + to_chat(usr, "You remove [bill] from [src].") + bill = null + usr.set_machine(src) @@ -494,26 +523,25 @@ vend_ready = 1 return else if(R in coin_records) - if(!coin) - to_chat(usr, "You need to insert a coin to get this item!") + if(!(coin || bill)) + to_chat(usr, "You need to insert money to get this item!") vend_ready = 1 return - if(coin.string_attached) + if(coin && coin.string_attached) if(prob(50)) if(usr.put_in_hands(coin)) to_chat(usr, "You successfully pull [coin] out before [src] could swallow it.") coin = null else to_chat(usr, "You couldn't pull [coin] out because your hands are full!") - qdel(coin) - coin = null + QDEL_NULL(coin) else to_chat(usr, "You weren't able to pull [coin] out fast enough, the machine ate it, string and all!") - qdel(coin) - coin = null + QDEL_NULL(coin) else - qdel(coin) - coin = null + QDEL_NULL(coin) + QDEL_NULL(bill) + else if (!(R in product_records)) vend_ready = 1 message_admins("Vending machine exploit attempted by [key_name(usr, usr.client)]!") diff --git a/tgstation.dme.rej b/tgstation.dme.rej new file mode 100644 index 0000000000..f8575768ad --- /dev/null +++ b/tgstation.dme.rej @@ -0,0 +1,9 @@ +diff a/tgstation.dme b/tgstation.dme (rejected hunks) +@@ -1383,6 +1383,7 @@ + #include "code\modules\hydroponics\grown\misc.dm" + #include "code\modules\hydroponics\grown\mushrooms.dm" + #include "code\modules\hydroponics\grown\nettle.dm" ++#include "code\modules\hydroponics\grown\onion.dm" + #include "code\modules\hydroponics\grown\potato.dm" + #include "code\modules\hydroponics\grown\pumpkin.dm" + #include "code\modules\hydroponics\grown\random.dm" From f3ef09736ee6417ad8d31afd7054eac2aff5b10f Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Tue, 20 Jun 2017 08:21:54 -0500 Subject: [PATCH 03/15] Changes tooltip verbs to be on preferences tab --- code/modules/client/verbs/etips.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/client/verbs/etips.dm b/code/modules/client/verbs/etips.dm index 9dc1662add..326f693b08 100644 --- a/code/modules/client/verbs/etips.dm +++ b/code/modules/client/verbs/etips.dm @@ -1,7 +1,7 @@ /client/verb/toggle_tips() set name = "Toggle examine tooltips" set desc = "Toggles examine hover-over tooltips" - set category = "OOC" + set category = "Preferences" prefs.enable_tips = !prefs.enable_tips prefs.save_preferences() @@ -10,7 +10,7 @@ /client/verb/change_tip_delay() set name = "Set examine tooltip delay" set desc = "Sets the delay in milliseconds before examine tooltips appear" - set category = "OOC" + set category = "Preferences" var/indelay = stripped_input(usr, "Enter the tooltip delay in milliseconds (default: 500)", "Enter tooltip delay", "", 10) indelay = text2num(indelay) From 8809db8230de0c26367ee7a9cf9a4e721bd2dd47 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Tue, 20 Jun 2017 10:31:24 -0500 Subject: [PATCH 04/15] Disablers now have an in-hand sprite (Fixes #28582) --- code/modules/projectiles/guns/energy/stun.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm index 643b032cda..00ce2bb3b8 100644 --- a/code/modules/projectiles/guns/energy/stun.dm +++ b/code/modules/projectiles/guns/energy/stun.dm @@ -37,7 +37,7 @@ name = "disabler" desc = "A self-defense weapon that exhausts organic targets, weakening them until they collapse." icon_state = "disabler" - item_state = "disabler" + item_state = null origin_tech = "combat=3" ammo_type = list(/obj/item/ammo_casing/energy/disabler) ammo_x_offset = 3 From 50a4f61663869ee74bda8b600a4b7a4964cca8d8 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Tue, 20 Jun 2017 12:09:15 -0500 Subject: [PATCH 05/15] Adds a heavily-damaged ripley as a lavaland ruin --- .../lavaland_surface_random_ripley.dmm | 84 +++++++++++++++++++ code/controllers/subsystem/mapping.dm | 2 +- code/datums/ruins/lavaland.dm | 8 ++ code/game/mecha/working/ripley.dm | 30 +++---- 4 files changed, 109 insertions(+), 15 deletions(-) create mode 100644 _maps/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm new file mode 100644 index 0000000000..f7dff903f5 --- /dev/null +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm @@ -0,0 +1,84 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/template_noop, +/area/lavaland/surface/outdoors) +"b" = ( +/turf/closed/mineral/volcanic, +/area/lavaland/surface/outdoors) +"c" = ( +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"d" = ( +/obj/mecha/working/ripley/mining, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"e" = ( +/obj/item/clothing/shoes/workboots/mining, +/obj/item/clothing/under/rank/miner/lavaland, +/obj/effect/decal/remains/human, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) + +(1,1,1) = {" +a +a +a +a +a +a +a +"} +(2,1,1) = {" +a +a +b +b +b +a +a +"} +(3,1,1) = {" +a +b +c +b +c +b +a +"} +(4,1,1) = {" +a +b +c +d +e +b +a +"} +(5,1,1) = {" +a +b +c +c +b +b +a +"} +(6,1,1) = {" +a +b +b +b +b +a +a +"} +(7,1,1) = {" +a +a +a +a +a +a +a +"} diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index 9c2f3d2845..c0919d7f20 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -43,7 +43,7 @@ SUBSYSTEM_DEF(mapping) loading_ruins = TRUE var/mining_type = config.minetype if (mining_type == "lavaland") - seedRuins(list(5), global.config.lavaland_budget, /area/lavaland/surface/outdoors/unexplored, lava_ruins_templates) + seedRuins(list(ZLEVEL_LAVALAND), global.config.lavaland_budget, /area/lavaland/surface/outdoors/unexplored, lava_ruins_templates) spawn_rivers() // deep space ruins diff --git a/code/datums/ruins/lavaland.dm b/code/datums/ruins/lavaland.dm index 011363f001..4f6be75f4f 100644 --- a/code/datums/ruins/lavaland.dm +++ b/code/datums/ruins/lavaland.dm @@ -183,3 +183,11 @@ suffix = "lavaland_surface_swarmer_crash.dmm" allow_duplicates = FALSE cost = 20 + +/datum/map_template/ruin/lavaland/miningripley + name = "Ripley" + id = "ripley" + description = "A heavily-damaged mining ripley, property of a very unfortunate miner. You might have to do a bit of work to fix this thing up." + suffix = "lavaland_surface_random_ripley.dmm" + allow_duplicates = FALSE + cost = 5 diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm index a752811fe7..e23cea0397 100644 --- a/code/game/mecha/working/ripley.dm +++ b/code/game/mecha/working/ripley.dm @@ -91,32 +91,34 @@ /obj/mecha/working/ripley/mining desc = "An old, dusty mining Ripley." name = "\improper APLU \"Miner\"" + obj_integrity = 75 //Low starting health -/obj/mecha/working/ripley/mining/New() - ..() - //Attach drill - if(prob(25)) //Possible diamond drill... Feeling lucky? - var/obj/item/mecha_parts/mecha_equipment/drill/diamonddrill/D = new /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill - D.attach(src) - else - var/obj/item/mecha_parts/mecha_equipment/drill/D = new /obj/item/mecha_parts/mecha_equipment/drill - D.attach(src) +/obj/mecha/working/ripley/mining/Initialize() + . = ..() + if(cell) + cell.charge = Floor(cell.charge * 0.25) //Starts at very low charge + if(prob(70)) //Maybe add a drill + if(prob(15)) //Possible diamond drill... Feeling lucky? + var/obj/item/mecha_parts/mecha_equipment/drill/diamonddrill/D = new + D.attach(src) + else + var/obj/item/mecha_parts/mecha_equipment/drill/D = new + D.attach(src) - //Add possible plasma cutter - if(prob(25)) - var/obj/item/mecha_parts/mecha_equipment/M = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma + else //Add possible plasma cutter if no drill + var/obj/item/mecha_parts/mecha_equipment/M = new M.attach(src) //Add ore box to cargo cargo.Add(new /obj/structure/ore_box(src)) //Attach hydraulic clamp - var/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/HC = new /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp + var/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/HC = new HC.attach(src) for(var/obj/item/mecha_parts/mecha_tracking/B in trackers)//Deletes the beacon so it can't be found easily qdel(B) - var/obj/item/mecha_parts/mecha_equipment/mining_scanner/scanner = new /obj/item/mecha_parts/mecha_equipment/mining_scanner + var/obj/item/mecha_parts/mecha_equipment/mining_scanner/scanner = new scanner.attach(src) /obj/mecha/working/ripley/Exit(atom/movable/O) From e57a75370109334a6c79eab4b8845e3f21fcf13a Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 25 Jun 2017 11:35:00 -0500 Subject: [PATCH 06/15] Exporting mechs! --- code/game/mecha/mecha.dm | 9 ++- code/game/mecha/mecha.dm.rej | 10 +++ code/modules/cargo/exports/large_objects.dm | 76 +++++++++++++++++++++ code/modules/cargo/exports/tools.dm | 1 + code/modules/shuttle/supply.dm | 2 +- 5 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 code/game/mecha/mecha.dm.rej diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 3cd142fcdc..8a66a88f33 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -56,7 +56,7 @@ var/datum/gas_mixture/cabin_air var/obj/machinery/atmospherics/components/unary/portables_connector/connected_port = null - var/obj/item/device/radio/radio = null + var/obj/item/device/radio/mech/radio var/list/trackers = list() var/max_temperature = 25000 @@ -117,6 +117,7 @@ hud_possible = list (DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_TRACK_HUD) +/obj/item/device/radio/mech //this has to go somewhere /obj/mecha/Initialize() . = ..() @@ -155,11 +156,9 @@ AI = M //AIs are loaded into the mech computer itself. When the mech dies, so does the AI. They can be recovered with an AI card from the wreck. else M.forceMove(loc) - - if(prob(30)) - explosion(get_turf(loc), 0, 0, 1, 3) - if(wreckage) + if(prob(30)) + explosion(get_turf(src), 0, 0, 1, 3) var/obj/structure/mecha_wreckage/WR = new wreckage(loc, AI) for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) if(E.salvageable && prob(30)) diff --git a/code/game/mecha/mecha.dm.rej b/code/game/mecha/mecha.dm.rej new file mode 100644 index 0000000000..1f2aa905dc --- /dev/null +++ b/code/game/mecha/mecha.dm.rej @@ -0,0 +1,10 @@ +diff a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm (rejected hunks) +@@ -146,7 +146,7 @@ + /obj/mecha/get_cell() + return cell + +-/obj/mecha/deconstruct(disassembled = TRUE) ++/obj/mecha/Destroy() + go_out() + var/mob/living/silicon/ai/AI + for(var/mob/M in src) //Let's just be ultra sure diff --git a/code/modules/cargo/exports/large_objects.dm b/code/modules/cargo/exports/large_objects.dm index f1555cebcd..1c6b10ff71 100644 --- a/code/modules/cargo/exports/large_objects.dm +++ b/code/modules/cargo/exports/large_objects.dm @@ -96,3 +96,79 @@ cost = 325 unit_name = "security barrier" export_types = list(/obj/item/weapon/grenade/barrier, /obj/structure/barricade/security) + +//Mecha +/datum/export/large/mech + export_types = list(/obj/mecha) + var/sellable + +/datum/export/large/mech/applies_to(obj/O) + if(!..()) + return FALSE + + var/obj/mecha/ME = O + ME.wreckage = null // So the mech doesn't blow up in the cargo shuttle + if(sellable) + return TRUE + +/datum/export/large/mech/sellable + export_types = list() + sellable = TRUE + +/datum/export/large/mech/sellable/ripley + cost = 7500 //boards cost 2500 and takes another 1566 worth of materials (glass, metal, plaseel) to build + significant labor + unit_name = "APLU \"Ripley\"" + export_types = list(/obj/mecha/working/ripley) + exclude_types = list(/obj/mecha/working/ripley/firefighter) + +/datum/export/large/mech/sellable/firefighter + cost = 9000 //same as a ripley but takes 10 more plasteel and 5 less metal + unit_name = "APLU \"Firefighter\"" + export_types = list(/obj/mecha/working/ripley/firefighter) + +/datum/export/large/mech/sellable/odysseus + cost = 6000 // 1540 of material + 2000 price boards + labor + unit_name = "odysseus" + export_types = list(/obj/mecha/medical/odysseus) + +/datum/export/large/mech/sellable/gygax + cost = 25000 // The material is worth 22631 alone. Not as big of a premium as one would expect, since R&D would have provided upgrades by then. + unit_name = "gygax" + export_types = list(/obj/mecha/combat/gygax) + exclude_types = list(/obj/mecha/combat/gygax/dark) + +/datum/export/large/mech/sellable/honkmech + cost = 80000 // The bananium alone is worth around 64887 credits + unit_name = "H.O.N.K" + message = "- HONK HONK HONK HONK HONK HONK HONK HONK HONK HONK HONK HONK HONK HONK HONK HONK HONK HONK HONK HONK HONKHONKHONKHONK" + export_types = list(/obj/mecha/combat/honker) + +/datum/export/large/mech/sellable/durand + cost = 12000 // 7586 worth of material. That's less than a gygax. Players will be disappointed by the durand's comparative lack of worth but oh well. Still a large premium because this requires significant cooperation between R&D, robotics, and cargo. + unit_name = "durand" + export_types = list(/obj/mecha/combat/durand) + +/datum/export/large/mech/sellable/phazon + cost = 50000 // 15767 material + anomaly core. Fuck it, if you're willing to try selling one of these you should get BIG FUCKING MONEY + unit_name = "phazon" + export_types = list(/obj/mecha/combat/phazon) + +/datum/export/large/mech/sellable/syndiegygax + cost = 50000 // You somehow stole a nuke op's gygax and sold it to nanotrasen. Go you. + unit_name = "captured syndicate gygax" + export_types = list(/obj/mecha/combat/gygax/dark) + +/datum/export/large/mech/sellable/syndiegygax/syndie + cost = 25000 // You somehow stole a nuke op's gygax and sold it back to the syndicate. Why would you do this? + unit_name = "gygax" + emagged = TRUE + +/datum/export/large/mech/sellable/mauler + cost = 87500 // Whoa, momma. + unit_name = "captured mauler" + export_types = list(/obj/mecha/combat/marauder/mauler) + +/datum/export/large/mech/sellable/mauler/syndie + cost = 43750 // Just like the mauler is worth 1.75x the telecrystals compared to the gygax, the price reflects this + unit_name = "mauler" + emagged = TRUE diff --git a/code/modules/cargo/exports/tools.dm b/code/modules/cargo/exports/tools.dm index 8dcf68a9f0..c0643d9c4d 100644 --- a/code/modules/cargo/exports/tools.dm +++ b/code/modules/cargo/exports/tools.dm @@ -99,6 +99,7 @@ cost = 5 unit_name = "radio" export_types = list(/obj/item/device/radio) + exclude_types = list(/obj/item/device/radio/mech) // High-tech tools. diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index 60b37236c1..bc8648b873 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -109,7 +109,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list( var/sold_atoms = "" for(var/atom/movable/AM in areaInstance) - if(AM.anchored) + if(AM.anchored && !istype(AM, /obj/mecha)) continue sold_atoms += export_item_and_contents(AM, contraband, emagged, dry_run = FALSE) From 1982321419f12ccabc8b81482912a0535f826221 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 25 Jun 2017 23:47:38 -0500 Subject: [PATCH 07/15] Robotic legs are not weak to glass shards --- code/game/objects/items/stacks/sheets/glass.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index e4ec02e746..622f878d4a 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -197,6 +197,8 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \ var/obj/item/bodypart/O = H.get_bodypart(picked_def_zone) if(!istype(O)) return + if(O.status == BODYPART_ROBOTIC) + return var/feetCover = (H.wear_suit && H.wear_suit.body_parts_covered & FEET) || (H.w_uniform && H.w_uniform.body_parts_covered & FEET) if(H.shoes || feetCover || H.movement_type & FLYING || H.buckled) return From 0178323fe1134aa731df08bf76af54a54dcc950e Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 26 Jun 2017 00:03:57 -0500 Subject: [PATCH 08/15] Makes goonchat robust. --- code/modules/client/verbs/ooc.dm | 83 ++++++++++++++++++++++++++ code/modules/goonchat/browserOutput.dm | 30 ++++++---- 2 files changed, 101 insertions(+), 12 deletions(-) diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm index 93c5e50da8..fc4d8dfab8 100644 --- a/code/modules/client/verbs/ooc.dm +++ b/code/modules/client/verbs/ooc.dm @@ -134,6 +134,89 @@ GLOBAL_VAR_INIT(normal_ooc_colour, OOC_COLOR) else to_chat(src, "There are no admin notices at the moment.") +/client/verb/fix_chat() + set name = "Fix chat" + set category = "OOC" + if (!chatOutput || !istype(chatOutput)) + var/action = alert(src, "Invalid Chat Output data found!\nRecreate data?", "Wot?", "Recreate Chat Output data", "Cancel") + if (action != "Recreate Chat Output data") + return + chatOutput = new /datum/chatOutput(src) + chatOutput.start() + action = alert(src, "Goon chat reloading, wait a bit and tell me if it's fixed", "", "Fixed", "Nope") + if (action == "Fixed") + log_game("GOONCHAT: [key_name(src)] Had to fix their goonchat by re-creating the chatOutput datum") + else + chatOutput.load() + action = alert(src, "How about now? (give it a moment (it may also try to load twice))", "", "Yes", "No") + if (action == "Yes") + log_game("GOONCHAT: [key_name(src)] Had to fix their goonchat by re-creating the chatOutput datum and forcing a load()") + else + action = alert(src, "Welp, I'm all out of ideas. Try closing byond and reconnecting.\nWe could also disable fancy chat and re-enable oldchat", "", "Thanks anyways", "Switch to old chat") + if (action == "Switch to old chat") + winset(src, "output", "is-visible=true;is-disabled=false") + winset(src, "browseroutput", "is-visible=false") + log_game("GOONCHAT: [key_name(src)] Failed to fix their goonchat window after recreating the chatOutput and forcing a load()") + + else if (chatOutput.loaded) + var/action = alert(src, "ChatOutput seems to be loaded\nDo you want me to force a reload, wiping the chat log or just refresh the chat window because it broke/went away?", "Hmmm", "Force Reload", "Refresh", "Cancel") + switch (action) + if ("Force Reload") + chatOutput.loaded = FALSE + chatOutput.start() //this is likely to fail since it asks , but we should try it anyways so we know. + action = alert(src, "Goon chat reloading, wait a bit and tell me if it's fixed", "", "Fixed", "Nope") + if (action == "Fixed") + log_game("GOONCHAT: [key_name(src)] Had to fix their goonchat by forcing a start()") + else + chatOutput.load() + action = alert(src, "How about now? (give it a moment (it may also try to load twice))", "", "Yes", "No") + if (action == "Yes") + log_game("GOONCHAT: [key_name(src)] Had to fix their goonchat by forcing a load()") + else + action = alert(src, "Welp, I'm all out of ideas. Try closing byond and reconnecting.\nWe could also disable fancy chat and re-enable oldchat", "", "Thanks anyways", "Switch to old chat") + if (action == "Switch to old chat") + winset(src, "output", "is-visible=true;is-disabled=false") + winset(src, "browseroutput", "is-visible=false") + log_game("GOONCHAT: [key_name(src)] Failed to fix their goonchat window forcing a start() and forcing a load()") + + if ("Refresh") + chatOutput.showChat() + action = alert(src, "Goon chat refreshing, wait a bit and tell me if it's fixed", "", "Fixed", "Nope, force a reload") + if (action == "Fixed") + log_game("GOONCHAT: [key_name(src)] Had to fix their goonchat by forcing a show()") + else + chatOutput.loaded = FALSE + chatOutput.load() + action = alert(src, "How about now? (give it a moment)", "", "Yes", "No") + if (action == "Yes") + log_game("GOONCHAT: [key_name(src)] Had to fix their goonchat by forcing a load()") + else + action = alert(src, "Welp, I'm all out of ideas. Try closing byond and reconnecting.\nWe could also disable fancy chat and re-enable oldchat", "", "Thanks anyways", "Switch to old chat") + if (action == "Switch to old chat") + winset(src, "output", "is-visible=true;is-disabled=false") + winset(src, "browseroutput", "is-visible=false") + log_game("GOONCHAT: [key_name(src)] Failed to fix their goonchat window forcing a show() and forcing a load()") + return + + else + chatOutput.start() + var/action = alert(src, "Manually loading Chat, wait a bit and tell me if it's fixed", "", "Fixed", "Nope") + if (action == "Fixed") + log_game("GOONCHAT: [key_name(src)] Had to fix their goonchat by manually calling start()") + else + chatOutput.load() + alert(src, "How about now? (give it a moment (it may also try to load twice))", "", "Yes", "No") + if (action == "Yes") + log_game("GOONCHAT: [key_name(src)] Had to fix their goonchat by manually calling start() and forcing a load()") + else + action = alert(src, "Welp, I'm all out of ideas. Try closing byond and reconnecting.\nWe could also disable fancy chat and re-enable oldchat", "", "Thanks anyways", "Switch to old chat") + if (action == "Switch to old chat") + winset(src, "output", list2params(list("on-show" = "", "is-disabled" = "false", "is-visible" = "true"))) + winset(src, "browseroutput", "is-disabled=true;is-visible=false") + log_game("GOONCHAT: [key_name(src)] Failed to fix their goonchat window after manually calling start() and forcing a load()") + + + /client/verb/motd() set name = "MOTD" set category = "OOC" diff --git a/code/modules/goonchat/browserOutput.dm b/code/modules/goonchat/browserOutput.dm index 7ab7950f2c..191da98ea1 100644 --- a/code/modules/goonchat/browserOutput.dm +++ b/code/modules/goonchat/browserOutput.dm @@ -90,8 +90,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic testing("Chat loaded for [owner.ckey]") loaded = TRUE - winset(owner, "output", "is-disabled=true;is-visible=false") - winset(owner, "browseroutput", "is-disabled=false;is-visible=true") + showChat() for(var/message in messageQueue) @@ -99,9 +98,16 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic messageQueue = null sendClientData() - + + //do not convert to to_chat() + owner << {"If you can see this, update byond."} + pingLoop() +/datum/chatOutput/proc/showChat() + winset(owner, "output", "is-visible=false") + winset(owner, "browseroutput", "is-disabled=false;is-visible=true") + /datum/chatOutput/proc/pingLoop() set waitfor = FALSE @@ -237,24 +243,24 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic message = replacetext(message, "\proper", "") message = replacetext(message, "\n", "
") message = replacetext(message, "\t", "[GLOB.TAB][GLOB.TAB]") - + for(var/I in targets) //Grab us a client if possible var/client/C = grab_client(I) - + if (!C) continue - + + //Send it to the old style output window. + C << original_message + if(!C.chatOutput || C.chatOutput.broken) // A player who hasn't updated his skin file. - C << original_message - return TRUE + continue if(!C.chatOutput.loaded) - //Client sucks at loading things, put their messages in a queue + //Client still loading, put their messages in a queue C.chatOutput.messageQueue += message - //But also send it to their output window since that shows until goonchat loads - C << original_message - return + continue // url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript. C << output(url_encode(url_encode(message)), "browseroutput:output") From 5f4e1ed721c3f0a1eb7d1838548393004d1f2634 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 26 Jun 2017 06:01:38 -0500 Subject: [PATCH 09/15] Improves Ahelp feedback --- code/modules/admin/verbs/adminhelp.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 632890e654..ce9f5a62f4 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -196,9 +196,6 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) else MessageNoRecipient(parsed_message) - //show it to the person adminhelping too - to_chat(C, "PM to-Admins: [name]") - //send it to irc if nobody is on and tell us how many were on var/admin_number_present = send2irc_adminless_only(initiator_ckey, "Ticket #[id]: [name]") log_admin_private("Ticket #[id]: [key_name(initiator)]: [name] - heard by [admin_number_present] non-AFK admins who have +BAN.") @@ -265,6 +262,9 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) window_flash(X, ignorepref = TRUE) to_chat(X, chat_msg) + //show it to the person adminhelping too + to_chat(initiator, "PM to-Admins: [name]") + //Reopen a closed ticket /datum/admin_help/proc/Reopen() if(state == AHELP_ACTIVE) From 04dd1ffdbd850c7ef3739c8d3b2795e0810b2db5 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 26 Jun 2017 06:03:44 -0500 Subject: [PATCH 10/15] Fixes resin attack message --- code/game/objects/effects/effect_system/effects_foam.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm index 9ca086fad2..0e1c88bb79 100644 --- a/code/game/objects/effects/effect_system/effects_foam.dm +++ b/code/game/objects/effects/effect_system/effects_foam.dm @@ -220,7 +220,7 @@ /obj/structure/foamedmetal/attack_hand(mob/user) user.changeNext_move(CLICK_CD_MELEE) user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) - to_chat(user, "You hit the metal foam but bounce off it!") + to_chat(user, "You hit [src] but bounce off it!") playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1) /obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target, height=1.5) From 55fe5afabdf6cf0da56b8b1e87454311271a0d36 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 26 Jun 2017 06:15:20 -0500 Subject: [PATCH 11/15] Automatic changelog generation for PR #1664 [ci skip] --- html/changelogs/AutoChangeLog-pr-1664.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-1664.yml diff --git a/html/changelogs/AutoChangeLog-pr-1664.yml b/html/changelogs/AutoChangeLog-pr-1664.yml new file mode 100644 index 0000000000..70700ac5c3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1664.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "Thanks to the invention of \"Bill slots\", vending machines can now accept space cash." From 46810f982f3c904f027c4f31041a67720d0ac391 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 26 Jun 2017 06:21:51 -0500 Subject: [PATCH 12/15] Automatic changelog generation for PR #1695 [ci skip] --- html/changelogs/AutoChangeLog-pr-1695.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-1695.yml diff --git a/html/changelogs/AutoChangeLog-pr-1695.yml b/html/changelogs/AutoChangeLog-pr-1695.yml new file mode 100644 index 0000000000..d66f67f7b6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1695.yml @@ -0,0 +1,4 @@ +author: "Xhuis" +delete-after: True +changes: + - bugfix: "Disablers now have an in-hand sprite." From 2552a1715f70cbc0eaeb0f44d4267eb19eff1593 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 26 Jun 2017 06:23:26 -0500 Subject: [PATCH 13/15] Automatic changelog generation for PR #1649 [ci skip] --- html/changelogs/AutoChangeLog-pr-1649.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-1649.yml diff --git a/html/changelogs/AutoChangeLog-pr-1649.yml b/html/changelogs/AutoChangeLog-pr-1649.yml new file mode 100644 index 0000000000..26d5e8ea6e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1649.yml @@ -0,0 +1,4 @@ +author: "Joan" +delete-after: True +changes: + - tweak: "The Hierophant is a little less chaotic and murdery on average." From f4172fe02903831fde9eea8742aca46f411b5107 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 26 Jun 2017 06:26:47 -0500 Subject: [PATCH 14/15] Automatic changelog generation for PR #1778 [ci skip] --- html/changelogs/AutoChangeLog-pr-1778.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-1778.yml diff --git a/html/changelogs/AutoChangeLog-pr-1778.yml b/html/changelogs/AutoChangeLog-pr-1778.yml new file mode 100644 index 0000000000..744e80fb95 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1778.yml @@ -0,0 +1,4 @@ +author: "Kor" +delete-after: True +changes: + - rscadd: "Glass shards will no longer hurt people with robotic legs." From 37aba60771574316acb92293908e6bccc9cf8212 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 26 Jun 2017 06:28:23 -0500 Subject: [PATCH 15/15] Automatic changelog generation for PR #1772 [ci skip] --- html/changelogs/AutoChangeLog-pr-1772.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-1772.yml diff --git a/html/changelogs/AutoChangeLog-pr-1772.yml b/html/changelogs/AutoChangeLog-pr-1772.yml new file mode 100644 index 0000000000..8ff81219e5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1772.yml @@ -0,0 +1,4 @@ +author: "RandomMarine" +delete-after: True +changes: + - rscadd: "Cargo can now export mechs!"