First merge from upstream

This commit is contained in:
Razgriz
2020-01-13 17:23:01 -07:00
575 changed files with 258115 additions and 66329 deletions
+1 -1
View File
@@ -35,4 +35,4 @@
name = "\improper VirGov banner"
icon_state = "banner-virgov"
desc = "A banner with the symbol of the local government, the Vir Governmental Authority, also known as VirGov."
catalogue_data = list(/datum/category_item/catalogue/information/organization/virgov)
//catalogue_data = list(/datum/category_item/catalogue/information/organization/virgov) YW Edit
@@ -180,10 +180,14 @@
The poster's captions explain the importance of knowing how to operate a mechatronic vehicle safely, especially near other personnel.\
The image seems important."
//VOREStation Removal Start TFF 17/12/19 - lore not used in our station's own lore.
/*
/datum/poster/nanotrasen/nt_4
icon_state = "ntposter04"
name = "Beware Aetotheans"
desc = "This poster displays a distinctly hostile-looking red Promethean in a black coat. The fine-print around the edges warns the reader about the dangers posed by Almachi Prometheans."
*/
//VOREstation Removal End
/datum/poster/nanotrasen/nt_5
icon_state = "ntposter05"
+8 -2
View File
@@ -74,16 +74,22 @@
switch(drawtype)
if("letter")
drawtype = input("Choose the letter.", "Crayon scribbles") in list("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z")
if(get_dist(target, user) > 1 || !(user.z == target.z))
if(get_dist(target, user) > 1 || !(user.z == target.z) || !drawtype)
return
to_chat(user, "You start drawing a letter on the [target.name].")
if("graffiti")
drawtype = input("Choose the graffiti.", "Crayon scribbles") in list("amyjon","face","matt","revolution","engie","guy","end","dwarf","uboa")
if(get_dist(target, user) > 1 || !(user.z == target.z) || !drawtype)
return
to_chat(user, "You start drawing graffiti on the [target.name].")
if("rune")
drawtype = input("Choose the rune.", "Crayon scribbles") in list("rune1", "rune2", "rune3", "rune4", "rune5", "rune6")
if(get_dist(target, user) > 1 || !(user.z == target.z) || !drawtype)
return
to_chat(user, "You start drawing a rune on the [target.name].")
if("arrow")
drawtype = input("Choose the arrow.", "Crayon scribbles") in list("left", "right", "up", "down")
if(get_dist(target, user) > 1 || !(user.z == target.z))
if(get_dist(target, user) > 1 || !(user.z == target.z) || !drawtype)
return
to_chat(user, "You start drawing an arrow on the [target.name].")
if(instant || do_after(user, 50))
@@ -63,6 +63,11 @@
if(ghost.exonet)
im_contacts_ui[++im_contacts_ui.len] = list("name" = sanitize(ghost.name), "address" = ghost.exonet.address, "ref" = "\ref[ghost]")
for(var/obj/item/integrated_circuit/input/EPv2/CIRC in im_contacts)
if(CIRC.exonet && CIRC.assembly)
im_contacts_ui[++im_contacts_ui.len] = list("name" = sanitize(CIRC.assembly.name), "address" = CIRC.exonet.address, "ref" = "\ref[CIRC]")
//Actual messages.
for(var/I in im_list)
im_list_ui[++im_list_ui.len] = list("address" = I["address"], "to_address" = I["to_address"], "im" = I["im"])
@@ -1,162 +1,166 @@
// Proc: receive_exonet_message()
// Parameters: 4 (origin atom - the source of the message's holder, origin_address - where the message came from, message - the message received,
// text - message text to send if message is of type "text")
// Description: Handles voice requests and invite messages originating from both real communicators and ghosts. Also includes a ping response and IM function.
/obj/item/device/communicator/receive_exonet_message(var/atom/origin_atom, origin_address, message, text)
if(message == "voice")
if(isobserver(origin_atom) || istype(origin_atom, /obj/item/device/communicator))
if(origin_atom in voice_invites)
var/user = null
if(ismob(origin_atom.loc))
user = origin_atom.loc
open_connection(user, origin_atom)
return
else if(origin_atom in voice_requests)
return //Spam prevention
else
request(origin_atom)
if(message == "ping")
if(network_visibility)
var/random = rand(200,350)
random = random / 10
exonet.send_message(origin_address, "64 bytes received from [exonet.address] ecmp_seq=1 ttl=51 time=[random] ms")
if(message == "text")
request_im(origin_atom, origin_address, text)
return
// Proc: receive_exonet_message()
// Parameters: 3 (origin atom - the source of the message's holder, origin_address - where the message came from, message - the message received)
// Description: Handles voice requests and invite messages originating from both real communicators and ghosts. Also includes a ping response.
/mob/observer/dead/receive_exonet_message(origin_atom, origin_address, message, text)
if(message == "voice")
if(istype(origin_atom, /obj/item/device/communicator))
var/obj/item/device/communicator/comm = origin_atom
if(src in comm.voice_invites)
comm.open_connection(src)
return
to_chat(src, "<span class='notice'>\icon[origin_atom] Receiving communicator request from [origin_atom]. To answer, use the <b>Call Communicator</b> \
verb, and select that name to answer the call.</span>")
src << 'sound/machines/defib_SafetyOn.ogg'
comm.voice_invites |= src
if(message == "ping")
if(client && client.prefs.communicator_visibility)
var/random = rand(450,700)
random = random / 10
exonet.send_message(origin_address, "64 bytes received from [exonet.address] ecmp_seq=1 ttl=51 time=[random] ms")
if(message == "text")
to_chat(src, "<span class='notice'>\icon[origin_atom] Received text message from [origin_atom]: <b>\"[text]\"</b></span>")
src << 'sound/machines/defib_safetyOff.ogg'
exonet_messages.Add("<b>From [origin_atom]:</b><br>[text]")
return
// Proc: request_im()
// Parameters: 3 (candidate - the communicator wanting to message the device, origin_address - the address of the sender, text - the message)
// Description: Response to a communicator trying to message the device.
// Adds them to the list of people that have messaged this device and adds the message to the message list.
/obj/item/device/communicator/proc/request_im(var/atom/candidate, var/origin_address, var/text)
var/who = null
if(isobserver(candidate))
var/mob/observer/dead/ghost = candidate
who = ghost
im_list += list(list("address" = origin_address, "to_address" = exonet.address, "im" = text))
else if(istype(candidate, /obj/item/device/communicator))
var/obj/item/device/communicator/comm = candidate
who = comm.owner
comm.im_contacts |= src
im_list += list(list("address" = origin_address, "to_address" = exonet.address, "im" = text))
else return
im_contacts |= candidate
if(!who)
return
if(ringer)
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1)
for (var/mob/O in hearers(2, loc))
O.show_message(text("\icon[src] *beep*"))
alert_called = 1
update_icon()
//Search for holder of the device.
var/mob/living/L = null
if(loc && isliving(loc))
L = loc
if(L)
to_chat(L, "<span class='notice'>\icon[src] Message from [who].</span>")
// Verb: text_communicator()
// Parameters: None
// Description: Allows a ghost to send a text message to a communicator.
/mob/observer/dead/verb/text_communicator()
set category = "Ghost"
set name = "Text Communicator"
set desc = "If there is a communicator available, send a text message to it."
if(ticker.current_state < GAME_STATE_PLAYING)
to_chat(src, "<span class='danger'>The game hasn't started yet!</span>")
return
if (!src.stat)
return
if (usr != src)
return //something is terribly wrong
for(var/mob/living/L in mob_list) //Simple check so you don't have dead people calling.
if(src.client.prefs.real_name == L.real_name)
to_chat(src, "<span class='danger'>Your identity is already present in the game world. Please load in a different character first.</span>")
return
var/obj/machinery/exonet_node/E = get_exonet_node()
if(!E || !E.on || !E.allow_external_communicators)
to_chat(src, "<span class='danger'>The Exonet node at telecommunications is down at the moment, or is actively blocking you, \
so your call can't go through.</span>")
return
var/list/choices = list()
for(var/obj/item/device/communicator/comm in all_communicators)
if(!comm.network_visibility || !comm.exonet || !comm.exonet.address)
continue
choices.Add(comm)
if(!choices.len)
to_chat(src, "<span class='danger'>There are no available communicators, sorry.</span>")
return
var/choice = input(src,"Send a text message to whom?") as null|anything in choices
if(choice)
var/obj/item/device/communicator/chosen_communicator = choice
var/mob/observer/dead/O = src
var/text_message = sanitize(input(src, "What do you want the message to say?")) as message
if(text_message && O.exonet)
O.exonet.send_message(chosen_communicator.exonet.address, "text", text_message)
to_chat(src, "<span class='notice'>You have sent '[text_message]' to [chosen_communicator].</span>")
exonet_messages.Add("<b>To [chosen_communicator]:</b><br>[text_message]")
log_pda("(DCOMM: [src]) sent \"[text_message]\" to [chosen_communicator]", src)
for(var/mob/M in player_list)
if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears))
if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat)
continue
if(M == src)
continue
M.show_message("Comm IM - [src] -> [chosen_communicator]: [text_message]")
// Verb: show_text_messages()
// Parameters: None
// Description: Lets ghosts review messages they've sent or received.
/mob/observer/dead/verb/show_text_messages()
set category = "Ghost"
set name = "Show Text Messages"
set desc = "Allows you to see exonet text messages you've sent and received."
var/HTML = "<html><head><title>Exonet Message Log</title></head><body>"
for(var/line in exonet_messages)
HTML += line + "<br>"
HTML +="</body></html>"
usr << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0")
// Proc: receive_exonet_message()
// Parameters: 4 (origin atom - the source of the message's holder, origin_address - where the message came from, message - the message received,
// text - message text to send if message is of type "text")
// Description: Handles voice requests and invite messages originating from both real communicators and ghosts. Also includes a ping response and IM function.
/obj/item/device/communicator/receive_exonet_message(var/atom/origin_atom, origin_address, message, text)
if(message == "voice")
if(isobserver(origin_atom) || istype(origin_atom, /obj/item/device/communicator))
if(origin_atom in voice_invites)
var/user = null
if(ismob(origin_atom.loc))
user = origin_atom.loc
open_connection(user, origin_atom)
return
else if(origin_atom in voice_requests)
return //Spam prevention
else
request(origin_atom)
if(message == "ping")
if(network_visibility)
var/random = rand(200,350)
random = random / 10
exonet.send_message(origin_address, "64 bytes received from [exonet.address] ecmp_seq=1 ttl=51 time=[random] ms")
if(message == "text")
request_im(origin_atom, origin_address, text)
return
// Proc: receive_exonet_message()
// Parameters: 3 (origin atom - the source of the message's holder, origin_address - where the message came from, message - the message received)
// Description: Handles voice requests and invite messages originating from both real communicators and ghosts. Also includes a ping response.
/mob/observer/dead/receive_exonet_message(origin_atom, origin_address, message, text)
if(message == "voice")
if(istype(origin_atom, /obj/item/device/communicator))
var/obj/item/device/communicator/comm = origin_atom
if(src in comm.voice_invites)
comm.open_connection(src)
return
to_chat(src, "<span class='notice'>\icon[origin_atom] Receiving communicator request from [origin_atom]. To answer, use the <b>Call Communicator</b> \
verb, and select that name to answer the call.</span>")
src << 'sound/machines/defib_SafetyOn.ogg'
comm.voice_invites |= src
if(message == "ping")
if(client && client.prefs.communicator_visibility)
var/random = rand(450,700)
random = random / 10
exonet.send_message(origin_address, "64 bytes received from [exonet.address] ecmp_seq=1 ttl=51 time=[random] ms")
if(message == "text")
to_chat(src, "<span class='notice'>\icon[origin_atom] Received text message from [origin_atom]: <b>\"[text]\"</b></span>")
src << 'sound/machines/defib_safetyOff.ogg'
exonet_messages.Add("<b>From [origin_atom]:</b><br>[text]")
return
// Proc: request_im()
// Parameters: 3 (candidate - the communicator wanting to message the device, origin_address - the address of the sender, text - the message)
// Description: Response to a communicator trying to message the device.
// Adds them to the list of people that have messaged this device and adds the message to the message list.
/obj/item/device/communicator/proc/request_im(var/atom/candidate, var/origin_address, var/text)
var/who = null
if(isobserver(candidate))
var/mob/observer/dead/ghost = candidate
who = ghost
im_list += list(list("address" = origin_address, "to_address" = exonet.address, "im" = text))
else if(istype(candidate, /obj/item/device/communicator))
var/obj/item/device/communicator/comm = candidate
who = comm.owner
comm.im_contacts |= src
im_list += list(list("address" = origin_address, "to_address" = exonet.address, "im" = text))
else if(istype(candidate, /obj/item/integrated_circuit))
var/obj/item/integrated_circuit/CIRC = candidate
who = CIRC
im_list += list(list("address" = origin_address, "to_address" = exonet.address, "im" = text))
else return
im_contacts |= candidate
if(!who)
return
if(ringer)
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1)
for (var/mob/O in hearers(2, loc))
O.show_message(text("\icon[src] *beep*"))
alert_called = 1
update_icon()
//Search for holder of the device.
var/mob/living/L = null
if(loc && isliving(loc))
L = loc
if(L)
to_chat(L, "<span class='notice'>\icon[src] Message from [who].</span>")
// Verb: text_communicator()
// Parameters: None
// Description: Allows a ghost to send a text message to a communicator.
/mob/observer/dead/verb/text_communicator()
set category = "Ghost"
set name = "Text Communicator"
set desc = "If there is a communicator available, send a text message to it."
if(ticker.current_state < GAME_STATE_PLAYING)
to_chat(src, "<span class='danger'>The game hasn't started yet!</span>")
return
if (!src.stat)
return
if (usr != src)
return //something is terribly wrong
for(var/mob/living/L in mob_list) //Simple check so you don't have dead people calling.
if(src.client.prefs.real_name == L.real_name)
to_chat(src, "<span class='danger'>Your identity is already present in the game world. Please load in a different character first.</span>")
return
var/obj/machinery/exonet_node/E = get_exonet_node()
if(!E || !E.on || !E.allow_external_communicators)
to_chat(src, "<span class='danger'>The Exonet node at telecommunications is down at the moment, or is actively blocking you, \
so your call can't go through.</span>")
return
var/list/choices = list()
for(var/obj/item/device/communicator/comm in all_communicators)
if(!comm.network_visibility || !comm.exonet || !comm.exonet.address)
continue
choices.Add(comm)
if(!choices.len)
to_chat(src, "<span class='danger'>There are no available communicators, sorry.</span>")
return
var/choice = input(src,"Send a text message to whom?") as null|anything in choices
if(choice)
var/obj/item/device/communicator/chosen_communicator = choice
var/mob/observer/dead/O = src
var/text_message = sanitize(input(src, "What do you want the message to say?")) as message
if(text_message && O.exonet)
O.exonet.send_message(chosen_communicator.exonet.address, "text", text_message)
to_chat(src, "<span class='notice'>You have sent '[text_message]' to [chosen_communicator].</span>")
exonet_messages.Add("<b>To [chosen_communicator]:</b><br>[text_message]")
log_pda("(DCOMM: [src]) sent \"[text_message]\" to [chosen_communicator]", src)
for(var/mob/M in player_list)
if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears))
if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat)
continue
if(M == src)
continue
M.show_message("Comm IM - [src] -> [chosen_communicator]: [text_message]")
// Verb: show_text_messages()
// Parameters: None
// Description: Lets ghosts review messages they've sent or received.
/mob/observer/dead/verb/show_text_messages()
set category = "Ghost"
set name = "Show Text Messages"
set desc = "Allows you to see exonet text messages you've sent and received."
var/HTML = "<html><head><title>Exonet Message Log</title></head><body>"
for(var/line in exonet_messages)
HTML += line + "<br>"
HTML +="</body></html>"
usr << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0")
@@ -54,6 +54,11 @@
var/failmsg = ""
var/charge = 0
// Eating used bulbs gives us bulb shards
var/bulb_shards = 0
// when we get this many shards, we get a free bulb.
var/shards_required = 4
/obj/item/device/lightreplacer/New()
failmsg = "The [name]'s refill light blinks red."
..()
@@ -76,18 +81,55 @@
to_chat(user, "<span class='warning'>You need one sheet of glass to replace lights.</span>")
if(istype(W, /obj/item/weapon/light))
var/new_bulbs = 0
var/obj/item/weapon/light/L = W
if(L.status == 0) // LIGHT OKAY
if(uses < max_uses)
if(!user.unEquip(W))
return
add_uses(1)
to_chat(user, "You insert \the [L.name] into \the [src.name]. You have [uses] light\s remaining.")
user.drop_item()
qdel(L)
return
else
to_chat(user, "You need a working light.")
if(!user.unEquip(W))
return
new_bulbs += AddShards(1)
qdel(L)
if(new_bulbs != 0)
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
to_chat(user, "You insert \the [L.name] into \the [src.name]. You have [uses] light\s remaining.")
return
if(istype(W, /obj/item/weapon/storage))
var/obj/item/weapon/storage/S = W
var/found_lightbulbs = FALSE
var/replaced_something = TRUE
for(var/obj/item/I in S.contents)
if(istype(I,/obj/item/weapon/light))
var/obj/item/weapon/light/L = I
found_lightbulbs = TRUE
if(src.uses >= max_uses)
break
if(L.status == LIGHT_OK)
replaced_something = TRUE
add_uses(1)
qdel(L)
else if(L.status == LIGHT_BROKEN || L.status == LIGHT_BURNED)
replaced_something = TRUE
AddShards(1)
qdel(L)
if(!found_lightbulbs)
to_chat(user, "<span class='warning'>\The [S] contains no bulbs.</span>")
return
if(!replaced_something && src.uses == max_uses)
to_chat(user, "<span class='warning'>\The [src] is full!</span>")
return
to_chat(user, "<span class='notice'>You fill \the [src] with lights from \the [S].</span>")
/obj/item/device/lightreplacer/attack_self(mob/user)
/* // This would probably be a bit OP. If you want it though, uncomment the code.
if(isrobot(user))
@@ -113,6 +155,15 @@
/obj/item/device/lightreplacer/proc/add_uses(var/amount = 1)
uses = min(max(uses + amount, 0), max_uses)
/obj/item/device/lightreplacer/proc/AddShards(amount = 1)
bulb_shards += amount
var/new_bulbs = round(bulb_shards / shards_required)
if(new_bulbs > 0)
add_uses(new_bulbs)
bulb_shards = bulb_shards % shards_required
return new_bulbs
/obj/item/device/lightreplacer/proc/Charge(var/mob/user, var/amount = 1)
charge += amount
if(charge > 6)
@@ -121,18 +172,41 @@
/obj/item/device/lightreplacer/proc/ReplaceLight(var/obj/machinery/light/target, var/mob/living/U)
if(target.status == LIGHT_OK)
if(target.status != LIGHT_OK)
if(CanUse(U))
if(!Use(U)) return
to_chat(U, "<span class='notice'>You replace the [target.get_fitting_name()] with the [src].</span>")
if(target.status != LIGHT_EMPTY)
var/new_bulbs = AddShards(1)
if(new_bulbs != 0)
to_chat(U, "<span class='notice'>\The [src] has fabricated a new bulb from the broken bulbs it has stored. It now has [uses] uses.</span>")
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
target.status = LIGHT_EMPTY
target.update()
var/obj/item/weapon/light/L2 = new target.light_type()
target.status = L2.status
target.switchcount = L2.switchcount
target.rigged = emagged
target.brightness_range = L2.brightness_range
target.brightness_power = L2.brightness_power
target.brightness_color = L2.brightness_color
target.on = target.has_power()
target.update()
qdel(L2)
if(target.on && target.rigged)
target.explode()
return
else
to_chat(U, failmsg)
return
else
to_chat(U, "There is a working [target.get_fitting_name()] already inserted.")
else if(!CanUse(U))
to_chat(U, failmsg)
else if(Use(U))
to_chat(U, "<span class='notice'>You replace the [target.get_fitting_name()] with the [src].</span>")
if(target.status != LIGHT_EMPTY)
target.remove_bulb()
var/obj/item/weapon/light/L = new target.light_type()
target.insert_bulb(L)
return
/obj/item/device/lightreplacer/emag_act(var/remaining_charges, var/mob/user)
emagged = !emagged
@@ -153,4 +227,4 @@
#undef LIGHT_OK
#undef LIGHT_EMPTY
#undef LIGHT_BROKEN
#undef LIGHT_BURNED
#undef LIGHT_BURNED
+2 -2
View File
@@ -51,10 +51,10 @@
return ..()
/obj/item/device/multitool/proc/mode_switch(mob/living/user)
if(++mode_index > modes.len) mode_index = 1
if(mode_index + 1 > modes.len) mode_index = 1
else
mode_index++
mode_index += 1
toolmode = modes[mode_index]
to_chat(user,"<span class='notice'>\The [src] is now set to [toolmode].</span>")
@@ -46,10 +46,10 @@
/obj/item/device/radio/headset/handle_message_mode(mob/living/M as mob, message, channel)
if (channel == "special")
if (translate_binary)
var/datum/language/binary = all_languages["Robot Talk"]
var/datum/language/binary = GLOB.all_languages["Robot Talk"]
binary.broadcast(M, message)
if (translate_hive)
var/datum/language/hivemind = all_languages["Hivemind"]
var/datum/language/hivemind = GLOB.all_languages["Hivemind"]
hivemind.broadcast(M, message)
return null
@@ -0,0 +1,66 @@
/obj/effect/falling_effect
name = "you should not see this"
desc = "no data"
invisibility = 101
anchored = TRUE
density = FALSE
unacidable = TRUE
var/falling_type = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita
var/crushing = TRUE
/obj/effect/falling_effect/Initialize(mapload, type = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita)
..()
falling_type = type
return INITIALIZE_HINT_LATELOAD
/obj/effect/falling_effect/LateInitialize()
new falling_type(src)
var/atom/movable/dropped = pick(contents) // Stupid, but allows to get spawn result without efforts if it is other type(Or if it was randomly generated).
dropped.loc = get_turf(src)
var/initial_x = dropped.pixel_x
var/initial_y = dropped.pixel_y
dropped.plane = 1
dropped.pixel_x = rand(-150, 150)
dropped.pixel_y = 500 // When you think that pixel_z is height but you are wrong
dropped.density = FALSE
dropped.opacity = FALSE
animate(dropped, pixel_y = initial_y, pixel_x = initial_x , time = 7)
spawn(7)
dropped.end_fall(crushing)
qdel(src)
/atom/movable/proc/end_fall(var/crushing = FALSE)
if(crushing)
for(var/atom/movable/AM in loc)
if(AM != src)
AM.ex_act(1)
for(var/mob/living/M in oviewers(3, src))
shake_camera(M, 2, 2)
playsound(loc, 'sound/effects/meteorimpact.ogg', 50, 1)
density = initial(density)
opacity = initial(opacity)
plane = initial(plane)
/obj/effect/falling_effect/singularity_act()
return
/obj/effect/falling_effect/singularity_pull()
return
/obj/effect/falling_effect/ex_act()
return
/obj/effect/falling_effect/pizza_delivery
name = "PIZZA PIE POWER!"
crushing = FALSE
/obj/effect/falling_effect/pizza_delivery/Initialize(mapload)
..()
falling_type = pick(prob(25);/obj/item/pizzabox/meat,
prob(25);/obj/item/pizzabox/margherita,
prob(25);/obj/item/pizzabox/vegetable,
prob(25);/obj/item/pizzabox/mushroom)
return INITIALIZE_HINT_LATELOAD
@@ -0,0 +1,61 @@
/obj/item/pizzavoucher
name = "free pizza voucher"
desc = "A pocket-sized plastic slip with a button in the middle. The writing on it seems to have faded."
icon = 'icons/obj/items.dmi'
icon_state = "pizza_voucher"
var/spent = FALSE
var/special_delivery = FALSE
w_class = ITEMSIZE_SMALL
/obj/item/pizzavoucher/New()
var/list/descstrings = list("24/7 PIZZA PIE HEAVEN",
"WE ALWAYS DELIVER!",
"24-HOUR PIZZA PIE POWER!",
"TOMATO SAUCE, CHEESE, WE'VE BOTH BOTH OF THESE!",
"COOKED WITH LOVE INSIDE A BIG OVEN!",
"WHEN YOU NEED A SLICE OF JOY IN YOUR LIFE!",
"WHEN YOU NEED A DISK OF OVEN BAKED BLISS!",
"EVERY TIME YOU DREAM OF CIRCULAR CUISINE!",
"WE ALWAYS DELIVER! WE ALWAYS DELIVER! WE ALWAYS DELIVER!")
desc = "A pocket-sized plastic slip with a button in the middle. \"[pick(descstrings)]\" is written on the back."
/obj/item/pizzavoucher/attack_self(mob/user)
add_fingerprint(user)
if(!spent)
user.visible_message("<span class='notice'>[user] presses a button on [src]!</span>")
desc = desc + " This one seems to be used-up."
spent = TRUE
if(special_delivery)
var/delivery = pick(prob(25);/obj/item/pizzabox/meat,
prob(25);/obj/item/pizzabox/margherita,
prob(25);/obj/item/pizzabox/vegetable,
prob(25);/obj/item/pizzabox/mushroom)
command_announcement.Announce("SPECIAL DELIVERY PIZZA ORDER #[rand(1000,9999)]-[rand(100,999)] HAS BEEN RECIEVED. SHIPMENT DISPATCHED VIA BALLISTIC SUPPLY POD FOR IMMEDIATE DELIVERY! THANK YOU AND ENJOY YOUR PIZZA!", "WE ALWAYS DELIVER!")
var/crash_x = user.x
var/crash_y = user.y
var/crash_z = user.z
spawn(rand(30, 75))
new /datum/random_map/droppod/pizza(null, crash_x, crash_y, crash_z, automated = TRUE, supplied_drop = delivery) // Splat.
else
user.visible_message("<span class='notice'>A small bluespace rift opens just above your head and spits out a pizza box!</span>")
new /obj/effect/falling_effect/pizza_delivery(user.loc)
else
to_chat(user, "<span class='warning'>The [src] is spent!</span>")
/obj/item/pizzavoucher/emag_act(var/remaining_charges, var/mob/user)
if(spent)
to_chat(user, "<span class='warning'>The [src] is spent!</span>")
return
if(!special_delivery)
to_chat(user, "<span class='warning'>You activate the special delivery protocol on the [src]!</span>")
special_delivery = TRUE
return 1
else
to_chat(user, "<span class='warning'>The [src] is already in special delivery mode!</span>")
/datum/random_map/droppod/pizza
placement_explosion_dev = 0
placement_explosion_heavy = 1
placement_explosion_light = 2
placement_explosion_flash = 4
+343
View File
@@ -0,0 +1,343 @@
#define PAINT_MODE -2
#define EATING_MODE -1
#define ATMOS_MODE 0
#define DISPOSALS_MODE 1
#define TRANSIT_MODE 2
/obj/item/weapon/pipe_dispenser
name = "Rapid Piping Device (RPD)"
desc = "A device used to rapidly pipe things."
icon = 'icons/obj/tools.dmi'
icon_state = "rpd"
flags = NOBLUDGEON
force = 10
throwforce = 10
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_NORMAL
matter = list(DEFAULT_WALL_MATERIAL = 50000, "glass" = 25000)
var/datum/effect/effect/system/spark_spread/spark_system
var/working = 0
var/mode = ATMOS_MODE
var/p_dir = NORTH
var/p_flipped = FALSE
var/paint_color="grey"
var/screen = ATMOS_MODE //Starts on the atmos tab.
var/piping_layer = PIPING_LAYER_DEFAULT
var/wrench_mode = FALSE
var/obj/item/weapon/tool/wrench/tool
var/datum/pipe_recipe/recipe
var/static/datum/pipe_recipe/first_atmos
var/static/datum/pipe_recipe/first_disposal
/obj/item/weapon/pipe_dispenser/New()
. = ..()
src.spark_system = new /datum/effect/effect/system/spark_spread
spark_system.set_up(5, 0, src)
spark_system.attach(src)
if(!first_atmos)
first_atmos = atmos_pipe_recipes[atmos_pipe_recipes[1]][1]
if(!first_disposal)
first_disposal = disposal_pipe_recipes[disposal_pipe_recipes[1]][1]
recipe = first_atmos
tool = new /obj/item/weapon/tool/wrench/cyborg(src) // RPDs have wrenches inside of them, so that they can wrench down spawned pipes without being used as superior wrenches themselves.
/obj/item/weapon/pipe_dispenser/Destroy()
qdel(spark_system)
spark_system = null
return ..()
/obj/item/weapon/pipe_dispenser/suicide_act(mob/user)
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
user.visible_message("<span class='suicide'>[user] points the end of the RPD down [TU.his] throat and presses a button! It looks like [TU.hes] trying to commit suicide...</span>")
playsound(get_turf(user), 'sound/machines/click.ogg', 50, 1)
playsound(get_turf(user), 'sound/items/deconstruct.ogg', 50, 1)
return(BRUTELOSS)
/obj/item/weapon/pipe_dispenser/attack_self(mob/user)
src.interact(user)
/obj/item/weapon/pipe_dispenser/interact(mob/user)
var/list/lines = list()
if(mode >= ATMOS_MODE)
lines += "<div class=\"block\"><h3>Direction:</h3><div class=\"item\">"
var/icon/preview = null
var/icon/previewm = null
if(recipe.icon && recipe.icon_state)
preview = new /icon(recipe.icon, recipe.icon_state)
if (recipe.icon_state_m)
previewm = new /icon(recipe.icon, recipe.icon_state_m)
switch(recipe.dirtype)
if(PIPE_STRAIGHT) // Straight, N-S, W-E
lines += render_dir_img(preview,user,NORTH,"Vertical","&#8597;")
lines += render_dir_img(preview,user,EAST,"Horizontal","&harr;")
if(PIPE_BENDABLE) // Bent, N-W, N-E etc
lines += render_dir_img(preview,user,NORTH,"Vertical","&#8597;")
lines += render_dir_img(preview,user,EAST,"Horizontal","&harr;")
lines += "<br />"
lines += render_dir_img(preview,user,NORTHWEST,"West to North","&#9565;")
lines += render_dir_img(preview,user,NORTHEAST,"North to East","&#9562;")
lines += "<br />"
lines += render_dir_img(preview,user,SOUTHWEST,"South to West","&#9559;")
lines += render_dir_img(preview,user,SOUTHEAST,"East to South","&#9556;")
if(PIPE_TRINARY) // Manifold
lines += render_dir_img(preview,user,NORTH,"West South East","&#9574;")
lines += render_dir_img(preview,user,EAST,"North West South","&#9571;")
lines += "<br />"
lines += render_dir_img(preview,user,SOUTH,"East North West","&#9577;")
lines += render_dir_img(preview,user,WEST,"South East North","&#9568;")
if(PIPE_TRIN_M) // Mirrored ones
//each mirror icon is 45 anticlockwise from it's real direction
lines += render_dir_img(preview,user,NORTH,"West South East","&#9574;")
lines += render_dir_img(preview,user,EAST,"North West South","&#9571;")
lines += "<br />"
lines += render_dir_img(preview,user,SOUTH,"East North West","&#9577;")
lines += render_dir_img(preview,user,WEST,"South East North","&#9568;")
lines += "<br />"
lines += render_dir_img(previewm,user,SOUTH,"West South East","&#9574;", 1)
lines += render_dir_img(previewm,user,EAST,"North West South","&#9571;", 1)
lines += "<br />"
lines += render_dir_img(previewm,user,NORTH,"East North West","&#9577;", 1)
lines += render_dir_img(previewm,user,WEST,"South East North","&#9568;", 1)
if(PIPE_DIRECTIONAL) // Stuff with four directions - includes pumps etc.
lines += render_dir_img(preview,user,NORTH,"North","&uarr;")
lines += render_dir_img(preview,user,EAST,"East","&rarr;")
lines += render_dir_img(preview,user,SOUTH,"South","&darr;")
lines += render_dir_img(preview,user,WEST,"West","&larr;")
if(PIPE_ONEDIR) // Single icon_state (eg 4-way manifolds)
lines += render_dir_img(preview,user,SOUTH,"Pipe","&#8597;")
lines += "</div></div>"
if(mode == ATMOS_MODE || mode == PAINT_MODE)
lines += "<div class=\"block\"><h3>Color:</h3>"
var/i = 0
for(var/c in pipe_colors)
++i
lines += "<a class='[paint_color == c? "linkOn" : ""]' href='?src=\ref[src];paint_color=[c]'>[c]</a>"
if(i == 4)
lines += "<br>"
i = 0
lines += "</div>"
lines += "<div class=\"block\"><h3>Utilities:</h3>"
lines += "<a class='[mode >= ATMOS_MODE ? "linkOn" : ""]' href='?src=\ref[src];mode=[screen]'>Lay Pipes</a>"
lines += "<a class='[mode == EATING_MODE ? "linkOn" : ""]' href='?src=\ref[src];mode=[EATING_MODE]'>Eat Pipes</a>"
lines += "<a class='[mode == PAINT_MODE ? "linkOn" : ""]' href='?src=\ref[src];mode=[PAINT_MODE]'>Paint Pipes</a>"
lines += "</div>"
lines += "<div class=\"block\"><h3>Catagory:</h3>"
lines += "<a class='[screen == ATMOS_MODE ? "linkOn" : ""]' href='?src=\ref[src];screen=[ATMOS_MODE]'>Atmospherics</a>"
lines += "<a class='[screen == DISPOSALS_MODE ? "linkOn" : ""]' href='?src=\ref[src];screen=[DISPOSALS_MODE]'>Disposals</a>"
//lines += "<a class='[screen == TRANSIT_MODE ? "linkOn" : ""]' href='?src=\ref[src];screen=[TRANSIT_MODE]'>Transit Tube</a>"
lines += "<br><a class='[wrench_mode ? "linkOn" : ""]' href='?src=\ref[src];switch_wrench=1;wrench_mode=[!wrench_mode]'>Wrench Mode</a>"
lines += "</div>"
if(screen == ATMOS_MODE)
for(var/category in atmos_pipe_recipes)
lines += "<div class=\"block\"><h3>[category]:</h3>"
if(category == "Pipes")
lines += "<div class=\"item\">"
lines += "<a class='[piping_layer == PIPING_LAYER_REGULAR ? "linkOn" : "linkOff"]' href='?src=\ref[src];piping_layer=[PIPING_LAYER_REGULAR]'>Regular</a> "
lines += "<a class='[piping_layer == PIPING_LAYER_SUPPLY ? "linkOn" : "linkOff"]' href='?src=\ref[src];piping_layer=[PIPING_LAYER_SUPPLY]'>Supply</a> "
lines += "<a class='[piping_layer == PIPING_LAYER_SCRUBBER ? "linkOn" : "linkOff"]' href='?src=\ref[src];piping_layer=[PIPING_LAYER_SCRUBBER]'>Scrubber</a> "
lines += "</div>"
for(var/i in 1 to atmos_pipe_recipes[category].len)
var/datum/pipe_recipe/PI = atmos_pipe_recipes[category][i]
lines += "<div class=\"item\">"
lines += "<a class='[recipe == PI ? "linkOn" : ""]' href='?src=\ref[src]&category=[category]&pipe_type=[i]'>[PI.name]</a>"
lines += "</div>"
lines += "</div>"
else if(screen == DISPOSALS_MODE)
for(var/category in disposal_pipe_recipes)
lines += "<div class=\"block\"><h3>[category]:</h3>"
for(var/i in 1 to disposal_pipe_recipes[category].len)
var/datum/pipe_recipe/PI = disposal_pipe_recipes[category][i]
lines += "<div class=\"item\">"
lines += "<a class='[recipe == PI ? "linkOn" : ""]' href='?src=\ref[src]&category=[category]&pipe_type=[i]'>[PI.name]</a>"
lines += "</div>"
lines += "</div>"
var/dat = lines.Join()
var/datum/browser/popup = new(user, "rpd", name, 300, 800, src)
popup.set_content("<TT>[dat]</TT>")
popup.open()
/obj/item/weapon/pipe_dispenser/Topic(href,href_list)
if(..())
return
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
return
var/playeffect = TRUE // Do we spark the device
var/anyclicked = FALSE // Tells us if we need to refresh the window.
if(href_list["paint_color"])
paint_color = href_list["paint_color"]
playeffect = FALSE
anyclicked = TRUE
if(href_list["mode"])
mode = text2num(href_list["mode"])
anyclicked = TRUE
if(href_list["screen"])
if(mode == screen)
mode = text2num(href_list["screen"])
screen = text2num(href_list["screen"])
switch(screen)
if(DISPOSALS_MODE)
recipe = first_disposal
if(ATMOS_MODE)
recipe = first_atmos
p_dir = NORTH
playeffect = FALSE
anyclicked = TRUE
if(href_list["piping_layer"])
piping_layer = text2num(href_list["piping_layer"])
playeffect = FALSE
anyclicked = TRUE
if(href_list["pipe_type"])
recipe = all_pipe_recipes[href_list["category"]][text2num(href_list["pipe_type"])]
if(recipe.dirtype == PIPE_ONEDIR) // One hell of a hack for the fact that the image previews for the onedir types only show on the south, but the default pipe type is north.
p_dir = SOUTH // Did I fuck this up? Maybe. Or maybe it's just the icon files not being ready for an RPD.
else // If going to try and fix this hack, be aware the pipe dispensers might rely on pipes defaulting south instead of north.
p_dir = NORTH
p_flipped = FALSE
anyclicked = TRUE
if(href_list["dir"])
p_dir = text2dir(href_list["dir"])
p_flipped = text2num(href_list["flipped"])
playeffect = FALSE
anyclicked = TRUE
if(href_list["switch_wrench"])
wrench_mode = text2num(href_list["wrench_mode"])
anyclicked = TRUE
if(anyclicked)
if(playeffect)
spark_system.start()
playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
src.interact(usr)
/obj/item/weapon/pipe_dispenser/afterattack(atom/A, mob/user as mob, proximity)
if(!user.IsAdvancedToolUser() || istype(A, /turf/space/transit) || !proximity)
return ..()
//So that changing the menu settings doesn't affect the pipes already being built.
var/queued_piping_layer = piping_layer
var/queued_p_type = recipe.pipe_type
var/queued_p_dir = p_dir
var/queued_p_flipped = p_flipped
var/queued_p_subtype = recipe.subtype
var/queued_p_paintable = recipe.paintable
//make sure what we're clicking is valid for the current mode
var/static/list/make_pipe_whitelist // This should probably be changed to be in line with polaris standards. Oh well.
if(!make_pipe_whitelist)
make_pipe_whitelist = typecacheof(list(/obj/structure/lattice, /obj/structure/girder, /obj/item/pipe))
var/can_make_pipe = (isturf(A) || is_type_in_typecache(A, make_pipe_whitelist))
. = FALSE
switch(mode) //if we've gotten this var, the target is valid
if(PAINT_MODE) //Paint pipes
if(!istype(A, /obj/machinery/atmospherics/pipe))
return ..()
var/obj/machinery/atmospherics/pipe/P = A
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
P.change_color(pipe_colors[paint_color])
user.visible_message("<span class='notice'>[user] paints \the [P] [paint_color].</span>","<span class='notice'>You paint \the [P] [paint_color].</span>")
return
if(EATING_MODE) //Eating pipes
if(!(istype(A, /obj/item/pipe) || istype(A, /obj/item/pipe_meter) || istype(A, /obj/structure/disposalconstruct)))
return ..()
to_chat(user, "<span class='notice'>You start destroying a pipe...</span>")
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 2, target = A))
activate()
qdel(A)
if(ATMOS_MODE) //Making pipes
if(!can_make_pipe)
return ..()
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
if (istype(recipe, /datum/pipe_recipe/meter))
to_chat(user, "<span class='notice'>You start building a meter...</span>")
if(do_after(user, 2, target = A))
activate()
var/obj/item/pipe_meter/PM = new /obj/item/pipe_meter(get_turf(A))
PM.setAttachLayer(queued_piping_layer)
if(wrench_mode)
do_wrench(PM, user)
else
to_chat(user, "<span class='notice'>You start building a pipe...</span>")
if(do_after(user, 2, target = A))
activate()
var/obj/machinery/atmospherics/path = queued_p_type
var/pipe_item_type = initial(path.construction_type) || /obj/item/pipe
var/obj/item/pipe/P = new pipe_item_type(get_turf(A), queued_p_type, queued_p_dir)
P.update()
P.add_fingerprint(usr)
P.setPipingLayer(queued_piping_layer)
if (queued_p_paintable)
P.color = pipe_colors[paint_color]
if(queued_p_flipped)
P.do_a_flip()
if(wrench_mode)
do_wrench(P, user)
if(DISPOSALS_MODE) //Making disposals pipes
if(!can_make_pipe)
return ..()
A = get_turf(A)
if(istype(A, /turf/unsimulated))
to_chat(user, "<span class='warning'>[src]'s error light flickers; there's something in the way!</span>")
return
to_chat(user, "<span class='notice'>You start building a disposals pipe...</span>")
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 4, target = A))
var/obj/structure/disposalconstruct/C = new(A, queued_p_type, queued_p_dir, queued_p_flipped, queued_p_subtype)
if(!C.can_place())
to_chat(user, "<span class='warning'>There's not enough room to build that here!</span>")
qdel(C)
return
activate()
C.add_fingerprint(usr)
C.update_icon()
if(wrench_mode)
do_wrench(C, user)
return
else
return ..()
/obj/item/weapon/pipe_dispenser/proc/activate()
playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1)
/obj/item/weapon/pipe_dispenser/proc/do_wrench(var/atom/target, mob/user)
var/resolved = target.attackby(tool,user)
if(!resolved && tool && target)
tool.afterattack(target,user,1)
/obj/item/weapon/pipe_dispenser/proc/render_dir_img(preview,user,_dir,title,noimg,flipped=0)
var/dirtext = dir2text(_dir)
var/selected = " style=\"height:34px;width:34px;display:inline-block\""
if(_dir == p_dir && flipped == p_flipped)
selected += " class=\"linkOn\""
if(preview)
user << browse_rsc(new /icon(preview, dir=_dir), "[dirtext][flipped ? "m" : ""].png")
return "<a href=\"?src=\ref[src];dir=[dirtext];flipped=[flipped]\" title=\"[title]\"[selected]\"><img src=\"[dirtext][flipped ? "m" : ""].png\" /></a>"
else
return "<a href=\"?src=\ref[src];dir=[dirtext];flipped=[flipped]\" title=\"[title]\"[selected]\">[noimg]</a>"
#undef PAINT_MODE
#undef EATING_MODE
#undef ATMOS_MODE
#undef DISPOSALS_MODE
+18 -11
View File
@@ -64,25 +64,29 @@ RSF
/obj/item/weapon/rsf/attack_self(mob/user as mob)
playsound(src.loc, 'sound/effects/pop.ogg', 50, 0)
if (mode == 1)
if(mode == 1)
mode = 2
to_chat(user,"<span class='notice'>Changed dispensing mode to 'Container'.</span>")
return
if (mode == 2)
if(mode == 2)
mode = 3
to_chat(user,"<span class='notice'>Changed dispensing mode to 'Paper'</span>")
to_chat(user,"Changed dispensing mode to 'Metamorphic Glass: Pint'") //YW Changes begin
return
if (mode == 3)
if(mode == 3)
mode = 4
to_chat(user,"<span class='notice'>Changed dispensing mode to 'Pen'</span>")
to_chat(user,"Changed dispensing mode to 'Paper'")
return
if (mode == 4)
if(mode == 4)
mode = 5
to_chat(user,"<span class='notice'>Changed dispensing mode to 'Dice Pack'</span>")
to_chat(user,"Changed dispensing mode to 'Pen'")
return
if (mode == 5)
if(mode == 5)
mode = 6
to_chat(user,"Changed dispensing mode to 'Dice Pack'")
return
if(mode == 6)
mode = 1
to_chat(user,"<span class='notice'>Changed dispensing mode to 'Cigarette'</span>")
to_chat(user,"Changed dispensing mode to 'Cigarette'") // YW Changes end
return
/obj/item/weapon/rsf/afterattack(atom/A, mob/user as mob, proximity)
@@ -112,12 +116,15 @@ RSF
product = new glasstype()
used_energy = 50
if(3)
product = new /obj/item/weapon/reagent_containers/food/drinks/metaglass() //YW Changes begin
used_energy = 50
if(4)
product = new /obj/item/weapon/paper()
used_energy = 10
if(4)
if(5)
product = new /obj/item/weapon/pen()
used_energy = 50
if(5)
if(6) //YW Changes end
product = new /obj/item/weapon/storage/pill_bottle/dice()
used_energy = 200
@@ -87,10 +87,10 @@ obj/item/weapon/circuitboard/rdserver/attackby(obj/item/I as obj, mob/user as mo
/obj/item/weapon/stock_parts/micro_laser = 1,
/obj/item/weapon/stock_parts/console_screen = 1)
obj/item/weapon/circuitboard/ntnet_relay
/obj/item/weapon/circuitboard/ntnet_relay
name = "Circuit board (NTNet Quantum Relay)"
build_path = "/obj/machinery/ntnet_relay"
board_type = "machine"
build_path = /obj/machinery/ntnet_relay
board_type = new /datum/frame/frame_types/machine
origin_tech = list(TECH_DATA = 4)
req_components = list(
"/obj/item/stack/cable_coil" = 15)
/obj/item/stack/cable_coil = 15)
@@ -23,8 +23,6 @@
var/primary_color = rgb(0,0,0) // Obtained by eyedroppering the stripe in the middle of the card
var/secondary_color = rgb(0,0,0) // Likewise for the oval in the top-left corner
var/datum/job/job_access_type = /datum/job/assistant // Job type to acquire access rights from, if any
//alt titles are handled a bit weirdly in order to unobtrusively integrate into existing ID system
var/assignment = null //can be alt title or the actual job
var/rank = null //actual job
@@ -134,16 +132,6 @@
icon_state = "silver"
item_state = "silver_id"
/obj/item/weapon/card/id/silver/secretary
assignment = "Command Secretary"
rank = "Command Secretary"
job_access_type = /datum/job/secretary
/obj/item/weapon/card/id/silver/hop
assignment = "Head of Personnel"
rank = "Head of Personnel"
job_access_type = /datum/job/hop
/obj/item/weapon/card/id/gold
name = "identification card"
desc = "A golden card which shows power and might."
@@ -154,14 +142,11 @@
/obj/item/weapon/card/id/gold/captain
assignment = "Colony Director"
rank = "Colony Director"
job_access_type = /datum/job/captain
preserve_item = 0
/obj/item/weapon/card/id/gold/captain/spare
name = "\improper Colony Director's spare ID"
desc = "The spare ID of the High Lord himself."
registered_name = "Colony Director"
job_access_type = /datum/job/captain
/obj/item/weapon/card/id/synthetic
name = "\improper Synthetic ID"
@@ -206,31 +191,6 @@
primary_color = rgb(189,237,237)
secondary_color = rgb(223,255,255)
/obj/item/weapon/card/id/medical/doctor
assignment = "Medical Doctor"
rank = "Medical Doctor"
job_access_type = /datum/job/doctor
/obj/item/weapon/card/id/medical/chemist
assignment = "Chemist"
rank = "Chemist"
job_access_type = /datum/job/chemist
/obj/item/weapon/card/id/medical/geneticist
assignment = "Geneticist"
rank = "Geneticist"
job_access_type = /datum/job/doctor //geneticist
/obj/item/weapon/card/id/medical/psychiatrist
assignment = "Psychiatrist"
rank = "Psychiatrist"
job_access_type = /datum/job/psychiatrist
/obj/item/weapon/card/id/medical/paramedic
assignment = "Paramedic"
rank = "Paramedic"
job_access_type = /datum/job/paramedic
/obj/item/weapon/card/id/medical/head
name = "identification card"
desc = "A card which represents care and compassion."
@@ -239,7 +199,6 @@
secondary_color = rgb(255,223,127)
assignment = "Chief Medical Officer"
rank = "Chief Medical Officer"
job_access_type = /datum/job/cmo
/obj/item/weapon/card/id/security
name = "identification card"
@@ -248,21 +207,6 @@
primary_color = rgb(189,47,0)
secondary_color = rgb(223,127,95)
/obj/item/weapon/card/id/security/officer
assignment = "Security Officer"
rank = "Security Officer"
job_access_type = /datum/job/officer
/obj/item/weapon/card/id/security/detective
assignment = "Detective"
rank = "Detective"
job_access_type = /datum/job/detective
/obj/item/weapon/card/id/security/warden
assignment = "Warden"
rank = "Warden"
job_access_type = /datum/job/warden
/obj/item/weapon/card/id/security/head
name = "identification card"
desc = "A card which represents honor and protection."
@@ -271,7 +215,6 @@
secondary_color = rgb(255,223,127)
assignment = "Head of Security"
rank = "Head of Security"
job_access_type = /datum/job/hos
/obj/item/weapon/card/id/engineering
name = "identification card"
@@ -280,16 +223,6 @@
primary_color = rgb(189,94,0)
secondary_color = rgb(223,159,95)
/obj/item/weapon/card/id/engineering/engineer
assignment = "Station Engineer"
rank = "Station Engineer"
job_access_type = /datum/job/engineer
/obj/item/weapon/card/id/engineering/atmos
assignment = "Atmospheric Technician"
rank = "Atmospheric Technician"
job_access_type = /datum/job/atmos
/obj/item/weapon/card/id/engineering/head
name = "identification card"
desc = "A card which represents creativity and ingenuity."
@@ -298,7 +231,6 @@
secondary_color = rgb(255,223,127)
assignment = "Chief Engineer"
rank = "Chief Engineer"
job_access_type = /datum/job/chief_engineer
/obj/item/weapon/card/id/science
name = "identification card"
@@ -307,21 +239,6 @@
primary_color = rgb(142,47,142)
secondary_color = rgb(191,127,191)
/obj/item/weapon/card/id/science/scientist
assignment = "Scientist"
rank = "Scientist"
job_access_type = /datum/job/scientist
/obj/item/weapon/card/id/science/xenobiologist
assignment = "Xenobiologist"
rank = "Xenobiologist"
job_access_type = /datum/job/xenobiologist
/obj/item/weapon/card/id/science/roboticist
assignment = "Roboticist"
rank = "Roboticist"
job_access_type = /datum/job/roboticist
/obj/item/weapon/card/id/science/head
name = "identification card"
desc = "A card which represents knowledge and reasoning."
@@ -330,7 +247,6 @@
secondary_color = rgb(255,223,127)
assignment = "Research Director"
rank = "Research Director"
job_access_type = /datum/job/rd
/obj/item/weapon/card/id/cargo
name = "identification card"
@@ -339,16 +255,6 @@
primary_color = rgb(142,94,0)
secondary_color = rgb(191,159,95)
/obj/item/weapon/card/id/cargo/cargo_tech
assignment = "Cargo Technician"
rank = "Cargo Technician"
job_access_type = /datum/job/cargo_tech
/obj/item/weapon/card/id/cargo/mining
assignment = "Shaft Miner"
rank = "Shaft Miner"
job_access_type = /datum/job/mining
/obj/item/weapon/card/id/cargo/head
name = "identification card"
desc = "A card which represents service and planning."
@@ -357,12 +263,10 @@
secondary_color = rgb(255,223,127)
assignment = "Quartermaster"
rank = "Quartermaster"
job_access_type = /datum/job/qm
/obj/item/weapon/card/id/assistant
assignment = USELESS_JOB //VOREStation Edit - Visitor not Assistant
rank = USELESS_JOB //VOREStation Edit - Visitor not Assistant
job_access_type = /datum/job/assistant
/obj/item/weapon/card/id/civilian
name = "identification card"
@@ -372,42 +276,6 @@
secondary_color = rgb(95,159,191)
assignment = "Civilian"
rank = "Assistant"
job_access_type = /datum/job/assistant
/obj/item/weapon/card/id/civilian/bartender
assignment = "Bartender"
rank = "Bartender"
job_access_type = /datum/job/bartender
/obj/item/weapon/card/id/civilian/botanist
assignment = "Botanist"
rank = "Botanist"
job_access_type = /datum/job/hydro
/obj/item/weapon/card/id/civilian/chaplain
assignment = "Chaplain"
rank = "Chaplain"
job_access_type = /datum/job/chaplain
/obj/item/weapon/card/id/civilian/chef
assignment = "Chef"
rank = "Chef"
job_access_type = /datum/job/chef
/obj/item/weapon/card/id/civilian/internal_affairs_agent
assignment = "Internal Affairs Agent"
rank = "Internal Affairs Agent"
job_access_type = /datum/job/lawyer
/obj/item/weapon/card/id/civilian/janitor
assignment = "Janitor"
rank = "Janitor"
job_access_type = /datum/job/janitor
/obj/item/weapon/card/id/civilian/librarian
assignment = "Librarian"
rank = "Librarian"
job_access_type = /datum/job/librarian
/obj/item/weapon/card/id/civilian/head //This is not the HoP. There's no position that uses this right now.
name = "identification card"
@@ -84,6 +84,11 @@ obj/item/weapon/chainsaw/afterattack(atom/A as mob|obj|turf|area, mob/user as mo
else if(istype(A,/obj/effect/plant))
var/obj/effect/plant/P = A
qdel(P) //Plant isn't surviving that. At all
else if(istype(A,/obj/machinery/portable_atmospherics/hydroponics))
var/obj/machinery/portable_atmospherics/hydroponics/Hyd = A
if(Hyd.seed && !Hyd.dead)
to_chat(user, "<span class='notice'>You shred the plant.</span>")
Hyd.die()
if (istype(A, /obj/structure/reagent_dispensers/fueltank) && get_dist(src,A) <= 1)
to_chat(user, "<span class='notice'>You begin filling the tank on the chainsaw.</span>")
if(do_after(usr, 15))
@@ -157,3 +157,18 @@
fragile = 1 //It's a haphazard thing of glass, wire, and steel
reach = 2 // Spears are long.
attackspeed = 14
//This is mostly for centaurs.
/obj/item/weapon/material/twohanded/spear/lance
name = "lance"
desc = "End him rightly"
icon = 'icons/obj/weapons_vr.dmi'
icon_state = "lance"
item_state = "lance"
force_divisor = 0.3
force = 10
thrown_force_divisor = 1
default_material = "DEFAULT_WALL_MATERIAL"
fragile = 0
sharp = 1
edge = 0
+1 -1
View File
@@ -27,7 +27,7 @@ var/global/list/cached_icons = list()
return ..()
New()
if(paint_type && lentext(paint_type) > 0)
if(paint_type && length(paint_type) > 0)
name = paint_type + " " + name
..()
reagents.add_reagent("water", volume*3/5)
@@ -326,6 +326,13 @@
icon_state = "donk_kit"
starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/donkpocket/sinpocket = 7)
/obj/item/weapon/storage/box/buns
name = "box of bread buns"
desc = "Freshly baked at some point in the past few months."
icon_state = "bun_box"
max_storage_space = ITEMSIZE_COST_NORMAL * 5
starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/bun = 12)
/obj/item/weapon/storage/box/monkeycubes
name = "monkey cube box"
desc = "Drymate brand monkey cubes. Just add water!"
@@ -346,7 +353,7 @@
/obj/item/weapon/storage/box/monkeycubes/neaeracubes
name = "neaera cube box"
desc = "Drymate brand neaera cubes, shipped from Jargon 4. Just add water!"
desc = "Drymate brand neaera cubes, shipped from Qerr'balak. Just add water!"
starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/neaeracube = 4)
/obj/item/weapon/storage/box/ids
@@ -401,7 +408,7 @@
W.lit = 1
W.damtype = "burn"
W.icon_state = "match_lit"
START_PROCESSING(SSobj, W)
START_PROCESSING(SSobj, W)
W.update_icon()
return
@@ -79,6 +79,14 @@
desc = "Miniature medical robots that swiftly restore bodily damage."
starts_with = list(/obj/item/weapon/reagent_containers/pill/healing_nanites = 7)
/obj/item/weapon/storage/pill_bottle/sleevingcure
name = "pill bottle (Vey-Med Resleeving Booster)"
desc = "A rare medication sold by Vey-Med that helps counteract negative side effects of using resleeving machinery." //Bye, KHI! Get lost.
starts_with = list(/obj/item/weapon/reagent_containers/pill/sleevingcure = 7)
/obj/item/weapon/storage/pill_bottle/sleevingcure/full
starts_with = list(/obj/item/weapon/reagent_containers/pill/sleevingcure = 14)
/obj/item/weapon/storage/firstaid/insiderepair
name = "combat organ kit"
desc = "Contains advanced organ medical treatments."
@@ -95,3 +103,15 @@
/obj/item/weapon/storage/pill_bottle/arithrazine,
/obj/item/device/healthanalyzer/advanced
)
/obj/item/weapon/storage/mrebag/pill
name = "vacuum-sealed pill"
desc = "A small vacuum-sealed package containing a singular pill. For emergencies only."
icon_state = "pouch_small"
max_w_class = ITEMSIZE_TINY
can_hold = list(/obj/item/weapon/reagent_containers/pill)
/obj/item/weapon/storage/mrebag/pill/sleevingcure
name = "vacuum-sealed pill (Vey-Med Resleeving Booster)"
desc = "A small vacuum-sealed package containing a singular pill. For emergencies only."
starts_with = list(/obj/item/weapon/reagent_containers/pill/sleevingcure)
@@ -502,7 +502,7 @@ var/list/global/tank_gauge_cache = list()
var/release_ratio = 0.002
if(tank_pressure)
release_ratio = CLAMP(0.002, sqrt(max(tank_pressure-env_pressure,0)/tank_pressure),1)
release_ratio = CLAMP(sqrt(max(tank_pressure-env_pressure,0)/tank_pressure), 0.002, 1)
var/datum/gas_mixture/leaked_gas = air_contents.remove_ratio(release_ratio)
//dynamic air release based on ambient pressure
+2 -2
View File
@@ -106,7 +106,7 @@
/obj/effect/energy_net/New()
..()
START_PROCESSING(SSobj, src)
START_PROCESSING(SSobj, src)
/obj/effect/energy_net/Destroy()
if(has_buckled_mobs())
@@ -136,7 +136,7 @@
/obj/effect/energy_net/user_unbuckle_mob(mob/living/buckled_mob, mob/user)
user.setClickCooldown(user.get_attack_speed())
visible_message("<span class='danger'>[user] begins to tear at \the [src]!</span>")
if(do_after(usr, escape_time, src, incapacitation_flags = INCAPACITATION_DEFAULT & ~(INCAPACITATION_RESTRAINED | INCAPACITATION_BUCKLED_FULLY)))
if(do_after(user, escape_time, src, incapacitation_flags = INCAPACITATION_DEFAULT & ~(INCAPACITATION_RESTRAINED | INCAPACITATION_BUCKLED_FULLY)))
if(!has_buckled_mobs())
return
visible_message("<span class='danger'>[user] manages to tear \the [src] apart!</span>")
+2 -1
View File
@@ -106,7 +106,8 @@ something, make sure it's not in one of the other lists.*/
prob(1);/obj/item/weapon/card/emag_broken,
prob(2);/obj/item/device/camera,
prob(3);/obj/item/device/pda,
prob(3);/obj/item/device/radio/headset)
prob(3);/obj/item/device/radio/headset,
prob(1);/obj/item/pizzavoucher)
/obj/random/maintenance/security
/*Maintenance loot list. This one is for around security areas*/
@@ -33,7 +33,8 @@
/obj/item/clothing/suit/storage/hooded/wintercoat/engineering,
/obj/item/clothing/shoes/boots/winter/engineering,
/obj/item/weapon/tank/emergency/oxygen/engi,
/obj/item/weapon/reagent_containers/spray/windowsealant) //VOREStation Add
/obj/item/weapon/reagent_containers/spray/windowsealant, //VOREStation Add,
/obj/item/weapon/pipe_dispenser) //YW Add
/obj/structure/closet/secure_closet/engineering_chief/Initialize()
if(prob(50))
@@ -138,7 +139,8 @@
/obj/item/taperoll/atmos,
/obj/item/clothing/suit/storage/hooded/wintercoat/engineering/atmos,
/obj/item/clothing/shoes/boots/winter/atmos,
/obj/item/weapon/tank/emergency/oxygen/engi)
/obj/item/weapon/tank/emergency/oxygen/engi,
/obj/item/weapon/pipe_dispenser) //YW Addition
/obj/structure/closet/secure_closet/atmos_personal/Initialize()
if(prob(50))
@@ -14,7 +14,7 @@
/obj/structure/closet/secure_closet/freezer/kitchen
name = "kitchen cabinet"
req_access = list(access_kitchen)
req_access = list()
starts_with = list(
/obj/item/weapon/reagent_containers/food/condiment/flour = 7,
@@ -28,3 +28,23 @@
else
starts_with += /obj/item/clothing/suit/storage/apron/overalls
return ..()
/obj/structure/closet/secure_closet/hydroponics/sci
name = "xenoflorist's locker"
req_access = list(access_xenobiology)
icon_state = "scihydrosecure1"
icon_closed = "scihydrosecure"
icon_locked = "scihydrosecure1"
icon_opened = "scihydrosecureopen"
icon_broken = "scihydrosecurebroken"
icon_off = "scihydrosecureoff"
/obj/structure/closet/secure_closet/hydroponics/sci/Initialize()
starts_with += /obj/item/clothing/head/bio_hood/scientist
starts_with += /obj/item/clothing/suit/bio_suit/scientist
starts_with += /obj/item/clothing/mask/gas // VOREStation Edit: Gasmasks we use are different
if(prob(1))
starts_with += /obj/item/weapon/chainsaw
return ..()
@@ -49,6 +49,10 @@
if(alert(user, "Are you sure you want to touch \the [src]?", "Confirm", "No", "Yes") == "No")
return
trigger()
// VOREStation Addition Start
if(!used)
activated = TRUE
// VOREStation Addition End
/obj/structure/ghost_pod/manual/attack_ai(var/mob/living/silicon/user)
if(Adjacent(user))
@@ -0,0 +1,31 @@
/obj/structure/ghost_pod/manual
var/remains_active = FALSE
var/activated = FALSE
/obj/structure/ghost_pod/manual/attack_ghost(var/mob/observer/dead/user)
if(!remains_active || busy)
return
if(!activated)
to_chat(user, "<span class='warning'>\the [src] has not yet been activated. Sorry.</span>")
return
if(used)
to_chat(user, "<span class='warning'>Another spirit appears to have gotten to \the [src] before you. Sorry.</span>")
return
busy = TRUE
var/choice = input(user, "Are you certain you wish to activate this pod?", "Control Pod") as null|anything in list("Yes", "No")
if(!choice || choice == "No")
busy = FALSE
return
else if(used)
to_chat(user, "<span class='warning'>Another spirit appears to have gotten to \the [src] before you. Sorry.</span>")
busy = FALSE
return
busy = FALSE
create_occupant(user)
@@ -1,7 +1,8 @@
/obj/structure/ghost_pod/manual/lost_drone/dogborg
remains_active = TRUE
/obj/structure/ghost_pod/manual/lost_drone/dogborg/create_occupant(var/mob/M)
var/response = alert(M, "What type of lost drone are you? Do note, that dogborgs may have experienced different type of corruption ((Potential for having vore-related laws))", "Drone Type", "Regular", "Dogborg")
var/response = alert(M, "What type of lost drone are you? Do note, that dogborgs may have experienced different type of corruption ((High potential for having vore-related laws))", "Drone Type", "Regular", "Dogborg")
if(!(response == "Dogborg")) // No response somehow or Regular
return ..()
else
+1 -1
View File
@@ -680,7 +680,7 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
)
uncommon_loot = list(
/obj/item/mecha_parts/mecha_equipment/tool/safety_clamp,
/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp/safety,
/obj/item/mecha_parts/mecha_equipment/weapon/energy/riggedlaser,
/obj/item/mecha_parts/mecha_equipment/repair_droid,
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay
+1 -1
View File
@@ -134,7 +134,7 @@
spawn(1)
var/newname = sanitizeSafe(input(vox,"Enter a name, or leave blank for the default name.", "Name change","") as text, MAX_NAME_LEN)
if(!newname || newname == "")
var/datum/language/L = all_languages[vox.species.default_language]
var/datum/language/L = GLOB.all_languages[vox.species.default_language]
newname = L.get_random_name()
vox.real_name = newname
vox.name = vox.real_name
+7 -7
View File
@@ -115,12 +115,12 @@
if(!playing || shouldStopPlaying(user))//If the instrument is playing, or special case
playing = 0
return
if(lentext(note) == 0)
if(length(note) == 0)
continue
var/cur_note = text2ascii(note) - 96
if(cur_note < 1 || cur_note > 7)
continue
for(var/i=2 to lentext(note))
for(var/i=2 to length(note))
var/ni = copytext(note,i,i+1)
if(!text2num(ni))
if(ni == "#" || ni == "b" || ni == "n")
@@ -208,11 +208,11 @@
t = html_encode(input(usr, "Please paste the entire song, formatted:", text("[]", name), t) as message)
if(!in_range(instrumentObj, usr))
return
if(lentext(t) >= INSTRUMENT_MAX_LINE_LENGTH*INSTRUMENT_MAX_LINE_NUMBER)
if(length(t) >= INSTRUMENT_MAX_LINE_LENGTH*INSTRUMENT_MAX_LINE_NUMBER)
var/cont = input(usr, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no")
if(cont == "no")
break
while(lentext(t) > INSTRUMENT_MAX_LINE_LENGTH*INSTRUMENT_MAX_LINE_NUMBER)
while(length(t) > INSTRUMENT_MAX_LINE_LENGTH*INSTRUMENT_MAX_LINE_NUMBER)
//split into lines
spawn()
lines = splittext(t, "\n")
@@ -226,7 +226,7 @@
lines.Cut(INSTRUMENT_MAX_LINE_NUMBER+1)
var/linenum = 1
for(var/l in lines)
if(lentext(l) > INSTRUMENT_MAX_LINE_LENGTH)
if(length(l) > INSTRUMENT_MAX_LINE_LENGTH)
to_chat(usr, "Line [linenum] too long!")
lines.Remove(l)
else
@@ -256,7 +256,7 @@
return
if(lines.len > INSTRUMENT_MAX_LINE_NUMBER)
return
if(lentext(newline) > INSTRUMENT_MAX_LINE_LENGTH)
if(length(newline) > INSTRUMENT_MAX_LINE_LENGTH)
newline = copytext(newline, 1, INSTRUMENT_MAX_LINE_LENGTH)
lines.Add(newline)
else if(href_list["deleteline"])
@@ -269,7 +269,7 @@
var/content = html_encode(input("Enter your line: ", instrumentObj.name, lines[num]) as text|null)
if(!content || !in_range(instrumentObj, usr))
return
if(lentext(content) > INSTRUMENT_MAX_LINE_LENGTH)
if(length(content) > INSTRUMENT_MAX_LINE_LENGTH)
content = copytext(content, 1, INSTRUMENT_MAX_LINE_LENGTH)
if(num > lines.len || num < 1)
return
+1 -1
View File
@@ -98,7 +98,7 @@
active_beams |= Beam(S,icon='icons/effects/beam.dmi',icon_state="holo_beam",time=3 SECONDS,maxdistance=3,beam_type = /obj/effect/ebeam,beam_sleep_time=2)
if(S.cell)
S.cell.give(rand(5, 30))
S.cell.give(rand(30, 120))
. = TRUE
+5 -2
View File
@@ -213,7 +213,8 @@
prob(1);/obj/item/weapon/spacecash/c100,
prob(1);/obj/item/weapon/spacecash/c50,
prob(1);/obj/item/weapon/storage/backpack/dufflebag/syndie,
prob(1);/obj/item/weapon/storage/box/cups)
prob(1);/obj/item/weapon/storage/box/cups,
prob(1);/obj/item/pizzavoucher)
var/obj/item/I = new path()
return I
@@ -222,6 +223,7 @@
var/path = pick(prob(6);/obj/item/weapon/storage/pill_bottle/tramadol,
prob(4);/obj/item/weapon/storage/pill_bottle/happy,
prob(4);/obj/item/weapon/storage/pill_bottle/zoom,
prob(4);/obj/item/seeds/ambrosiavulgarisseed,
prob(4);/obj/item/weapon/gun/energy/sizegun,
prob(3);/obj/item/weapon/material/butterfly,
prob(3);/obj/item/weapon/material/butterfly/switchblade,
@@ -243,7 +245,8 @@
prob(1);/obj/item/weapon/material/knife/tacknife,
prob(1);/obj/item/weapon/storage/box/survival/space,
prob(1);/obj/item/weapon/storage/secure/briefcase/trashmoney,
prob(1);/obj/item/weapon/reagent_containers/syringe/steroid)
prob(1);/obj/item/weapon/reagent_containers/syringe/steroid,
prob(1);/obj/item/seeds/gnomes)
var/obj/item/I = new path()
return I