This commit is contained in:
LetterJay
2017-06-26 06:32:33 -05:00
24 changed files with 443 additions and 116 deletions
@@ -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
"}
+1 -1
View File
@@ -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
+8
View File
@@ -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
+56 -28
View File
@@ -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, "<span class='warning'>[src] already has [coin] inserted</span>")
return
if(bill)
to_chat(user, "<span class='warning'>[src] already has [bill] inserted</span>")
return
if(!premium.len)
to_chat(user, "<span class='warning'>[src] doesn't have a coin slot.</span>")
return
@@ -320,6 +326,21 @@
coin = W
to_chat(user, "<span class='notice'>You insert [W] into [src].</span>")
return
else if(istype(W, /obj/item/stack/spacecash))
if(coin)
to_chat(user, "<span class='warning'>[src] already has [coin] inserted</span>")
return
if(bill)
to_chat(user, "<span class='warning'>[src] already has [bill] inserted</span>")
return
var/obj/item/stack/S = W
if(!premium.len)
to_chat(user, "<span class='warning'>[src] doesn't have a bill slot.</span>")
return
S.use(1)
bill = new S.type(src,1)
to_chat(user, "<span class='notice'>You insert [W] into [src].</span>")
return
else if(istype(W, refill_canister) && refill_canister != null)
if(stat & (BROKEN|NOPOWER))
to_chat(user, "<span class='notice'>It does nothing.</span>")
@@ -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 += "<ul>"
for (var/datum/data/vending_product/R in display_records)
@@ -403,11 +424,11 @@
dat += "</ul>"
dat += "</div>"
if(premium.len > 0)
dat += "<b>Coin slot:</b> "
if (coin)
dat += "[coin]&nbsp;&nbsp;<a href='byond://?src=\ref[src];remove_coin=1'>Remove</a>"
dat += "<b>Change Return:</b> "
if (coin || bill)
dat += "[(coin ? coin : "")][(bill ? bill : "")]&nbsp;&nbsp;<a href='byond://?src=\ref[src];remove_coin=1'>Remove</a>"
else
dat += "<i>No coin</i>&nbsp;&nbsp;<span class='linkOff'>Remove</span>"
dat += "<i>No money</i>&nbsp;&nbsp;<span class='linkOff'>Remove</span>"
if(istype(src, /obj/machinery/vending/snack))
dat += "<h3>Chef's Food Selection</h3>"
dat += "<div class='statusDisplay'>"
@@ -443,16 +464,24 @@
return
if(href_list["remove_coin"])
if(!coin)
to_chat(usr, "<span class='notice'>There is no coin in this machine.</span>")
if(!(coin || bill))
to_chat(usr, "<span class='notice'>There is no money in this machine.</span>")
return
coin.loc = loc
if(!usr.get_active_held_item())
usr.put_in_hands(coin)
to_chat(usr, "<span class='notice'>You remove [coin] from [src].</span>")
coin = null
if(coin)
if(!usr.get_active_held_item())
usr.put_in_hands(coin)
else
coin.forceMove(get_turf(src))
to_chat(usr, "<span class='notice'>You remove [coin] from [src].</span>")
coin = null
if(bill)
if(!usr.get_active_held_item())
usr.put_in_hands(bill)
else
bill.forceMove(get_turf(src))
to_chat(usr, "<span class='notice'>You remove [bill] from [src].</span>")
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, "<span class='warning'>You need to insert a coin to get this item!</span>")
if(!(coin || bill))
to_chat(usr, "<span class='warning'>You need to insert money to get this item!</span>")
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, "<span class='notice'>You successfully pull [coin] out before [src] could swallow it.</span>")
coin = null
else
to_chat(usr, "<span class='warning'>You couldn't pull [coin] out because your hands are full!</span>")
qdel(coin)
coin = null
QDEL_NULL(coin)
else
to_chat(usr, "<span class='warning'>You weren't able to pull [coin] out fast enough, the machine ate it, string and all!</span>")
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)]!")
+4 -5
View File
@@ -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))
+10
View File
@@ -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
+16 -14
View File
@@ -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)
@@ -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, "<span class='warning'>You hit the metal foam but bounce off it!</span>")
to_chat(user, "<span class='warning'>You hit [src] but bounce off it!</span>")
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
/obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target, height=1.5)
@@ -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
+3 -3
View File
@@ -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, "<span class='adminnotice'>PM to-<b>Admins</b>: [name]</span>")
//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, "<span class='adminnotice'>PM to-<b>Admins</b>: [name]</span>")
//Reopen a closed ticket
/datum/admin_help/proc/Reopen()
if(state == AHELP_ACTIVE)
@@ -103,3 +103,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
+1
View File
@@ -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.
+2 -2
View File
@@ -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)
+83
View File
@@ -134,6 +134,89 @@ GLOBAL_VAR_INIT(normal_ooc_colour, OOC_COLOR)
else
to_chat(src, "<span class='notice'>There are no admin notices at the moment.</span>")
/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"
+18 -12
View File
@@ -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 << {"<span class="userdanger">If you can see this, update byond.</span>"}
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", "<br>")
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")
@@ -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("<span class='hierophant'>\"Mx ampp rsx iwgeti.\"</span>")
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("<span class='hierophant'>\"Mx gerrsx lmhi.\"</span>")
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))
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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)
@@ -0,0 +1,4 @@
author: "Joan"
delete-after: True
changes:
- tweak: "The Hierophant is a little less chaotic and murdery on average."
@@ -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."
@@ -0,0 +1,4 @@
author: "Xhuis"
delete-after: True
changes:
- bugfix: "Disablers now have an in-hand sprite."
@@ -0,0 +1,4 @@
author: "RandomMarine"
delete-after: True
changes:
- rscadd: "Cargo can now export mechs!"
@@ -0,0 +1,4 @@
author: "Kor"
delete-after: True
changes:
- rscadd: "Glass shards will no longer hurt people with robotic legs."
+9
View File
@@ -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"