Merge remote-tracking branch 'upstream/master' into unrestricted-airlocks

This commit is contained in:
Couls
2019-08-13 21:46:32 -04:00
381 changed files with 14426 additions and 3501 deletions
+6
View File
@@ -231,6 +231,12 @@ GLOBAL_DATUM_INIT(pipe_icon_manager, /datum/pipe_icon_manager, new())
var/turf/T = loc
level = T.intact ? 2 : 1
add_fingerprint(usr)
if(!SSair.initialized) //If there's no atmos subsystem, we can't really initialize pipenets
SSair.machinery_to_construct.Add(src)
return
initialize_atmos_network()
/obj/machinery/atmospherics/proc/initialize_atmos_network()
atmos_init()
var/list/nodes = pipeline_expansion()
for(var/obj/machinery/atmospherics/A in nodes)
+1 -1
View File
@@ -189,7 +189,7 @@
T.to_be_destroyed = 0
T.max_fire_temperature_sustained = 0
/obj/effect/hotspot/Crossed(mob/living/L)
/obj/effect/hotspot/Crossed(mob/living/L, oldloc)
..()
if(isliving(L))
L.fire_act()
+1
View File
@@ -6,6 +6,7 @@
#define TARGET_INVALID_UNREACHABLE 5
#define TARGET_INVALID_GOLEM 6
#define TARGET_INVALID_EVENT 7
#define TARGET_INVALID_IS_TARGET 8
//gamemode istype helpers
#define GAMEMODE_IS_BLOB (SSticker && istype(SSticker.mode, /datum/game_mode/blob))
+1
View File
@@ -55,6 +55,7 @@
#define DATA_HUD_ABDUCTOR 18
#define ANTAG_HUD_DEVIL 19
#define ANTAG_HUD_EVENTMISC 20
#define ANTAG_HUD_BLOB 21
// Notification action types
#define NOTIFY_JUMP "jump"
+10 -1
View File
@@ -132,7 +132,12 @@
for(type in view(range, dview_mob))
#define END_FOR_DVIEW dview_mob.loc = null
//Turf locational stuff
#define get_turf(A) (get_step(A, 0))
#define NORTH_OF_TURF(T) locate(T.x, T.y + 1, T.z)
#define EAST_OF_TURF(T) locate(T.x + 1, T.y, T.z)
#define SOUTH_OF_TURF(T) locate(T.x, T.y - 1, T.z)
#define WEST_OF_TURF(T) locate(T.x - 1, T.y, T.z)
#define MIN_SUPPLIED_LAW_NUMBER 15
#define MAX_SUPPLIED_LAW_NUMBER 50
@@ -393,4 +398,8 @@
#define SENSOR_COORDS 3
// Cult summon possibilities
#define SUMMON_POSSIBILITIES 3
#define SUMMON_POSSIBILITIES 3
#define DICE_NOT_RIGGED 1
#define DICE_BASICALLY_RIGGED 2
#define DICE_TOTALLY_RIGGED 3
+5 -1
View File
@@ -298,8 +298,12 @@ This is always put in the attack log.
loglevel = ATKLOG_FEW
else if(istype(user) && !user.ckey && !target.ckey) // Attacks between NPCs are only shown to admins with ATKLOG_ALL
loglevel = ATKLOG_ALL
else if(!target.ckey) // Attacks by players on NPCs are only shown to admins with ATKLOG_ALL or ATKLOG_ALMOSTALL
else if(!user.ckey || !target.ckey) // Player v NPC combat is de-prioritized.
loglevel = ATKLOG_ALMOSTALL
else
var/area/A = get_area(target)
if(A && A.hide_attacklogs)
loglevel = ATKLOG_ALMOSTALL
msg_admin_attack("[key_name_admin(user)] vs [key_name_admin(target)]: [what_done]", loglevel)
+9 -2
View File
@@ -28,6 +28,11 @@
/*
* Text sanitization
*/
// Can be used almost the same way as normal input for text
/proc/clean_input(Message, Title, Default, mob/user=usr)
var/txt = input(user, Message, Title, Default) as text | null
if(txt)
return html_encode(txt)
//Simply removes < and > and limits the length of the message
/proc/strip_html_simple(var/t,var/limit=MAX_MESSAGE_LEN)
@@ -125,8 +130,10 @@
//Filters out undesirable characters from names
/proc/reject_bad_name(var/t_in, var/allow_numbers=0, var/max_length=MAX_NAME_LEN)
// Decode so that names with characters like < are still rejected. Will be encoded again at the end
t_in = html_decode(t_in)
if(!t_in || length(t_in) > max_length)
return //Rejects the input if it is null or if it is longer then the max length allowed
return //Rejects the input if it is null or if it is longer than the max length allowed
var/number_of_alphanumeric = 0
var/last_char_group = 0
@@ -185,7 +192,7 @@
for(var/bad_name in list("space","floor","wall","r-wall","monkey","unknown","inactive ai","plating")) //prevents these common metagamey names
if(cmptext(t_out,bad_name)) return //(not case sensitive)
return t_out
return html_encode(t_out)
//checks text for html tags
//if tag is not in whitelist (var/list/paper_tag_whitelist in global.dm)
+3 -1
View File
@@ -88,4 +88,6 @@ var/copier_items_printed_logged = FALSE
GLOBAL_VAR(map_name) // Self explanatory
var/global/datum/datacore/data_core = null // Station datacore, manifest, etc
var/global/datum/datacore/data_core = null // Station datacore, manifest, etc
GLOBAL_VAR_INIT(panic_bunker_enabled, 0) // Is the panic bunker enabled
+7 -1
View File
@@ -256,4 +256,10 @@
//Add multicamera camera
using = new /obj/screen/ai/add_multicam()
using.screen_loc = ui_ai_add_multicam
static_inventory += using
static_inventory += using
//Intent
using = new /obj/screen/act_intent/robot/AI()
using.icon_state = mymob.a_intent
static_inventory += using
action_intent = using
+3
View File
@@ -95,6 +95,9 @@
icon = 'icons/mob/screen_robot.dmi'
screen_loc = ui_borg_intents
/obj/screen/act_intent/robot/AI
screen_loc = "EAST-1:32,SOUTH:70"
/obj/screen/mov_intent
name = "run/walk toggle"
icon_state = "running"
+5 -9
View File
@@ -79,9 +79,8 @@
var/auto_cryo_ssd_mins = 0
var/ssd_warning = 0
var/prob_free_golems = 75 //chance for free golems spawners to appear roundstart
var/unrestricted_free_golems = FALSE //if true, free golems can appear on all roundtypes
var/list_afk_minimum = 5 // How long people have to be AFK before it's listed on the "List AFK players" verb
var/traitor_objectives_amount = 2
var/shadowling_max_age = 0
@@ -310,12 +309,6 @@
if("jobs_have_minimal_access")
config.jobs_have_minimal_access = 1
if("prob_free_golems")
config.prob_free_golems = text2num(value)
if("unrestricted_free_golems")
config.unrestricted_free_golems = TRUE
if("shadowling_max_age")
config.shadowling_max_age = text2num(value)
@@ -331,6 +324,9 @@
if("ssd_warning")
config.ssd_warning = 1
if("list_afk_minimum")
config.list_afk_minimum = text2num(value)
if("ipintel_email")
if(value != "ch@nge.me")
config.ipintel_email = value
+3 -1
View File
@@ -30,6 +30,7 @@ SUBSYSTEM_DEF(air)
var/list/networks = list()
var/list/atmos_machinery = list()
var/list/pipe_init_dirs_cache = list()
var/list/machinery_to_construct = list()
@@ -67,9 +68,10 @@ SUBSYSTEM_DEF(air)
setup_allturfs()
setup_atmos_machinery(GLOB.machines)
setup_pipenets(GLOB.machines)
for(var/obj/machinery/atmospherics/A in machinery_to_construct)
A.initialize_atmos_network()
return ..()
/datum/controller/subsystem/air/fire(resumed = 0)
var/timer = TICK_USAGE_REAL
+1 -1
View File
@@ -249,7 +249,7 @@ SUBSYSTEM_DEF(events)
else if(href_list["back"])
selected_event_container = null
else if(href_list["set_name"])
var/name = input("Enter event name.", "Set Name") as text|null
var/name = clean_input("Enter event name.", "Set Name")
if(name)
var/datum/event_meta/EM = locate(href_list["set_name"])
EM.name = name
+1 -1
View File
@@ -20,7 +20,7 @@ SUBSYSTEM_DEF(mapping)
var/num_extra_space = rand(config.extra_space_ruin_levels_min, config.extra_space_ruin_levels_max)
for(var/i = 1, i <= num_extra_space, i++)
var/zlev = space_manager.add_new_zlevel("[EMPTY_AREA] #[i]", linkage = CROSSLINKED)
var/zlev = space_manager.add_new_zlevel("[EMPTY_AREA] #[i]", linkage = CROSSLINKED, traits = list(REACHABLE))
seedRuins(list(zlev), rand(0, 3), /area/space, space_ruins_templates)
// Setup the Z-level linkage
@@ -8,7 +8,7 @@ GLOBAL_REAL(SSmentor_tickets, /datum/controller/subsystem/tickets/mentor_tickets
name = "Mentor Tickets"
ticket_system_name = "Mentor Tickets"
ticket_name = "Mentor Ticket"
span_text = "<span class='mentorhelp'>"
span_class = "mentorhelp"
close_rights = R_MENTOR | R_ADMIN
/datum/controller/subsystem/tickets/mentor_tickets/message_staff(var/msg)
@@ -17,5 +17,5 @@ GLOBAL_REAL(SSmentor_tickets, /datum/controller/subsystem/tickets/mentor_tickets
/datum/controller/subsystem/tickets/mentor_tickets/Initialize()
close_messages = list("<font color='red' size='3'><b>- [ticket_name] Closed -</b></font>",
"<span class='boldmessage'>Please try to be as descriptive as possible in mentor helps. Mentors do not know the full situation you're in and need more information to give you a helpful response.</span>",
"[span_text]Your [ticket_name] has now been closed.</span>")
"<span class='[span_class]'>Your [ticket_name] has now been closed.</span>")
return ..()
+18 -16
View File
@@ -12,7 +12,7 @@
SUBSYSTEM_DEF(tickets)
name = "Admin Tickets"
var/span_text = "<span class='adminticket'>"
var/span_class = "adminticket"
var/ticket_system_name = "Admin Tickets"
var/ticket_name = "Admin Ticket"
var/close_rights = R_ADMIN
@@ -30,7 +30,7 @@ SUBSYSTEM_DEF(tickets)
/datum/controller/subsystem/tickets/Initialize()
close_messages = list("<font color='red' size='4'><b>- [ticket_name] Rejected! -</b></font>",
"<span class='boldmessage'>Please try to be calm, clear, and descriptive in admin helps, do not assume the staff member has seen any related events, and clearly state the names of anybody you are reporting. If you asked a question, please ensure it was clear what you were asking.</span>",
"[span_text]Your [ticket_name] has now been closed.</span>")
"<span class='[span_class]'>Your [ticket_name] has now been closed.</span>")
LAZYINITLIST(allTickets)
return ..()
@@ -40,7 +40,7 @@ SUBSYSTEM_DEF(tickets)
var/report
for(var/num in stales)
report += "[num], "
message_staff("[span_text]Tickets [report] have been open for over [TICKET_TIMEOUT / 600] minutes. Changing status to stale.</span>")
message_staff("<span class='[span_class]'>Tickets [report] have been open for over [TICKET_TIMEOUT / 600] minutes. Changing status to stale.</span>")
/datum/controller/subsystem/tickets/stat_entry()
..("Tickets: [LAZYLEN(allTickets)]")
@@ -80,7 +80,7 @@ SUBSYSTEM_DEF(tickets)
var/datum/ticket/existingTicket = checkForOpenTicket(C)
if(existingTicket)
existingTicket.setCooldownPeriod()
to_chat(C.mob, "[span_text]Your [ticket_name] #[existingTicket.ticketNum] remains open! Visit \"My tickets\" under the Admin Tab to view it.</span>")
to_chat(C.mob, "<span class='[span_class]'>Your [ticket_name] #[existingTicket.ticketNum] remains open! Visit \"My tickets\" under the Admin Tab to view it.</span>")
return
if(!title)
@@ -93,7 +93,7 @@ SUBSYSTEM_DEF(tickets)
T.mobControlled = C.mob
//Inform the user that they have opened a ticket
to_chat(C, "[span_text]You have opened [ticket_name] number #[(getTicketCounter() - 1)]! Please be patient and we will help you soon!</span>")
to_chat(C, "<span class='[span_class]'>You have opened [ticket_name] number #[(getTicketCounter() - 1)]! Please be patient and we will help you soon!</span>")
//Set ticket state with key N to open
/datum/controller/subsystem/tickets/proc/openTicket(N)
@@ -138,8 +138,10 @@ SUBSYSTEM_DEF(tickets)
var/datum/ticket/T = allTickets[N]
return T.clientName
/datum/controller/subsystem/tickets/proc/assignStaffToTicket(client/C, var/N)
/datum/controller/subsystem/tickets/proc/assignStaffToTicket(client/C, N)
var/datum/ticket/T = allTickets[N]
if(T.staffAssigned != null && T.staffAssigned != C && alert("Ticket is already assigned to [T.staffAssigned.ckey]. Are you sure you want to take it?","Take ticket","No","Yes") != "Yes")
return FALSE
T.assignStaff(C)
return TRUE
@@ -158,7 +160,7 @@ SUBSYSTEM_DEF(tickets)
var/ticketState // State of the ticket, open, closed, resolved etc
var/timeUntilStale // When the ticket goes stale
var/ticketCooldown // Cooldown before allowing the user to open another ticket.
var/staffAssigned // Staff member who has assigned themselves to this ticket
var/client/staffAssigned // Staff member who has assigned themselves to this ticket
/datum/ticket/New(tit, cont, num)
title = tit
@@ -367,15 +369,15 @@ UI STUFF
if(href_list["resolve"])
var/indexNum = text2num(href_list["resolve"])
if(resolveTicket(indexNum))
message_staff("[span_text][usr.client] / ([usr]) resolved [ticket_name] number [indexNum]</span>")
to_chat_safe(returnClient(indexNum), "[span_text]Your [ticket_name] has now been resolved.</span>")
message_staff("<span class='[span_class]'>[usr.client] / ([usr]) resolved [ticket_name] number [indexNum]</span>")
to_chat_safe(returnClient(indexNum), "<span class='[span_class]'>Your [ticket_name] has now been resolved.</span>")
showUI(usr)
if(href_list["detailresolve"])
var/indexNum = text2num(href_list["detailresolve"])
if(resolveTicket(indexNum))
message_staff("[span_text][usr.client] / ([usr]) resolved [ticket_name] number [indexNum]</span>")
to_chat_safe(returnClient(indexNum), "[span_text]Your [ticket_name] has now been resolved.</span>")
message_staff("<span class='[span_class]'>[usr.client] / ([usr]) resolved [ticket_name] number [indexNum]</span>")
to_chat_safe(returnClient(indexNum), "<span class='[span_class]'>Your [ticket_name] has now been resolved.</span>")
showDetailUI(usr, indexNum)
if(href_list["detailclose"])
@@ -386,7 +388,7 @@ UI STUFF
if(alert("Are you sure? This will send a negative message.",,"Yes","No") != "Yes")
return
if(closeTicket(indexNum))
message_staff("[span_text][usr.client] / ([usr]) closed [ticket_name] number [indexNum]</span>")
message_staff("<span class='[span_class]'>[usr.client] / ([usr]) closed [ticket_name] number [indexNum]</span>")
to_chat_safe(returnClient(indexNum), close_messages)
showDetailUI(usr, indexNum)
@@ -394,7 +396,7 @@ UI STUFF
if(href_list["detailreopen"])
var/indexNum = text2num(href_list["detailreopen"])
if(openTicket(indexNum))
message_staff("[span_text][usr.client] / ([usr]) re-opened [ticket_name] number [indexNum]</span>")
message_staff("<span class='[span_class]'>[usr.client] / ([usr]) re-opened [ticket_name] number [indexNum]</span>")
showDetailUI(usr, indexNum)
if(href_list["assignstaff"])
@@ -404,8 +406,8 @@ UI STUFF
/datum/controller/subsystem/tickets/proc/takeTicket(var/index)
if(assignStaffToTicket(usr.client, index))
if(span_text == "<span class='mentorhelp'>")
message_staff("[span_text][usr.client] / ([usr]) has taken [ticket_name] number [index]</span>")
if(span_class == "mentorhelp")
message_staff("<span class='[span_class]'>[usr.client] / ([usr]) has taken [ticket_name] number [index]</span>")
else
message_staff("<span class='admin_channel'>[usr.client] / ([usr]) has taken [ticket_name] number [index]</span>", TRUE)
to_chat_safe(returnClient(index), "[span_text]Your [ticket_name] is being handled by [usr.client].</span>")
to_chat_safe(returnClient(index), "<span class='[span_class]'>Your [ticket_name] is being handled by [usr.client].</span>")
+1 -1
View File
@@ -119,7 +119,7 @@
owner = null
return ..()
/obj/effect/ebeam/deadly/Crossed(atom/A)
/obj/effect/ebeam/deadly/Crossed(atom/A, oldloc)
..()
A.ex_act(1)
+15
View File
@@ -0,0 +1,15 @@
/datum/component/waddling
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
/datum/component/waddling/Initialize()
if(!isliving(parent))
return COMPONENT_INCOMPATIBLE
RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/Waddle)
/datum/component/waddling/proc/Waddle()
var/mob/living/L = parent
if(L.incapacitated() || L.lying)
return
animate(L, pixel_z = 4, time = 0)
animate(pixel_z = 0, transform = turn(matrix(), pick(-12, 0, 12)), time=2)
animate(pixel_z = 0, transform = matrix(), time = 0)
+16 -2
View File
@@ -100,15 +100,20 @@
height = 400
immediate_submit = TRUE
/datum/async_input/ranked/New()
..()
popup.add_script("rankedInput.js", 'html/browser/rankedInput.js')
popup.add_head_content("<title>Drag and drop or use the buttons to reorder</title>")
/datum/async_input/ranked/render_choices()
var/dat = "<div>"
dat += "<table style='margin: auto; text-align: left;'>"
dat += "<table id='choices' uid=[UID()] style='margin: auto; text-align: left;'>"
for(var/i = 1, i <= choices.len, i++)
var/choice = choices[i]
dat += "<tr>"
dat += "<td>[button("+", i != 1 ? "upvote=[i]" : "", , i == 1)]</td>"
dat += "<td>[button("-", i != choices.len ? "downvote=[i]" : "", , i == choices.len)]</td>"
dat += "<td>[i]. [choice]</td>"
dat += "<td style='cursor: move;' index='[i]' ondrop='drop(event)' ondragover='allowDrop(event)' draggable='true' ondragstart='drag(event)'>[i]. [choice]</td>"
dat += "</tr>"
dat += "</table>"
dat += "</div>"
@@ -131,6 +136,15 @@
show()
return
if(href_list["cut"] && href_list["insert"])
var/cut = text2num(href_list["cut"])
var/insert = text2num(href_list["insert"])
var/choice = choices[cut]
choices.Cut(cut, cut + 1)
choices.Insert(insert, choice)
show()
return
..()
/datum/async_input/autocomplete
+2 -1
View File
@@ -22,7 +22,8 @@ var/datum/atom_hud/huds = list( \
ANTAG_HUD_ABDUCTOR = new/datum/atom_hud/antag/hidden(),\
DATA_HUD_ABDUCTOR = new/datum/atom_hud/abductor(),\
ANTAG_HUD_DEVIL = new/datum/atom_hud/antag/hidden(),\
ANTAG_HUD_EVENTMISC = new/datum/atom_hud/antag/hidden()\
ANTAG_HUD_EVENTMISC = new/datum/atom_hud/antag/hidden(),\
ANTAG_HUD_BLOB = new/datum/atom_hud/antag/hidden()\
)
/datum/atom_hud
+1
View File
@@ -42,6 +42,7 @@
var/list/kills = list()
var/list/datum/objective/objectives = list()
var/list/datum/objective/special_verbs = list()
var/list/targets = list()
var/has_been_rev = 0//Tracks if this mind has been a rev or not
+121 -1
View File
@@ -12,6 +12,14 @@
Comes with a rustic wooden bar and suicidal bartender."
suffix = "lavaland_biodome_beach.dmm"
/datum/map_template/ruin/lavaland/cube
name = "The Wishgranter Cube"
id = "wishgranter-cube"
description = "Nothing good can come from this. Learn from their mistakes and turn around."
suffix = "lavaland_surface_cube.dmm"
cost = 10
allow_duplicates = FALSE
/datum/map_template/ruin/lavaland/seed_vault
name = "Seed Vault"
id = "seed-vault"
@@ -38,6 +46,15 @@ datum/map_template/ruin/lavaland/ash_walker
cost = 20
allow_duplicates = FALSE
/datum/map_template/ruin/lavaland/free_golem
name = "Free Golem Ship"
id = "golem-ship"
description = "Lumbering humanoids, made out of precious metals, move inside this ship. They frequently leave to mine more minerals, which they somehow turn into more of them. \
Seem very intent on research and individual liberty, and also geology based naming?"
cost = 20
suffix = "lavaland_surface_golem_ship.dmm"
allow_duplicates = FALSE
/datum/map_template/ruin/lavaland/animal_hospital
name = "Animal Hospital"
id = "animal-hospital"
@@ -46,6 +63,49 @@ datum/map_template/ruin/lavaland/ash_walker
suffix = "lavaland_surface_animal_hospital.dmm"
allow_duplicates = FALSE
/datum/map_template/ruin/lavaland/sin
cost = 10
allow_duplicates = FALSE
/datum/map_template/ruin/lavaland/sin/envy
name = "Ruin of Envy"
id = "envy"
description = "When you get what they have, then you'll finally be happy."
suffix = "lavaland_surface_envy.dmm"
/datum/map_template/ruin/lavaland/sin/gluttony
name = "Ruin of Gluttony"
id = "gluttony"
description = "If you eat enough, then eating will be all that you do."
suffix = "lavaland_surface_gluttony.dmm"
/datum/map_template/ruin/lavaland/sin/greed
name = "Ruin of Greed"
id = "greed"
description = "Sure you don't need magical powers, but you WANT them, and that's what's important."
suffix = "lavaland_surface_greed.dmm"
/datum/map_template/ruin/lavaland/sin/pride
name = "Ruin of Pride"
id = "pride"
description = "Wormhole lifebelts are for LOSERS, who you are better than."
suffix = "lavaland_surface_pride.dmm"
/datum/map_template/ruin/lavaland/sin/sloth
name = "Ruin of Sloth"
id = "sloth"
description = "..."
suffix = "lavaland_surface_sloth.dmm"
cost = 0
/datum/map_template/ruin/lavaland/ratvar
name = "Dead God"
id = "ratvar"
description = "Ratvars final resting place."
suffix = "lavaland_surface_dead_ratvar.dmm"
cost = 0
allow_duplicates = FALSE
/datum/map_template/ruin/lavaland/hierophant
name = "Hierophant's Arena"
id = "hierophant"
@@ -70,6 +130,51 @@ datum/map_template/ruin/lavaland/ash_walker
name = "Blood-Drunk Miner (Hunter)"
suffix = "lavaland_surface_blooddrunk3.dmm"
/datum/map_template/ruin/lavaland/ufo_crash
name = "UFO Crash"
id = "ufo-crash"
description = "Turns out that keeping your abductees unconscious is really important. Who knew?"
suffix = "lavaland_surface_ufo_crash.dmm"
cost = 5
/datum/map_template/ruin/lavaland/xeno_nest
name = "Xenomorph Nest"
id = "xeno-nest"
description = "These xenomorphs got bored of horrifically slaughtering people on space stations, and have settled down on a nice lava filled hellscape to focus on what's really important in life. \
Quality memes."
suffix = "lavaland_surface_xeno_nest.dmm"
cost = 20
/datum/map_template/ruin/lavaland/fountain
name = "Fountain Hall"
id = "fountain"
description = "The fountain has a warning on the side. DANGER: May have undeclared side effects that only become obvious when implemented."
suffix = "lavaland_surface_fountain_hall.dmm"
cost = 5
/datum/map_template/ruin/lavaland/survivalcapsule
name = "Survival Capsule Ruins"
id = "survivalcapsule"
description = "What was once sanctuary to the common miner, is now their tomb."
suffix = "lavaland_surface_survivalpod.dmm"
cost = 5
/datum/map_template/ruin/lavaland/pizza
name = "Ruined Pizza Party"
id = "pizza"
description = "Little Timmy's birthday pizza-bash took a turn for the worse when a bluespace anomaly passed by."
suffix = "lavaland_surface_pizzaparty.dmm"
allow_duplicates = FALSE
cost = 5
/datum/map_template/ruin/lavaland/cultaltar
name = "Summoning Ritual"
id = "cultaltar"
description = "A place of vile worship, the scrawling of blood in the middle glowing eerily. A demonic laugh echoes throughout the caverns"
suffix = "lavaland_surface_cultaltar.dmm"
allow_duplicates = FALSE
cost = 10
/datum/map_template/ruin/lavaland/hermit
name = "Makeshift Shelter"
id = "hermitcave"
@@ -84,4 +189,19 @@ datum/map_template/ruin/lavaland/ash_walker
description = "A Syndicate shuttle had an unfortunate stowaway..."
suffix = "lavaland_surface_swarmer_crash.dmm"
allow_duplicates = FALSE
cost = 20
cost = 20
/datum/map_template/ruin/lavaland/miningripley
name = "Ripley"
id = "ripley"
description = "A heavily-damaged mining ripley, property of a very unfortunate miner. You might have to do a bit of work to fix this thing up."
suffix = "lavaland_surface_random_ripley.dmm"
allow_duplicates = FALSE
cost = 5
/datum/map_template/ruin/lavaland/puzzle
name = "Ancient Puzzle"
id = "puzzle"
description = "Mystery to be solved."
suffix = "lavaland_surface_puzzle.dmm"
cost = 5
+3 -3
View File
@@ -1107,10 +1107,10 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
cost = 2
/datum/uplink_item/stealthy_tools/thermal
name = "Thermal Imaging Glasses"
desc = "These glasses are thermals disguised as engineers' optical meson scanners. They allow you to see organisms through walls by capturing the upper portion of the infra-red light spectrum, emitted as heat and light by objects. Hotter objects, such as warm bodies, cybernetic organisms and artificial intelligence cores emit more of this light than cooler objects like walls and airlocks."
name = "Thermal Chameleon Glasses"
desc = "These glasses are thermals with Syndicate chameleon technology built into them. They allow you to see organisms through walls by capturing the upper portion of the infra-red light spectrum, emitted as heat and light by objects. Hotter objects, such as warm bodies, cybernetic organisms and artificial intelligence cores emit more of this light than cooler objects like walls and airlocks."
reference = "THIG"
item = /obj/item/clothing/glasses/thermal/syndi
item = /obj/item/clothing/glasses/chameleon/thermal
cost = 6
/datum/uplink_item/stealthy_tools/traitor_belt
+1 -1
View File
@@ -95,7 +95,7 @@
receivers -= M
garbled_receivers |= M
for(var/mob/M in GLOB.dead_mob_list)
if(M.client && M.stat == DEAD)
if(M.client && M.stat == DEAD && !isnewplayer(M))
receivers |= M
return list(receivers, garbled_receivers)
+3
View File
@@ -50,6 +50,7 @@ var/list/ghostteleportlocs = list()
icon_state = "start"
requires_power = FALSE
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
hide_attacklogs = TRUE
/area/adminconstruction
@@ -57,6 +58,7 @@ var/list/ghostteleportlocs = list()
icon_state = "start"
requires_power = FALSE
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
hide_attacklogs = TRUE
/area/space
icon_state = "space"
@@ -522,6 +524,7 @@ var/list/ghostteleportlocs = list()
icon_state = "thunder"
requires_power = FALSE
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
hide_attacklogs = TRUE
/area/tdome/arena_source
+2 -1
View File
@@ -33,7 +33,7 @@
var/static_equip
var/static_light = FALSE
var/static_environ
var/has_gravity = TRUE
var/list/apc = list()
var/no_air = null
@@ -65,6 +65,7 @@
var/fast_despawn = FALSE
var/can_get_auto_cryod = TRUE
var/hide_attacklogs = FALSE // For areas such as thunderdome, lavaland syndiebase, etc which generate a lot of spammy attacklogs. Reduces log priority.
/area/Initialize(mapload)
GLOB.all_areas += src
+2 -1
View File
@@ -16,7 +16,7 @@
icon_state = "dk_yellow"
/area/ruin/powered/golem_ship
name = "Free Golem Ship"
name = "Free Golem Landing"
icon_state = "dk_yellow"
/area/ruin/powered/greed
@@ -37,6 +37,7 @@
icon_state = "dk_yellow"
ambientsounds = list('sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg')
report_alerts = FALSE
hide_attacklogs = TRUE
/area/ruin/unpowered/syndicate_lava_base/engineering
name = "Syndicate Lavaland Engineering"
+4 -2
View File
@@ -219,7 +219,7 @@
// Previously known as HasEntered()
// This is automatically called when something enters your square
/atom/movable/Crossed(atom/movable/AM)
/atom/movable/Crossed(atom/movable/AM, oldloc)
SEND_SIGNAL(src, COMSIG_MOVABLE_CROSSED, AM)
/atom/movable/Bump(atom/A, yes) //the "yes" arg is to differentiate our Bump proc from byond's, without it every Bump() call would become a double Bump().
@@ -245,7 +245,9 @@
if(destination)
destination.Entered(src)
for(var/atom/movable/AM in destination)
AM.Crossed(src)
if(AM == src)
continue
AM.Crossed(src, old_loc)
var/turf/oldturf = get_turf(old_loc)
var/turf/destturf = get_turf(destination)
var/old_z = (oldturf ? oldturf.z : null)
+15 -1
View File
@@ -437,4 +437,18 @@ var/global/list/bad_blocks[0]
var/datum/species/S = data["species"]
species = new S
b_type = data["b_type"]
real_name = data["real_name"]
real_name = data["real_name"]
/datum/dna/proc/transfer_identity(mob/living/carbon/human/destination)
if(!istype(destination))
return
// We manually set the species to ensure all proper species change procs are called.
destination.set_species(species.type, retain_damage = TRUE)
var/datum/dna/new_dna = Clone()
new_dna.species = destination.dna.species
destination.dna = new_dna
destination.dna.species.handle_dna(destination) // Handle DNA has to be re-called as the DNA was changed.
destination.UpdateAppearance()
domutcheck(destination, null, MUTCHK_FORCED)
+14 -5
View File
@@ -14,7 +14,6 @@ var/list/blob_nodes = list()
required_enemies = 1
recommended_enemies = 1
restricted_jobs = list("Cyborg", "AI")
free_golems_disabled = TRUE
var/declared = 0
var/burst = 0
@@ -43,9 +42,11 @@ var/list/blob_nodes = list()
for(var/j = 0, j < cores_to_spawn, j++)
if(!possible_blobs.len)
break
var/datum/mind/blob = pick(possible_blobs)
infected_crew += blob
blob.special_role = SPECIAL_ROLE_BLOB
update_blob_icons_added(blob)
blob.restricted_roles = restricted_jobs
log_game("[key_name(blob)] has been selected as a Blob")
possible_blobs -= blob
@@ -67,8 +68,11 @@ var/list/blob_nodes = list()
var/datum/mind/blobmind = blob.mind
if(!istype(blobmind))
return 0
infected_crew += blobmind
blobmind.special_role = SPECIAL_ROLE_BLOB
update_blob_icons_added(blobmind)
log_game("[key_name(blob)] has been selected as a Blob")
greet_blob(blobmind)
to_chat(blob, "<span class='userdanger'>You feel very tired and bloated! You don't have long before you burst!</span>")
@@ -186,16 +190,21 @@ var/list/blob_nodes = list()
return ..()
/datum/game_mode/blob/proc/stage(var/stage)
switch(stage)
if(0)
send_intercept(1)
declared = 1
if(1)
event_announcement.Announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/AI/outbreak5.ogg')
if(2)
send_intercept(2)
return
/datum/game_mode/proc/update_blob_icons_added(datum/mind/mob_mind)
var/datum/atom_hud/antag/antaghud = huds[ANTAG_HUD_BLOB]
antaghud.join_hud(mob_mind.current)
set_antag_hud(mob_mind.current, "hudblob")
/datum/game_mode/proc/update_blob_icons_removed(datum/mind/mob_mind)
var/datum/atom_hud/antag/antaghud = huds[ANTAG_HUD_BLOB]
antaghud.leave_hud(mob_mind.current)
set_antag_hud(mob_mind.current, null)
+1 -1
View File
@@ -388,7 +388,7 @@
set name = "Blob Broadcast"
set desc = "Speak with your blob spores and blobbernauts as your mouthpieces. This action is free."
var/speak_text = input(usr, "What would you like to say with your minions?", "Blob Broadcast", null) as text
var/speak_text = clean_input("What would you like to say with your minions?", "Blob Broadcast", null)
if(!speak_text)
return
+1 -1
View File
@@ -142,7 +142,7 @@
take_damage(Proj.damage, Proj.damage_type)
return 0
/obj/structure/blob/Crossed(var/mob/living/L)
/obj/structure/blob/Crossed(var/mob/living/L, oldloc)
..()
L.blob_act(src)
-1
View File
@@ -43,7 +43,6 @@ var/global/list/all_cults = list()
required_players = 30
required_enemies = 3
recommended_enemies = 4
free_golems_disabled = TRUE
var/datum/mind/sacrifice_target = null
var/finished = 0
+1 -1
View File
@@ -42,7 +42,7 @@
for(var/mob/M in GLOB.player_list)
if(iscultist(M))
to_chat(M, my_message)
else if(M in GLOB.dead_mob_list)
else if((M in GLOB.dead_mob_list) && !isnewplayer(M))
to_chat(M, "<span class='cultspeech'> <a href='?src=[M.UID()];follow=[user.UID()]'>(F)</a> [my_message] </span>")
log_say("(CULT) [message]", user)
+1 -1
View File
@@ -271,7 +271,7 @@ var/list/blacklisted_pylon_turfs = typecacheof(list(
return
return
/obj/effect/gateway/Crossed(AM as mob|obj)
/obj/effect/gateway/Crossed(AM as mob|obj, oldloc)
spawn(0)
return
return
+2 -3
View File
@@ -494,9 +494,8 @@ var/list/teleport_runes = list()
/obj/effect/rune/narsie/New()
..()
cultist_name = "Summon [SSticker.cultdat.entity_name]"
cultist_desc = "tears apart dimensional barriers, calling forth [SSticker.cultdat.entity_title3]. Requires 9 invokers."
cultist_name = "Summon [SSticker.cultdat ? SSticker.cultdat.entity_name : "your god"]"
cultist_desc = "tears apart dimensional barriers, calling forth [SSticker.cultdat ? SSticker.cultdat.entity_title3 : "your god"]. Requires 9 invokers."
/obj/effect/rune/narsie/check_icon()
return
-8
View File
@@ -27,7 +27,6 @@
var/recommended_enemies = 0
var/newscaster_announcements = null
var/ert_disabled = 0
var/free_golems_disabled = FALSE
var/uplink_welcome = "Syndicate Uplink Console:"
var/uplink_uses = 20
@@ -81,7 +80,6 @@
// feedback_set_details("revision","[revdata.revision]")
feedback_set_details("server_ip","[world.internet_address]:[world.port]")
generate_station_goals()
check_free_golems()
start_state = new /datum/station_state()
start_state.count()
return 1
@@ -513,12 +511,6 @@ proc/display_roundstart_logout_report()
var/datum/station_goal/G = V
G.print_result()
/datum/game_mode/proc/check_free_golems() //check config and gamemode for free golems setting and run the prob to check if the round will have free golems spawned or not
if((config.unrestricted_free_golems || !free_golems_disabled) && prob(config.prob_free_golems))
for(var/obj/effect/landmark/free_golem_spawn/L in GLOB.landmarks_list)
if(isturf(L.loc))
new /obj/effect/mob_spawn/human/golem/adamantine(L.loc)
/datum/game_mode/proc/update_eventmisc_icons_added(datum/mind/mob_mind)
var/datum/atom_hud/antag/antaghud = huds[ANTAG_HUD_EVENTMISC]
antaghud.join_hud(mob_mind.current)
@@ -545,7 +545,7 @@
light_color = LIGHT_COLOR_CYAN
health = 10
/obj/structure/swarmer/trap/Crossed(var/atom/movable/AM)
/obj/structure/swarmer/trap/Crossed(var/atom/movable/AM, oldloc)
if(isliving(AM))
var/mob/living/L = AM
if(!istype(L, /mob/living/simple_animal/hostile/swarmer))
@@ -42,7 +42,7 @@
do_teleport(M, M, 10)
new /obj/effect/temp_visual/guardian/phase/out(get_turf(M))
/mob/living/simple_animal/hostile/guardian/fire/Crossed(AM as mob|obj)
/mob/living/simple_animal/hostile/guardian/fire/Crossed(AM as mob|obj, oldloc)
..()
collision_ignite(AM)
@@ -103,7 +103,7 @@
invisibility = 1
/obj/item/effect/snare/Crossed(AM as mob|obj)
/obj/item/effect/snare/Crossed(AM as mob|obj, oldloc)
if(isliving(AM))
var/turf/snare_loc = get_turf(loc)
if(spawner)
-1
View File
@@ -12,7 +12,6 @@ proc/issyndicate(mob/living/M as mob)
required_players = 30 // 30 players - 5 players to be the nuke ops = 25 players remaining
required_enemies = 5
recommended_enemies = 5
free_golems_disabled = TRUE
var/const/agents_possible = 5 //If we ever need more syndicate agents.
+6 -2
View File
@@ -25,6 +25,8 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu
/datum/objective/proc/is_invalid_target(datum/mind/possible_target)
if(possible_target == owner)
return TARGET_INVALID_IS_OWNER
if(possible_target in owner.targets)
return TARGET_INVALID_IS_TARGET
if(!ishuman(possible_target.current))
return TARGET_INVALID_NOT_HUMAN
if(!possible_target.current.stat == DEAD)
@@ -52,7 +54,6 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu
if(possible_targets.len > 0)
target = pick(possible_targets)
/datum/objective/assassinate
martyr_compatible = 1
@@ -361,9 +362,12 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu
var/datum/theft_objective/O = new thefttype
if(owner.assigned_role in O.protected_jobs)
continue
if(O in owner.targets)
continue
if(O.flags & 2)
continue
steal_target=O
steal_target = O
explanation_text = "Steal [steal_target]. One was last seen in [get_location()]. "
if(islist(O.protected_jobs) && O.protected_jobs.len)
explanation_text += "It may also be in the possession of the [jointext(O.protected_jobs, ", ")]."
+7
View File
@@ -87,6 +87,7 @@
yandere_one.owner = traitor
traitor.objectives += yandere_one
yandere_one.find_target()
traitor.targets += yandere_one.target
objective_count++
var/datum/objective/maroon/yandere_two = new
yandere_two.owner = traitor
@@ -99,6 +100,7 @@
kill_objective.owner = traitor
kill_objective.find_target()
traitor.objectives += kill_objective
traitor.targets += kill_objective.target
var/datum/objective/survive/survive_objective = new
survive_objective.owner = traitor
@@ -124,26 +126,31 @@
destroy_objective.owner = traitor
destroy_objective.find_target()
traitor.objectives += destroy_objective
traitor.targets += destroy_objective.target
else if(prob(5))
var/datum/objective/debrain/debrain_objective = new
debrain_objective.owner = traitor
debrain_objective.find_target()
traitor.objectives += debrain_objective
traitor.targets += debrain_objective.target
else if(prob(30))
var/datum/objective/maroon/maroon_objective = new
maroon_objective.owner = traitor
maroon_objective.find_target()
traitor.objectives += maroon_objective
traitor.targets += maroon_objective.target
else
var/datum/objective/assassinate/kill_objective = new
kill_objective.owner = traitor
kill_objective.find_target()
traitor.objectives += kill_objective
traitor.targets += kill_objective.target
else
var/datum/objective/steal/steal_objective = new
steal_objective.owner = traitor
steal_objective.find_target()
traitor.objectives += steal_objective
traitor.targets += steal_objective.steal_target
if(is_hijacker && objective_count <= config.traitor_objectives_amount) //Don't assign hijack if it would exceed the number of objectives set in config.traitor_objectives_amount
if(!(locate(/datum/objective/hijack) in traitor.objectives))
@@ -349,8 +349,16 @@
SSticker.mode.vampire_enthralled.Add(H.mind)
SSticker.mode.vampire_enthralled[H.mind] = user.mind
H.mind.special_role = SPECIAL_ROLE_VAMPIRE_THRALL
to_chat(H, "<span class='danger'>You have been Enthralled by [user]. Follow [user.p_their()] every command.</span>")
var/datum/objective/protect/serve_objective = new
serve_objective.owner = user.mind
serve_objective.target = H.mind
serve_objective.explanation_text = "You have been Enthralled by [user]. Follow [user.p_their()] every command."
H.mind.objectives += serve_objective
to_chat(H, "<span class='biggerdanger'>You have been Enthralled by [user]. Follow [user.p_their()] every command.</span>")
to_chat(user, "<span class='warning'>You have successfully Enthralled [H]. <i>If [H.p_they()] refuse[H.p_s()] to do as you say just adminhelp.</i></span>")
H.Stun(2)
add_attack_logs(user, H, "Vampire-thralled")
+10
View File
@@ -906,3 +906,13 @@
spellname = "sacred flame"
icon_state ="booksacredflame"
desc = "Become one with the flames that burn within... and invite others to do so as well."
/obj/item/spellbook/oneuse/random
icon_state = "random_book"
/obj/item/spellbook/oneuse/random/initialize()
. = ..()
var/static/banned_spells = list(/obj/item/spellbook/oneuse/mime, /obj/item/spellbook/oneuse/mime/fingergun, /obj/item/spellbook/oneuse/mime/fingergun/fake, /obj/item/spellbook/oneuse/mime/greaterwall)
var/real_type = pick(subtypesof(/obj/item/spellbook/oneuse) - banned_spells)
new real_type(loc)
qdel(src)
-1
View File
@@ -7,7 +7,6 @@
required_players = 20
required_enemies = 1
recommended_enemies = 1
free_golems_disabled = TRUE
var/use_huds = 0
var/finished = 0
var/but_wait_theres_more = 0
+19 -18
View File
@@ -601,28 +601,29 @@ proc/get_all_job_icons() //For all existing HUD icons
return GLOB.joblist + list("Prisoner")
/obj/proc/GetJobName() //Used in secHUD icon generation
var/obj/item/card/id/I
var/assignmentName = "Unknown"
var/rankName = "Unknown"
if(istype(src, /obj/item/pda))
var/obj/item/pda/P = src
I = P.id
assignmentName = P.ownjob
rankName = P.ownrank
else if(istype(src, /obj/item/card/id))
I = src
var/obj/item/card/id/I = src
assignmentName = I.assignment
rankName = I.rank
if(I)
var/job_icons = get_all_job_icons()
var/centcom = get_all_centcom_jobs()
var/job_icons = get_all_job_icons()
var/centcom = get_all_centcom_jobs()
if(I.assignment in centcom) //Return with the NT logo if it is a Centcom job
return "Centcom"
if(I.rank in centcom)
return "Centcom"
if(I.assignment in job_icons) //Check if the job has a hud icon
return I.assignment
if(I.rank in job_icons)
return I.rank
else
return
if(assignmentName in centcom) //Return with the NT logo if it is a Centcom job
return "Centcom"
if(rankName in centcom)
return "Centcom"
if(assignmentName in job_icons) //Check if the job has a hud icon
return assignmentName
if(rankName in job_icons)
return rankName
return "Unknown" //Return unknown if none of the above apply
+31
View File
@@ -193,7 +193,38 @@
backpack = /obj/item/storage/backpack/explorer
satchel = /obj/item/storage/backpack/explorer
/datum/outfit/job/mining/equipped
name = "Shaft Miner"
suit = /obj/item/clothing/suit/hooded/explorer
mask = /obj/item/clothing/mask/gas/explorer
glasses = /obj/item/clothing/glasses/meson
suit_store = /obj/item/tank/emergency_oxygen
internals_slot = slot_s_store
backpack_contents = list(
/obj/item/flashlight/seclite=1,\
/obj/item/kitchen/knife/combat/survival=1,
/obj/item/mining_voucher=1,
/obj/item/t_scanner/adv_mining_scanner/lesser=1,
/obj/item/gun/energy/kinetic_accelerator=1,\
/obj/item/stack/marker_beacon/ten=1
)
backpack = /obj/item/storage/backpack/explorer
satchel = /obj/item/storage/backpack/explorer
/datum/outfit/job/miner/equipped/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()
if(visualsOnly)
return
if(istype(H.wear_suit, /obj/item/clothing/suit/hooded))
var/obj/item/clothing/suit/hooded/S = H.wear_suit
S.ToggleHood()
/datum/outfit/job/miner/equipped/hardsuit
name = "Shaft Miner (Equipment + Hardsuit)"
suit = /obj/item/clothing/suit/space/hardsuit/mining
mask = /obj/item/clothing/mask/breath
//Griff //BS12 EDIT
+1 -1
View File
@@ -99,7 +99,7 @@
icon_state = "table2-idle"
return 0
/obj/machinery/optable/Crossed(atom/movable/AM)
/obj/machinery/optable/Crossed(atom/movable/AM, oldloc)
. = ..()
if(iscarbon(AM) && LAZYLEN(injected_reagents))
to_chat(AM, "<span class='danger'>You feel a series of tiny pricks!</span>")
+1 -1
View File
@@ -357,7 +357,7 @@
return O:id_tag in sensors
/obj/machinery/computer/general_air_control/linkWith(mob/user, obj/O, link/context)
sensors[O:id_tag] = reject_bad_name(input(user, "Choose a sensor label:", "Sensor Label") as text|null, allow_numbers=1)
sensors[O:id_tag] = reject_bad_name(clean_input(user, "Choose a sensor label:", "Sensor Label"), allow_numbers=1)
return 1
/obj/machinery/computer/general_air_control/large_tank_control
@@ -334,9 +334,6 @@
/obj/item/circuitboard/white_ship
name = "circuit Board (White Ship)"
build_path = /obj/machinery/computer/shuttle/white_ship
/obj/item/circuitboard/golem_ship
name = "circuit Board (Golem Ship)"
build_path = /obj/machinery/computer/shuttle/golem_ship
/obj/item/circuitboard/shuttle/syndicate
name = "circuit board (Syndicate Shuttle)"
build_path = /obj/machinery/computer/shuttle/syndicate
@@ -346,7 +343,9 @@
/obj/item/circuitboard/shuttle/syndicate/drop_pod
name = "circuit board (Syndicate Drop Pod)"
build_path = /obj/machinery/computer/shuttle/syndicate/drop_pod
/obj/item/circuitboard/shuttle/golem_ship
name = "circuit Board (Golem Ship)"
build_path = /obj/machinery/computer/shuttle/golem_ship
/obj/item/circuitboard/HolodeckControl
name = "Circuit board (Holodeck Control)"
@@ -156,7 +156,7 @@
message_cooldown = 0
if("callshuttle")
var/input = input(usr, "Please enter the reason for calling the shuttle.", "Shuttle Call Reason.","") as text|null
var/input = clean_input("Please enter the reason for calling the shuttle.", "Shuttle Call Reason.","")
if(!input || ..() || !is_authenticated(usr))
SSnanoui.update_uis(src)
return
@@ -217,11 +217,11 @@
setMenuState(usr,COMM_SCREEN_STAT)
if("setmsg1")
stat_msg1 = input("Line 1", "Enter Message Text", stat_msg1) as text|null
stat_msg1 = clean_input("Line 1", "Enter Message Text", stat_msg1)
setMenuState(usr,COMM_SCREEN_STAT)
if("setmsg2")
stat_msg2 = input("Line 2", "Enter Message Text", stat_msg2) as text|null
stat_msg2 = clean_input("Line 2", "Enter Message Text", stat_msg2)
setMenuState(usr,COMM_SCREEN_STAT)
if("nukerequest")
+1 -1
View File
@@ -466,7 +466,7 @@
active2.fields["comments"] -= active2.fields["comments"][index]
if(href_list["search"])
var/t1 = input("Search String: (Name, DNA, or ID)", "Med. records", null, null) as text
var/t1 = clean_input("Search String: (Name, DNA, or ID)", "Med. records", null, null)
if(!t1 || ..())
return 1
active1 = null
+5 -5
View File
@@ -281,7 +281,7 @@
auth = 0
screen = 0
else
var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null)
var/dkey = trim(clean_input("Please enter the decryption key."))
if(dkey && dkey != "")
if(src.linkedServer.decryptkey == dkey)
auth = 1
@@ -332,7 +332,7 @@
message = noserver
else
if(auth)
var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null)
var/dkey = trim(clean_input("Please enter the decryption key."))
if(dkey && dkey != "")
if(src.linkedServer.decryptkey == dkey)
var/newkey = trim(input(usr,"Please enter the new key (3 - 16 characters max):"))
@@ -395,7 +395,7 @@
//Select Your Name
if("Sender")
customsender = input(usr, "Please enter the sender's name.") as text|null
customsender = clean_input("Please enter the sender's name.")
//Select Receiver
if("Recepient")
@@ -414,11 +414,11 @@
//Enter custom job
if("RecJob")
customjob = input(usr, "Please enter the sender's job.") as text|null
customjob = clean_input("Please enter the sender's job.")
//Enter message
if("Message")
custommessage = input(usr, "Please enter your message.") as text|null
custommessage = clean_input("Please enter your message.")
custommessage = sanitize(copytext(custommessage, 1, MAX_MESSAGE_LEN))
//Send message
+1 -1
View File
@@ -398,7 +398,7 @@
switch(href_list["field"])
if("name")
if(istype(active1, /datum/data/record))
var/t1 = reject_bad_name(input("Please input name:", "Secure. records", active1.fields["name"], null) as text)
var/t1 = reject_bad_name(clean_input("Please input name:", "Secure. records", active1.fields["name"], null))
if(!t1 || !length(trim(t1)) || ..() || active1 != a1)
return 1
active1.fields["name"] = t1
+1 -1
View File
@@ -245,7 +245,7 @@
switch(href_list["field"])
if("name")
if(istype(active1, /datum/data/record))
var/t1 = reject_bad_name(input("Please input name:", "Secure. records", active1.fields["name"], null) as text)
var/t1 = reject_bad_name(clean_input("Please input name:", "Secure. records", active1.fields["name"], null))
if(!t1 || !length(trim(t1)) || incapable || active1 != a1)
return 1
active1.fields["name"] = t1
@@ -76,6 +76,21 @@
name = "Airlock Controller"
tag_secure = 1
/obj/machinery/embedded_controller/radio/airlock/airlock_controller/Initialize(mapload, given_id_tag, given_frequency, given_tag_exterior_door, given_tag_interior_door, given_tag_airpump, given_tag_chamber_sensor)
if(given_id_tag)
id_tag = given_id_tag
if(given_frequency)
set_frequency(given_frequency)
if(given_tag_exterior_door)
tag_exterior_door = given_tag_exterior_door
if(given_tag_interior_door)
tag_interior_door = given_tag_interior_door
if(given_tag_airpump)
tag_airpump = given_tag_airpump
if(given_tag_chamber_sensor)
tag_chamber_sensor = given_tag_chamber_sensor
..()
/obj/machinery/embedded_controller/radio/airlock/airlock_controller/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
@@ -129,7 +144,6 @@
name = "Access Controller"
tag_secure = 1
/obj/machinery/embedded_controller/radio/airlock/access_controller/update_icon()
if(on && program)
if(program.memory["processing"])
+1 -3
View File
@@ -553,9 +553,7 @@ Class Procs:
threatcount += 2
if(check_records || check_arrest)
var/perpname = perp.name
if(id)
perpname = id.registered_name
var/perpname = perp.get_visible_name(TRUE)
var/datum/data/record/R = find_security_record("name", perpname)
if(check_records && !R)
+3 -3
View File
@@ -409,10 +409,10 @@ GLOBAL_DATUM_INIT(nttc_config, /datum/nttc_configuration, new())
// if(href_list["table"] && href_list["table"] in tables)
// if(requires_unlock[href_list["table"]] && !source.unlocked)
// return
// var/new_key = input(user, "Provide a key for the new row.", "New Row") as text|null
// var/new_key = clean_input(user, "Provide a key for the new row.", "New Row")
// if(!new_key)
// return
// var/new_value = input(user, "Provide a new value for the key [new_key]", "New Row") as text|null
// var/new_value = clean_input(user, "Provide a new value for the key [new_key]", "New Row")
// if(new_value == null)
// return
// if(word_blacklist.Find(new_value)) //uh oh, they tried to be naughty
@@ -439,7 +439,7 @@ GLOBAL_DATUM_INIT(nttc_config, /datum/nttc_configuration, new())
if(href_list["array"] && href_list["array"] in arrays)
if(requires_unlock[href_list["array"]] && !source.unlocked)
return
var/new_value = input(user, "Provide a value for the new index.", "New Index") as text|null
var/new_value = clean_input(user, "Provide a value for the new index.", "New Index")
if(new_value == null)
return
var/list/array = vars[href_list["array"]]
+1
View File
@@ -1083,6 +1083,7 @@
premium = list(/obj/item/clothing/mask/cigarette/cigar/havana = 2,
/obj/item/storage/fancy/cigarettes/cigpack_robustgold = 1,
/obj/item/lighter/zippo = 3)
prices = list()
/obj/machinery/vending/cigarette/New()
..()
+45 -37
View File
@@ -13,26 +13,28 @@
/obj/machinery/wish_granter/attack_hand(mob/living/carbon/user)
. = ..()
if(.)
return
return ..()
if(charges <= 0)
to_chat(user, "The Wish Granter lies silent.")
return
to_chat(user, "<span class='warning'>The Wish Granter lies silent.</span>")
return TRUE
else if(!ishuman(user))
to_chat(user, "You feel a dark stirring inside of the Wish Granter, something you want nothing of. Your instincts are better than any man's.")
to_chat(user, "<span class='warning'>You feel a dark stirring inside of the Wish Granter, something you want nothing of. Your instincts are better than any man's..</span>")
return
else if(is_special_character(user))
to_chat(user, "Even to a heart as dark as yours, you know nothing good will come of this. Something instinctual makes you pull away.")
to_chat(user, "<span class='warning'>Even to a heart as dark as yours, you know nothing good will come of this. Something instinctual makes you pull away.</span>")
else if(!insisting)
to_chat(user, "Your first touch makes the Wish Granter stir, listening to you. Are you really sure you want to do this?")
to_chat(user, "<span class='warning'>Your first touch makes the Wish Granter stir, listening to you. Are you really sure you want to do this?</span>")
insisting = TRUE
else
to_chat(user, "You speak. [pick("I want the station to disappear", "Humanity is corrupt, mankind must be destroyed", "I want to be rich", "I want to rule the world", "I want immortality.")]. The Wish Granter answers.")
to_chat(user, "Your head pounds for a moment, before your vision clears. You are the avatar of the Wish Granter, and your power is LIMITLESS! And it's all yours. You need to make sure no one can take it from you. No one can know, first.")
to_chat(user, "<span class='notice'>You speak. [pick("I want the station to disappear", "Humanity is corrupt, mankind must be destroyed", "I want to be rich", "I want to rule the world", "I want immortality.")]. The Wish Granter answers.</span>")
to_chat(user, "<span class='notice'>Your head pounds for a moment, before your vision clears. You are the avatar of the Wish Granter, and your power is LIMITLESS! And it's all yours. You need to make sure no one can take it from you. No one can know, first.</span>")
charges--
insisting = FALSE
@@ -46,37 +48,43 @@
var/list/types = list()
/obj/machinery/wish_granter/super/attack_hand(mob/living/carbon/user)
. = ..()
if(.)
return ..()
if(!ishuman(user))
to_chat(user, "You feel a dark stirring inside of the Wish Granter, something you want nothing of. Your instincts are better than any man's.")
return
else if(is_special_character(user) || jobban_isbanned(user, ROLE_TRAITOR) || jobban_isbanned(user, "Syndicate"))
to_chat(user, "Something instinctual makes you pull away.")
return
to_chat(user, "<span class='warning'>You feel a dark stirring inside of the Wish Granter, something you want nothing of. Your instincts are better than any man's.</warning>")
return TRUE
if(is_special_character(user) || jobban_isbanned(user, ROLE_TRAITOR) || jobban_isbanned(user, "Syndicate"))
to_chat(user, "<span class='warning'>Something instinctual makes you pull away.</span>")
return TRUE
to_chat(user, "<span class='notice'>Your touch makes the Wish Granter stir. Are you really sure you want to do this?</span>")
for(var/supname in GLOB.all_superheroes)
types += supname
var/wish
if(types.len == 1)
wish = pick(types)
else
to_chat(user, "Your touch makes the Wish Granter stir. Are you really sure you want to do this?")
for(var/supname in GLOB.all_superheroes)
types += supname
var/wish
if(types.len == 1)
wish = pick(types)
else
wish = input("You want to become...","Wish") as null|anything in types
wish = input("You want to become...", "Wish") as null|anything in types
if(!src || !wish || user.stat == DEAD || (get_dist(src, user) > 4)) //another check after the input to check if someone already used it, closed it, or if they're dead, or if they ran off
return
if(!wish || user.stat == DEAD || (get_dist(src, user) > 4)) // Another check after the input to check if someone already used it, closed it, or if they're dead, or if they ran off.
return
var/datum/superheroes/S = GLOB.all_superheroes[wish]
if(S.activated)
to_chat(user,"<span class='warning'>There can only be one! Pick something else!</span>")
return
var/datum/superheroes/S = GLOB.all_superheroes[wish]
if(S.activated)
to_chat(user,"<span class='warning'>There can only be one! Pick something else!</span>")
return
S.create(user)
S.activated = TRUE //sets this superhero as taken so we don't have duplicates
playsound(src.loc, 'sound/effects/bamf.ogg', 50, 1)
visible_message("<span class='notice'>The wishgranter fades into mist..</span>")
add_attack_logs(null, user, "Became [GLOB.all_superheroes[wish]]")
notify_ghosts("[GLOB.all_superheroes[wish]] has appeared in [get_area(user)].", source = user)
qdel(src)
S.create(user)
S.activated = TRUE //sets this superhero as taken so we don't have duplicates
playsound(src.loc, 'sound/effects/bamf.ogg', 50, 1)
visible_message("<span class='notice'>The wishgranter fades into mist..</span>")
add_attack_logs(null, user, "Became [GLOB.all_superheroes[wish]]")
notify_ghosts("[GLOB.all_superheroes[wish]] has appeared in [get_area(user)].", source = user)
qdel(src)
+1
View File
@@ -23,6 +23,7 @@
infra_luminosity = 15 //byond implementation is bugged.
force = 5
armor = list(melee = 20, bullet = 10, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
var/ruin_mecha = FALSE //if the mecha starts on a ruin, don't automatically give it a tracking beacon to prevent metagaming.
var/initial_icon = null //Mech type for resetting icon. Only used for reskinning kits (see custom items)
var/can_move = 0 // time of next allowed movement
var/mob/living/carbon/occupant = null
+2 -1
View File
@@ -3,4 +3,5 @@
/obj/mecha/working/New()
..()
trackers += new /obj/item/mecha_parts/mecha_tracking(src)
if(!ruin_mecha)
trackers += new /obj/item/mecha_parts/mecha_tracking(src)
@@ -88,7 +88,7 @@ var/global/list/image/splatter_cache = list()
return TRUE
//Add "bloodiness" of this blood's type, to the human's shoes
/obj/effect/decal/cleanable/blood/Crossed(atom/movable/O)
/obj/effect/decal/cleanable/blood/Crossed(atom/movable/O, oldloc)
if(!off_floor && ishuman(O))
var/mob/living/carbon/human/H = O
var/obj/item/organ/external/l_foot = H.get_organ("l_foot")
@@ -29,7 +29,7 @@ var/global/list/image/fluidtrack_cache = list()
blood_state = BLOOD_STATE_HUMAN //the icon state to load images from
/obj/effect/decal/cleanable/blood/footprints/Crossed(atom/movable/O)
/obj/effect/decal/cleanable/blood/footprints/Crossed(atom/movable/O, oldloc)
if(ishuman(O))
var/mob/living/carbon/human/H = O
var/obj/item/clothing/shoes/S = H.shoes
+4 -4
View File
@@ -345,7 +345,7 @@ steam.start() -- spawns the effect
return 1
/obj/effect/effect/bad_smoke/Crossed(mob/living/carbon/M as mob )
/obj/effect/effect/bad_smoke/Crossed(mob/living/carbon/M as mob, oldloc)
..()
if(istype(M, /mob/living/carbon))
if(M.internal != null && M.wear_mask && (M.wear_mask.flags & AIRTIGHT))
@@ -569,7 +569,7 @@ steam.start() -- spawns the effect
M.coughedtime = 0
return
/obj/effect/effect/sleep_smoke/Crossed(mob/living/carbon/M as mob )
/obj/effect/effect/sleep_smoke/Crossed(mob/living/carbon/M as mob, oldloc)
..()
if(istype(M, /mob/living/carbon))
if(M.internal != null && M.wear_mask && (M.wear_mask.flags & AIRTIGHT))
@@ -672,7 +672,7 @@ steam.start() -- spawns the effect
R.updatehealth()
return
/obj/effect/effect/mustard_gas/Crossed(mob/living/carbon/human/R as mob )
/obj/effect/effect/mustard_gas/Crossed(mob/living/carbon/human/R as mob, oldloc)
..()
if(istype(R, /mob/living/carbon/human))
if(R.internal != null && usr.wear_mask && (R.wear_mask.flags & AIRTIGHT) && R.wear_suit != null && !istype(R.wear_suit, /obj/item/clothing/suit/storage/labcoat) && !istype(R.wear_suit, /obj/item/clothing/suit/straight_jacket) && !istype(R.wear_suit, /obj/item/clothing/suit/straight_jacket && !istype(R.wear_suit, /obj/item/clothing/suit/armor)))
@@ -984,7 +984,7 @@ steam.start() -- spawns the effect
qdel(src)
/obj/structure/foam/Crossed(var/atom/movable/AM)
/obj/structure/foam/Crossed(var/atom/movable/AM, oldloc)
if(metal)
return
@@ -94,7 +94,7 @@
spawn(5)
qdel(src)
/obj/effect/particle_effect/foam/Crossed(atom/movable/AM)
/obj/effect/particle_effect/foam/Crossed(atom/movable/AM, oldloc)
if(metal)
return
@@ -52,7 +52,7 @@
steps--
return 1
/obj/effect/particle_effect/smoke/Crossed(mob/living/M)
/obj/effect/particle_effect/smoke/Crossed(mob/living/M, oldloc)
if(!istype(M))
return
smoke_mob(M)
@@ -207,4 +207,4 @@
return 1
/datum/effect_system/smoke_spread/sleeping
effect_type = /obj/effect/particle_effect/smoke/sleeping
effect_type = /obj/effect/particle_effect/smoke/sleeping
+1 -1
View File
@@ -11,7 +11,7 @@
/obj/effect/mine/proc/mineEffect(mob/living/victim)
to_chat(victim, "<span class='danger'>*click*</span>")
/obj/effect/mine/Crossed(AM as mob|obj)
/obj/effect/mine/Crossed(AM as mob|obj, oldloc)
if(!isliving(AM))
return
var/mob/living/M = AM
+4 -5
View File
@@ -3,7 +3,6 @@
desc = "Looks unstable. Best to test it with the clown."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "portal"
density = TRUE
unacidable = TRUE
anchored = TRUE
@@ -17,9 +16,6 @@
var/can_multitool_to_remove = FALSE
var/ignore_tele_proof_area_setting = FALSE
/obj/effect/portal/Bumped(mob/M as mob|obj)
teleport(M)
/obj/effect/portal/New(loc, turf/target, creator = null, lifespan = 300)
..()
@@ -49,10 +45,13 @@
/obj/effect/portal/singularity_act()
return
/obj/effect/portal/Crossed(atom/movable/AM)
/obj/effect/portal/Crossed(atom/movable/AM, oldloc)
if(isobserver(AM))
return ..()
if(target && (get_turf(oldloc) == get_turf(target)))
return ..()
if(!teleport(AM))
return ..()
@@ -0,0 +1,345 @@
/*
Spawners for mappers. Just plonk one down of the desired size and it will place the machinery for you. The red arrow things indicate where the chamber is.
This spawner places pipe leading up to the interior door, you will need to finish it off yourself with a connector, canister, and pipe connecting the two. It also assumes you already put in wall and floor.
*/
#define HALF_X round((tiles_in_x_direction - 1) * 0.5) //These are required so that the airlock can be in the middle of the chamber wall
#define HALF_Y round((tiles_in_y_direction - 1) * 0.5)
#define CHAMBER_LONG 1
#define CHAMBER_SQUARE 2
#define CHAMBER_BIGGER 3
#define DOOR_NORMAL_PLACEMENT 1
#define DOOR_FLIPPED_PLACEMENT 2
#define AIRPUMP_TAG "[id_to_link]_pump"
#define SENSOR_TAG "[id_to_link]_sensor"
#define OUTER_DOOR_TAG "[id_to_link]_outer"
#define INNER_DOOR_TAG "[id_to_link]_inner"
/obj/effect/spawner/airlock
name = "1 by 1 airlock spawner (interior north, exterior south)"
desc = "If you can see this, there's probably a missing airlock here. Better tell an admin and report this on the github."
icon = 'icons/obj/airlock_spawner.dmi'
icon_state = "1x1_N_to_S"
layer = SPLASHSCREEN_PLANE //So we absolutely always appear above everything else. We delete ourself after spawning so this is fine
var/interior_direction = NORTH //This is also the direction the spawner will send the pipe
var/exterior_direction = SOUTH
var/opposite_interior_direction //We're checking these often enough for them to merit their own vars
var/interior_direction_cw
var/interior_direction_ccw
var/north_or_south_interior //Used a bit everywhere for locational stuff
var/north_or_south_exterior //Likewise
var/tiles_in_x_direction = 1
var/tiles_in_y_direction = 1
var/id_to_link
var/radio_frequency = 1379
var/required_access = list(access_external_airlocks)
var/door_name = "external access"
var/door_type = /obj/machinery/door/airlock/external/glass
var/one_door_interior //For square airlocks, if you set this then a) only one door will spawn, and b) you can choose if the door should go opposite to how it normally goes. Please use the define
var/one_door_exterior //See above
/obj/effect/spawner/airlock/Initialize()
..()
forceMove(locate(x + 1, y + 1, z)) //Needs to move because our icon_state implies we are one turf to the northeast, when we're not
opposite_interior_direction = turn(interior_direction, 180) //Do it this way (instead of setting it directly) to avoid code mishaps
interior_direction_cw = turn(interior_direction, 90)
interior_direction_ccw = turn(interior_direction, 270)
if(interior_direction == NORTH || interior_direction == SOUTH)
north_or_south_interior = TRUE
if(exterior_direction == NORTH || exterior_direction == SOUTH)
north_or_south_exterior = TRUE
id_to_link = "[UID()]" //We want unique IDs, this will give us a unique ID
var/turf/turf_interior = get_airlock_location(interior_direction)
var/turf/turf_exterior = get_airlock_location(exterior_direction)
handle_door_creation(turf_interior, TRUE, one_door_interior)
handle_door_creation(turf_exterior, FALSE, one_door_exterior)
handle_pipes_creation(turf_interior)
handle_control_placement()
qdel(src)
/obj/effect/spawner/airlock/proc/get_airlock_location(desired_direction) //Finds a turf to place an airlock and returns it, this turf will be in the middle of the relevant wall
var/turf/T
switch(desired_direction)
if(NORTH)
T = locate(x + HALF_X, y + tiles_in_y_direction, z)
if(SOUTH)
T = locate(x + HALF_X, y - 1, z)
if(EAST)
T = locate(x + tiles_in_x_direction, y + HALF_Y, z)
if(WEST)
T = locate(x - 1, y + HALF_Y, z)
return T
/obj/effect/spawner/airlock/proc/handle_door_creation(turf/T, is_this_an_interior_airlock, one_door_only) //Creates a door (or two) and also creates a button
var/obj/machinery/door/airlock/A
if(one_door_only != DOOR_FLIPPED_PLACEMENT)
A = new door_type(T)
handle_door_stuff(A, is_this_an_interior_airlock)
var/obj/machinery/access_button/the_button = spawn_button(T, is_this_an_interior_airlock ? interior_direction : exterior_direction)
if(one_door_only == DOOR_NORMAL_PLACEMENT) //We only need one door, we are done
return
if(!(tiles_in_x_direction % 2) && (is_this_an_interior_airlock && north_or_south_interior || !is_this_an_interior_airlock && north_or_south_exterior)) //Handle extra airlock for aesthetics
A = new door_type(get_step(T, EAST))
handle_door_stuff(A, is_this_an_interior_airlock)
if(one_door_only == DOOR_FLIPPED_PLACEMENT)
the_button.forceMove(get_step(the_button, EAST))
else if(!(tiles_in_y_direction % 2) && (is_this_an_interior_airlock && !north_or_south_interior || !is_this_an_interior_airlock && !north_or_south_exterior)) //Handle extra airlock for aesthetics
A = new door_type(get_step(T, NORTH))
handle_door_stuff(A, is_this_an_interior_airlock)
if(one_door_only == DOOR_FLIPPED_PLACEMENT)
the_button.forceMove(get_step(the_button, NORTH))
/obj/effect/spawner/airlock/proc/handle_door_stuff(obj/machinery/door/airlock/A, is_this_an_interior_airlock) //This sets up the door vars correctly and then locks it before first use
A.set_frequency(radio_frequency)
A.id_tag = is_this_an_interior_airlock ? INNER_DOOR_TAG : OUTER_DOOR_TAG
A.req_access = required_access
A.name = door_name
A.lock()
/obj/effect/spawner/airlock/proc/spawn_button(turf/T, some_direction)
var/obj/machinery/access_button/the_button = new(T)
the_button.master_tag = id_to_link
the_button.set_frequency(radio_frequency)
switch(some_direction)
if(NORTH)
the_button.pixel_x -= 25
the_button.pixel_y = 7
if(EAST)
the_button.pixel_x = 7
the_button.pixel_y = -25
if(SOUTH)
the_button.pixel_x -= 25
the_button.pixel_y -= 7
if(WEST)
the_button.pixel_x -= 7
the_button.pixel_y -= 25
the_button.req_access = required_access
return the_button
/obj/effect/spawner/airlock/proc/handle_control_placement() //Stick the sensor and controller on the same bit of wall, this will ONLY be unsuitable if airlocks are on both the south and west turfs
var/turf/T = get_turf(src)
var/obj/machinery/airlock_sensor/AS = new(T)
var/obj/machinery/embedded_controller/radio/airlock/airlock_controller/AC = new(T, id_to_link, radio_frequency, OUTER_DOOR_TAG, INNER_DOOR_TAG, AIRPUMP_TAG, SENSOR_TAG)
AC.req_access = required_access
AS.id_tag = SENSOR_TAG
AS.set_frequency(radio_frequency)
if(interior_direction != WEST && exterior_direction != WEST) //If west wall is free, place stuff there
AC.pixel_x -= 25
AC.pixel_y += 9
AS.pixel_x -= 25
AS.pixel_y -= 9
else if(interior_direction != SOUTH && exterior_direction != SOUTH) //If south wall is free, place stuff there
AC.pixel_x += 9
AC.pixel_y -= 25
AS.pixel_x -= 9
AS.pixel_y -= 25
else //Send them over to the other side of the chamber
T = locate(x + tiles_in_x_direction - 1, y + tiles_in_y_direction - 1, z)
AC.forceMove(T)
AS.forceMove(T)
AC.pixel_x += 25
AC.pixel_y += 9
AS.pixel_x += 25
AS.pixel_y -= 9
/obj/effect/spawner/airlock/proc/handle_pipes_creation(turf/T) //This places all required piping down, then properly initializes it. T is the turf that the interior airlock occupies
var/turf/below_T = get_step(T, opposite_interior_direction)
var/two_way_pipe = interior_direction | opposite_interior_direction
var/chamber_shape //This determines the layout of the chamber and therefore how many vents should be present
if(tiles_in_x_direction == 2 && tiles_in_y_direction == 2)
chamber_shape = CHAMBER_SQUARE
else if(tiles_in_x_direction > 1 && tiles_in_y_direction > 1)
chamber_shape = CHAMBER_BIGGER
else
chamber_shape = CHAMBER_LONG
pipe_creation_helper(/obj/machinery/atmospherics/pipe/simple/visible, T, interior_direction, two_way_pipe)
switch(chamber_shape)
if(CHAMBER_LONG) //Easy enough, place a single vent
pipe_creation_helper(/obj/machinery/atmospherics/unary/vent_pump/high_volume,
below_T,
interior_direction)
if(CHAMBER_SQUARE) //We need a T-manifold and two vents for this
pipe_creation_helper(/obj/machinery/atmospherics/pipe/manifold/visible,
below_T,
north_or_south_interior ? WEST : SOUTH,
NORTH | EAST | (north_or_south_interior ? SOUTH : WEST))
pipe_creation_helper(/obj/machinery/atmospherics/unary/vent_pump/high_volume,
get_step(below_T, opposite_interior_direction),
interior_direction)
pipe_creation_helper(/obj/machinery/atmospherics/unary/vent_pump/high_volume,
north_or_south_interior ? EAST_OF_TURF(below_T) : NORTH_OF_TURF(below_T),
turn(interior_direction, interior_direction == SOUTH || interior_direction == EAST ? -90 : 90))
if(CHAMBER_BIGGER) //We need a central column of manifolds and a vent either side of each manifold
var/depth = north_or_south_interior ? tiles_in_y_direction : tiles_in_x_direction
var/turf/put_thing_here = below_T
for(var/i in 1 to depth)
if(i != depth)//We're placing more pipe later, so we need a 4-way manifold
pipe_creation_helper(/obj/machinery/atmospherics/pipe/manifold4w/visible, put_thing_here, interior_direction, NORTH | EAST | SOUTH | WEST)
else //We stop here, so place a T-manifold down
pipe_creation_helper(/obj/machinery/atmospherics/pipe/manifold/visible,
put_thing_here,
opposite_interior_direction,
interior_direction_cw | interior_direction | interior_direction_ccw)
pipe_creation_helper(/obj/machinery/atmospherics/unary/vent_pump/high_volume,
get_step(put_thing_here, interior_direction_cw),
interior_direction_ccw)
pipe_creation_helper(/obj/machinery/atmospherics/unary/vent_pump/high_volume,
get_step(put_thing_here, interior_direction_ccw),
interior_direction_cw)
put_thing_here = get_step(put_thing_here, opposite_interior_direction) //Now move the turf we're generating stuff from 1 forward
/obj/effect/spawner/airlock/proc/pipe_creation_helper(path, location, direction, initialization_directions) //Create some kind of atmospherics machinery and initialize it properly
var/obj/machinery/atmospherics/A = new path(location)
A.dir = direction
A.on_construction(A.dir, initialization_directions ? initialization_directions : A.dir)
if(istype(A, /obj/machinery/atmospherics/unary/vent_pump/high_volume))
var/obj/machinery/atmospherics/unary/vent_pump/high_volume/created_pump = A
created_pump.id_tag = AIRPUMP_TAG
created_pump.set_frequency(radio_frequency)
//Premade airlocks for mappers, probably won't need all of these but whatever
/obj/effect/spawner/airlock/s_to_n
name = "1 by 1 airlock spawner (interior south, exterior north)"
icon_state = "1x1_S_to_N"
interior_direction = SOUTH
exterior_direction = NORTH
/obj/effect/spawner/airlock/e_to_w
name = "1 by 1 airlock spawner (interior east, exterior west)"
icon_state = "1x1_E_to_W"
interior_direction = EAST
exterior_direction = WEST
/obj/effect/spawner/airlock/w_to_e
name = "1 by 1 airlock spawner (interior west, exterior east)"
icon_state = "1x1_W_to_E"
interior_direction = WEST
exterior_direction = EAST
/obj/effect/spawner/airlock/long //Long and thin
name = "long airlock spawner (interior north, exterior south)"
icon_state = "1x2_N_to_S"
tiles_in_y_direction = 2
/obj/effect/spawner/airlock/s_to_n/long
name = "long airlock spawner (interior south, exterior north)"
icon_state = "1x2_S_to_N"
tiles_in_y_direction = 2
/obj/effect/spawner/airlock/e_to_w/long
name = "long airlock spawner (interior east, exterior west)"
icon_state = "1x2_E_to_W"
tiles_in_x_direction = 2
/obj/effect/spawner/airlock/w_to_e/long
name = "long airlock spawner (interior west, exterior east)"
icon_state = "1x2_W_to_E"
tiles_in_x_direction = 2
/obj/effect/spawner/airlock/long/square //Square
name = "square airlock spawner (interior north, exterior south)"
icon_state = "2x2_N_to_S"
tiles_in_x_direction = 2
/obj/effect/spawner/airlock/s_to_n/long/square
name = "square airlock spawner (interior south, exterior north)"
icon_state = "2x2_S_to_N"
tiles_in_x_direction = 2
/obj/effect/spawner/airlock/e_to_w/long/square
name = "square airlock spawner (interior east, exterior west)"
icon_state = "2x2_E_to_W"
tiles_in_y_direction = 2
/obj/effect/spawner/airlock/w_to_e/long/square
name = "square airlock spawner (interior west, exterior east)"
icon_state = "2x2_W_to_E"
tiles_in_y_direction = 2
/obj/effect/spawner/airlock/long/square/e_to_s
name = "square airlock spawner (interior east, exterior south)"
icon_state = "2x2_E_to_S"
interior_direction = EAST
exterior_direction = SOUTH
/obj/effect/spawner/airlock/long/square/wide
name = "rectangular airlock spawner (interior north, exterior south)"
icon_state = "3x2_N_to_S"
tiles_in_x_direction = 3
/obj/effect/spawner/airlock/s_to_n/long/square/wide
name = "rectangular airlock spawner (interior south, exterior north)"
icon_state = "3x2_S_to_N"
tiles_in_x_direction = 3
/obj/effect/spawner/airlock/e_to_w/long/square/wide
name = "rectangular airlock spawner (interior east, exterior west)"
icon_state = "3x2_E_to_W"
tiles_in_y_direction = 3
/obj/effect/spawner/airlock/w_to_e/long/square/wide
name = "rectangular airlock spawner (interior west, exterior east)"
icon_state = "3x2_W_to_E"
tiles_in_y_direction = 3
/obj/effect/spawner/airlock/long/square/three
name = "3 by 3 square airlock spawner (interior north, exterior south)"
icon_state = "3x3_N_to_S"
interior_direction = NORTH
exterior_direction = SOUTH
tiles_in_x_direction = 3
tiles_in_y_direction = 3
/obj/effect/spawner/airlock/e_to_w/arrivals
required_access = null
/obj/effect/spawner/airlock/engineer
required_access = list(access_engine)
door_name = "engineering external access"
/obj/effect/spawner/airlock/e_to_w/engineer
required_access = list(access_engine)
door_name = "engineering external access"
/obj/effect/spawner/airlock/s_to_n/engineer
required_access = list(access_engine)
door_name = "engineering external access"
/obj/effect/spawner/airlock/long/engineer
required_access = list(access_engine)
door_name = "engineering external access"
/obj/effect/spawner/airlock/long/square/engine
required_access = list(access_engine)
door_name = "engine external access"
icon_state = "2x2_N_to_S_leftdoors"
door_type = /obj/machinery/door/airlock/external
one_door_interior = DOOR_NORMAL_PLACEMENT
one_door_exterior = DOOR_NORMAL_PLACEMENT
/obj/effect/spawner/airlock/long/square/engine/reversed
icon_state = "2x2_N_to_S_rightdoors"
one_door_interior = DOOR_FLIPPED_PLACEMENT
one_door_exterior = DOOR_FLIPPED_PLACEMENT
/obj/effect/spawner/airlock/w_to_e/long/square/wide/mining
door_name = "mining external access"
required_access = list(access_mining)
/obj/effect/spawner/airlock/long/square/wide/mining
door_name = "mining external access"
required_access = list(access_mining)
/obj/effect/spawner/airlock/e_to_w/minisat
door_name = "minisat external access"
required_access = list(access_minisat)
/obj/effect/spawner/airlock/long/square/e_to_s/telecoms
door_name = "telecoms external access"
required_access = list(access_tcomsat, access_external_airlocks)
door_type = /obj/machinery/door/airlock/external
/obj/effect/spawner/airlock/long/square/three/syndicate
name = "3 by 3 square airlock spawner (interior west, exterior north)"
icon_state = "3x3_W_to_N"
interior_direction = WEST
exterior_direction = NORTH
door_name = "ship external access"
req_access = list(access_syndicate)
door_type = /obj/machinery/door/airlock/external
#undef HALF_X
#undef HALF_Y
#undef CHAMBER_LONG
#undef CHAMBER_SQUARE
#undef CHAMBER_BIGGER
#undef DOOR_NORMAL_PLACEMENT
#undef DOOR_FLIPPED_PLACEMENT
#undef AIRPUMP_TAG
#undef SENSOR_TAG
#undef OUTER_DOOR_TAG
#undef INNER_DOOR_TAG
+139 -58
View File
@@ -1,23 +1,43 @@
/* Simple object type, calls a proc when "stepped" on by something */
/obj/effect/step_trigger
var/affect_ghosts = 0
var/stopper = 1 // stops throwers
invisibility = 101 // nope cant see this shit
anchored = 1
var/affect_ghosts = FALSE
var/stopper = TRUE // stops throwers
var/mobs_only = FALSE
invisibility = INVISIBILITY_ABSTRACT // nope cant see this shit
anchored = TRUE
/obj/effect/step_trigger/proc/Trigger(var/atom/movable/A)
return 0
return FALSE
/obj/effect/step_trigger/Crossed(H as mob|obj)
..()
/obj/effect/step_trigger/Crossed(var/H, oldloc)
. = ..()
if(!H)
return
if(istype(H, /mob/dead/observer) && !affect_ghosts)
if(isobserver(H) && !affect_ghosts)
return
if(!ismob(H) && mobs_only)
return
Trigger(H)
/obj/effect/step_trigger/singularity_act()
return
/obj/effect/step_trigger/singularity_pull()
return
/* Sends a message to mob when triggered*/
/obj/effect/step_trigger/message
var/message //the message to give to the mob
var/once = 1
mobs_only = TRUE
/obj/effect/step_trigger/message/Trigger(mob/M)
if(M.client)
to_chat(M, "<span class='info'>[message]</span>")
if(once)
qdel(src)
/* Tosses things in a certain direction */
@@ -30,57 +50,57 @@
var/nostop = 0 // if 1: will only be stopped by teleporters
var/list/affecting = list()
Trigger(var/atom/A)
if(!A || !istype(A, /atom/movable))
/obj/effect/step_trigger/thrower/Trigger(atom/A)
if(!A || !ismovableatom(A))
return
var/atom/movable/AM = A
var/curtiles = 0
var/stopthrow = 0
for(var/obj/effect/step_trigger/thrower/T in orange(2, src))
if(AM in T.affecting)
return
var/atom/movable/AM = A
var/curtiles = 0
var/stopthrow = 0
for(var/obj/effect/step_trigger/thrower/T in orange(2, src))
if(AM in T.affecting)
return
if(ismob(AM))
var/mob/M = AM
if(immobilize)
M.canmove = 0
if(isliving(AM))
var/mob/living/M = AM
if(immobilize)
M.canmove = FALSE
affecting.Add(AM)
while(AM && !stopthrow)
if(tiles)
if(curtiles >= tiles)
break
if(AM.z != src.z)
affecting.Add(AM)
while(AM && !stopthrow)
if(tiles)
if(curtiles >= tiles)
break
if(AM.z != src.z)
break
curtiles++
curtiles++
sleep(speed)
sleep(speed)
// Calculate if we should stop the process
if(!nostop)
for(var/obj/effect/step_trigger/T in get_step(AM, direction))
if(T.stopper && T != src)
stopthrow = 1
else
for(var/obj/effect/step_trigger/teleporter/T in get_step(AM, direction))
if(T.stopper)
stopthrow = 1
// Calculate if we should stop the process
if(!nostop)
for(var/obj/effect/step_trigger/T in get_step(AM, direction))
if(T.stopper && T != src)
stopthrow = 1
else
for(var/obj/effect/step_trigger/teleporter/T in get_step(AM, direction))
if(T.stopper)
stopthrow = 1
if(AM)
var/predir = AM.dir
step(AM, direction)
if(!facedir)
AM.dir = predir
if(AM)
var/predir = AM.dir
step(AM, direction)
if(!facedir)
AM.setDir(predir)
affecting.Remove(AM)
affecting.Remove(AM)
if(ismob(AM))
var/mob/M = AM
if(immobilize)
M.canmove = 1
if(isliving(AM))
var/mob/living/M = AM
if(immobilize)
M.canmove = TRUE
/* Stops things thrown by a thrower, doesn't do anything */
@@ -93,12 +113,11 @@
var/teleport_y = 0
var/teleport_z = 0
Trigger(var/atom/movable/A)
if(teleport_x && teleport_y && teleport_z)
/obj/effect/step_trigger/teleporter/Trigger(atom/movable/A)
if(teleport_x && teleport_y && teleport_z)
A.x = teleport_x
A.y = teleport_y
A.z = teleport_z
var/turf/T = locate(teleport_x, teleport_y, teleport_z)
A.forceMove(T)
/* Random teleporter, teleports atoms to locations ranging from teleport_x - teleport_x_offset, etc */
@@ -107,11 +126,73 @@
var/teleport_y_offset = 0
var/teleport_z_offset = 0
Trigger(var/atom/movable/A)
if(teleport_x && teleport_y && teleport_z)
if(teleport_x_offset && teleport_y_offset && teleport_z_offset)
/obj/effect/step_trigger/teleporter/random/Trigger(atom/movable/A)
if(teleport_x && teleport_y && teleport_z)
if(teleport_x_offset && teleport_y_offset && teleport_z_offset)
A.x = rand(teleport_x, teleport_x_offset)
A.y = rand(teleport_y, teleport_y_offset)
A.z = rand(teleport_z, teleport_z_offset)
var/turf/T = locate(rand(teleport_x, teleport_x_offset), rand(teleport_y, teleport_y_offset), rand(teleport_z, teleport_z_offset))
if (T)
A.forceMove(T)
/* Fancy teleporter, creates sparks and smokes when used */
/obj/effect/step_trigger/teleport_fancy
var/locationx
var/locationy
var/uses = 1 //0 for infinite uses
var/entersparks = 0
var/exitsparks = 0
var/entersmoke = 0
var/exitsmoke = 0
/obj/effect/step_trigger/teleport_fancy/Trigger(mob/M)
var/dest = locate(locationx, locationy, z)
M.Move(dest)
if(entersparks)
var/datum/effect_system/spark_spread/s = new
s.set_up(4, 1, src)
s.start()
if(exitsparks)
var/datum/effect_system/spark_spread/s = new
s.set_up(4, 1, dest)
s.start()
if(entersmoke)
var/datum/effect_system/smoke_spread/s = new
s.set_up(4, 1, src, 0)
s.start()
if(exitsmoke)
var/datum/effect_system/smoke_spread/s = new
s.set_up(4, 1, dest, 0)
s.start()
uses--
if(uses == 0)
qdel(src)
/* Simple sound player, Mapper friendly! */
/obj/effect/step_trigger/sound_effect
var/sound //eg. path to the sound, inside '' eg: 'growl.ogg'
var/volume = 100
var/freq_vary = 1 //Should the frequency of the sound vary?
var/extra_range = 0 // eg World.view = 7, extra_range = 1, 7+1 = 8, 8 turfs radius
var/happens_once = 0
var/triggerer_only = 0 //Whether the triggerer is the only person who hears this
/obj/effect/step_trigger/sound_effect/Trigger(atom/movable/A)
var/turf/T = get_turf(A)
if(!T)
return
if(triggerer_only && ismob(A))
var/mob/B = A
B.playsound_local(T, sound, volume, freq_vary)
else
playsound(T, sound, volume, freq_vary, extra_range)
if(happens_once)
qdel(src)
@@ -6,6 +6,10 @@
randomdir = 0
layer = ABOVE_NORMAL_TURF_LAYER
/obj/effect/temp_visual/ratvar/door
icon_state = "ratvardoorglow"
layer = CLOSED_DOOR_LAYER //above closed doors
/obj/effect/temp_visual/ratvar/door/window
icon_state = "ratvarwindoorglow"
layer = ABOVE_WINDOW_LAYER
@@ -16,9 +20,27 @@
/obj/effect/temp_visual/ratvar/beam/grille
layer = BELOW_OBJ_LAYER
/obj/effect/temp_visual/ratvar/beam/itemconsume
layer = HIGH_OBJ_LAYER
/obj/effect/temp_visual/ratvar/beam/falsewall
layer = OBJ_LAYER
/obj/effect/temp_visual/ratvar/beam/catwalk
layer = LATTICE_LAYER
/obj/effect/temp_visual/ratvar/wall
icon_state = "ratvarwallglow"
/obj/effect/temp_visual/ratvar/wall/false
layer = OBJ_LAYER
/obj/effect/temp_visual/ratvar/floor
icon_state = "ratvarfloorglow"
/obj/effect/temp_visual/ratvar/floor/catwalk
layer = LATTICE_LAYER
/obj/effect/temp_visual/ratvar/window
icon_state = "ratvarwindowglow"
layer = ABOVE_OBJ_LAYER
@@ -26,6 +48,10 @@
/obj/effect/temp_visual/ratvar/window/single
icon_state = "ratvarwindowglow_s"
/obj/effect/temp_visual/ratvar/gear
icon_state = "ratvargearglow"
layer = BELOW_OBJ_LAYER
/obj/effect/temp_visual/ratvar/grille
icon_state = "ratvargrilleglow"
layer = BELOW_OBJ_LAYER
+1 -1
View File
@@ -578,7 +578,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
/obj/item/proc/is_equivalent(obj/item/I)
return I == src
/obj/item/Crossed(atom/movable/AM)
/obj/item/Crossed(atom/movable/AM, oldloc)
. = ..()
if(prob(trip_chance) && ishuman(AM))
var/mob/living/carbon/human/H = AM
+1
View File
@@ -50,6 +50,7 @@
to_chat(user, "<span class='danger'>[D]'s ID scan is disabled!</span>")
return
if(D.check_access(src.ID))
D.add_hiddenprint(user)
switch(mode)
if(WAND_OPEN)
if(D.density)
+1 -1
View File
@@ -34,7 +34,7 @@
A.UpdateButtonIcon()
/obj/item/voice_changer/proc/set_voice(mob/user)
var/chosen_voice = input(user, "What voice would you like to mimic? Leave this empty to use the voice on your ID card.", "Set Voice Changer", voice) as text
var/chosen_voice = clean_input("What voice would you like to mimic? Leave this empty to use the voice on your ID card.", "Set Voice Changer", voice, user)
if(!chosen_voice)
voice = null
to_chat(user, "<span class='notice'>You are now mimicking the voice on your ID card.</span>")
+27 -22
View File
@@ -195,8 +195,6 @@
heal_burn = 25
//Medical Herbs//
/obj/item/stack/medical/bruise_pack/comfrey
name = "\improper Comfrey leaf"
singular_name = "Comfrey leaf"
@@ -217,48 +215,55 @@
color = "#4CC5C7"
heal_burn = 12
//Splints//
// Splints
/obj/item/stack/medical/splint
name = "medical splints"
singular_name = "medical splint"
icon_state = "splint"
unique_handling = 1
unique_handling = TRUE
self_delay = 100
var/other_delay = 0
/obj/item/stack/medical/splint/attack(mob/living/M, mob/user)
if(..())
return 1
return TRUE
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
var/limb = affecting.name
if(!(affecting.limb_name in list("l_arm", "r_arm", "l_hand", "r_hand", "l_leg", "r_leg", "l_foot", "r_foot")))
to_chat(user, "<span class='danger'>You can't apply a splint there!</span>")
return
return TRUE
if(affecting.status & ORGAN_SPLINTED)
to_chat(user, "<span class='danger'>[H]'s [limb] is already splinted!</span>")
if(alert(user, "Would you like to remove the splint from [H]'s [limb]?", "Removing.", "Yes", "No") == "Yes")
if(alert(user, "Would you like to remove the splint from [H]'s [limb]?", "Splint removal.", "Yes", "No") == "Yes")
affecting.status &= ~ORGAN_SPLINTED
H.handle_splints()
to_chat(user, "<span class='notice'>You remove the splint from [H]'s [limb].</span>")
return
if(M == user)
user.visible_message("<span class='notice'>[user] starts to apply [src] to [user.p_their()] [limb].</span>", \
"<span class='notice'>You start to apply [src] to your [limb].</span>", \
"<span class='notice'>You hear something being wrapped.</span>")
if(!do_mob(user, H, self_delay))
return
else
user.visible_message("<span class='green'>[user] applies [src] to [H]'s [limb].</span>", \
"<span class='green'>You apply [src] to [H]'s [limb].</span>", \
"<span class='green'>You hear something being wrapped.</span>")
return TRUE
if((M == user && self_delay > 0) || (M != user && other_delay > 0))
user.visible_message("<span class='notice'>[user] starts to apply [src] to [H]'s [limb].</span>", \
"<span class='notice'>You start to apply [src] to [H]'s [limb].</span>", \
"<span class='notice'>You hear something being wrapped.</span>")
if(M == user && !do_mob(user, H, self_delay))
return TRUE
else if(!do_mob(user, H, other_delay))
return TRUE
user.visible_message("<span class='notice'>[user] applies [src] to [H]'s [limb].</span>", \
"<span class='notice'>You apply [src] to [H]'s [limb].</span>")
affecting.status |= ORGAN_SPLINTED
affecting.splinted_count = H.step_count
H.handle_splints()
use(1)
/obj/item/stack/medical/splint/tribal
name = "tribal splints"
icon_state = "tribal_splint"
other_delay = 50
@@ -16,6 +16,7 @@
var/global/list/datum/stack_recipe/metal_recipes = list(
new /datum/stack_recipe("stool", /obj/structure/chair/stool, one_per_turf = 1, on_floor = 1),
new /datum/stack_recipe("chair", /obj/structure/chair, one_per_turf = 1, on_floor = 1),
new /datum/stack_recipe("shuttle seat", /obj/structure/chair/comfy/shuttle, 2, one_per_turf = 1, on_floor = 1),
new /datum/stack_recipe("sofa (middle)", /obj/structure/chair/sofa, one_per_turf = 1, on_floor = 1),
new /datum/stack_recipe("sofa (left)", /obj/structure/chair/sofa/left, one_per_turf = 1, on_floor = 1),
new /datum/stack_recipe("sofa (right)", /obj/structure/chair/sofa/right, one_per_turf = 1, on_floor = 1),
@@ -216,6 +217,8 @@ var/global/list/datum/stack_recipe/cloth_recipes = list ( \
null, \
new/datum/stack_recipe("fingerless gloves", /obj/item/clothing/gloves/fingerless, 1), \
new/datum/stack_recipe("black gloves", /obj/item/clothing/gloves/color/black, 3), \
null, \
new/datum/stack_recipe("blindfold", /obj/item/clothing/glasses/sunglasses/blindfold, 3), \
)
/obj/item/stack/sheet/cloth
@@ -335,10 +338,13 @@ var/global/list/datum/stack_recipe/cult = list ( \
* Brass
*/
var/global/list/datum/stack_recipe/brass_recipes = list (\
new/datum/stack_recipe("wall gear", /obj/structure/clockwork/wall_gear, 3, time = 10, one_per_turf = TRUE, on_floor = TRUE), \
null,
new/datum/stack_recipe/window("brass windoor", /obj/machinery/door/window/clockwork, 2, time = 30, on_floor = TRUE, window_checks = TRUE), \
null,
new/datum/stack_recipe/window("directional brass window", /obj/structure/window/reinforced/clockwork, time = 0, on_floor = TRUE, window_checks = TRUE), \
new/datum/stack_recipe/window("fulltile brass window", /obj/structure/window/reinforced/clockwork/fulltile, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \
new/datum/stack_recipe("brass chair", /obj/structure/chair/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("brass table frame", /obj/structure/table_frame/brass, 1, time = 5, one_per_turf = TRUE, on_floor = TRUE), \
)
+1 -1
View File
@@ -31,7 +31,7 @@
if(S.merge_type == merge_type)
merge(S)
/obj/item/stack/Crossed(obj/O)
/obj/item/stack/Crossed(obj/O, oldloc)
if(amount >= max_amount || ismob(loc)) // Prevents unnecessary call. Also prevents merging stack automatically in a mob's inventory
return
if(istype(O, merge_type) && !O.throwing)
+2 -1
View File
@@ -208,6 +208,7 @@
origin_tech = null
attack_verb = list("attacked", "struck", "hit")
brightness_on = 0
sharp_when_wielded = FALSE // It's a toy
/obj/item/twohanded/dualsaber/toy/hit_reaction()
return 0
@@ -283,7 +284,7 @@
..()
pop_burst()
/obj/item/toy/snappop/Crossed(H as mob|obj)
/obj/item/toy/snappop/Crossed(H as mob|obj, oldloc)
if(ishuman(H) || issilicon(H)) //i guess carp and shit shouldn't set them off
var/mob/living/carbon/M = H
if(issilicon(H) || M.m_intent == MOVE_INTENT_RUN)
+33 -9
View File
@@ -25,20 +25,34 @@
if(special_die == "100")
new /obj/item/dice/d100(src)
/obj/item/storage/pill_bottle/dice/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is gambling with death! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (OXYLOSS)
/obj/item/dice //depreciated d6, use /obj/item/dice/d6 if you actually want a d6
name = "die"
desc = "A die with six sides. Basic and servicable."
icon = 'icons/obj/dice.dmi'
icon_state = "d6"
w_class = WEIGHT_CLASS_TINY
var/sides = 6
var/result = null
var/list/special_faces = list() //entries should match up to sides var if used
/obj/item/dice/New()
result = rand(1, sides)
var/rigged = DICE_NOT_RIGGED
var/rigged_value
/obj/item/dice/Initialize(mapload)
. = ..()
if(!result)
result = roll(sides)
update_icon()
/obj/item/dice/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is gambling with death! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (OXYLOSS)
/obj/item/dice/d1
name = "d1"
desc = "A die with one side. Deterministic!"
@@ -117,11 +131,19 @@
. = ..()
/obj/item/dice/proc/diceroll(mob/user)
result = rand(1, sides)
var/fake_result = rand(1, sides)//Daredevil isn't as good as he used to be
result = roll(sides)
if(rigged != DICE_NOT_RIGGED && result != rigged_value)
if(rigged == DICE_BASICALLY_RIGGED && prob(Clamp(1/(sides - 1) * 100, 25, 80)))
result = rigged_value
else if(rigged == DICE_TOTALLY_RIGGED)
result = rigged_value
. = result
var/fake_result = roll(sides)//Daredevil isn't as good as he used to be
var/comment = ""
if(sides == 20 && result == 20)
comment = "Nat 20!"
comment = "NAT 20!"
else if(sides == 20 && result == 1)
comment = "Ouch, bad luck."
update_icon()
@@ -130,16 +152,18 @@
if(special_faces.len == sides)
result = special_faces[result]
if(user != null) //Dice was rolled in someone's hand
user.visible_message("<span class='notice'>[user] has thrown [src]. It lands on [result]. [comment]</span>", \
user.visible_message("[user] has thrown [src]. It lands on [result]. [comment]", \
"<span class='notice'>You throw [src]. It lands on [result]. [comment]</span>", \
"<span class='italics'>You hear [src] rolling, it sounds like a [fake_result].</span>")
else if(!throwing) //Dice was thrown and is coming to rest
else if(!src.throwing) //Dice was thrown and is coming to rest
visible_message("<span class='notice'>[src] rolls to a stop, landing on [result]. [comment]</span>")
/obj/item/dice/d20/e20/diceroll(mob/user as mob, thrown)
if(triggered)
return
..()
. = ..()
if(result == 1)
to_chat(user, "<span class='danger'>Rocks fall, you die.</span>")
user.gib()
@@ -166,7 +190,7 @@
/obj/item/dice/update_icon()
overlays.Cut()
overlays += "[src.icon_state][src.result]"
overlays += "[icon_state][result]"
/obj/item/storage/box/dice
name = "Box of dice"
@@ -48,9 +48,9 @@
/obj/item/grenade/plastic/receive_signal()
prime()
/obj/item/grenade/plastic/Crossed(atom/movable/AM)
/obj/item/grenade/plastic/Crossed(atom/movable/AM, oldloc)
if(nadeassembly)
nadeassembly.Crossed(AM)
nadeassembly.Crossed(AM, oldloc)
/obj/item/grenade/plastic/on_found(mob/finder)
if(nadeassembly)
@@ -239,9 +239,9 @@
if(nadeassembly)
nadeassembly.process_movement()
/obj/item/grenade/chem_grenade/Crossed(atom/movable/AM)
/obj/item/grenade/chem_grenade/Crossed(atom/movable/AM, oldloc)
if(nadeassembly)
nadeassembly.Crossed(AM)
nadeassembly.Crossed(AM, oldloc)
/obj/item/grenade/chem_grenade/on_found(mob/finder)
if(nadeassembly)
@@ -289,7 +289,7 @@
var/mob/last = get_mob_by_ckey(nadeassembly.fingerprintslast)
var/turf/T = get_turf(src)
var/area/A = get_area(T)
message_admins("grenade primed by an assembly, attached by [key_name_admin(M)][ADMIN_QUE(M,"(?)")] ([admin_jump_link(M)]) and last touched by [key_name_admin(last)][ADMIN_QUE(last,"(?)")] ([admin_jump_link(last)]) ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>[A.name] (JMP)</a>. [contained]")
message_admins("grenade primed by an assembly, attached by [key_name_admin(M)] and last touched by [key_name_admin(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>[A.name] (JMP)</a>. [contained]")
log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] ([T.x], [T.y], [T.z]) [contained]")
update_mob()
@@ -419,7 +419,7 @@
var/mob/last = get_mob_by_ckey(nadeassembly.fingerprintslast)
var/turf/T = get_turf(src)
var/area/A = get_area(T)
message_admins("grenade primed by an assembly, attached by [key_name_admin(M)][ADMIN_QUE(M,"(?)")] ([ADMIN_FLW(M,"FLW")]) and last touched by [key_name_admin(last)][ADMIN_QUE(last,"(?)")] ([ADMIN_FLW(last,"FLW")]) ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>[A.name] (JMP)</a>.")
message_admins("grenade primed by an assembly, attached by [key_name_admin(M)] and last touched by [key_name_admin(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>[A.name] (JMP)</a>.")
log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] ([T.x], [T.y], [T.z])")
else
addtimer(CALLBACK(src, .proc/prime), det_time)
+2 -2
View File
@@ -87,7 +87,7 @@
return
..()
/obj/item/restraints/legcuffs/beartrap/Crossed(AM as mob|obj)
/obj/item/restraints/legcuffs/beartrap/Crossed(AM as mob|obj, oldloc)
if(armed && isturf(src.loc))
if( (iscarbon(AM) || isanimal(AM)) && !istype(AM, /mob/living/simple_animal/parrot) && !istype(AM, /mob/living/simple_animal/hostile/construct) && !istype(AM, /mob/living/simple_animal/shade) && !istype(AM, /mob/living/simple_animal/hostile/viscerator))
var/mob/living/L = AM
@@ -193,6 +193,6 @@
/obj/item/restraints/legcuffs/bola/energy/throw_impact(atom/hit_atom)
if(iscarbon(hit_atom))
var/obj/item/restraints/legcuffs/beartrap/B = new /obj/item/restraints/legcuffs/beartrap/energy/cyborg(get_turf(hit_atom))
B.Crossed(hit_atom)
B.Crossed(hit_atom, null)
qdel(src)
..()
+1 -1
View File
@@ -67,7 +67,7 @@
else
return ..()
/obj/item/shard/Crossed(AM as mob|obj)
/obj/item/shard/Crossed(AM as mob|obj, oldloc)
if(isliving(AM))
var/mob/living/M = AM
if(M.incorporeal_move || M.flying || M.throwing)//you are incorporal or flying or being thrown ..no shard stepping!
@@ -398,7 +398,7 @@
new /obj/item/gun/projectile/automatic/shotgun/bulldog(src)
new /obj/item/ammo_box/magazine/m12g(src)
new /obj/item/ammo_box/magazine/m12g(src)
new /obj/item/clothing/glasses/thermal/syndi(src)
new /obj/item/clothing/glasses/chameleon/thermal(src)
/obj/item/storage/backpack/duffel/syndie/med/medicalbundle
desc = "A large duffel bag containing a tactical medkit, a Donksoft machine gun and a big jumbo box of riot darts."
@@ -116,15 +116,10 @@
/obj/item/storage/lockbox/medal/New()
..()
new /obj/item/clothing/accessory/medal/gold/heroism(src)
new /obj/item/clothing/accessory/medal/silver/security(src)
new /obj/item/clothing/accessory/medal/silver/valor(src)
new /obj/item/clothing/accessory/medal/nobel_science(src)
new /obj/item/clothing/accessory/medal/bronze_heart(src)
new /obj/item/clothing/accessory/medal/conduct(src)
new /obj/item/clothing/accessory/medal/conduct(src)
new /obj/item/clothing/accessory/medal/conduct(src)
new /obj/item/clothing/accessory/medal/gold/captain(src)
new /obj/item/clothing/accessory/medal/silver/leadership(src)
new /obj/item/clothing/accessory/medal/silver/valor(src)
new /obj/item/clothing/accessory/medal/heart(src)
/obj/item/storage/lockbox/t4
name = "lockbox (T4)"
@@ -20,7 +20,7 @@
if("thief") // 40TC
new /obj/item/gun/energy/kinetic_accelerator/crossbow(src) // 12TC
new /obj/item/chameleon(src) // 8TC
new /obj/item/clothing/glasses/thermal/syndi(src) // 6TC
new /obj/item/clothing/glasses/chameleon/thermal(src) // 6TC
new /obj/item/clothing/gloves/color/black/thief(src) // 6TC
new /obj/item/card/id/syndicate(src) // 2TC
new /obj/item/clothing/shoes/chameleon/noslip(src) // 2TC
@@ -108,7 +108,7 @@
new /obj/item/gun/projectile/automatic/sniper_rifle/syndicate/penetrator(src) // 16TC
new /obj/item/ammo_box/magazine/sniper_rounds/penetrator(src) // 5TC
new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src) // 3TC
new /obj/item/clothing/glasses/thermal/syndi/sunglasses(src) // 6TC
new /obj/item/clothing/glasses/chameleon/thermal(src) // 6TC
new /obj/item/clothing/gloves/combat(src) // 0 TC
new /obj/item/clothing/under/suit_jacket/really_black(src) // 0 TC
new /obj/item/clothing/suit/storage/lawyer/blackjacket/armored(src) // 0TC
+6 -1
View File
@@ -28,12 +28,15 @@
var/force_wielded = 0
var/wieldsound = null
var/unwieldsound = null
var/sharp_when_wielded = FALSE
/obj/item/twohanded/proc/unwield(mob/living/carbon/user)
if(!wielded || !user)
return
wielded = FALSE
force = force_unwielded
if(sharp_when_wielded)
sharp = FALSE
var/sf = findtext(name," (Wielded)")
if(sf)
name = copytext(name, 1, sf)
@@ -66,6 +69,8 @@
return
wielded = TRUE
force = force_wielded
if(sharp_when_wielded)
sharp = TRUE
name = "[name] (Wielded)"
update_icon()
if(user)
@@ -224,7 +229,7 @@
origin_tech = "magnets=4;syndicate=5"
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
block_chance = 75
sharp = TRUE
sharp_when_wielded = TRUE // only sharp when wielded
light_power = 2
var/brightness_on = 2
var/colormap = list(red=LIGHT_COLOR_RED, blue=LIGHT_COLOR_LIGHTBLUE, green=LIGHT_COLOR_GREEN, purple=LIGHT_COLOR_PURPLE, rainbow=LIGHT_COLOR_WHITE)
+10 -2
View File
@@ -235,14 +235,22 @@
var/status = GROWING //can be GROWING, GROWN or BURST; all mutually exclusive
layer = MOB_LAYER
/obj/structure/alien/egg/grown
status = GROWN
icon_state = "egg"
/obj/structure/alien/egg/burst
status = BURST
icon_state = "egg_hatched"
/obj/structure/alien/egg/New()
new /obj/item/clothing/mask/facehugger(src)
..()
spawn(rand(MIN_GROWTH_TIME, MAX_GROWTH_TIME))
Grow()
if(status == BURST)
obj_integrity = integrity_failure
else if(status != GROWN)
spawn(rand(MIN_GROWTH_TIME, MAX_GROWTH_TIME))
Grow()
/obj/structure/alien/egg/attack_alien(mob/living/carbon/alien/user)
return attack_hand(user)
@@ -452,7 +452,7 @@
icon_closed = transparent ? "bluespacetrans" : "bluespace"
icon_state = opened ? icon_opened : icon_closed
/obj/structure/closet/bluespace/Crossed(atom/movable/AM)
/obj/structure/closet/bluespace/Crossed(atom/movable/AM, oldloc)
if(AM.density)
icon_state = opened ? "bluespaceopentrans" : "bluespacetrans"
@@ -38,6 +38,7 @@
new /obj/item/rpd(src)
new /obj/item/reagent_containers/food/drinks/mug/ce(src)
new /obj/item/organ/internal/cyberimp/eyes/meson(src)
new /obj/item/clothing/accessory/medal/engineering(src)
/obj/structure/closet/secure_closet/engineering_electrical
@@ -193,6 +193,7 @@
new /obj/item/organ/internal/cyberimp/eyes/hud/medical(src)
new /obj/item/door_remote/chief_medical_officer(src)
new /obj/item/reagent_containers/food/drinks/mug/cmo(src)
new /obj/item/clothing/accessory/medal/medical(src)
/obj/structure/closet/secure_closet/animal
@@ -77,7 +77,7 @@
new /obj/item/door_remote/research_director(src)
new /obj/item/reagent_containers/food/drinks/mug/rd(src)
new /obj/item/organ/internal/cyberimp/eyes/hud/diagnostic(src)
new /obj/item/clothing/accessory/medal/science(src)
/obj/structure/closet/secure_closet/research_reagents
name = "research chemical storage closet"
@@ -60,7 +60,7 @@
new /obj/item/clothing/accessory/petcollar(src)
new /obj/item/door_remote/civillian(src)
new /obj/item/reagent_containers/food/drinks/mug/hop(src)
new /obj/item/clothing/accessory/medal/service(src)
/obj/structure/closet/secure_closet/hop2
name = "head of personnel's attire"
@@ -128,7 +128,7 @@
new /obj/item/door_remote/head_of_security(src)
new /obj/item/reagent_containers/food/drinks/mug/hos(src)
new /obj/item/organ/internal/cyberimp/eyes/hud/security(src)
new /obj/item/clothing/accessory/medal/security(src)
/obj/structure/closet/secure_closet/warden
name = "warden's locker"
@@ -464,4 +464,5 @@
new /obj/item/clothing/head/powdered_wig(src)
new /obj/item/gavelblock(src)
new /obj/item/gavelhammer(src)
new /obj/item/clothing/head/justice_wig(src)
new /obj/item/clothing/head/justice_wig(src)
new /obj/item/clothing/accessory/medal/legal(src)
+71 -45
View File
@@ -9,19 +9,26 @@
/obj/structure/falsewall
name = "wall"
desc = "A huge chunk of metal used to seperate rooms."
anchored = 1
anchored = TRUE
icon = 'icons/turf/walls/wall.dmi'
icon_state = "wall"
var/mineral = "metal"
var/walltype = "metal"
var/opening = 0
density = 1
opacity = 1
var/mineral = /obj/item/stack/sheet/metal
var/mineral_amount = 2
var/walltype = /turf/simulated/wall
var/girder_type = /obj/structure/girder/displaced
var/opening = FALSE
density = TRUE
opacity = TRUE
can_deconstruct = TRUE
canSmoothWith = list(
/turf/simulated/wall,
/turf/simulated/wall/r_wall,
/obj/structure/falsewall,
/obj/structure/falsewall/brass,
/obj/structure/falsewall/reinforced, // WHY DO WE SMOOTH WITH FALSE R-WALLS WHEN WE DON'T SMOOTH WITH REAL R-WALLS. //because we do smooth with real r-walls now
/turf/simulated/wall/rust,
/turf/simulated/wall/r_wall/rust)
@@ -31,6 +38,10 @@
..()
air_update_turf(1)
/obj/structure/falsewall/ratvar_act()
new /obj/structure/falsewall/brass(loc)
qdel(src)
/obj/structure/falsewall/Destroy()
density = 0
air_update_turf(1)
@@ -124,18 +135,11 @@
/obj/structure/falsewall/proc/dismantle(mob/user)
user.visible_message("<span class='notice'>[user] dismantles the false wall.</span>", "<span class='warning'>You dismantle the false wall.</span>")
new /obj/structure/girder/displaced(loc)
if(mineral == "metal")
if(istype(src, /obj/structure/falsewall/reinforced))
new /obj/item/stack/sheet/plasteel(loc, 2)
else
new /obj/item/stack/sheet/metal(loc, 2)
else if(mineral == "wood")
new/obj/item/stack/sheet/wood(loc, 2)
else
var/P = text2path("/obj/item/stack/sheet/mineral/[mineral]")
new P(loc)
new P(loc)
if(can_deconstruct)
new girder_type(loc)
if(mineral_amount)
for(var/i in 1 to mineral_amount)
new mineral(loc)
playsound(src, 'sound/items/welder.ogg', 100, 1)
qdel(src)
@@ -148,7 +152,8 @@
desc = "A huge chunk of reinforced metal used to seperate rooms."
icon = 'icons/turf/walls/reinforced_wall.dmi'
icon_state = "r_wall"
walltype = "rwall"
walltype = /turf/simulated/wall/r_wall
mineral = /obj/item/stack/sheet/plasteel
/obj/structure/falsewall/reinforced/ChangeToWall(delete = 1)
var/turf/T = get_turf(src)
@@ -166,8 +171,8 @@
desc = "A wall with uranium plating. This is probably a bad idea."
icon = 'icons/turf/walls/uranium_wall.dmi'
icon_state = "uranium"
mineral = "uranium"
walltype = "uranium"
mineral = /obj/item/stack/sheet/mineral/uranium
walltype = /turf/simulated/wall/mineral/uranium
var/active = null
var/last_event = 0
canSmoothWith = list(/obj/structure/falsewall/uranium, /turf/simulated/wall/mineral/uranium)
@@ -201,8 +206,8 @@
desc = "A wall with gold plating. Swag!"
icon = 'icons/turf/walls/gold_wall.dmi'
icon_state = "gold"
mineral = "gold"
walltype = "gold"
mineral = /obj/item/stack/sheet/mineral/gold
walltype = /turf/simulated/wall/mineral/gold
canSmoothWith = list(/obj/structure/falsewall/gold, /turf/simulated/wall/mineral/gold)
/obj/structure/falsewall/silver
@@ -210,8 +215,8 @@
desc = "A wall with silver plating. Shiny."
icon = 'icons/turf/walls/silver_wall.dmi'
icon_state = "silver"
mineral = "silver"
walltype = "silver"
mineral = /obj/item/stack/sheet/mineral/silver
walltype = /turf/simulated/wall/mineral/silver
canSmoothWith = list(/obj/structure/falsewall/silver, /turf/simulated/wall/mineral/silver)
/obj/structure/falsewall/diamond
@@ -219,8 +224,8 @@
desc = "A wall with diamond plating. You monster."
icon = 'icons/turf/walls/diamond_wall.dmi'
icon_state = "diamond"
mineral = "diamond"
walltype = "diamond"
mineral = /obj/item/stack/sheet/mineral/diamond
walltype = /turf/simulated/wall/mineral/diamond
canSmoothWith = list(/obj/structure/falsewall/diamond, /turf/simulated/wall/mineral/diamond)
@@ -229,18 +234,18 @@
desc = "A wall with plasma plating. This is definately a bad idea."
icon = 'icons/turf/walls/plasma_wall.dmi'
icon_state = "plasma"
mineral = "plasma"
walltype = "plasma"
mineral = /obj/item/stack/sheet/mineral/plasma
walltype = /turf/simulated/wall/mineral/plasma
canSmoothWith = list(/obj/structure/falsewall/plasma, /turf/simulated/wall/mineral/plasma, /turf/simulated/wall/mineral/alien)
/obj/structure/falsewall/plasma/attackby(obj/item/W, mob/user, params)
if(is_hot(W) > 300)
message_admins("Plasma falsewall ignited by [key_name_admin(user)] in ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
log_game("Plasma falsewall ignited by [key_name(user)] in ([x],[y],[z])")
message_admins("Plasma falsewall ignited by [key_name_admin(user)] in [ADMIN_VERBOSEJMP(T)]")
log_game("Plasma falsewall ignited by [key_name(user)] in [AREACOORD(T)]")
investigate_log("was <font color='red'><b>ignited</b></font> by [key_name(user)]","atmos")
burnbabyburn()
return
..()
else
return ..()
/obj/structure/falsewall/plasma/proc/burnbabyburn(user)
playsound(src, 'sound/items/welder.ogg', 100, 1)
@@ -258,8 +263,8 @@
desc = "A strange-looking alien wall."
icon = 'icons/turf/walls/plasma_wall.dmi'
icon_state = "plasma"
mineral = "alien"
walltype = "alien"
mineral = /obj/item/stack/sheet/mineral/abductor
walltype = /turf/simulated/wall/mineral/abductor
canSmoothWith = list(/obj/structure/falsewall/alien, /turf/simulated/wall/mineral/alien)
@@ -268,16 +273,16 @@
desc = "A wall with bananium plating. Honk!"
icon = 'icons/turf/walls/bananium_wall.dmi'
icon_state = "bananium"
mineral = "clown"
walltype = "clown"
mineral = /obj/item/stack/sheet/mineral/bananium
walltype = /turf/simulated/wall/mineral/bananium
canSmoothWith = list(/obj/structure/falsewall/bananium, /turf/simulated/wall/mineral/bananium)
/obj/structure/falsewall/sandstone
name = "sandstone wall"
desc = "A wall with sandstone plating."
icon_state = "sandstone"
mineral = "sandstone"
walltype = "sandstone"
mineral = /obj/item/stack/sheet/mineral/sandstone
walltype = /turf/simulated/wall/mineral/sandstone
canSmoothWith = list(/obj/structure/falsewall/sandstone, /turf/simulated/wall/mineral/sandstone)
/obj/structure/falsewall/wood
@@ -285,8 +290,8 @@
desc = "A wall with wooden plating. Stiff."
icon = 'icons/turf/walls/wood_wall.dmi'
icon_state = "wood"
mineral = "wood"
walltype = "wood"
mineral = /obj/item/stack/sheet/wood
walltype = /turf/simulated/wall/mineral/wood
canSmoothWith = list(/obj/structure/falsewall/wood, /turf/simulated/wall/mineral/wood)
/obj/structure/falsewall/iron
@@ -294,8 +299,9 @@
desc = "A wall with rough metal plating."
icon = 'icons/turf/walls/iron_wall.dmi'
icon_state = "iron"
mineral = "metal"
walltype = "iron"
mineral = /obj/item/stack/rods
mineral_amount = 5
walltype = /turf/simulated/wall/mineral/iron
canSmoothWith = list(/obj/structure/falsewall/iron, /turf/simulated/wall/mineral/iron)
/obj/structure/falsewall/abductor
@@ -303,8 +309,8 @@
desc = "A wall with alien alloy plating."
icon = 'icons/turf/walls/abductor_wall.dmi'
icon_state = "abductor"
mineral = "abductor"
walltype = "abductor"
mineral = /obj/item/stack/sheet/mineral/abductor
walltype = /turf/simulated/wall/mineral/abductor
canSmoothWith = list(/obj/structure/falsewall/abductor, /turf/simulated/wall/mineral/abductor)
/obj/structure/falsewall/titanium
@@ -324,3 +330,23 @@
walltype = /turf/simulated/wall/mineral/plastitanium
smooth = SMOOTH_MORE
canSmoothWith = list(/turf/simulated/wall/mineral/plastitanium, /obj/machinery/door/airlock/shuttle, /obj/machinery/door/airlock, /obj/structure/window/full/shuttle, /obj/structure/shuttle/engine/heater)
/obj/structure/falsewall/brass
name = "clockwork wall"
desc = "A huge chunk of warm metal. The clanging of machinery emanates from within."
icon = 'icons/turf/walls/clockwork_wall.dmi'
icon_state = "clockwork_wall"
resistance_flags = FIRE_PROOF
unacidable = TRUE
mineral_amount = 1
canSmoothWith = list(/obj/effect/clockwork/overlay/wall, /obj/structure/falsewall/brass)
girder_type = /obj/structure/clockwork/wall_gear/displaced
walltype = /turf/simulated/wall/clockwork
mineral = /obj/item/stack/tile/brass
/obj/structure/falsewall/brass/New(loc)
..()
var/turf/T = get_turf(src)
new /obj/effect/temp_visual/ratvar/wall/false(T)
new /obj/effect/temp_visual/ratvar/beam/falsewall(T)
+16
View File
@@ -63,3 +63,19 @@
/obj/structure/fluff/drake_statue/falling //A variety of statue in disrepair; parts are broken off and a gemstone is missing
desc = "A towering basalt sculpture of a drake. Cracks run down its surface and parts of it have fallen off."
icon_state = "drake_statue_falling"
/obj/structure/fluff/divine
name = "Miracle"
icon = 'icons/obj/hand_of_god_structures.dmi'
anchored = TRUE
density = TRUE
/obj/structure/fluff/divine/nexus
name = "nexus"
desc = "It anchors a deity to this world. It radiates an unusual aura. It looks well protected from explosive shock."
icon_state = "nexus"
/obj/structure/fluff/divine/conduit
name = "conduit"
desc = "It allows a deity to extend their reach. Their powers are just as potent near a conduit as a nexus."
icon_state = "conduit"
+49
View File
@@ -32,6 +32,8 @@
if(resistance_flags & INDESTRUCTIBLE)
return
if(istype(C, /obj/item/wirecutters))
var/obj/item/wirecutters/W = C
playsound(loc, W.usesound, 50, 1)
to_chat(user, "<span class='notice'>Slicing [name] joints...</span>")
deconstruct()
else
@@ -58,6 +60,26 @@
if(current_size >= STAGE_FOUR)
qdel(src)
/obj/structure/lattice/clockwork
name = "cog lattice"
desc = "A lightweight support lattice. These hold the Justicar's station together."
icon = 'icons/obj/smooth_structures/lattice_clockwork.dmi'
/obj/structure/lattice/clockwork/Initialize(mapload)
. = ..()
ratvar_act()
/obj/structure/lattice/clockwork/ratvar_act()
if((x + y) % 2 != 0)
icon = 'icons/obj/smooth_structures/lattice_clockwork_large.dmi'
pixel_x = -9
pixel_y = -9
else
icon = 'icons/obj/smooth_structures/lattice_clockwork.dmi'
pixel_x = 0
pixel_y = 0
return TRUE
/obj/structure/lattice/catwalk
name = "catwalk"
desc = "A catwalk for easier EVA maneuvering and cable placement."
@@ -81,3 +103,30 @@
for(var/obj/structure/cable/C in T)
C.deconstruct()
..()
/obj/structure/lattice/catwalk/clockwork
name = "clockwork catwalk"
icon = 'icons/obj/smooth_structures/catwalk_clockwork.dmi'
canSmoothWith = list(/obj/structure/lattice,
/turf/simulated/floor,
/turf/simulated/wall,
/obj/structure/falsewall)
smooth = SMOOTH_MORE
/obj/structure/lattice/catwalk/clockwork/Initialize(mapload)
. = ..()
ratvar_act()
if(!mapload)
new /obj/effect/temp_visual/ratvar/floor/catwalk(loc)
new /obj/effect/temp_visual/ratvar/beam/catwalk(loc)
/obj/structure/lattice/catwalk/clockwork/ratvar_act()
if((x + y) % 2 != 0)
icon = 'icons/obj/smooth_structures/catwalk_clockwork_large.dmi'
pixel_x = -9
pixel_y = -9
else
icon = 'icons/obj/smooth_structures/catwalk_clockwork.dmi'
pixel_x = 0
pixel_y = 0
return TRUE
+24 -12
View File
@@ -6,7 +6,6 @@
icon_state = "mirror"
density = 0
anchored = 1
var/shattered = 0
var/list/ui_users = list()
/obj/structure/mirror/New(turf/T, newdir = SOUTH, building = FALSE)
@@ -23,7 +22,7 @@
pixel_x = 32
/obj/structure/mirror/attack_hand(mob/user)
if(shattered)
if(broken)
return
if(ishuman(user))
@@ -36,9 +35,9 @@
AC.ui_interact(user)
/obj/structure/mirror/proc/shatter()
if(shattered)
if(broken)
return
shattered = 1
broken = TRUE
icon_state = "mirror_broke"
playsound(src, "shatter", 70, 1)
desc = "Oh no, seven years of bad luck!"
@@ -46,7 +45,7 @@
/obj/structure/mirror/bullet_act(obj/item/projectile/Proj)
if(prob(Proj.damage * 2))
if(!shattered)
if(!broken)
shatter()
else
playsound(src, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
@@ -58,7 +57,7 @@
if(isscrewdriver(I))
user.visible_message("<span class='notice'>[user] begins to unfasten [src].</span>", "<span class='notice'>You begin to unfasten [src].</span>")
if(do_after(user, 30 * I.toolspeed, target = src))
if(shattered)
if(broken)
user.visible_message("<span class='notice'>[user] drops the broken shards to the floor.</span>", "<span class='notice'>You drop the broken shards on the floor.</span>")
new /obj/item/shard(get_turf(user))
else
@@ -68,7 +67,7 @@
return
user.do_attack_animation(src)
if(shattered)
if(broken)
playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
return
@@ -85,7 +84,7 @@
if(islarva(user))
return
user.do_attack_animation(src)
if(shattered)
if(broken)
playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
return
user.visible_message("<span class='danger'>[user] smashes [src]!</span>")
@@ -100,7 +99,7 @@
if(M.melee_damage_upper <= 0)
return
M.do_attack_animation(src)
if(shattered)
if(broken)
playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
return
user.visible_message("<span class='danger'>[user] smashes [src]!</span>")
@@ -113,7 +112,7 @@
if(!S.is_adult)
return
user.do_attack_animation(src)
if(shattered)
if(broken)
playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
return
user.visible_message("<span class='danger'>[user] smashes [src]!</span>")
@@ -136,7 +135,7 @@
icon_state = "magic_mirror"
/obj/structure/mirror/magic/attack_hand(mob/user)
if(!ishuman(user))
if(!ishuman(user) || broken)
return
var/mob/living/carbon/human/H = user
@@ -154,6 +153,9 @@
H.dna.real_name = newname
if(H.mind)
H.mind.name = newname
if(newname)
curse(user)
if("Body")
var/list/race_list = list("Human", "Tajaran", "Skrell", "Unathi", "Diona", "Vulpkanin")
@@ -172,6 +174,7 @@
AC.whitelist = race_list
ui_users[user] = AC
AC.ui_interact(user)
if("Voice")
var/voice_choice = input(user, "Perhaps...", "Voice effects") as null|anything in list("Comic Sans", "Wingdings", "Swedish", "Chav")
var/voice_mutation
@@ -192,8 +195,17 @@
H.dna.SetSEState(voice_mutation, TRUE)
genemutcheck(H, voice_mutation, null, MUTCHK_FORCED)
if(voice_choice)
curse(user)
/obj/structure/mirror/magic/on_ui_close(mob/user)
curse(user)
/obj/structure/mirror/magic/attackby(obj/item/I, mob/living/user, params)
return
/obj/structure/mirror/magic/shatter()
return //can't be broken. it's magic, i ain't gotta explain shit
return //can't be broken. it's magic, i ain't gotta explain shit
/obj/structure/mirror/magic/proc/curse(mob/living/user)
return
@@ -28,6 +28,11 @@
W.setDir(dir)
qdel(src)
/obj/structure/chair/ratvar_act()
var/obj/structure/chair/brass/B = new(get_turf(src))
B.setDir(dir)
qdel(src)
/obj/structure/chair/Move(atom/newloc, direct)
..()
handle_rotation()
@@ -146,35 +151,38 @@
name = "comfy chair"
desc = "It looks comfy."
icon_state = "comfychair"
color = rgb(255,255,255)
color = rgb(255, 255, 255)
burn_state = FLAMMABLE
burntime = 30
buildstackamount = 2
item_chair = null
var/image/armrest = null
/obj/structure/chair/comfy/New()
armrest = image("icons/obj/chairs.dmi", "comfychair_armrest")
/obj/structure/chair/comfy/Initialize(mapload)
armrest = GetArmrest()
armrest.layer = ABOVE_MOB_LAYER
return ..()
/obj/structure/chair/comfy/proc/GetArmrest()
return mutable_appearance('icons/obj/chairs.dmi', "comfychair_armrest")
/obj/structure/chair/comfy/Destroy()
QDEL_NULL(armrest)
return ..()
/obj/structure/chair/comfy/post_buckle_mob(mob/living/M)
..()
if(buckled_mob)
overlays += armrest
else
overlays -= armrest
. = ..()
update_armrest()
/obj/structure/chair/comfy/post_unbuckle_mob(mob/living/M)
..()
if(buckled_mob)
overlays -= armrest
. = ..()
update_armrest()
/obj/structure/chair/comfy/proc/update_armrest()
if(has_buckled_mobs())
add_overlay(armrest)
else
overlays += armrest
cut_overlay(armrest)
/obj/structure/chair/comfy/brown
color = rgb(141,70,0)
@@ -209,6 +217,14 @@
item_chair = null
buildstackamount = 5
/obj/structure/chair/comfy/shuttle
name = "shuttle seat"
desc = "A comfortable, secure seat. It has a more sturdy looking buckling system, for smoother flights."
icon_state = "shuttle_chair"
/obj/structure/chair/comfy/shuttle/GetArmrest()
return mutable_appearance('icons/obj/chairs.dmi', "shuttle_chair_armrest")
/obj/structure/chair/office/Bump(atom/A)
..()
if(!buckled_mob)
@@ -416,3 +432,41 @@
desc = "You sit in this. Either by will or force. Looks REALLY uncomfortable."
icon_state = "chairold"
item_chair = null
// Brass chair
/obj/structure/chair/brass
name = "brass chair"
desc = "A spinny chair made of brass. It looks uncomfortable."
icon_state = "brass_chair"
max_integrity = 150
buildstacktype = /obj/item/stack/tile/brass
buildstackamount = 1
item_chair = null
var/turns = 0
/obj/structure/chair/brass/Destroy()
STOP_PROCESSING(SSfastprocess, src)
. = ..()
/obj/structure/chair/brass/process()
setDir(turn(dir,-90))
playsound(src, 'sound/effects/servostep.ogg', 50, FALSE)
turns++
if(turns >= 8)
STOP_PROCESSING(SSfastprocess, src)
/obj/structure/chair/brass/ratvar_act()
return
/obj/structure/chair/brass/AltClick(mob/living/user)
turns = 0
if(!istype(user) || user.incapacitated() || !in_range(src, user))
return
if(!isprocessing)
user.visible_message("<span class='notice'>[user] spins [src] around, and Ratvarian technology keeps it spinning FOREVER.</span>", \
"<span class='notice'>Automated spinny chairs. The pinnacle of Ratvarian technology.</span>")
START_PROCESSING(SSfastprocess, src)
else
user.visible_message("<span class='notice'>[user] stops [src]'s uncontrollable spinning.</span>", \
"<span class='notice'>You grab [src] and stop its wild spinning.</span>")
STOP_PROCESSING(SSfastprocess, src)

Some files were not shown because too many files have changed in this diff Show More