mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-25 14:08:31 +01:00
Merge branch 'master' into spellcheck
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
anchored = TRUE
|
||||
var/popped = FALSE
|
||||
|
||||
/obj/effect/fun_balloon/New()
|
||||
/obj/effect/fun_balloon/Initialize()
|
||||
. = ..()
|
||||
SSobj.processing |= src
|
||||
|
||||
|
||||
@@ -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"])
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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>")
|
||||
|
||||
|
||||
@@ -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]"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
))
|
||||
|
||||
|
||||
@@ -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>")
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
..()
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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]"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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!"
|
||||
|
||||
@@ -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!"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user