Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13
This commit is contained in:
@@ -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
|
||||
"}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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] <a href='byond://?src=\ref[src];remove_coin=1'>Remove</a>"
|
||||
dat += "<b>Change Return:</b> "
|
||||
if (coin || bill)
|
||||
dat += "[(coin ? coin : "")][(bill ? bill : "")] <a href='byond://?src=\ref[src];remove_coin=1'>Remove</a>"
|
||||
else
|
||||
dat += "<i>No coin</i> <span class='linkOff'>Remove</span>"
|
||||
dat += "<i>No money</i> <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)]!")
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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."
|
||||
@@ -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"
|
||||
Reference in New Issue
Block a user