Merge branch 'master' into spellcheck

This commit is contained in:
ShizCalev
2018-06-26 16:43:41 -04:00
committed by GitHub
186 changed files with 2073 additions and 1570 deletions
+2 -2
View File
@@ -1,11 +1,11 @@
////////////////////////////////
/proc/message_admins(msg)
msg = "<span class=\"admin\"><span class=\"prefix\">ADMIN LOG:</span> <span class=\"message\">[msg]</span></span>"
msg = "<span class=\"admin\"><span class=\"prefix\">ADMIN LOG:</span> <span class=\"message linkify\">[msg]</span></span>"
to_chat(GLOB.admins, msg)
/proc/relay_msg_admins(msg)
msg = "<span class=\"admin\"><span class=\"prefix\">RELAY:</span> <span class=\"message\">[msg]</span></span>"
msg = "<span class=\"admin\"><span class=\"prefix\">RELAY:</span> <span class=\"message linkify\">[msg]</span></span>"
to_chat(GLOB.admins, msg)
+1 -1
View File
@@ -6,7 +6,7 @@
anchored = TRUE
var/popped = FALSE
/obj/effect/fun_balloon/New()
/obj/effect/fun_balloon/Initialize()
. = ..()
SSobj.processing |= src
+9 -2
View File
@@ -1056,14 +1056,21 @@
if(!check_rights(R_ADMIN))
return
var/mob/M = locate(href_list["boot2"])
if (ismob(M))
if(ismob(M))
if(!check_if_greater_rights_than(M.client))
to_chat(usr, "<span class='danger'>Error: They have more rights than you do.</span>")
return
if(alert(usr, "Kick [key_name(M)]?", "Confirm", "Yes", "No") != "Yes")
return
if(!M)
to_chat(usr, "<span class='danger'>Error: [M] no longer exists!</span>")
return
if(!M.client)
to_chat(usr, "<span class='danger'>Error: [M] no longer has a client!</span>")
return
to_chat(M, "<span class='danger'>You have been kicked from the server by [usr.client.holder.fakekey ? "an Administrator" : "[usr.client.ckey]"].</span>")
log_admin("[key_name(usr)] kicked [key_name(M)].")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] kicked [key_name_admin(M)].</span>")
//M.client = null
qdel(M.client)
else if(href_list["addmessage"])
+2 -2
View File
@@ -255,7 +255,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
/datum/admin_help/proc/MessageNoRecipient(msg)
var/ref_src = "[REF(src)]"
//Message to be sent to all admins
var/admin_msg = "<span class='adminnotice'><span class='adminhelp'>Ticket [TicketHref("#[id]", ref_src)]</span><b>: [LinkedReplyName(ref_src)] [FullMonty(ref_src)]:</b> [keywords_lookup(msg)]</span>"
var/admin_msg = "<span class='adminnotice'><span class='adminhelp'>Ticket [TicketHref("#[id]", ref_src)]</span><b>: [LinkedReplyName(ref_src)] [FullMonty(ref_src)]:</b> <span class='linkify'>[keywords_lookup(msg)]</span></span>"
AddInteraction("<font color='red'>[LinkedReplyName(ref_src)]: [msg]</font>")
@@ -267,7 +267,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
to_chat(X, admin_msg)
//show it to the person adminhelping too
to_chat(initiator, "<span class='adminnotice'>PM to-<b>Admins</b>: [msg]</span>")
to_chat(initiator, "<span class='adminnotice'>PM to-<b>Admins</b>: <span class='linkify'>[msg]</span></span>")
//Reopen a closed ticket
/datum/admin_help/proc/Reopen()
+7 -7
View File
@@ -145,15 +145,15 @@
var/keywordparsedmsg = keywords_lookup(msg)
if(irc)
to_chat(src, "<font color='blue'>PM to-<b>Admins</b>: [rawmsg]</font>")
to_chat(src, "<font color='blue'>PM to-<b>Admins</b>: <span class='linkify'>[rawmsg]</span></font>")
var/datum/admin_help/AH = admin_ticket_log(src, "<font color='red'>Reply PM from-<b>[key_name(src, TRUE, TRUE)] to <i>IRC</i>: [keywordparsedmsg]</font>")
ircreplyamount--
send2irc("[AH ? "#[AH.id] " : ""]Reply: [ckey]", rawmsg)
else
if(recipient.holder)
if(holder) //both are admins
to_chat(recipient, "<font color='red'>Admin PM from-<b>[key_name(src, recipient, 1)]</b>: [keywordparsedmsg]</font>")
to_chat(src, "<font color='blue'>Admin PM to-<b>[key_name(recipient, src, 1)]</b>: [keywordparsedmsg]</font>")
to_chat(recipient, "<font color='red'>Admin PM from-<b>[key_name(src, recipient, 1)]</b>: <span class='linkify'>[keywordparsedmsg]</span></font>")
to_chat(src, "<font color='blue'>Admin PM to-<b>[key_name(recipient, src, 1)]</b>: <span class='linkify'>[keywordparsedmsg]</span></font>")
//omg this is dumb, just fill in both their tickets
var/interaction_message = "<font color='purple'>PM from-<b>[key_name(src, recipient, 1)]</b> to-<b>[key_name(recipient, src, 1)]</b>: [keywordparsedmsg]</font>"
@@ -162,10 +162,10 @@
admin_ticket_log(recipient, interaction_message)
else //recipient is an admin but sender is not
var/replymsg = "<font color='red'>Reply PM from-<b>[key_name(src, recipient, 1)]</b>: [keywordparsedmsg]</font>"
var/replymsg = "<font color='red'>Reply PM from-<b>[key_name(src, recipient, 1)]</b>: <span class='linkify'>[keywordparsedmsg]</span></font>"
admin_ticket_log(src, replymsg)
to_chat(recipient, replymsg)
to_chat(src, "<font color='blue'>PM to-<b>Admins</b>: [msg]</font>")
to_chat(src, "<font color='blue'>PM to-<b>Admins</b>: <span class='linkify'>[msg]</font></font>")
//play the receiving admin the adminhelp sound (if they have them enabled)
if(recipient.prefs.toggles & SOUND_ADMINHELP)
@@ -177,9 +177,9 @@
new /datum/admin_help(msg, recipient, TRUE)
to_chat(recipient, "<font color='red' size='4'><b>-- Administrator private message --</b></font>")
to_chat(recipient, "<font color='red'>Admin PM from-<b>[key_name(src, recipient, 0)]</b>: [msg]</font>")
to_chat(recipient, "<font color='red'>Admin PM from-<b>[key_name(src, recipient, 0)]</b>: <span class='linkify'>[msg]</span></font>")
to_chat(recipient, "<font color='red'><i>Click on the administrator's name to reply.</i></font>")
to_chat(src, "<font color='blue'>Admin PM to-<b>[key_name(recipient, src, 1)]</b>: [msg]</font>")
to_chat(src, "<font color='blue'>Admin PM to-<b>[key_name(recipient, src, 1)]</b>: <span class='linkify'>[msg]</span></font>")
admin_ticket_log(recipient, "<font color='blue'>PM From [key_name_admin(src)]: [keywordparsedmsg]</font>")
+2 -2
View File
@@ -12,10 +12,10 @@
log_talk(mob,"[key_name(src)] : [msg]",LOGASAY)
msg = keywords_lookup(msg)
if(check_rights(R_ADMIN,0))
msg = "<span class='admin'><span class='prefix'>ADMIN:</span> <EM>[key_name(usr, 1)]</EM> [ADMIN_FLW(mob)]: <span class='message'>[msg]</span></span>"
msg = "<span class='admin'><span class='prefix'>ADMIN:</span> <EM>[key_name(usr, 1)]</EM> [ADMIN_FLW(mob)]: <span class='message linkify'>[msg]</span></span>"
to_chat(GLOB.admins, msg)
else
msg = "<span class='adminobserver'><span class='prefix'>ADMIN:</span> <EM>[key_name(usr, 1)]</EM> [ADMIN_FLW(mob)]: <span class='message'>[msg]</span></span>"
msg = "<span class='adminobserver'><span class='prefix'>ADMIN:</span> <EM>[key_name(usr, 1)]</EM> [ADMIN_FLW(mob)]: <span class='message linkify'>[msg]</span></span>"
to_chat(GLOB.admins, msg)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Asay") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -629,6 +629,7 @@ GLOBAL_PROTECT(VVpixelmovement)
if (O.vv_edit_var(variable, var_new) == FALSE)
to_chat(src, "Your edit was rejected by the object.")
return
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_VAR_EDIT, args)
log_world("### VarEdit by [key_name(src)]: [O.type] [variable]=[var_value] => [var_new]")
log_admin("[key_name(src)] modified [original_name]'s [variable] from [html_encode("[var_value]")] to [html_encode("[var_new]")]")
var/msg = "[key_name_admin(src)] modified [original_name]'s [variable] from [var_value] to [var_new]"
+1 -1
View File
@@ -57,7 +57,7 @@
var/mob/living/carbon/human/H = null
for(var/mob/living/carbon/human/applicant in GLOB.player_list)
if(isReadytoRumble(applicant, ROLE_TRAITOR, FALSE))
if(isReadytoRumble(applicant, ROLE_TRAITOR))
if(temp.age_check(applicant.client))
if(!(applicant.job in temp.restricted_jobs))
candidates += applicant
+1 -1
View File
@@ -39,7 +39,7 @@
font_color = "blue"
prayer_type = "SPIRITUAL PRAYER"
msg = "<span class='adminnotice'>[icon2html(cross, GLOB.admins)]<b><font color=[font_color]>[prayer_type][deity ? " (to [deity])" : ""]: </font>[ADMIN_FULLMONTY(src)] [ADMIN_SC(src)]:</b> [msg]</span>"
msg = "<span class='adminnotice'>[icon2html(cross, GLOB.admins)]<b><font color=[font_color]>[prayer_type][deity ? " (to [deity])" : ""]: </font>[ADMIN_FULLMONTY(src)] [ADMIN_SC(src)]:</b> <span class='linkify'>[msg]</span></span>"
for(var/client/C in GLOB.admins)
if(C.prefs.chat_toggles & CHAT_PRAYER)
+1 -1
View File
@@ -521,7 +521,7 @@
sleep(20)
var/global/list/curses
if(!curses)
curses = list("A fuel technician just slit his own throat and begged for death. The shuttle will be delayed by three minutes.",
curses = list("A fuel technician just slit his own throat and begged for death.",
"The shuttle's navigation programming was replaced by a file containing just two words: IT COMES.",
"The shuttle's custodian was found washing the windows with their own blood.",
"A shuttle engineer began screaming 'DEATH IS NOT THE END' and ripped out wires until an arc flash seared off her flesh.",
@@ -555,6 +555,9 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
/datum/action/innate/ai/ranged/overload_machine/proc/detonate_machine(obj/machinery/M)
if(M && !QDELETED(M))
var/turf/T = get_turf(M)
message_admins("[ADMIN_LOOKUPFLW(usr)] overloaded [M.name] at [ADMIN_VERBOSEJMP(T)].")
log_game("[key_name(usr)] overloaded [M.name] at [AREACOORD(T)].")
explosion(get_turf(M), 0, 2, 3, 0)
if(M) //to check if the explosion killed it before we try to delete it
qdel(M)
+1
View File
@@ -186,6 +186,7 @@ Code:
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
resistance_flags = FIRE_PROOF
var/anomaly_type = /obj/effect/anomaly
/obj/item/assembly/signaler/anomaly/receive_signal(datum/signal/signal)
@@ -402,13 +402,13 @@
var/pressure = air.return_pressure()
var/old_heat_capacity = air.heat_capacity()
var/reaction_efficency = min(1/((pressure/(0.1*ONE_ATMOSPHERE))*(max(cached_gases[/datum/gas/plasma][MOLES]/cached_gases[/datum/gas/tritium][MOLES],1))),cached_gases[/datum/gas/tritium][MOLES],cached_gases[/datum/gas/plasma][MOLES]/2)
var/reaction_efficency = min(1/((pressure/(0.1*ONE_ATMOSPHERE))*(max(cached_gases[/datum/gas/plasma][MOLES]/cached_gases[/datum/gas/nitrous_oxide][MOLES],1))),cached_gases[/datum/gas/nitrous_oxide][MOLES],cached_gases[/datum/gas/plasma][MOLES]/2)
var/energy_released = 2*reaction_efficency*FIRE_CARBON_ENERGY_RELEASED
if ((cached_gases[/datum/gas/tritium][MOLES] - reaction_efficency < 0 )|| (cached_gases[/datum/gas/plasma][MOLES] - (2*reaction_efficency) < 0)) //Shouldn't produce gas from nothing.
if ((cached_gases[/datum/gas/nitrous_oxide][MOLES] - reaction_efficency < 0 )|| (cached_gases[/datum/gas/plasma][MOLES] - (2*reaction_efficency) < 0)) //Shouldn't produce gas from nothing.
return NO_REACTION
ASSERT_GAS(/datum/gas/bz,air)
cached_gases[/datum/gas/bz][MOLES] += reaction_efficency
cached_gases[/datum/gas/tritium][MOLES] -= reaction_efficency
cached_gases[/datum/gas/nitrous_oxide][MOLES] -= reaction_efficency
cached_gases[/datum/gas/plasma][MOLES] -= 2*reaction_efficency
@@ -422,6 +422,7 @@
priority = 5
name = "Stimulum formation"
id = "stimformation"
/datum/gas_reaction/stimformation/init_reqs()
min_requirements = list(
/datum/gas/tritium = 30,
@@ -496,10 +497,4 @@
#undef STIMULUM_SECOND_RISE
#undef STIMULUM_ABSOLUTE_DROP
#undef REACTION_OPPRESSION_THRESHOLD
#undef PLASMA_BINDING_ENERGY
#undef MAX_CATALYST_EFFICENCY
#undef PLASMA_FUSED_COEFFICENT
#undef CATALYST_COEFFICENT
#undef FUSION_PURITY_THRESHOLD
#undef FUSION_HEAT_DROPOFF
#undef NOBLIUM_FORMATION_ENERGY
@@ -125,7 +125,7 @@ Pipelines + Other Objects -> Pipe network
pixel_y = (piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y
layer = initial(layer) + ((piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_LCHANGE)
/obj/machinery/atmospherics/proc/can_be_node(obj/machinery/atmospherics/target)
/obj/machinery/atmospherics/proc/can_be_node(obj/machinery/atmospherics/target, iteration)
return connection_check(target, piping_layer)
//Find a connecting /obj/machinery/atmospherics in specified direction
@@ -1,7 +1,6 @@
/obj/machinery/atmospherics/pipe/heat_exchanging
icon = 'icons/obj/atmospherics/pipes/heat.dmi'
level = 2
var/initialize_directions_he
var/minimum_temperature_difference = 20
var/thermal_conductivity = WINDOW_HEAT_TRANSFER_COEFFICIENT
color = "#404040"
@@ -9,22 +8,18 @@
var/icon_temperature = T20C //stop small changes in temperature causing icon refresh
resistance_flags = LAVA_PROOF | FIRE_PROOF
/obj/machinery/atmospherics/pipe/heat_exchanging/New()
..()
/obj/machinery/atmospherics/pipe/heat_exchanging/Initialize()
. = ..()
add_atom_colour("#404040", FIXED_COLOUR_PRIORITY)
/obj/machinery/atmospherics/pipe/heat_exchanging/can_be_node(obj/machinery/atmospherics/pipe/heat_exchanging/target)
if(!istype(target))
return 0
if(target.initialize_directions_he & get_dir(target,src))
return 1
/obj/machinery/atmospherics/pipe/heat_exchanging/isConnectable(obj/machinery/atmospherics/pipe/heat_exchanging/target, given_layer, HE_type_check = TRUE)
if(istype(target, /obj/machinery/atmospherics/pipe/heat_exchanging) != HE_type_check)
return FALSE
. = ..()
/obj/machinery/atmospherics/pipe/heat_exchanging/hide()
return
/obj/machinery/atmospherics/pipe/heat_exchanging/GetInitDirections()
return ..() | initialize_directions_he
/obj/machinery/atmospherics/pipe/heat_exchanging/process_atmos()
var/environment_temperature = 0
var/datum/gas_mixture/pipe_air = return_air()
@@ -56,8 +51,6 @@
L.bodytemperature = avg_temp
pipe_air.temperature = avg_temp
/obj/machinery/atmospherics/pipe/heat_exchanging/process()
if(!parent)
return //machines subsystem fires before atmos is initialized so this prevents race condition runtimes
@@ -9,11 +9,9 @@
thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT
dir = SOUTH
initialize_directions = NORTH
initialize_directions_he = SOUTH
device_type = BINARY
construction_type = /obj/item/pipe/directional
pipe_state = "junction"
@@ -26,34 +24,18 @@
piping_layer = PIPING_LAYER_MAX
pixel_x = PIPING_LAYER_P_X
pixel_y = PIPING_LAYER_P_Y
/obj/machinery/atmospherics/pipe/heat_exchanging/junction/SetInitDirections()
switch(dir)
if(SOUTH)
initialize_directions = NORTH
initialize_directions_he = SOUTH
if(NORTH)
initialize_directions = SOUTH
initialize_directions_he = NORTH
if(EAST)
initialize_directions = WEST
initialize_directions_he = EAST
if(WEST)
initialize_directions = EAST
initialize_directions_he = WEST
if(NORTH,SOUTH)
initialize_directions = SOUTH|NORTH
if(EAST,WEST)
initialize_directions = WEST|EAST
/obj/machinery/atmospherics/pipe/heat_exchanging/junction/getNodeConnects()
return list(turn(dir, 180), dir)
/obj/machinery/atmospherics/pipe/heat_exchanging/junction/can_be_node(obj/machinery/atmospherics/target, iteration)
var/init_dir
switch(iteration)
if(1)
init_dir = target.initialize_directions
if(2)
var/obj/machinery/atmospherics/pipe/heat_exchanging/H = target
if(!istype(H))
return 0
init_dir = H.initialize_directions_he
if(init_dir & get_dir(target,src))
return 1
/obj/machinery/atmospherics/pipe/heat_exchanging/junction/isConnectable(obj/machinery/atmospherics/target, given_layer, he_type_check)
if(dir == get_dir(target, src))
return ..(target, given_layer, FALSE) //we want a normal pipe instead
return ..(target, given_layer, TRUE)
@@ -6,13 +6,13 @@
desc = "A manifold composed of regular pipes."
dir = SOUTH
initialize_directions_he = EAST|NORTH|WEST
initialize_directions = EAST|NORTH|WEST
device_type = TRINARY
construction_type = /obj/item/pipe/trinary
pipe_state = "he_manifold"
/obj/machinery/atmospherics/pipe/heat_exchanging/manifold/layer1
piping_layer = PIPING_LAYER_MIN
pixel_x = -PIPING_LAYER_P_X
@@ -26,13 +26,13 @@
/obj/machinery/atmospherics/pipe/heat_exchanging/manifold/SetInitDirections()
switch(dir)
if(NORTH)
initialize_directions_he = EAST|SOUTH|WEST
initialize_directions = EAST|SOUTH|WEST
if(SOUTH)
initialize_directions_he = WEST|NORTH|EAST
initialize_directions = WEST|NORTH|EAST
if(EAST)
initialize_directions_he = SOUTH|WEST|NORTH
initialize_directions = SOUTH|WEST|NORTH
if(WEST)
initialize_directions_he = NORTH|EAST|SOUTH
initialize_directions = NORTH|EAST|SOUTH
/obj/machinery/atmospherics/pipe/heat_exchanging/manifold/update_icon()
var/invis = invisibility ? "-f" : ""
@@ -53,13 +53,13 @@
name = "4-way pipe manifold"
desc = "A manifold composed of heat-exchanging pipes."
initialize_directions_he = NORTH|SOUTH|EAST|WEST
initialize_directions = NORTH|SOUTH|EAST|WEST
device_type = QUATERNARY
construction_type = /obj/item/pipe/quaternary
pipe_state = "he_manifold4w"
/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/layer1
piping_layer = PIPING_LAYER_MIN
pixel_x = -PIPING_LAYER_P_X
@@ -71,7 +71,7 @@
pixel_y = PIPING_LAYER_P_Y
/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/SetInitDirections()
initialize_directions_he = initial(initialize_directions_he)
initialize_directions = initial(initialize_directions)
/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/update_icon()
var/invis = invisibility ? "-f" : ""
@@ -5,13 +5,13 @@
desc = "A one meter section of heat-exchanging pipe."
dir = SOUTH
initialize_directions_he = SOUTH|NORTH
initialize_directions = SOUTH|NORTH
device_type = BINARY
construction_type = /obj/item/pipe/binary/bendable
pipe_state = "he"
/obj/machinery/atmospherics/pipe/heat_exchanging/simple/layer1
piping_layer = PIPING_LAYER_MIN
pixel_x = -PIPING_LAYER_P_X
@@ -24,12 +24,12 @@
/obj/machinery/atmospherics/pipe/heat_exchanging/simple/SetInitDirections()
if(dir in GLOB.diagonals)
initialize_directions_he = dir
initialize_directions = dir
switch(dir)
if(NORTH,SOUTH)
initialize_directions_he = SOUTH|NORTH
initialize_directions = SOUTH|NORTH
if(EAST,WEST)
initialize_directions_he = WEST|EAST
initialize_directions = WEST|EAST
/obj/machinery/atmospherics/pipe/heat_exchanging/simple/proc/normalize_dir()
if(dir==SOUTH)
+28 -30
View File
@@ -1125,8 +1125,7 @@
desc = "Contains refills for medical vending machines."
cost = 2000
contains = list(/obj/item/vending_refill/medical,
/obj/item/vending_refill/medical,
/obj/item/vending_refill/medical)
/obj/item/vending_refill/wallmed)
crate_name = "medical vending crate"
/datum/supply_pack/medical/virus
@@ -1359,53 +1358,41 @@
/datum/supply_pack/service/vending/bartending
name = "Bartending Supply Crate"
desc = "Bring on the booze with six vending machine refills, as well as a free book containing the well-kept secrets to the bartending trade!"
desc = "Bring on the booze with vending machine refills, as well as a free book containing the well-kept secrets to the bartending trade!"
cost = 2000
contains = list(/obj/item/vending_refill/boozeomat,
/obj/item/vending_refill/boozeomat,
/obj/item/vending_refill/boozeomat,
/obj/item/vending_refill/coffee,
/obj/item/vending_refill/coffee,
/obj/item/vending_refill/coffee,
/obj/item/book/granter/action/drink_fling)
crate_name = "bartending supply crate"
/datum/supply_pack/service/vending/cigarette
name = "Cigarette Supply Crate"
desc = "Don't believe the reports - smoke today! Contains cigarette vending machine refills."
desc = "Don't believe the reports - smoke today! Contains a cigarette vending machine refill."
cost = 1500
contains = list(/obj/item/vending_refill/cigarette,
/obj/item/vending_refill/cigarette,
/obj/item/vending_refill/cigarette)
contains = list(/obj/item/vending_refill/cigarette)
crate_name = "cigarette supply crate"
crate_type = /obj/structure/closet/crate
/datum/supply_pack/service/vending/games
name = "Games Supply Crate"
desc = "Get your game on with these three game vending machine refills."
desc = "Get your game on with this game vending machine refill."
cost = 1000
contains = list(/obj/item/vending_refill/games,
/obj/item/vending_refill/games,
/obj/item/vending_refill/games)
contains = list(/obj/item/vending_refill/games)
crate_name = "games supply crate"
crate_type = /obj/structure/closet/crate
/datum/supply_pack/service/vending/snack
name = "Snack Supply Crate"
desc = "Three vending machine refills of cavity-bringin' goodness! The number one dentist recommended order!"
desc = "One vending machine refill of cavity-bringin' goodness! The number one dentist recommended order!"
cost = 1500
contains = list(/obj/item/vending_refill/snack,
/obj/item/vending_refill/snack,
/obj/item/vending_refill/snack)
contains = list(/obj/item/vending_refill/snack)
crate_name = "snacks supply crate"
/datum/supply_pack/service/vending/cola
name = "Softdrinks Supply Crate"
desc = "Got whacked by a toolbox, but you still have those pesky teeth? Get rid of those pearly whites with these three soda machine refills, today!"
desc = "Got whacked by a toolbox, but you still have those pesky teeth? Get rid of those pearly whites with this soda machine refill, today!"
cost = 1500
contains = list(/obj/item/vending_refill/cola,
/obj/item/vending_refill/cola,
/obj/item/vending_refill/cola)
contains = list(/obj/item/vending_refill/cola)
crate_name = "soft drinks supply crate"
//////////////////////////////////////////////////////////////////////////////
@@ -1738,14 +1725,26 @@
/datum/supply_pack/costumes_toys/randomised/contraband
name = "Contraband Crate"
desc = "Psst.. bud... want some contraband? I can get you a poster, some nice cigs, bling, even some ambrosia deus...you know, the good stuff. Just keep it away from the cops, kay?"
desc = "Psst.. bud... want some contraband? I can get you a poster, some nice cigs, dank, even some sponsored items...you know, the good stuff. Just keep it away from the cops, kay?"
contraband = TRUE
cost = 3000
num_contained = 5
num_contained = 7
contains = list(/obj/item/poster/random_contraband,
/obj/item/poster/random_contraband,
/obj/item/reagent_containers/food/snacks/grown/cannabis,
/obj/item/reagent_containers/food/snacks/grown/cannabis/rainbow,
/obj/item/reagent_containers/food/snacks/grown/cannabis/white,
/obj/item/storage/pill_bottle/zoom,
/obj/item/storage/pill_bottle/happy,
/obj/item/storage/pill_bottle/lsd,
/obj/item/storage/pill_bottle/aranesp,
/obj/item/storage/pill_bottle/stimulant,
/obj/item/toy/cards/deck/syndicate,
/obj/item/reagent_containers/food/drinks/bottle/absinthe,
/obj/item/clothing/under/syndicate/tacticool,
/obj/item/storage/fancy/cigarettes/cigpack_syndicate,
/obj/item/storage/fancy/cigarettes/cigpack_shadyjims,
/obj/item/storage/fancy/cigarettes/cigpack_midori,
/obj/item/seeds/ambrosia/deus,
/obj/item/clothing/mask/gas/syndicate,
/obj/item/clothing/neck/necklace/dope)
crate_name = "crate"
@@ -1937,10 +1936,9 @@
/datum/supply_pack/costumes_toys/wardrobes/autodrobe
name = "Autodrobe Supply Crate"
desc = "Autodrobe missing your favorite dress? Solve that issue today with these two autodrobe refills."
desc = "Autodrobe missing your favorite dress? Solve that issue today with this autodrobe refill."
cost = 1500
contains = list(/obj/item/vending_refill/autodrobe,
/obj/item/vending_refill/autodrobe)
contains = list(/obj/item/vending_refill/autodrobe)
crate_name = "autodrobe supply crate"
/datum/supply_pack/costumes_toys/wardrobes/cargo
+1
View File
@@ -6,6 +6,7 @@
GLOBAL_LIST_INIT(blacklisted_builds, list(
"1407" = "bug preventing client display overrides from working leads to clients being able to see things/mobs they shouldn't be able to see",
"1408" = "bug preventing client display overrides from working leads to clients being able to see things/mobs they shouldn't be able to see",
"1428" = "bug causing right-click menus to show too many verbs that's been fixed in version 1429",
))
+6 -5
View File
@@ -58,18 +58,19 @@
if(prefs.unlock_content)
if(prefs.toggles & MEMBER_PUBLIC)
keyname = "<font color='[prefs.ooccolor ? prefs.ooccolor : GLOB.normal_ooc_colour]'>[icon2html('icons/member_content.dmi', world, "blag")][keyname]</font>"
//The linkify span classes and linkify=TRUE below make ooc text get clickable chat href links if you pass in something resembling a url
for(var/client/C in GLOB.clients)
if(C.prefs.chat_toggles & CHAT_OOC)
if(holder)
if(!holder.fakekey || C.holder)
if(check_rights_for(src, R_ADMIN))
to_chat(C, "<span class='adminooc'>[CONFIG_GET(flag/allow_admin_ooccolor) && prefs.ooccolor ? "<font color=[prefs.ooccolor]>" :"" ]<span class='prefix'>OOC:</span> <EM>[keyname][holder.fakekey ? "/([holder.fakekey])" : ""]:</EM> <span class='message'>[msg]</span></span></font>")
to_chat(C, "<span class='adminooc'>[CONFIG_GET(flag/allow_admin_ooccolor) && prefs.ooccolor ? "<font color=[prefs.ooccolor]>" :"" ]<span class='prefix'>OOC:</span> <EM>[keyname][holder.fakekey ? "/([holder.fakekey])" : ""]:</EM> <span class='message linkify'>[msg]</span></span></font>")
else
to_chat(C, "<span class='adminobserverooc'><span class='prefix'>OOC:</span> <EM>[keyname][holder.fakekey ? "/([holder.fakekey])" : ""]:</EM> <span class='message'>[msg]</span></span>")
to_chat(C, "<span class='adminobserverooc'><span class='prefix'>OOC:</span> <EM>[keyname][holder.fakekey ? "/([holder.fakekey])" : ""]:</EM> <span class='message linkify'>[msg]</span></span>")
else
to_chat(C, "<font color='[GLOB.normal_ooc_colour]'><span class='ooc'><span class='prefix'>OOC:</span> <EM>[holder.fakekey ? holder.fakekey : key]:</EM> <span class='message'>[msg]</span></span></font>")
to_chat(C, "<font color='[GLOB.normal_ooc_colour]'><span class='ooc'><span class='prefix'>OOC:</span> <EM>[holder.fakekey ? holder.fakekey : key]:</EM> <span class='message linkify'>[msg]</span></span></font>")
else if(!(key in C.prefs.ignoring))
to_chat(C, "<font color='[GLOB.normal_ooc_colour]'><span class='ooc'><span class='prefix'>OOC:</span> <EM>[keyname]:</EM> <span class='message'>[msg]</span></span></font>")
to_chat(C, "<font color='[GLOB.normal_ooc_colour]'><span class='ooc'><span class='prefix'>OOC:</span> <EM>[keyname]:</EM> <span class='message linkify'>[msg]</span></span></font>")
/proc/toggle_ooc(toggle = null)
if(toggle != null) //if we're specifically en/disabling ooc
@@ -232,7 +233,7 @@ GLOBAL_VAR_INIT(normal_ooc_colour, OOC_COLOR)
var/motd = global.config.motd
if(motd)
to_chat(src, "<div class=\"motd\">[motd]</div>")
to_chat(src, "<div class=\"motd\">[motd]</div>", handle_whitespace=FALSE)
else
to_chat(src, "<span class='notice'>The Message of the Day has not been set.</span>")
+7 -2
View File
@@ -100,6 +100,11 @@
icon_state = "scarf"
color = "#4A4A4B" //Grey but it looks black
/obj/item/clothing/neck/scarf/pink
name = "pink scarf"
icon_state = "scarf"
color = "#F699CD" //Pink
/obj/item/clothing/neck/scarf/red
name = "red scarf"
icon_state = "scarf"
@@ -118,7 +123,7 @@
/obj/item/clothing/neck/scarf/purple
name = "purple scarf"
icon_state = "scarf"
color = "#9557C5" //purple
color = "#9557C5" //Purple
/obj/item/clothing/neck/scarf/yellow
name = "yellow scarf"
@@ -128,7 +133,7 @@
/obj/item/clothing/neck/scarf/orange
name = "orange scarf"
icon_state = "scarf"
color = "#C67A4B" //orange
color = "#C67A4B" //Orange
/obj/item/clothing/neck/scarf/cyan
name = "cyan scarf"
+24 -8
View File
@@ -12,17 +12,33 @@
announceWhen = 1
/datum/round_event/anomaly/setup(loop=0)
var/safety_loop = loop + 1
if(safety_loop > 50)
kill()
end()
/datum/round_event/anomaly/proc/findEventArea()
var/static/list/allowed_areas
if(!allowed_areas)
//Places that shouldn't explode
var/list/safe_area_types = typecacheof(list(
/area/ai_monitored/turret_protected/ai,
/area/ai_monitored/turret_protected/ai_upload,
/area/engine,
/area/solar,
/area/holodeck,
/area/shuttle)
)
//Subtypes from the above that actually should explode.
var/list/unsafe_area_subtypes = typecacheof(list(/area/engine/break_room))
allowed_areas = make_associative(GLOB.the_station_areas) - safe_area_types + unsafe_area_subtypes
return safepick(typecache_filter_list(GLOB.sortedAreas,allowed_areas))
/datum/round_event/anomaly/setup()
impact_area = findEventArea()
if(!impact_area)
setup(safety_loop)
CRASH("No valid areas for anomaly found.")
var/list/turf_test = get_area_turfs(impact_area)
if(!turf_test.len)
setup(safety_loop)
CRASH("Anomaly : No valid turfs found for [impact_area] - [impact_area.type]")
/datum/round_event/anomaly/announce(fake)
priority_announce("Localized energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert")
@@ -30,4 +46,4 @@
/datum/round_event/anomaly/start()
var/turf/T = safepick(get_area_turfs(impact_area))
if(T)
newAnomaly = new /obj/effect/anomaly/flux(T)
newAnomaly = new /obj/effect/anomaly/flux(T)
@@ -59,7 +59,7 @@
if(!proximity)
return
if(target.is_refillable()) //Something like a glass. Player probably wants to transfer TO it.
if(target.is_refillable() && is_drainable()) //Something like a glass. Player probably wants to transfer TO it.
if(!reagents.total_volume)
to_chat(user, "<span class='warning'>[src] is empty.</span>")
return
+6 -4
View File
@@ -97,7 +97,8 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
for(var/message in messageQueue)
to_chat(owner, message)
// whitespace has already been handled by the original to_chat
to_chat(owner, message, handle_whitespace=FALSE)
messageQueue = null
sendClientData()
@@ -175,7 +176,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
//Global chat procs
/proc/to_chat(target, message)
/proc/to_chat(target, message, handle_whitespace=TRUE)
if(!target)
return
@@ -201,8 +202,9 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
//Some macros remain in the string even after parsing and fuck up the eventual output
message = replacetext(message, "\improper", "")
message = replacetext(message, "\proper", "")
message = replacetext(message, "\n", "<br>")
message = replacetext(message, "\t", "[GLOB.TAB][GLOB.TAB]")
if(handle_whitespace)
message = replacetext(message, "\n", "<br>")
message = replacetext(message, "\t", "[GLOB.TAB][GLOB.TAB]")
for(var/I in targets)
//Grab us a client if possible
@@ -95,8 +95,53 @@ if (typeof String.prototype.trim !== 'function') {
};
}
// Linkify the contents of a node, within its parent.
function linkify(parent, insertBefore, text) {
var start = 0;
var match;
var regex = /(?:(?:https?:\/\/)|(?:www\.))(?:[^ ]*?\.[^ ]*?)+[-A-Za-z0-9+&@#\/%?=~_|$!:,.;()]+/ig;
while ((match = regex.exec(text)) !== null) {
// add the unmatched text
parent.insertBefore(document.createTextNode(text.substring(start, match.index)), insertBefore);
var href = match[0];
if (!/^https?:\/\//i.test(match[0])) {
href = "http://" + match[0];
}
// add the link
var link = document.createElement("a");
link.href = href;
link.textContent = match[0];
parent.insertBefore(link, insertBefore);
start = regex.lastIndex;
}
if (start !== 0) {
// add the remaining text and remove the original text node
parent.insertBefore(document.createTextNode(text.substring(start)), insertBefore);
parent.removeChild(insertBefore);
}
}
// Recursively linkify the children of a given node.
function linkify_node(node) {
var children = node.childNodes;
// work backwards to avoid the risk of looping forever on our own output
for (var i = children.length - 1; i >= 0; --i) {
var child = children[i];
if (child.nodeType == Node.TEXT_NODE) {
// text is to be linkified
linkify(node, child, child.textContent);
} else if (child.nodeName != "A" && child.nodeName != "a") {
// do not linkify existing links
linkify_node(child);
}
}
}
//Shit fucking piece of crap that doesn't work god fuckin damn it
function linkify(text) {
function linkify_fallback(text) {
var rex = /((?:<a|<iframe|<img)(?:.*?(?:src="|href=").*?))?(?:(?:https?:\/\/)|(?:www\.))+(?:[^ ]*?\.[^ ]*?)+[-A-Za-z0-9+&@#\/%?=~_|$!:,.;]+/ig;
return text.replace(rex, function ($0, $1) {
if(/^https?:\/\/.+/i.test($0)) {
@@ -283,11 +328,6 @@ function output(message, flag) {
}
}
//Url stuff
if (message.length && flag != 'preventLink') {
message = linkify(message);
}
opts.messageCount++;
//Pop the top message off if history limit reached
@@ -340,6 +380,20 @@ function output(message, flag) {
$last_message = trimmed_message;
$messages[0].appendChild(entry);
$(entry).find("img.icon").error(iconError);
var to_linkify = $(entry).find(".linkify");
if (typeof Node === 'undefined') {
// Linkify fallback for old IE
for(var i = 0; i < to_linkify.length; ++i) {
to_linkify[i].innerHTML = linkify_fallback(to_linkify[i].innerHTML);
}
} else {
// Linkify for modern IE versions
for(var i = 0; i < to_linkify.length; ++i) {
linkify_node(to_linkify[i]);
}
}
//Actually do the snap
//Stuff we can do after the message shows can go here, in the interests of responsiveness
if (opts.highlightTerms && opts.highlightTerms.length > 0) {
@@ -892,23 +946,26 @@ $(function() {
});
$('#saveLog').click(function(e) {
// Requires IE 10+ to issue download commands. Just opening a popup
// window will cause Ctrl+S to save a blank page, ignoring innerHTML.
if (!window.Blob) {
output('<span class="big red">This function is only supported on IE 10+. Upgrade if possible.</span>', 'internal');
return;
}
$.ajax({
type: 'GET',
url: 'browserOutput.css',
success: function(styleData) {
var win;
var blob = new Blob(['<head><title>Chat Log</title><style>', styleData, '</style></head><body>', $messages.html(), '</body>']);
try {
win = window.open('', 'Chat Log', 'toolbar=no, location=no, directories=no, status=no, menubar=yes, scrollbars=yes, resizable=yes, width=780, height=600, top=' + (screen.height/2 - 635/2) + ', left=' + (screen.width/2 - 780/2));
} catch (e) {
return;
}
var fname = 'SS13 Chat Log';
var date = new Date(), month = date.getMonth(), day = date.getDay(), hours = date.getHours(), mins = date.getMinutes(), secs = date.getSeconds();
fname += ' ' + date.getFullYear() + '-' + (month < 10 ? '0' : '') + month + '-' + (day < 10 ? '0' : '') + day;
fname += ' ' + (hours < 10 ? '0' : '') + hours + (mins < 10 ? '0' : '') + mins + (secs < 10 ? '0' : '') + secs;
fname += '.html';
if (win) {
win.document.head.innerHTML = '<title>Chat Log</title>';
win.document.head.innerHTML += '<style>' + styleData + '</style>';
win.document.body.innerHTML = $messages.html();
}
window.navigator.msSaveBlob(blob, fname);
}
});
});
+3 -1
View File
@@ -427,7 +427,7 @@
/obj/item/disk/plantgene/proc/update_name()
if(gene)
name = "[gene.get_name()] (Plant Data Disk)"
name = "[gene.get_name()] (plant data disk)"
else
name = "plant data disk"
@@ -437,4 +437,6 @@
/obj/item/disk/plantgene/examine(mob/user)
..()
if(gene && (istype(gene, /datum/plant_gene/core/potency)))
to_chat(user,"<span class='notice'>Percent is relative to potency, not maximum volume of the plant.</span>")
to_chat(user, "The write-protect tab is set to [src.read_only ? "protected" : "unprotected"].")
@@ -1,5 +1,5 @@
/obj/item/integrated_circuit/input/card_reader
name = "card reader"
name = "ID card reader" //To differentiate it from the data card reader
desc = "A circuit that can read the registred name, assignment, and PassKey string from an ID card."
icon_state = "card_reader"
@@ -14,6 +14,10 @@
"on read" = IC_PINTYPE_PULSE_OUT
)
/obj/item/integrated_circuit/input/card_reader/old
name = "card reader"
spawn_flags = 0
/obj/item/integrated_circuit/input/card_reader/attackby_react(obj/item/I, mob/living/user, intent)
var/obj/item/card/id/card = I.GetID()
var/list/access = I.GetAccess()
@@ -1104,3 +1104,104 @@
else
activate_pin(3)
/obj/item/integrated_circuit/input/atmospheric_analyzer
name = "atmospheric analyzer"
desc = "A miniaturized analyzer which can scan anything that contains gases. Leave target as NULL to scan the air around the assembly."
extended_desc = "The nth element of gas amounts is the number of moles of the \
nth gas in gas list. \
Pressure is in kPa, temperature is in Kelvin. \
Due to programming limitations, scanning an object that does \
not contain a gas will return the air around it instead."
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
inputs = list(
"target" = IC_PINTYPE_REF
)
outputs = list(
"gas list" = IC_PINTYPE_LIST,
"gas amounts" = IC_PINTYPE_LIST,
"total moles" = IC_PINTYPE_NUMBER,
"pressure" = IC_PINTYPE_NUMBER,
"temperature" = IC_PINTYPE_NUMBER,
"volume" = IC_PINTYPE_NUMBER
)
activators = list(
"scan" = IC_PINTYPE_PULSE_IN,
"on success" = IC_PINTYPE_PULSE_OUT,
"on failure" = IC_PINTYPE_PULSE_OUT
)
power_draw_per_use = 5
/obj/item/integrated_circuit/input/atmospheric_analyzer/do_work()
for(var/i=1 to 6)
set_pin_data(IC_OUTPUT, i, null)
var/atom/target = get_pin_data_as_type(IC_INPUT, 1, /atom)
var/atom/movable/acting_object = get_object()
if(!target)
target = acting_object.loc
if(!target.Adjacent(acting_object))
activate_pin(3)
return
var/datum/gas_mixture/air_contents = target.return_air()
if(!air_contents)
activate_pin(3)
return
var/list/gases = air_contents.gases
var/list/gas_names = list()
var/list/gas_amounts = list()
for(var/id in gases)
var/name = gases[id][GAS_META][META_GAS_NAME]
var/amt = round(gases[id][MOLES], 0.001)
gas_names.Add(name)
gas_amounts.Add(amt)
set_pin_data(IC_OUTPUT, 1, gas_names)
set_pin_data(IC_OUTPUT, 2, gas_amounts)
set_pin_data(IC_OUTPUT, 3, round(air_contents.total_moles(), 0.001))
set_pin_data(IC_OUTPUT, 4, round(air_contents.return_pressure(), 0.001))
set_pin_data(IC_OUTPUT, 5, round(air_contents.temperature, 0.001))
set_pin_data(IC_OUTPUT, 6, round(air_contents.return_volume(), 0.001))
push_data()
activate_pin(2)
/obj/item/integrated_circuit/input/data_card_reader
name = "data card reader"
desc = "A circuit that can read from and write to data cards."
extended_desc = "Setting the \"write mode\" boolean to true will cause any data cards that are used on the assembly to replace\
their existing function and data strings with the given strings, if it is set to false then using a data card on the assembly will cause\
the function and data strings stored on the card to be written to the output pins."
icon_state = "card_reader"
complexity = 4
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
inputs = list(
"function" = IC_PINTYPE_STRING,
"data to store" = IC_PINTYPE_STRING,
"write mode" = IC_PINTYPE_BOOLEAN
)
outputs = list(
"function" = IC_PINTYPE_STRING,
"stored data" = IC_PINTYPE_STRING
)
activators = list(
"on write" = IC_PINTYPE_PULSE_OUT,
"on read" = IC_PINTYPE_PULSE_OUT
)
/obj/item/integrated_circuit/input/data_card_reader/attackby_react(obj/item/I, mob/living/user, intent)
var/obj/item/card/data/card = I.GetCard()
var/write_mode = get_pin_data(IC_INPUT, 3)
if(card)
if(write_mode == TRUE)
card.function = get_pin_data(IC_INPUT, 1)
card.data = get_pin_data(IC_INPUT, 2)
push_data()
activate_pin(1)
else
set_pin_data(IC_OUTPUT, 1, card.function)
set_pin_data(IC_OUTPUT, 2, card.data)
push_data()
activate_pin(2)
else
return FALSE
return TRUE
@@ -367,7 +367,7 @@
var/atom/movable/acting_object = get_object()
var/turf/T = get_turf(acting_object)
var/obj/item/AM = get_pin_data_as_type(IC_INPUT, 1, /obj/item)
if(AM)
if(!QDELETED(AM) && !istype(AM, /obj/item/electronic_assembly))
var/mode = get_pin_data(IC_INPUT, 2)
if(mode == 1)
if(check_target(AM))
+1 -2
View File
@@ -85,5 +85,4 @@ Cyborg
return H.Robotize(FALSE, latejoin)
/datum/job/cyborg/after_spawn(mob/living/silicon/robot/R, mob/M)
if(CONFIG_GET(flag/rename_cyborg)) //name can't be set in robot/New without the client
R.rename_self("cyborg", M.client)
R.rename_self("cyborg", M.client)
+4 -5
View File
@@ -56,10 +56,10 @@
if (top_atom)
LAZYREMOVE(top_atom.light_sources, src)
if (needs_update)
GLOB.lighting_update_lights -= src
. = ..()
// Yes this doesn't align correctly on anything other than 4 width tabs.
@@ -116,7 +116,6 @@
. = LUM_FALLOFF(C, pixel_turf); \
. *= light_power; \
var/OLD = effect_str[C]; \
\
effect_str[C] = .; \
\
C.update_lumcount \
@@ -126,7 +125,6 @@
(. * lum_b) - (OLD * applied_lum_b) \
);
#define REMOVE_CORNER(C) \
. = -effect_str[C]; \
C.update_lumcount \
@@ -167,8 +165,9 @@
/datum/light_source/proc/update_corners()
var/update = FALSE
var/atom/source_atom = src.source_atom
if (!source_atom || QDELETED(source_atom))
if (QDELETED(source_atom))
qdel(src)
return
@@ -17,6 +17,7 @@
z_list += S
/datum/controller/subsystem/mapping/proc/add_new_zlevel(name, traits = list(), z_type = /datum/space_level)
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_NEW_Z, args)
var/new_z = z_list.len + 1
if (world.maxz < new_z)
world.incrementMaxZ()
+17 -14
View File
@@ -1,3 +1,5 @@
GLOBAL_LIST(labor_sheet_values)
/**********************Prisoners' Console**************************/
/obj/machinery/mineral/labor_claim_console
@@ -20,6 +22,18 @@
Radio.listening = FALSE
locate_stacking_machine()
if(!GLOB.labor_sheet_values)
var/sheet_list = list()
for(var/sheet_type in subtypesof(/obj/item/stack/sheet))
var/obj/item/stack/sheet/sheet = sheet_type
if(!initial(sheet.point_value) || (initial(sheet.merge_type) && initial(sheet.merge_type) != sheet_type)) //ignore no-value sheets and x/fifty subtypes
continue
sheet_list += list(list("ore" = initial(sheet.name), "value" = initial(sheet.point_value)))
GLOB.labor_sheet_values = sortList(sheet_list, /proc/cmp_sheet_list)
/proc/cmp_sheet_list(list/a, list/b)
return a["value"] - b["value"]
/obj/machinery/mineral/labor_claim_console/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/card/id/prisoner))
if(!inserted_id)
@@ -52,16 +66,10 @@
if(check_auth())
can_go_home = TRUE
var/list/ores = list()
if(stacking_machine)
data["unclaimed_points"] = stacking_machine.points
for(var/ore in stacking_machine.ore_values)
var/list/O = list()
O["ore"] = ore
O["value"] = stacking_machine.ore_values[ore]
ores += list(O)
data["ores"] = ores
data["ores"] = GLOB.labor_sheet_values
data["can_go_home"] = can_go_home
return data
@@ -127,15 +135,10 @@
/obj/machinery/mineral/stacking_machine/laborstacker
var/points = 0 //The unclaimed value of ore stacked. Value for each ore loosely relative to its rarity.
var/list/ore_values = list("glass" = 1, "metal" = 2, "reinforced glass" = 4, "gold" = 20, "silver" = 20, "uranium" = 20, "titanium" = 20, "solid plasma" = 20, "plasteel" = 23, "plasma glass" = 23, "diamond" = 25, "bluespace polycrystal" = 30, "plastitanium" = 45, "bananium" = 50)
var/points = 0 //The unclaimed value of ore stacked.
/obj/machinery/mineral/stacking_machine/laborstacker/process_sheet(obj/item/stack/sheet/inp)
if(istype(inp))
var/n = inp.name
var/a = inp.amount
if(n in ore_values)
points += ore_values[n] * a
points += inp.point_value * inp.amount
..()
+1 -1
View File
@@ -105,8 +105,8 @@
stack_list[inp.type] = s
var/obj/item/stack/sheet/storage = stack_list[inp.type]
storage.amount += inp.amount //Stack the sheets
qdel(inp) //Let the old sheet garbage collect
while(storage.amount > stack_amt) //Get rid of excessive stackage
var/obj/item/stack/sheet/out = new inp.type(null, stack_amt)
unload_mineral(out)
storage.amount -= stack_amt
qdel(inp) //Let the old sheet garbage collect
-4
View File
@@ -171,8 +171,6 @@
if("Survival Capsule and Explorer's Webbing")
new /obj/item/storage/belt/mining/vendor(drop_location)
if("Resonator Kit")
new /obj/item/storage/belt/mining/alt(drop_location)
new /obj/item/t_scanner/adv_mining_scanner(drop_location)
new /obj/item/extinguisher/mini(drop_location)
new /obj/item/resonator(drop_location)
if("Minebot Kit")
@@ -185,8 +183,6 @@
new /obj/item/fulton_core(drop_location)
new /obj/item/stack/marker_beacon/thirty(drop_location)
if("Crusher Kit")
new /obj/item/storage/belt/mining/alt(drop_location)
new /obj/item/t_scanner/adv_mining_scanner(drop_location)
new /obj/item/extinguisher/mini(drop_location)
new /obj/item/twohanded/required/kinetic_crusher(drop_location)
if("Mining Conscription Kit")
+1 -1
View File
@@ -11,7 +11,7 @@
var/motd = global.config.motd
if(motd)
to_chat(src, "<div class=\"motd\">[motd]</div>")
to_chat(src, "<div class=\"motd\">[motd]</div>", handle_whitespace=FALSE)
if(GLOB.admin_notice)
to_chat(src, "<span class='notice'><b>Admin Notice:</b>\n \t [GLOB.admin_notice]</span>")
@@ -137,3 +137,6 @@
update_inv_wear_mask()
update_inv_head()
/mob/living/carbon/proc/get_holding_bodypart_of_item(obj/item/I)
var/index = get_held_index_of_item(I)
return index && hand_bodyparts[index]
+1 -1
View File
@@ -54,7 +54,7 @@
var/turf/T = get_turf(src)
for(var/obj/item/I in contents)
I.on_mob_death(src, gibbed)
if(mind && mind.name && mind.active && (!(T.flags_1 & NO_DEATHRATTLE_1)))
if(mind && mind.name && mind.active && !istype(T.loc, /area/ctf))
var/rendered = "<span class='deadsay'><b>[mind.name]</b> has died at <b>[get_area_name(T)]</b>.</span>"
deadchat_broadcast(rendered, follow_target = src, turf_target = T, message_type=DEADCHAT_DEATHRATTLE)
if(mind)
@@ -18,12 +18,21 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
// The object used for the clickable stat() button.
var/obj/effect/statclick/statclick
// The object used in vis_contents of obscured turfs
var/vis_contents
// The image given to the effect in vis_contents on AI clients
var/image/obscured
/datum/cameranet/New()
vis_contents = new /obj/effect/overlay/camera_static()
obscured = new('icons/effects/cameravis.dmi', vis_contents, null, BYOND_LIGHTING_LAYER + 0.1)
obscured.plane = BYOND_LIGHTING_PLANE + 1
// Checks if a chunk has been Generated in x, y, z.
/datum/cameranet/proc/chunkGenerated(x, y, z)
x &= ~(CHUNK_SIZE - 1)
y &= ~(CHUNK_SIZE - 1)
var/key = "[x],[y],[z]"
return (chunks[key])
return chunks["[x],[y],[z]"]
// Returns the chunk in the x, y, z.
// If there is no chunk, it creates a new chunk and returns that.
@@ -31,10 +40,9 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
x &= ~(CHUNK_SIZE - 1)
y &= ~(CHUNK_SIZE - 1)
var/key = "[x],[y],[z]"
if(!chunks[key])
chunks[key] = new /datum/camerachunk(null, x, y, z)
return chunks[key]
. = chunks[key]
if(!.)
chunks[key] = . = new /datum/camerachunk(x, y, z)
// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set.
@@ -46,14 +54,8 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
else
other_eyes = list()
var/list/chunks_pre_seen = list()
var/list/chunks_post_seen = list()
for(var/V in moved_eyes)
var/mob/camera/aiEye/eye = V
if(C)
chunks_pre_seen |= eye.visibleCameraChunks
// 0xf = 15
var/static_range = eye.static_visibility_range
var/x1 = max(0, eye.x - static_range) & ~(CHUNK_SIZE - 1)
var/y1 = max(0, eye.y - static_range) & ~(CHUNK_SIZE - 1)
@@ -71,44 +73,26 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
for(var/chunk in remove)
var/datum/camerachunk/c = chunk
c.remove(eye, FALSE)
c.remove(eye)
for(var/chunk in add)
var/datum/camerachunk/c = chunk
c.add(eye, FALSE)
if(C)
chunks_post_seen |= eye.visibleCameraChunks
c.add(eye)
if(C)
for(var/V in other_eyes)
var/mob/camera/aiEye/eye = V
chunks_post_seen |= eye.visibleCameraChunks
var/list/remove = chunks_pre_seen - chunks_post_seen
var/list/add = chunks_post_seen - chunks_pre_seen
for(var/chunk in remove)
var/datum/camerachunk/c = chunk
C.images -= c.obscured
for(var/chunk in add)
var/datum/camerachunk/c = chunk
C.images += c.obscured
C.images += obscured
// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open.
/datum/cameranet/proc/updateVisibility(atom/A, opacity_check = 1)
if(!SSticker || (opacity_check && !A.opacity))
return
majorChunkChange(A, 2)
/datum/cameranet/proc/updateChunk(x, y, z)
// 0xf = 15
if(!chunkGenerated(x, y, z))
var/datum/camerachunk/chunk = chunkGenerated(x, y, z)
if (!chunk)
return
var/datum/camerachunk/chunk = getCameraChunk(x, y, z)
chunk.hasChanged()
// Removes a camera from a chunk.
@@ -135,7 +119,6 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
// If you want to update the chunks around an object, without adding/removing a camera, use choice 2.
/datum/cameranet/proc/majorChunkChange(atom/c, choice)
// 0xf = 15
if(!c)
return
@@ -147,8 +130,8 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1)
for(var/x = x1; x <= x2; x += CHUNK_SIZE)
for(var/y = y1; y <= y2; y += CHUNK_SIZE)
if(chunkGenerated(x, y, T.z))
var/datum/camerachunk/chunk = getCameraChunk(x, y, T.z)
var/datum/camerachunk/chunk = chunkGenerated(x, y, T.z)
if(chunk)
if(choice == 0)
// Remove the camera.
chunk.cameras -= c
@@ -160,14 +143,12 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0.
/datum/cameranet/proc/checkCameraVis(mob/living/target)
// 0xf = 15
var/turf/position = get_turf(target)
return checkTurfVis(position)
/datum/cameranet/proc/checkTurfVis(turf/position)
var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z)
var/datum/camerachunk/chunk = chunkGenerated(position.x, position.y, position.z)
if(chunk)
if(chunk.changed)
chunk.hasChanged(1) // Update now, no matter if it's visible or not.
@@ -180,3 +161,17 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
stat(name, statclick.update("Cameras: [GLOB.cameranet.cameras.len] | Chunks: [GLOB.cameranet.chunks.len]"))
/obj/effect/overlay/camera_static
name = "static"
icon = null
icon_state = null
anchored = TRUE // should only appear in vis_contents, but to be safe
appearance_flags = RESET_TRANSFORM | TILE_BOUND
// this combination makes the static block clicks to everything below it,
// without appearing in the right-click menu for non-AI clients
mouse_opacity = MOUSE_OPACITY_ICON
invisibility = INVISIBILITY_ABSTRACT
layer = BYOND_LIGHTING_LAYER + 0.1
plane = BYOND_LIGHTING_PLANE + 1
@@ -8,11 +8,9 @@
/datum/camerachunk
var/list/obscuredTurfs = list()
var/list/visibleTurfs = list()
var/list/obscured = list()
var/list/cameras = list()
var/list/turfs = list()
var/list/seenby = list()
var/visible = FALSE
var/changed = 0
var/x = 0
var/y = 0
@@ -20,28 +18,17 @@
// Add an AI eye to the chunk, then update if changed.
/datum/camerachunk/proc/add(mob/camera/aiEye/eye, add_images = TRUE)
if(add_images)
var/client/client = eye.GetViewerClient()
if(client)
client.images += obscured
/datum/camerachunk/proc/add(mob/camera/aiEye/eye)
eye.visibleCameraChunks += src
visible++
seenby += eye
if(changed)
update()
// Remove an AI eye from the chunk, then update if changed.
/datum/camerachunk/proc/remove(mob/camera/aiEye/eye, remove_images = TRUE)
if(remove_images)
var/client/client = eye.GetViewerClient()
if(client)
client.images -= obscured
/datum/camerachunk/proc/remove(mob/camera/aiEye/eye)
eye.visibleCameraChunks -= src
seenby -= eye
if(visible > 0)
visible--
// Called when a chunk has changed. I.E: A wall was deleted.
@@ -54,7 +41,7 @@
// instead be flagged to update the next time an AI Eye moves near it.
/datum/camerachunk/proc/hasChanged(update_now = 0)
if(visible || update_now)
if(seenby.len || update_now)
addtimer(CALLBACK(src, .proc/update), UPDATE_BUFFER, TIMER_UNIQUE)
else
changed = 1
@@ -94,41 +81,18 @@
for(var/turf in visAdded)
var/turf/t = turf
if(t.obscured)
obscured -= t.obscured
for(var/eye in seenby)
var/mob/camera/aiEye/m = eye
if(!m)
continue
var/client/client = m.GetViewerClient()
if(client)
client.images -= t.obscured
t.vis_contents -= GLOB.cameranet.vis_contents
for(var/turf in visRemoved)
var/turf/t = turf
if(obscuredTurfs[t])
if(!t.obscured)
t.obscured = image('icons/effects/cameravis.dmi', t, null, BYOND_LIGHTING_LAYER+0.1)
t.obscured.pixel_x = -t.pixel_x
t.obscured.pixel_y = -t.pixel_y
t.obscured.plane = BYOND_LIGHTING_PLANE+0.1
obscured += t.obscured
for(var/eye in seenby)
var/mob/camera/aiEye/m = eye
if(!m)
seenby -= m
continue
var/client/client = m.GetViewerClient()
if(client)
client.images += t.obscured
if(obscuredTurfs[t] && !istype(t, /turf/open/ai_visible))
t.vis_contents += GLOB.cameranet.vis_contents
changed = 0
// Create a new camera chunk, since the chunks are made as they are needed.
/datum/camerachunk/New(loc, x, y, z)
// 0xf = 15
/datum/camerachunk/New(x, y, z)
x &= ~(CHUNK_SIZE - 1)
y &= ~(CHUNK_SIZE - 1)
@@ -164,12 +128,7 @@
for(var/turf in obscuredTurfs)
var/turf/t = turf
if(!t.obscured)
t.obscured = image('icons/effects/cameravis.dmi', t, null, BYOND_LIGHTING_LAYER+0.1)
t.obscured.pixel_x = -t.pixel_x
t.obscured.pixel_y = -t.pixel_y
t.obscured.plane = BYOND_LIGHTING_PLANE+0.1
obscured += t.obscured
t.vis_contents += GLOB.cameranet.vis_contents
#undef UPDATE_BUFFER
#undef CHUNK_SIZE
@@ -50,9 +50,7 @@
/mob/camera/aiEye/proc/RemoveImages()
var/client/C = GetViewerClient()
if(C && use_static)
for(var/V in visibleCameraChunks)
var/datum/camerachunk/c = V
C.images -= c.obscured
C.images -= GLOB.cameranet.obscured
/mob/camera/aiEye/Destroy()
if(ai)
@@ -88,10 +88,6 @@
icon_state = "room_background"
flags_1 = NOJAUNT_1
/turf/open/ai_visible/Initialize()
. = ..()
obscured = image(null, src, null)
/area/ai_multicam_room
name = "ai_multicam_room"
icon_state = "ai_camera_room"
@@ -162,8 +162,8 @@
//If there's an MMI in the robot, have it ejected when the mob goes away. --NEO
/mob/living/silicon/robot/Destroy()
var/atom/T = drop_location()//To hopefully prevent run time errors.
if(mmi && mind)//Safety for when a cyborg gets dust()ed. Or there is no MMI inside.
var/turf/T = get_turf(loc)//To hopefully prevent run time errors.
if(T)
mmi.forceMove(T)
if(mmi.brainmob)
@@ -182,6 +182,10 @@
connected_ai.connected_robots -= src
if(shell)
GLOB.available_ai_shells -= src
else
if(T && istype(radio) && istype(radio.keyslot))
radio.keyslot.forceMove(T)
radio.keyslot = null
qdel(wires)
qdel(module)
qdel(eye_lights)
@@ -228,7 +232,8 @@
if(custom_name)
changed_name = custom_name
if(changed_name == "" && client)
changed_name = client.prefs.custom_names["cyborg"]
rename_self(src, client)
return //built in camera handled in proc
if(!changed_name)
changed_name = get_standard_name()
@@ -1,3 +1,5 @@
#define MEDAL_PREFIX "Bubblegum"
/*
BUBBLEGUM
@@ -7,15 +9,15 @@ Bubblegum's footsteps are heralded by shaking booms, proving its tremendous size
It acts as a melee creature, chasing down and attacking its target while also using different attacks to augment its power that increase as it takes damage.
It tries to strike at its target through any bloodpools under them; if it fails to do that, it will spray blood and then attempt to warp to a bloodpool near the target.
If it fails to warp to a target, it may summon up to 6 slaughterlings from the blood around it.
If it does not summon all 6 slaughterlings, it will instead charge at its target, dealing massive damage to anything it hits and spraying a stream of blood.
At half health, it will either charge three times or warp, then charge, instead of doing a single charge.
It often charges, dealing massive damage to anything unfortunate enough to be standing where it's aiming.
Whenever it isn't chasing something down, it will sink into nearby blood pools (if possible) and springs out of the closest one to its target.
To make this possible, it sprays streams of blood at random.
From these blood pools Bubblegum may summon slaughterlings - weak, low-damage minions designed to impede the target's progress.
When Bubblegum dies, it leaves behind a H.E.C.K. mining suit as well as a chest that can contain three things:
1. A bottle that, when activated, drives everyone nearby into a frenzy
2. A contract that marks for death the chosen target
3. A spellblade that can slice off limbs at range
When Bubblegum dies, it leaves behind a H.E.C.K. suit+helmet as well as a chest that can contain three things:
1. A spellblade that can slice off limbs at range
2. A bottle that, when activated, drives everyone nearby into a frenzy
3. A contract that marks for death the chosen target
Difficulty: Hard
@@ -44,8 +46,7 @@ Difficulty: Hard
del_on_death = 1
crusher_loot = list(/obj/structure/closet/crate/necropolis/bubblegum/crusher)
loot = list(/obj/structure/closet/crate/necropolis/bubblegum)
blood_volume = BLOOD_VOLUME_MAXIMUM //BLEED FOR ME
var/charging = FALSE
var/charging = 0
medal_type = BOSS_MEDAL_BUBBLEGUM
score_type = BUBBLEGUM_SCORE
deathmessage = "sinks into a pool of blood, fleeing the battle. You've won, for now... "
@@ -57,54 +58,33 @@ Difficulty: Hard
desc = "You're not quite sure how a signal can be bloody."
invisibility = 100
/mob/living/simple_animal/hostile/megafauna/bubblegum/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE)
. = ..()
if(. > 0 && prob(25))
var/obj/effect/decal/cleanable/blood/gibs/bubblegum/B = new /obj/effect/decal/cleanable/blood/gibs/bubblegum(loc)
if(prob(40))
step(B, pick(GLOB.cardinals))
else
B.setDir(pick(GLOB.cardinals))
/obj/effect/decal/cleanable/blood/gibs/bubblegum
name = "thick blood"
desc = "Thick, splattered blood."
random_icon_states = list("gib3", "gib5", "gib6")
bloodiness = 20
/obj/effect/decal/cleanable/blood/gibs/bubblegum/can_bloodcrawl_in()
return TRUE
/mob/living/simple_animal/hostile/megafauna/bubblegum/Life()
..()
move_to_delay = CLAMP((health/maxHealth) * 10, 5, 10)
move_to_delay = CLAMP(round((health/maxHealth) * 10), 5, 10)
/mob/living/simple_animal/hostile/megafauna/bubblegum/OpenFire()
anger_modifier = CLAMP(((maxHealth - health)/60),0,20)
anger_modifier = CLAMP(((maxHealth - health)/50),0,20)
if(charging)
return
ranged_cooldown = world.time + ranged_cooldown_time
var/warped = FALSE
if(!try_bloodattack())
INVOKE_ASYNC(src, .proc/blood_spray)
warped = blood_warp()
if(warped && prob(100 - anger_modifier))
return
blood_warp()
if(prob(90 - anger_modifier) || slaughterlings())
if(health > maxHealth * 0.5)
if(prob(25))
INVOKE_ASYNC(src, .proc/blood_spray)
else if(prob(5+anger_modifier/2))
slaughterlings()
else
if(health > maxHealth/2 && !client)
INVOKE_ASYNC(src, .proc/charge)
else
if(prob(70) || warped)
INVOKE_ASYNC(src, .proc/charge, 2)
else
INVOKE_ASYNC(src, .proc/warp_charge)
INVOKE_ASYNC(src, .proc/triple_charge)
/mob/living/simple_animal/hostile/megafauna/bubblegum/Initialize()
. = ..()
for(var/mob/living/simple_animal/hostile/megafauna/bubblegum/B in GLOB.mob_living_list)
for(var/mob/living/simple_animal/hostile/megafauna/bubblegum/B in GLOB.mob_list)
if(B != src)
return INITIALIZE_HINT_QDEL //There can be only one
var/obj/effect/proc_holder/spell/bloodcrawl/bloodspell = new
@@ -118,56 +98,53 @@ Difficulty: Hard
if(.)
SSshuttle.shuttle_purchase_requirements_met |= "bubblegum"
/mob/living/simple_animal/hostile/megafauna/bubblegum/do_attack_animation(atom/A, visual_effect_icon)
if(!charging)
..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/do_attack_animation(atom/A)
if(charging)
return
..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/AttackingTarget()
if(!charging)
return ..()
if(charging)
return
..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/Goto(target, delay, minimum_distance)
if(!charging)
..()
if(charging)
return
..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/Move()
if(!stat)
playsound(src.loc, 'sound/effects/meteorimpact.ogg', 200, 1, 2, 1)
if(charging)
new /obj/effect/temp_visual/decoy/fading(loc,src)
new/obj/effect/temp_visual/decoy/fading(loc,src)
DestroySurroundings()
. = ..()
if(!stat && .)
playsound(src, 'sound/effects/meteorimpact.ogg', 200, 1, 2, 1)
if(charging)
DestroySurroundings()
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/warp_charge()
blood_warp()
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/triple_charge()
charge()
sleep(10)
charge()
sleep(10)
charge()
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/charge(bonus_charges)
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/charge()
var/turf/T = get_turf(target)
if(!T || T == loc)
return
new /obj/effect/temp_visual/dragon_swoop/bubblegum(T)
charging = TRUE
new /obj/effect/temp_visual/dragon_swoop(T)
charging = 1
DestroySurroundings()
walk(src, 0)
setDir(get_dir(src, T))
var/obj/effect/temp_visual/decoy/D = new /obj/effect/temp_visual/decoy(loc,src)
animate(D, alpha = 0, color = "#FF0000", transform = matrix()*2, time = 3)
sleep(3)
throw_at(T, get_dist(src, T), 1, src, 0, callback = CALLBACK(src, .charge_end, bonus_charges))
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/charge_end(bonus_charges, list/effects_to_destroy)
charging = FALSE
try_bloodattack()
if(target)
if(bonus_charges)
bonus_charges--
charge(bonus_charges)
else
Goto(target, move_to_delay, minimum_distance)
SetRecoveryTime(MEGAFAUNA_DEFAULT_RECOVERY_TIME)
animate(D, alpha = 0, color = "#FF0000", transform = matrix()*2, time = 5)
sleep(5)
throw_at(T, get_dist(src, T), 1, src, 0)
charging = 0
Goto(target, move_to_delay, minimum_distance)
/mob/living/simple_animal/hostile/megafauna/bubblegum/Collide(atom/A)
@@ -191,142 +168,20 @@ Difficulty: Hard
var/throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(L, src)))
L.throw_at(throwtarget, 3)
charging = FALSE
charging = 0
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/get_mobs_on_blood()
var/list/targets = ListTargets()
. = list()
for(var/mob/living/L in targets)
var/list/bloodpool = get_pools(get_turf(L), 0)
if(bloodpool.len && (!faction_check_mob(L) || L.stat == DEAD))
. += L
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/try_bloodattack()
var/list/targets = get_mobs_on_blood()
if(targets.len)
INVOKE_ASYNC(src, .proc/bloodattack, targets, prob(50))
return TRUE
return FALSE
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodattack(list/targets, handedness)
var/mob/living/target_one = pick_n_take(targets)
var/turf/target_one_turf = get_turf(target_one)
var/mob/living/target_two
if(targets.len)
target_two = pick_n_take(targets)
var/turf/target_two_turf = get_turf(target_two)
if(target_two.stat != CONSCIOUS || prob(10))
bloodgrab(target_two_turf, handedness)
else
bloodsmack(target_two_turf, handedness)
if(target_one)
var/list/pools = get_pools(get_turf(target_one), 0)
if(pools.len)
target_one_turf = get_turf(target_one)
if(target_one_turf)
if(target_one.stat != CONSCIOUS || prob(10))
bloodgrab(target_one_turf, !handedness)
else
bloodsmack(target_one_turf, !handedness)
if(!target_two && target_one)
var/list/poolstwo = get_pools(get_turf(target_one), 0)
if(poolstwo.len)
target_one_turf = get_turf(target_one)
if(target_one_turf)
if(target_one.stat != CONSCIOUS || prob(10))
bloodgrab(target_one_turf, handedness)
else
bloodsmack(target_one_turf, handedness)
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodsmack(turf/T, handedness)
if(handedness)
new /obj/effect/temp_visual/bubblegum_hands/rightsmack(T)
else
new /obj/effect/temp_visual/bubblegum_hands/leftsmack(T)
sleep(2.5)
for(var/mob/living/L in T)
if(!faction_check_mob(L))
to_chat(L, "<span class='userdanger'>[src] rends you!</span>")
playsound(T, attack_sound, 100, 1, -1)
var/limb_to_hit = L.get_bodypart(pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG))
L.apply_damage(25, BRUTE, limb_to_hit, L.run_armor_check(limb_to_hit, "melee", null, null, armour_penetration))
sleep(3)
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodgrab(turf/T, handedness)
if(handedness)
new /obj/effect/temp_visual/bubblegum_hands/rightpaw(T)
new /obj/effect/temp_visual/bubblegum_hands/rightthumb(T)
else
new /obj/effect/temp_visual/bubblegum_hands/leftpaw(T)
new /obj/effect/temp_visual/bubblegum_hands/leftthumb(T)
sleep(6)
for(var/mob/living/L in T)
if(!faction_check_mob(L))
to_chat(L, "<span class='userdanger'>[src] drags you through the blood!</span>")
playsound(T, 'sound/magic/enter_blood.ogg', 100, 1, -1)
var/turf/targetturf = get_step(src, dir)
L.forceMove(targetturf)
playsound(targetturf, 'sound/magic/exit_blood.ogg', 100, 1, -1)
if(L.stat != CONSCIOUS)
addtimer(CALLBACK(src, .proc/devour, L), 2)
sleep(1)
/obj/effect/temp_visual/dragon_swoop/bubblegum
duration = 10
/obj/effect/temp_visual/bubblegum_hands
icon = 'icons/effects/bubblegum.dmi'
duration = 9
/obj/effect/temp_visual/bubblegum_hands/rightthumb
icon_state = "rightthumbgrab"
/obj/effect/temp_visual/bubblegum_hands/leftthumb
icon_state = "leftthumbgrab"
/obj/effect/temp_visual/bubblegum_hands/rightpaw
icon_state = "rightpawgrab"
layer = BELOW_MOB_LAYER
/obj/effect/temp_visual/bubblegum_hands/leftpaw
icon_state = "leftpawgrab"
layer = BELOW_MOB_LAYER
/obj/effect/temp_visual/bubblegum_hands/rightsmack
icon_state = "rightsmack"
/obj/effect/temp_visual/bubblegum_hands/leftsmack
icon_state = "leftsmack"
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_warp()
if(Adjacent(target))
return FALSE
var/list/can_jaunt = get_pools(get_turf(src), 1)
if(!can_jaunt.len)
return FALSE
var/list/pools = get_pools(get_turf(target), 2)
var/list/pools_to_remove = get_pools(get_turf(target), 1)
pools -= pools_to_remove
if(!pools.len)
return FALSE
var/obj/effect/temp_visual/decoy/DA = new /obj/effect/temp_visual/decoy(loc,src)
DA.color = "#FF0000"
var/oldtransform = DA.transform
DA.transform = matrix()*2
animate(DA, alpha = 255, color = initial(DA.color), transform = oldtransform, time = 3)
sleep(3)
qdel(DA)
var/obj/effect/decal/cleanable/blood/found_bloodpool
pools = get_pools(get_turf(target), 2)
pools_to_remove = get_pools(get_turf(target), 1)
pools -= pools_to_remove
var/list/pools = list()
var/can_jaunt = FALSE
for(var/obj/effect/decal/cleanable/blood/nearby in view(src,2))
can_jaunt = TRUE
break
if(!can_jaunt)
return
for(var/obj/effect/decal/cleanable/blood/nearby in view(get_turf(target),2))
pools += nearby
if(pools.len)
shuffle_inplace(pools)
found_bloodpool = pick(pools)
@@ -336,51 +191,30 @@ Difficulty: Hard
forceMove(get_turf(found_bloodpool))
playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1)
visible_message("<span class='danger'>And springs back out!</span>")
return TRUE
return FALSE
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/get_pools(turf/T, range)
. = list()
for(var/obj/effect/decal/cleanable/nearby in view(T, range))
if(nearby.can_bloodcrawl_in())
. += nearby
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_spray()
visible_message("<span class='danger'>[src] sprays a stream of gore!</span>")
var/range = 6 + round(anger_modifier * 0.4)
var/turf/E = get_edge_target_turf(src, src.dir)
var/range = 10
var/turf/previousturf = get_turf(src)
var/turf/J = previousturf
var/targetdir = get_dir(src, target)
if(target.loc == loc)
targetdir = dir
face_atom(target)
new /obj/effect/decal/cleanable/blood/bubblegum(J)
for(var/i in 1 to range)
J = get_step(previousturf, targetdir)
new /obj/effect/temp_visual/dir_setting/bloodsplatter(previousturf, get_dir(previousturf, J))
playsound(previousturf,'sound/effects/splat.ogg', 100, 1, -1)
if(!J || !previousturf.atmos_adjacent_turfs || !previousturf.atmos_adjacent_turfs[J])
for(var/turf/J in getline(src,E))
if(!range)
break
new /obj/effect/decal/cleanable/blood/bubblegum(J)
new /obj/effect/temp_visual/dir_setting/bloodsplatter(previousturf, get_dir(previousturf, J))
if(!previousturf.CanAtmosPass(J))
break
playsound(J,'sound/effects/splat.ogg', 100, 1, -1)
new /obj/effect/decal/cleanable/blood(J)
range--
previousturf = J
sleep(1)
/obj/effect/decal/cleanable/blood/bubblegum
bloodiness = 0
/obj/effect/decal/cleanable/blood/bubblegum/can_bloodcrawl_in()
return TRUE
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/slaughterlings()
visible_message("<span class='danger'>[src] summons a shoal of slaughterlings!</span>")
var/max_amount = 6
for(var/H in get_pools(get_turf(src), 1))
if(!max_amount)
break
max_amount--
var/obj/effect/decal/cleanable/blood/B = H
new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/slaughter(B.loc)
return max_amount
for(var/obj/effect/decal/cleanable/blood/H in range(src, 10))
if(prob(25))
new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/slaughter(H.loc)
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/slaughter
name = "slaughterling"
@@ -398,3 +232,5 @@ Difficulty: Hard
if(istype(mover, /mob/living/simple_animal/hostile/megafauna/bubblegum))
return 1
return 0
#undef MEDAL_PREFIX
+1
View File
@@ -7,6 +7,7 @@
hud_possible = list(ANTAG_HUD)
pressure_resistance = 8
mouse_drag_pointer = MOUSE_ACTIVE_POINTER
throwforce = 10
var/lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
var/datum/mind/mind
var/list/datum/action/actions = list()
+1 -2
View File
@@ -379,8 +379,7 @@
else if(transfer_after)
R.key = key
if (CONFIG_GET(flag/rename_cyborg))
R.rename_self("cyborg")
R.rename_self("cyborg")
if(R.mmi)
R.mmi.name = "Man-Machine Interface: [real_name]"
@@ -40,7 +40,10 @@
return data
/datum/computer_file/program/alarm_monitor/proc/triggerAlarm(class, area/A, O, obj/source)
if(!is_station_level(source.z) && !is_mining_level(source.z))
if(is_station_level(source.z))
if(!(A.type in GLOB.the_station_areas))
return
else if(!is_mining_level(source.z) || istype(A, /area/ruin))
return
var/list/L = alarms[class]
@@ -95,4 +98,4 @@
/datum/computer_file/program/alarm_monitor/kill_program(forced = FALSE)
GLOB.alarmdisplay -= src
..()
..()
+2
View File
@@ -130,6 +130,8 @@
return
/obj/item/gun/energy/update_icon(force_update)
if(QDELETED(src))
return
..()
if(!automatic_charge_overlays)
return
@@ -11,8 +11,21 @@
clumsy_check = FALSE
randomspread = FALSE
var/hugbox = TRUE
var/max_power = INFINITY
var/reaction_volume_mod = 0
var/reaction_cycles = 3 //How many times gases react() before calculation. Very finnicky value, do not mess with without good reason.
var/prereaction = TRUE
var/bombcheck = TRUE
var/debug_power = 0
var/obj/item/transfer_valve/bomb
/obj/item/gun/blastcannon/debug
debug_power = 80
bombcheck = FALSE
/obj/item/gun/blastcannon/Initialize()
. = ..()
if(!pin)
@@ -56,27 +69,33 @@
return TRUE
return ..()
//returns the third value of a bomb blast
/obj/item/gun/blastcannon/proc/calculate_bomb()
if(!istype(bomb) || !istype(bomb.tank_one) || !istype(bomb.tank_two))
return 0
var/datum/gas_mixture/temp = new(60) //directional buff.
temp.merge(bomb.tank_one.air_contents.remove_ratio(1))
temp.merge(bomb.tank_two.air_contents.remove_ratio(2))
for(var/i in 1 to 6)
var/datum/gas_mixture/temp = new(max(reaction_volume_mod, 0))
bomb.merge_gases(temp)
if(prereaction)
temp.react(src)
var/prereaction_pressure = temp.return_pressure()
if(prereaction_pressure < TANK_FRAGMENT_PRESSURE)
return 0
for(var/i in 1 to reaction_cycles)
temp.react(src)
var/pressure = temp.return_pressure()
qdel(temp)
if(pressure < TANK_FRAGMENT_PRESSURE)
return 0
return (pressure / TANK_FRAGMENT_SCALE)
return ((pressure - TANK_FRAGMENT_PRESSURE) / TANK_FRAGMENT_SCALE)
/obj/item/gun/blastcannon/afterattack(atom/target, mob/user, flag, params)
if((!bomb) || (!target) || (get_dist(get_turf(target), get_turf(user)) <= 2))
if((!bomb && bombcheck) || (!target) || (get_dist(get_turf(target), get_turf(user)) <= 2))
return ..()
var/power = calculate_bomb()
var/power = bomb? calculate_bomb() : debug_power
power = min(power, max_power)
QDEL_NULL(bomb)
update_icon()
var/heavy = power * 0.2
var/heavy = power * 0.25
var/medium = power * 0.5
var/light = power
user.visible_message("<span class='danger'>[user] opens [bomb] on [user.p_their()] [name] and fires a blast wave at [target]!</span>","<span class='danger'>You open [bomb] on your [name] and fire a blast wave at [target]!</span>")
@@ -87,7 +106,8 @@
message_admins(log_str)
log_game(log_str)
var/obj/item/projectile/blastwave/BW = new(loc, heavy, medium, light)
BW.preparePixelProjectile(target, get_turf(target), user, params, 0)
BW.hugbox = hugbox
BW.preparePixelProjectile(target, get_turf(src), params, 0)
BW.fire()
/obj/item/projectile/blastwave
@@ -99,6 +119,7 @@
var/heavyr = 0
var/mediumr = 0
var/lightr = 0
var/hugbox = TRUE
range = 150
/obj/item/projectile/blastwave/Initialize(mapload, _h, _m, _l)
@@ -110,14 +131,25 @@
/obj/item/projectile/blastwave/Range()
..()
var/amount_destruction = EXPLODE_NONE
var/wallbreak_chance = 0
if(heavyr)
amount_destruction = EXPLODE_DEVASTATE
wallbreak_chance = 99
else if(mediumr)
amount_destruction = EXPLODE_HEAVY
wallbreak_chance = 66
else if(lightr)
amount_destruction = EXPLODE_LIGHT
wallbreak_chance = 33
if(amount_destruction)
loc.ex_act(amount_destruction)
if(hugbox)
loc.contents_explosion(EXPLODE_HEAVY, loc)
if(istype(loc, /turf/closed/wall))
var/turf/closed/wall/W = loc
if(prob(wallbreak_chance))
W.dismantle_wall(TRUE, TRUE)
else
loc.ex_act(amount_destruction)
else
qdel(src)
@@ -11,7 +11,7 @@
. = ..()
if(isliving(target))
var/mob/living/L = target
L.adjust_bodytemperature(L.bodytemperature + (((100-blocked)/100)*(temperature - L.bodytemperature))) // the new body temperature is adjusted by 100-blocked % of the delta between body temperature and the bullet's effect temperature
L.adjust_bodytemperature(((100-blocked)/100)*(temperature - L.bodytemperature)) // the new body temperature is adjusted by 100-blocked % of the delta between body temperature and the bullet's effect temperature
/obj/item/projectile/temp/hot
name = "heat beam"
+4 -4
View File
@@ -115,10 +115,10 @@
to_chat(M, "<span class='boldannounce'>You're not feeling good at all! You really need some [name].</span>")
return
/proc/pretty_string_from_reagent_list(var/list/reagent_list)
/proc/pretty_string_from_reagent_list(list/reagent_list)
//Convert reagent list to a printable string for logging etc
var/result = "| "
var/list/rs = list()
for (var/datum/reagent/R in reagent_list)
result += "[R.name], [R.volume] | "
rs += "[R.name], [R.volume]"
return result
return rs.Join(" | ")
@@ -283,10 +283,10 @@
if(ishuman(victim))
var/mob/living/carbon/human/H = victim
if( H.head )
if ( H.head.flags_cover & MASKCOVERSEYES )
if ( H.head.flags_cover & HEADCOVERSEYES )
eyes_covered = 1
safe_thing = H.head
if ( H.head.flags_cover & MASKCOVERSMOUTH )
if ( H.head.flags_cover & HEADCOVERSMOUTH )
mouth_covered = 1
safe_thing = H.head
if(H.glasses)
@@ -286,10 +286,16 @@
/obj/item/reagent_containers/glass/bucket/equipped(mob/user, slot)
..()
if(slot == SLOT_HEAD && reagents.total_volume)
to_chat(user, "<span class='userdanger'>[src]'s contents spill all over you!</span>")
reagents.reaction(user, TOUCH)
reagents.clear_reagents()
if (slot == SLOT_HEAD)
if(reagents.total_volume)
to_chat(user, "<span class='userdanger'>[src]'s contents spill all over you!</span>")
reagents.reaction(user, TOUCH)
reagents.clear_reagents()
container_type = NONE
/obj/item/reagent_containers/glass/bucket/dropped(mob/user)
. = ..()
container_type = initial(container_type)
/obj/item/reagent_containers/glass/bucket/equip_to_best_slot(var/mob/M)
if(reagents.total_volume) //If there is water in a bucket, don't quick equip it to the head
@@ -151,10 +151,32 @@
icon_state = "pill18"
list_reagents = list("insulin" = 50)
roundstart = 1
///////////////////////////////////////// this pill is used only in a legion mob drop
/obj/item/reagent_containers/pill/shadowtoxin
name = "black pill"
desc = "I wouldn't eat this if I were you."
icon_state = "pill9"
color = "#454545"
list_reagents = list("shadowmutationtoxin" = 1)
list_reagents = list("shadowmutationtoxin" = 1)
//////////////////////////////////////// drugs
/obj/item/reagent_containers/pill/zoom
name = "zoom pill"
list_reagents = list("synaptizine" = 10, "nicotine" = 10, "methamphetamine" = 1)
/obj/item/reagent_containers/pill/happy
name = "happy pill"
list_reagents = list("sugar" = 10, "space_drugs" = 10)
/obj/item/reagent_containers/pill/lsd
name = "hallucinogen pill"
list_reagents = list("mushroomhallucinogen" = 15, "mindbreaker" = 15)
/obj/item/reagent_containers/pill/aranesp
name = "speedy pill"
list_reagents = list("aranesp" = 10)
@@ -423,10 +423,11 @@
/datum/design/healthanalyzer
name = "Health Analyzer"
id = "healthanalyzer"
build_type = AUTOLATHE
build_type = AUTOLATHE | PROTOLATHE
materials = list(MAT_METAL = 500, MAT_GLASS = 50)
build_path = /obj/item/healthanalyzer
category = list("initial", "Medical")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
/datum/design/pillbottle
name = "Pill Bottle"
@@ -200,7 +200,17 @@
materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500)
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
/datum/design/healthanalyzer_advanced
name = "advanced health analyzer"
desc = "A hand-held body scanner able to distinguish vital signs of the subject with high accuracy."
id = "healthanalyzer_advanced"
build_path = /obj/item/healthanalyzer/advanced
build_type = PROTOLATHE
materials = list(MAT_METAL = 5000, MAT_GLASS = 2500, MAT_SILVER = 2000, MAT_GOLD = 1500)
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
/////////////////////////////////////////
//////////Cybernetic Implants////////////
/////////////////////////////////////////
@@ -126,7 +126,12 @@ Note: Must be placed within 3 tiles of the R&D Console
var/list/point_value = techweb_item_point_check(loaded_item)
if(linked_console.stored_research.deconstructed_items[loaded_item.type])
point_value = list()
var/choice = input("Are you sure you want to destroy [loaded_item] for [length(point_value) ? "[json_encode(point_value)] points" : "material reclamation"]?") in list("Proceed", "Cancel")
var/user_mode_string = ""
if(length(point_value))
user_mode_string = " for [json_encode(point_value)] points"
else if(loaded_item.materials.len)
user_mode_string = " for material reclamation"
var/choice = input("Are you sure you want to destroy [loaded_item][user_mode_string]?") in list("Proceed", "Cancel")
if(choice == "Cancel")
return FALSE
if(QDELETED(loaded_item) || QDELETED(linked_console) || !user.Adjacent(linked_console) || QDELETED(src))
+3 -3
View File
@@ -594,9 +594,9 @@ Nothing else in the console has ID requirements.
l += "This item is worth: <BR>[techweb_point_display_generic(point_values)]!"
l += "</div>[RDSCREEN_NOBREAK]"
var/list/materials = linked_destroy.loaded_item.materials
if (materials.len)
l += "<div class='statusDisplay'><A href='?src=[REF(src)];deconstruct=[RESEARCH_MATERIAL_RECLAMATION_ID]'>Material Reclamation</A>"
if(!(linked_destroy.loaded_item.resistance_flags & INDESTRUCTIBLE))
var/list/materials = linked_destroy.loaded_item.materials
l += "<div class='statusDisplay'><A href='?src=[REF(src)];deconstruct=[RESEARCH_MATERIAL_RECLAMATION_ID]'>[materials.len? "Material Reclamation" : "Destroy Item"]</A>"
for (var/M in materials)
l += "* [CallMaterialName(M)] x [materials[M]]"
l += "</div>[RDSCREEN_NOBREAK]"
+2 -2
View File
@@ -18,7 +18,7 @@
display_name = "Biological Technology"
description = "What makes us tick." //the MC, silly!
prereq_ids = list("base")
design_ids = list("chem_heater", "chem_master", "chem_dispenser", "sleeper", "vr_sleeper", "pandemic", "defibmount", "operating", "soda_dispenser", "beer_dispenser")
design_ids = list("chem_heater", "chem_master", "chem_dispenser", "sleeper", "vr_sleeper", "pandemic", "defibmount", "operating", "soda_dispenser", "beer_dispenser", "healthanalyzer")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
@@ -27,7 +27,7 @@
display_name = "Advanced Biotechnology"
description = "Advanced Biotechnology"
prereq_ids = list("biotech")
design_ids = list("piercesyringe", "smoke_machine", "plasmarefiller", "limbgrower", "defibrillator", "meta_beaker")
design_ids = list("piercesyringe", "smoke_machine", "plasmarefiller", "limbgrower", "defibrillator", "meta_beaker", "healthanalyzer_advanced")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
+1 -1
View File
@@ -124,7 +124,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
continue
if(bounty_ship_item_and_contents(AM, dry_run = FALSE))
matched_bounty = TRUE
if(!AM.anchored)
if(!AM.anchored || istype(AM, /obj/mecha))
sold_atoms += export_item_and_contents(AM, contraband, emagged, dry_run = FALSE)
if(sold_atoms)
+1 -4
View File
@@ -60,10 +60,7 @@
target.visible_message("<span class='warning'>[target]'s [A] glows brightly as it wards off the spell!</span>")
user.visible_message("<span class='warning'>The feedback blows [user]'s arm off!</span>","<span class='userdanger'>The spell bounces from [M]'s skin back into your arm!</span>")
user.flash_act()
var/obj/item/bodypart/part
var/index = user.get_held_index_of_item(src)
if(index)
part = user.hand_bodyparts[index]
var/obj/item/bodypart/part = user.get_holding_bodypart_of_item(src)
if(part)
part.dismember()
..()
@@ -199,7 +199,7 @@
/obj/item/bodypart/r_leg/drop_limb(special)
if(owner && !special)
if(owner.legcuffed)
owner.legcuffed.forceMove(drop_location())
owner.legcuffed.forceMove(owner.drop_location()) //At this point bodypart is still in nullspace
owner.legcuffed.dropped(owner)
owner.legcuffed = null
owner.update_inv_legcuffed()
@@ -210,7 +210,7 @@
/obj/item/bodypart/l_leg/drop_limb(special) //copypasta
if(owner && !special)
if(owner.legcuffed)
owner.legcuffed.forceMove(drop_location())
owner.legcuffed.forceMove(owner.drop_location())
owner.legcuffed.dropped(owner)
owner.legcuffed = null
owner.update_inv_legcuffed()
+10
View File
@@ -1412,6 +1412,16 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
limited_stock = 2 //you can't use more than two!
restricted_roles = list("Shaft Miner")
/datum/uplink_item/role_restricted/blastcannon
name = "Blast Cannon"
desc = "A highly specialized weapon, the Blast Cannon is actually relatively simple. It contains an attachment for a tank transfer valve mounted to an angled pipe specially constructed \
withstand extreme pressure and temperatures, and has a mechanical trigger for triggering the transfer valve. Essentially, it turns the explosive force of a bomb into a narrow-angle \
blast wave \"projectile\". Aspiring scientists may find this highly useful, as forcing the pressure shockwave into a narrow angle seems to be able to bypass whatever quirk of physics \
disallows explosive ranges above a certain distance, allowing for the device to use the theoretical yield of a transfer valve bomb, instead of the factual yield."
item = /obj/item/gun/blastcannon
cost = 14 //High cost because of the potential for extreme damage in the hands of a skilled scientist.
restricted_roles = list("Research Director", "Scientist")
/datum/uplink_item/device_tools/clown_bomb
name = "Clown Bomb"
desc = "The Clown bomb is a hilarious device capable of massive pranks. It has an adjustable timer, \
+120 -114
View File
@@ -1,7 +1,3 @@
#define STANDARD_CHARGE 1
#define CONTRABAND_CHARGE 2
#define COIN_CHARGE 3
/*
* Vending machine types - Can be found under /code/modules/vending/
*/
@@ -21,7 +17,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
*/
/datum/data/vending_product
var/product_name = "generic"
name = "generic"
var/product_path = null
var/amount = 0
var/max_amount = 0
@@ -74,7 +70,6 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
var/dish_quants = list() //used by the snack machine's custom compartment to count dishes.
var/obj/item/vending_refill/refill_canister = null //The type of refill canisters used by this machine.
var/refill_count = 3 //The number of canisters the vending machine uses
/obj/machinery/vending/Initialize()
var/build_inv = FALSE
@@ -84,9 +79,9 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
. = ..()
wires = new /datum/wires/vending(src)
if(build_inv) //non-constructable vending machine
build_inventory(products)
build_inventory(contraband, 1)
build_inventory(premium, 0, 1)
build_inventory(products, product_records)
build_inventory(contraband, hidden_records)
build_inventory(premium, coin_records)
slogan_list = splittext(product_slogans, ";")
// So not all machines speak at the exact same time.
@@ -102,17 +97,17 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
return ..()
/obj/machinery/vending/RefreshParts() //Better would be to make constructable child
if(component_parts)
product_records = list()
hidden_records = list()
coin_records = list()
build_inventory(products, start_empty = 1)
build_inventory(contraband, 1, start_empty = 1)
build_inventory(premium, 0, 1, start_empty = 1)
for(var/obj/item/vending_refill/VR in component_parts)
refill_inventory(VR, product_records, STANDARD_CHARGE)
refill_inventory(VR, coin_records, COIN_CHARGE)
refill_inventory(VR, hidden_records, CONTRABAND_CHARGE)
if(!component_parts)
return
product_records = list()
hidden_records = list()
coin_records = list()
build_inventory(products, product_records, start_empty = TRUE)
build_inventory(contraband, hidden_records, start_empty = TRUE)
build_inventory(premium, coin_records, start_empty = TRUE)
for(var/obj/item/vending_refill/VR in component_parts)
restock(VR)
/obj/machinery/vending/deconstruct(disassembled = TRUE)
if(!refill_canister) //the non constructable vendors drop metal instead of a machine frame.
@@ -124,25 +119,33 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
/obj/machinery/vending/obj_break(damage_flag)
if(!(stat & BROKEN) && !(flags_1 & NODECONSTRUCT_1))
var/dump_amount = 0
for(var/datum/data/vending_product/R in product_records)
if(R.amount <= 0) //Try to use a record that actually has something to dump.
continue
var/dump_path = R.product_path
if(!dump_path)
continue
while(R.amount>0)
var/obj/O = new dump_path(loc)
step(O, pick(GLOB.alldirs)) //we only drop 20% of the total of each products and spread it
R.amount -= 5 //around to not fill the turf with too many objects.
dump_amount++
if(dump_amount > 15) //so we don't drop too many items (e.g. ClothesMate)
break
stat |= BROKEN
icon_state = "[initial(icon_state)]-broken"
/obj/machinery/vending/proc/build_inventory(list/productlist, hidden=0, req_coin=0, start_empty = null)
var/dump_amount = 0
var/found_anything = TRUE
while (found_anything)
found_anything = FALSE
for(var/record in shuffle(product_records))
var/datum/data/vending_product/R = record
if(R.amount <= 0) //Try to use a record that actually has something to dump.
continue
var/dump_path = R.product_path
if(!dump_path)
continue
R.amount--
// busting open a vendor will destroy some of the contents
if(found_anything && prob(80))
continue
var/obj/O = new dump_path(loc)
step(O, pick(GLOB.alldirs))
found_anything = TRUE
dump_amount++
if (dump_amount >= 16)
return
/obj/machinery/vending/proc/build_inventory(list/productlist, list/recordlist, start_empty = FALSE)
for(var/typepath in productlist)
var/amount = productlist[typepath]
if(isnull(amount))
@@ -150,47 +153,54 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
var/atom/temp = typepath
var/datum/data/vending_product/R = new /datum/data/vending_product()
R.product_name = initial(temp.name)
R.name = initial(temp.name)
R.product_path = typepath
if(!start_empty)
R.amount = amount
R.max_amount = amount
R.display_color = pick("red","blue","green")
R.display_color = pick("#ff8080","#80ff80","#8080ff")
recordlist += R
if(hidden)
hidden_records += R
else if(req_coin)
coin_records += R
else
product_records += R
/obj/machinery/vending/proc/restock(obj/item/vending_refill/canister)
if (!canister.products)
canister.products = products.Copy()
if (!canister.contraband)
canister.contraband = contraband.Copy()
if (!canister.premium)
canister.premium = premium.Copy()
. = 0
. += refill_inventory(canister.products, product_records)
. += refill_inventory(canister.contraband, hidden_records)
. += refill_inventory(canister.premium, coin_records)
/obj/machinery/vending/proc/refill_inventory(obj/item/vending_refill/refill, datum/data/vending_product/machine, var/charge_type = STANDARD_CHARGE)
var/total = 0
var/to_restock = 0
/obj/machinery/vending/proc/refill_inventory(list/productlist, list/recordlist)
. = 0
for(var/R in recordlist)
var/datum/data/vending_product/record = R
var/diff = min(record.max_amount - record.amount, productlist[record.product_path])
if (diff)
productlist[record.product_path] -= diff
record.amount += diff
. += diff
for(var/datum/data/vending_product/machine_content in machine)
if(machine_content.amount == 0 && refill.charges[charge_type] > 0)
machine_content.amount++
refill.charges[charge_type]--
total++
to_restock += machine_content.max_amount - machine_content.amount
if(to_restock <= refill.charges[charge_type])
for(var/datum/data/vending_product/machine_content in machine)
machine_content.amount = machine_content.max_amount
refill.charges[charge_type] -= to_restock
total += to_restock
else
var/tmp_charges = refill.charges[charge_type]
for(var/datum/data/vending_product/machine_content in machine)
if(refill.charges[charge_type] == 0)
break
var/restock = CEILING(((machine_content.max_amount - machine_content.amount)/to_restock)*tmp_charges, 1)
if(restock > refill.charges[charge_type])
restock = refill.charges[charge_type]
machine_content.amount += restock
refill.charges[charge_type] -= restock
total += restock
return total
/obj/machinery/vending/proc/update_canister()
if (!component_parts)
return
var/obj/item/vending_refill/R = locate() in component_parts
if (!R)
CRASH("Constructible vending machine did not have a refill canister")
return
R.products = unbuild_inventory(product_records)
R.contraband = unbuild_inventory(hidden_records)
R.premium = unbuild_inventory(coin_records)
/obj/machinery/vending/proc/unbuild_inventory(list/recordlist)
. = list()
for(var/R in recordlist)
var/datum/data/vending_product/record = R
.[record.product_path] += record.amount
/obj/machinery/vending/crowbar_act(mob/living/user, obj/item/I)
if(!component_parts)
@@ -248,46 +258,52 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
bill = new S.type(src, 1)
to_chat(user, "<span class='notice'>You insert [I] into [src].</span>")
return
else if(istype(I, refill_canister) && refill_canister != null)
if(stat & (BROKEN|NOPOWER))
to_chat(user, "<span class='notice'>It does nothing.</span>")
else if(panel_open)
else if(refill_canister && istype(I, refill_canister))
if (!panel_open)
to_chat(user, "<span class='notice'>You should probably unscrew the service panel first.</span>")
else if (stat & (BROKEN|NOPOWER))
to_chat(user, "<span class='notice'>[src] does not respond.</span>")
else
//if the panel is open we attempt to refill the machine
var/obj/item/vending_refill/canister = I
if(canister.charges[STANDARD_CHARGE] == 0)
to_chat(user, "<span class='notice'>This [canister.name] is empty!</span>")
if(canister.get_part_rating() == 0)
to_chat(user, "<span class='notice'>[canister] is empty!</span>")
else
var/transfered = refill_inventory(canister,product_records,STANDARD_CHARGE)
transfered += refill_inventory(canister,coin_records,COIN_CHARGE)
transfered += refill_inventory(canister,hidden_records,CONTRABAND_CHARGE)
if(transfered)
to_chat(user, "<span class='notice'>You loaded [transfered] items in \the [name].</span>")
// instantiate canister if needed
var/transferred = restock(canister)
if(transferred)
to_chat(user, "<span class='notice'>You loaded [transferred] items in [src].</span>")
else
to_chat(user, "<span class='notice'>The [name] is fully stocked.</span>")
to_chat(user, "<span class='notice'>There's nothing to restock!</span>")
return
else
to_chat(user, "<span class='notice'>You should probably unscrew the service panel first.</span>")
else
return ..()
/obj/machinery/vending/exchange_parts(mob/user, obj/item/storage/part_replacer/W)
if(!istype(W))
return FALSE
if((flags_1 & NODECONSTRUCT_1) && !W.works_from_distance)
return FALSE
if(!component_parts || !refill_canister)
return FALSE
var/moved = 0
if(panel_open || W.works_from_distance)
if(W.works_from_distance)
display_parts(user)
for(var/I in W)
if(istype(I, refill_canister))
moved += restock(I)
else
display_parts(user)
if(moved)
to_chat(user, "[moved] items restocked.")
W.play_rped_sound()
return TRUE
/obj/machinery/vending/on_deconstruction()
var/product_list = list(product_records, hidden_records, coin_records)
for(var/i=1, i<=3, i++)
for(var/datum/data/vending_product/machine_content in product_list[i])
while(machine_content.amount !=0)
var/safety = 0 //to avoid infinite loop
for(var/obj/item/vending_refill/VR in component_parts)
safety++
if(VR.charges[i] < VR.init_charges[i])
VR.charges[i]++
machine_content.amount--
if(!machine_content.amount)
break
else
safety--
if(safety <= 0) // all refill canisters are full
break
..()
update_canister()
. = ..()
/obj/machinery/vending/emag_act(mob/user)
if(obj_flags & EMAGGED)
@@ -323,7 +339,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
dat += "<a href='byond://?src=[REF(src)];vend=[REF(R)]'>Vend</a> "
else
dat += "<span class='linkOff'>Sold out</span> "
dat += "<font color = '[R.display_color]'><b>[sanitize(R.product_name)]</b>:</font>"
dat += "<font color = '[R.display_color]'><b>[sanitize(R.name)]</b>:</font>"
dat += " <b>[R.amount]</b>"
dat += "</li>"
dat += "</ul>"
@@ -358,17 +374,11 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
to_chat(usr, "<span class='notice'>There is no money in this machine.</span>")
return
if(coin)
if(!usr.get_active_held_item())
usr.put_in_hands(coin)
else
coin.forceMove(get_turf(src))
usr.put_in_hands(coin)
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))
usr.put_in_hands(bill)
to_chat(usr, "<span class='notice'>You remove [bill] from [src].</span>")
bill = null
@@ -545,7 +555,3 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
/obj/machinery/vending/onTransitZ()
return
#undef STANDARD_CHARGE
#undef CONTRABAND_CHARGE
#undef COIN_CHARGE
+4 -2
View File
@@ -122,8 +122,10 @@
/obj/item/skub = 1)
refill_canister = /obj/item/vending_refill/autodrobe
/obj/machinery/vending/autodrobe/all_access
desc = "A vending machine for costumes. This model appears to have no access restrictions."
req_access = null
/obj/item/vending_refill/autodrobe
machine_name = "AutoDrobe"
icon_state = "refill_costume"
charges = list(32, 2, 3)// of 96 standard, 6 contraband, 9 premium
init_charges = list(32, 2, 3)
+4 -2
View File
@@ -38,6 +38,10 @@
req_access = list(ACCESS_BAR)
refill_canister = /obj/item/vending_refill/boozeomat
/obj/machinery/vending/boozeomat/all_access
desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one. This model appears to have no access restrictions."
req_access = null
/obj/machinery/vending/boozeomat/pubby_maint //abandoned bar on Pubbystation
products = list(/obj/item/reagent_containers/food/drinks/bottle/whiskey = 1,
/obj/item/reagent_containers/food/drinks/bottle/absinthe = 1,
@@ -62,5 +66,3 @@
/obj/item/vending_refill/boozeomat
machine_name = "Booze-O-Mat"
icon_state = "refill_booze"
charges = list(61, 4, 0)//of 182 standard, 12 contraband
init_charges = list(61, 4, 0)
-2
View File
@@ -41,8 +41,6 @@
/obj/item/vending_refill/cigarette
machine_name = "ShadyCigs Deluxe"
icon_state = "refill_smoke"
charges = list(12, 3, 2)// of 36 standard, 9 contraband, 6 premium
init_charges = list(12, 3, 2)
/obj/machinery/vending/cigarette/pre_throw(obj/item/I)
if(istype(I, /obj/item/lighter))
+1 -2
View File
@@ -35,6 +35,7 @@
/obj/item/clothing/neck/tie/red = 1,
/obj/item/clothing/neck/tie/black = 1,
/obj/item/clothing/neck/tie/horrible = 1,
/obj/item/clothing/neck/scarf/pink = 1,
/obj/item/clothing/neck/scarf/red = 1,
/obj/item/clothing/neck/scarf/green = 1,
/obj/item/clothing/neck/scarf/darkblue = 1,
@@ -118,5 +119,3 @@
/obj/item/vending_refill/clothing
machine_name = "ClothesMate"
icon_state = "refill_clothes"
charges = list(37, 4, 4)// of 111 standard, 12 contraband, 10 premium(?)
init_charges = list(37, 4, 4)
+2 -4
View File
@@ -4,8 +4,8 @@
product_ads = "Have a drink!;Drink up!;It's good for you!;Would you like a hot joe?;I'd kill for some coffee!;The best beans in the galaxy.;Only the finest brew for you.;Mmmm. Nothing like a coffee.;I like coffee, don't you?;Coffee helps you work!;Try some tea.;We hope you like the best!;Try our new chocolate!;Admin conspiracies"
icon_state = "coffee"
icon_vend = "coffee-vend"
products = list(/obj/item/reagent_containers/food/drinks/coffee = 25,
/obj/item/reagent_containers/food/drinks/mug/tea = 25,
products = list(/obj/item/reagent_containers/food/drinks/coffee = 25,
/obj/item/reagent_containers/food/drinks/mug/tea = 25,
/obj/item/reagent_containers/food/drinks/mug/coco = 25)
contraband = list(/obj/item/reagent_containers/food/drinks/ice = 12)
refill_canister = /obj/item/vending_refill/coffee
@@ -13,5 +13,3 @@
/obj/item/vending_refill/coffee
machine_name = "Solar's Best Hot Drinks"
icon_state = "refill_joe"
charges = list(25, 4, 0)//of 75 standard, 12 contraband
init_charges = list(25, 4, 0)
-2
View File
@@ -22,8 +22,6 @@
/obj/item/vending_refill/cola
machine_name = "Robust Softdrinks"
icon_state = "refill_cola"
charges = list(30, 4, 1)//of 90 standard, 12 contraband, 1 premium
init_charges = list(30, 4, 1)
/obj/machinery/vending/cola/random
name = "\improper Random Drinkies"
-2
View File
@@ -13,5 +13,3 @@
/obj/item/vending_refill/games
machine_name = "\improper Good Clean Fun"
icon_state = "refill_games"
charges = list(7, 3, 0) //of 21 standard, 9 contraband
init_charges = list(7, 3, 0)
-1
View File
@@ -2,7 +2,6 @@
name = "\improper Liberation Station"
desc = "An overwhelming amount of <b>ancient patriotism</b> washes over you just by looking at the machine."
icon_state = "liberationstation"
req_access = list(ACCESS_SECURITY)
product_slogans = "Liberation Station: Your one-stop shop for all things second ammendment!;Be a patriot today, pick up a gun!;Quality weapons for cheap prices!;Better dead than red!"
product_ads = "Float like an astronaut, sting like a bullet!;Express your second ammendment today!;Guns don't kill people, but you can!;Who needs responsibilities when you have guns?"
vend_reply = "Remember the name: Liberation Station!"
-1
View File
@@ -2,7 +2,6 @@
name = "\improper Syndicate Donksoft Toy Vendor"
desc = "An ages 8 and up approved vendor that dispenses toys. If you were to find the right wires, you can unlock the adult mode setting!"
icon_state = "syndi"
req_access = list(ACCESS_SECURITY)
product_slogans = "Get your cool toys today!;Trigger a valid hunter today!;Quality toy weapons for cheap prices!;Give them to HoPs for all access!;Give them to HoS to get permabrigged!"
product_ads = "Feel robust with your toys!;Express your inner child today!;Toy weapons don't kill people, but valid hunters do!;Who needs responsibilities when you have toy weapons?;Make your next murder FUN!"
vend_reply = "Come back for more!"
+14 -16
View File
@@ -5,24 +5,24 @@
icon_deny = "med-deny"
product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?;Ping!"
req_access = list(ACCESS_MEDICAL)
products = list(/obj/item/reagent_containers/syringe = 12,
/obj/item/reagent_containers/dropper = 3,
/obj/item/healthanalyzer = 4,
/obj/item/sensor_device = 2,
products = list(/obj/item/reagent_containers/syringe = 12,
/obj/item/reagent_containers/dropper = 3,
/obj/item/healthanalyzer = 4,
/obj/item/sensor_device = 2,
/obj/item/pinpointer/crew = 2,
/obj/item/reagent_containers/medspray/sterilizine = 1,
/obj/item/stack/medical/gauze = 8,
/obj/item/reagent_containers/pill/patch/styptic = 5,
/obj/item/reagent_containers/medspray/styptic = 2,
/obj/item/reagent_containers/pill/patch/silver_sulf = 5,
/obj/item/stack/medical/gauze = 8,
/obj/item/reagent_containers/pill/patch/styptic = 5,
/obj/item/reagent_containers/medspray/styptic = 2,
/obj/item/reagent_containers/pill/patch/silver_sulf = 5,
/obj/item/reagent_containers/medspray/silver_sulf = 2,
/obj/item/reagent_containers/pill/insulin = 10,
/obj/item/reagent_containers/pill/salbutamol = 2,
/obj/item/reagent_containers/glass/bottle/charcoal = 4,
/obj/item/reagent_containers/glass/bottle/epinephrine = 4,
/obj/item/reagent_containers/pill/salbutamol = 2,
/obj/item/reagent_containers/glass/bottle/charcoal = 4,
/obj/item/reagent_containers/glass/bottle/epinephrine = 4,
/obj/item/reagent_containers/glass/bottle/salglu_solution = 3,
/obj/item/reagent_containers/glass/bottle/morphine = 4,
/obj/item/reagent_containers/glass/bottle/toxin = 3,
/obj/item/reagent_containers/glass/bottle/morphine = 4,
/obj/item/reagent_containers/glass/bottle/toxin = 3,
/obj/item/reagent_containers/syringe/antiviral = 6)
contraband = list(/obj/item/reagent_containers/pill/tox = 3,
/obj/item/reagent_containers/pill/morphine = 4,
@@ -36,7 +36,5 @@
refill_canister = /obj/item/vending_refill/medical
/obj/item/vending_refill/medical
machine_name = "NanoMed"
machine_name = "NanoMed Plus"
icon_state = "refill_medical"
charges = list(26, 5, 3)// of 76 standard, 13 contraband, 8 premium
init_charges = list(26, 5, 3)
+5 -2
View File
@@ -15,5 +15,8 @@
/obj/item/reagent_containers/pill/morphine = 2)
armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50)
resistance_flags = FIRE_PROOF
refill_canister = /obj/item/vending_refill/medical
refill_count = 1
refill_canister = /obj/item/vending_refill/wallmed
/obj/item/vending_refill/wallmed
machine_name = "NanoMed"
icon_state = "refill_medical"
-2
View File
@@ -17,8 +17,6 @@
/obj/item/vending_refill/snack
machine_name = "Getmore Chocolate Corp"
charges = list(12, 2, 0)//of 36 standard, 6 contraband
init_charges = list(12, 2, 0)
/obj/machinery/vending/snack/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/reagent_containers/food/snacks))
+16 -16
View File
@@ -6,20 +6,22 @@
product_ads = "Feel robust with your toys!;Express your inner child today!;Toy weapons don't kill people, but valid hunters do!;Who needs responsibilities when you have toy weapons?;Make your next murder FUN!"
vend_reply = "Come back for more!"
circuit = /obj/item/circuitboard/machine/vending/donksofttoyvendor
products = list(/obj/item/gun/ballistic/automatic/toy/unrestricted = 10,
/obj/item/gun/ballistic/automatic/toy/pistol/unrestricted = 10,
/obj/item/gun/ballistic/shotgun/toy/unrestricted = 10,
/obj/item/toy/sword = 10,
/obj/item/ammo_box/foambox = 20,
/obj/item/toy/foamblade = 10,
/obj/item/toy/syndicateballoon = 10,
/obj/item/clothing/suit/syndicatefake = 5,
/obj/item/clothing/head/syndicatefake = 5)
contraband = list(/obj/item/gun/ballistic/shotgun/toy/crossbow = 10,
/obj/item/gun/ballistic/automatic/c20r/toy/unrestricted = 10,
/obj/item/gun/ballistic/automatic/l6_saw/toy/unrestricted = 10,
/obj/item/toy/katana = 10,
/obj/item/twohanded/dualsaber/toy = 5)
products = list(
/obj/item/gun/ballistic/automatic/toy/unrestricted = 10,
/obj/item/gun/ballistic/automatic/toy/pistol/unrestricted = 10,
/obj/item/gun/ballistic/shotgun/toy/unrestricted = 10,
/obj/item/toy/sword = 10,
/obj/item/ammo_box/foambox = 20,
/obj/item/toy/foamblade = 10,
/obj/item/toy/syndicateballoon = 10,
/obj/item/clothing/suit/syndicatefake = 5,
/obj/item/clothing/head/syndicatefake = 5)
contraband = list(
/obj/item/gun/ballistic/shotgun/toy/crossbow = 10,
/obj/item/gun/ballistic/automatic/c20r/toy/unrestricted = 10,
/obj/item/gun/ballistic/automatic/l6_saw/toy/unrestricted = 10,
/obj/item/toy/katana = 10,
/obj/item/twohanded/dualsaber/toy = 5)
armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50)
resistance_flags = FIRE_PROOF
refill_canister = /obj/item/vending_refill/donksoft
@@ -27,5 +29,3 @@
/obj/item/vending_refill/donksoft
machine_name = "Donksoft Toy Vendor"
icon_state = "refill_donksoft"
charges = list(32,28,0)// of 90 standard, 75 contraband, 0 premium
init_charges = list(32,28,0)
-34
View File
@@ -26,8 +26,6 @@
/obj/item/vending_refill/wardrobe/sec_wardrobe
machine_name = "SecDrobe"
charges = list(10, 0, 3)
init_charges = list(10, 0, 3)
/obj/machinery/vending/wardrobe/medi_wardrobe
name = "\improper MediDrobe"
@@ -56,8 +54,6 @@
/obj/item/vending_refill/wardrobe/medi_wardrobe
machine_name = "MediDrobe"
charges = list(10, 0, 0)
init_charges = list(10, 0, 0)
/obj/machinery/vending/wardrobe/engi_wardrobe
name = "EngiDrobe"
@@ -78,8 +74,6 @@
/obj/item/vending_refill/wardrobe/engi_wardrobe
machine_name = "EngiDrobe"
charges = list(7, 0, 0)
init_charges = list(7, 0, 0)
/obj/machinery/vending/wardrobe/atmos_wardrobe
name = "AtmosDrobe"
@@ -98,8 +92,6 @@
/obj/item/vending_refill/wardrobe/atmos_wardrobe
machine_name = "AtmosDrobe"
charges = list(5, 0, 0)
init_charges = list(5, 0, 0)
/obj/machinery/vending/wardrobe/cargo_wardrobe
name = "CargoDrobe"
@@ -117,8 +109,6 @@
/obj/item/vending_refill/wardrobe/cargo_wardrobe
machine_name = "CargoDrobe"
charges = list(5, 0, 0)
init_charges = list(5, 0, 0)
/obj/machinery/vending/wardrobe/robo_wardrobe
name = "RoboDrobe"
@@ -137,8 +127,6 @@
/obj/item/vending_refill/wardrobe/robo_wardrobe
machine_name = "RoboDrobe"
charges = list(4, 0, 0)
init_charges = list(4, 0, 0)
/obj/machinery/vending/wardrobe/science_wardrobe
name = "SciDrobe"
@@ -159,8 +147,6 @@
/obj/item/vending_refill/wardrobe/science_wardrobe
machine_name = "SciDrobe"
charges = list(8, 0, 0)
init_charges = list(8, 0, 0)
/obj/machinery/vending/wardrobe/hydro_wardrobe
name = "Hydrobe"
@@ -179,8 +165,6 @@
/obj/item/vending_refill/wardrobe/hydro_wardrobe
machine_name = "HyDrobe"
charges = list(6, 0, 0)
init_charges = list(6, 0, 0)
/obj/machinery/vending/wardrobe/curator_wardrobe
name = "CuraDrobe"
@@ -198,8 +182,6 @@
/obj/item/vending_refill/wardrobe/curator_wardrobe
machine_name = "CuraDrobe"
charges = list(3, 0, 0)
init_charges = list(3, 0, 0)
/obj/machinery/vending/wardrobe/bar_wardrobe
name = "BarDrobe"
@@ -227,8 +209,6 @@
/obj/item/vending_refill/wardrobe/bar_wardrobe
machine_name = "BarDrobe"
charges = list(8, 0, 0)
init_charges = list(8, 0, 0)
/obj/machinery/vending/wardrobe/chef_wardrobe
name = "ChefDrobe"
@@ -251,8 +231,6 @@
/obj/item/vending_refill/wardrobe/chef_wardrobe
machine_name = "ChefDrobe"
charges = list(6, 0, 0)
init_charges = list(6, 0, 0)
/obj/machinery/vending/wardrobe/jani_wardrobe
name = "JaniDrobe"
@@ -279,8 +257,6 @@
/obj/item/vending_refill/wardrobe/jani_wardrobe
machine_name = "JaniDrobe"
charges = list(7, 0, 0)
init_charges = list(7, 0, 0)
/obj/machinery/vending/wardrobe/law_wardrobe
name = "LawDrobe"
@@ -303,8 +279,6 @@
/obj/item/vending_refill/wardrobe/law_wardrobe
machine_name = "LawDrobe"
charges = list(5, 0, 0)
init_charges = list(5, 0, 0)
/obj/machinery/vending/wardrobe/chap_wardrobe
name = "ChapDrobe"
@@ -325,8 +299,6 @@
/obj/item/vending_refill/wardrobe/chap_wardrobe
machine_name = "ChapDrobe"
charges = list(6, 0, 0)
init_charges = list(6, 0, 0)
/obj/machinery/vending/wardrobe/chem_wardrobe
name = "ChemDrobe"
@@ -344,8 +316,6 @@
/obj/item/vending_refill/wardrobe/chem_wardrobe
machine_name = "ChemDrobe"
charges = list(4, 0, 0)
init_charges = list(4, 0, 0)
/obj/machinery/vending/wardrobe/gene_wardrobe
name = "GeneDrobe"
@@ -362,8 +332,6 @@
/obj/item/vending_refill/wardrobe/gene_wardrobe
machine_name = "GeneDrobe"
charges = list(4, 0, 0)
init_charges = list(4, 0, 0)
/obj/machinery/vending/wardrobe/viro_wardrobe
name = "ViroDrobe"
@@ -381,5 +349,3 @@
/obj/item/vending_refill/wardrobe/viro_wardrobe
machine_name = "ViroDrobe"
charges = list(4, 0, 0)
init_charges = list(4, 0, 0)