Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into putnamos-for-real
This commit is contained in:
@@ -35,101 +35,368 @@
|
||||
else
|
||||
painting = null
|
||||
|
||||
|
||||
//////////////
|
||||
// CANVASES //
|
||||
//////////////
|
||||
|
||||
#define AMT_OF_CANVASES 4 //Keep this up to date or shit will break.
|
||||
|
||||
//To safe memory on making /icons we cache the blanks..
|
||||
GLOBAL_LIST_INIT(globalBlankCanvases, new(AMT_OF_CANVASES))
|
||||
|
||||
/obj/item/canvas
|
||||
name = "canvas"
|
||||
desc = "Draw out your soul on this canvas!"
|
||||
icon = 'icons/obj/artstuff.dmi'
|
||||
icon_state = "11x11"
|
||||
resistance_flags = FLAMMABLE
|
||||
var/whichGlobalBackup = 1 //List index
|
||||
var/width = 11
|
||||
var/height = 11
|
||||
var/list/grid
|
||||
var/canvas_color = "#ffffff" //empty canvas color
|
||||
var/ui_x = 400
|
||||
var/ui_y = 400
|
||||
var/used = FALSE
|
||||
var/painting_name //Painting name, this is set after framing.
|
||||
var/finalized = FALSE //Blocks edits
|
||||
var/author_ckey
|
||||
var/icon_generated = FALSE
|
||||
var/icon/generated_icon
|
||||
|
||||
/obj/item/canvas/nineteenXnineteen
|
||||
icon_state = "19x19"
|
||||
whichGlobalBackup = 2
|
||||
// Painting overlay offset when framed
|
||||
var/framed_offset_x = 11
|
||||
var/framed_offset_y = 10
|
||||
|
||||
/obj/item/canvas/twentythreeXnineteen
|
||||
icon_state = "23x19"
|
||||
whichGlobalBackup = 3
|
||||
pixel_x = 10
|
||||
pixel_y = 9
|
||||
|
||||
/obj/item/canvas/twentythreeXtwentythree
|
||||
icon_state = "23x23"
|
||||
whichGlobalBackup = 4
|
||||
|
||||
//HEY YOU
|
||||
//ARE YOU READING THE CODE FOR CANVASES?
|
||||
//ARE YOU AWARE THEY CRASH HALF THE SERVER WHEN SOMEONE DRAWS ON THEM...
|
||||
//...AND NOBODY CAN FIGURE OUT WHY?
|
||||
//THEN GO ON BRAVE TRAVELER
|
||||
//TRY TO FIX THEM AND REMOVE THIS CODE
|
||||
/obj/item/canvas/Initialize()
|
||||
..()
|
||||
return INITIALIZE_HINT_QDEL //Delete on creation
|
||||
. = ..()
|
||||
reset_grid()
|
||||
|
||||
//Find the right size blank canvas
|
||||
/obj/item/canvas/proc/getGlobalBackup()
|
||||
. = null
|
||||
if(GLOB.globalBlankCanvases[whichGlobalBackup])
|
||||
. = GLOB.globalBlankCanvases[whichGlobalBackup]
|
||||
else
|
||||
var/icon/I = icon(initial(icon),initial(icon_state))
|
||||
GLOB.globalBlankCanvases[whichGlobalBackup] = I
|
||||
. = I
|
||||
/obj/item/canvas/proc/reset_grid()
|
||||
grid = new/list(width,height)
|
||||
for(var/x in 1 to width)
|
||||
for(var/y in 1 to height)
|
||||
grid[x][y] = canvas_color
|
||||
|
||||
/obj/item/canvas/attack_self(mob/user)
|
||||
. = ..()
|
||||
ui_interact(user)
|
||||
|
||||
/obj/item/canvas/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
|
||||
//One pixel increments
|
||||
/obj/item/canvas/attackby(obj/item/I, mob/user, params)
|
||||
//Click info
|
||||
var/list/click_params = params2list(params)
|
||||
var/pixX = text2num(click_params["icon-x"])
|
||||
var/pixY = text2num(click_params["icon-y"])
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "canvas", name, ui_x, ui_y, master_ui, state)
|
||||
ui.set_autoupdate(FALSE)
|
||||
ui.open()
|
||||
|
||||
//Should always be true, otherwise you didn't click the object, but let's check because SS13~
|
||||
if(!click_params || !click_params["icon-x"] || !click_params["icon-y"])
|
||||
return
|
||||
|
||||
//Cleaning one pixel with a soap or rag
|
||||
if(istype(I, /obj/item/soap) || istype(I, /obj/item/reagent_containers/rag))
|
||||
//Pixel info created only when needed
|
||||
var/icon/masterpiece = icon(icon,icon_state)
|
||||
var/thePix = masterpiece.GetPixel(pixX,pixY)
|
||||
var/icon/Ico = getGlobalBackup()
|
||||
if(!Ico)
|
||||
qdel(masterpiece)
|
||||
return
|
||||
|
||||
var/theOriginalPix = Ico.GetPixel(pixX,pixY)
|
||||
if(thePix != theOriginalPix) //colour changed
|
||||
DrawPixelOn(theOriginalPix,pixX,pixY)
|
||||
qdel(masterpiece)
|
||||
|
||||
//Drawing one pixel with a crayon
|
||||
else if(istype(I, /obj/item/toy/crayon))
|
||||
var/obj/item/toy/crayon/C = I
|
||||
DrawPixelOn(C.paint_color, pixX, pixY)
|
||||
/obj/item/canvas/attackby(obj/item/I, mob/living/user, params)
|
||||
if(user.a_intent == INTENT_HELP)
|
||||
ui_interact(user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/canvas/ui_data(mob/user)
|
||||
. = ..()
|
||||
.["grid"] = grid
|
||||
.["name"] = painting_name
|
||||
.["finalized"] = finalized
|
||||
|
||||
//Clean the whole canvas
|
||||
/obj/item/canvas/attack_self(mob/user)
|
||||
if(!user)
|
||||
/obj/item/canvas/examine(mob/user)
|
||||
. = ..()
|
||||
ui_interact(user)
|
||||
|
||||
/obj/item/canvas/ui_act(action, params)
|
||||
. = ..()
|
||||
if(. || finalized)
|
||||
return
|
||||
var/icon/blank = getGlobalBackup()
|
||||
if(blank)
|
||||
//it's basically a giant etch-a-sketch
|
||||
icon = blank
|
||||
user.visible_message("<span class='notice'>[user] cleans the canvas.</span>","<span class='notice'>You clean the canvas.</span>")
|
||||
var/mob/user = usr
|
||||
switch(action)
|
||||
if("paint")
|
||||
var/obj/item/I = user.get_active_held_item()
|
||||
var/color = get_paint_tool_color(I)
|
||||
if(!color)
|
||||
return FALSE
|
||||
var/x = text2num(params["x"])
|
||||
var/y = text2num(params["y"])
|
||||
grid[x][y] = color
|
||||
used = TRUE
|
||||
update_icon()
|
||||
. = TRUE
|
||||
if("finalize")
|
||||
. = TRUE
|
||||
if(!finalized)
|
||||
finalize(user)
|
||||
|
||||
/obj/item/canvas/proc/finalize(mob/user)
|
||||
finalized = TRUE
|
||||
author_ckey = user.ckey
|
||||
generate_proper_overlay()
|
||||
try_rename(user)
|
||||
|
||||
/obj/item/canvas/update_overlays()
|
||||
. = ..()
|
||||
if(!icon_generated)
|
||||
if(used)
|
||||
var/mutable_appearance/detail = mutable_appearance(icon,"[icon_state]wip")
|
||||
detail.pixel_x = 1
|
||||
detail.pixel_y = 1
|
||||
. += detail
|
||||
else
|
||||
var/mutable_appearance/detail = mutable_appearance(generated_icon)
|
||||
detail.pixel_x = 1
|
||||
detail.pixel_y = 1
|
||||
. += detail
|
||||
|
||||
/obj/item/canvas/proc/generate_proper_overlay()
|
||||
if(icon_generated)
|
||||
return
|
||||
var/png_filename = "data/paintings/temp_painting.png"
|
||||
var/result = rustg_dmi_create_png(png_filename,"[width]","[height]",get_data_string())
|
||||
if(result)
|
||||
CRASH("Error generating painting png : [result]")
|
||||
generated_icon = new(png_filename)
|
||||
icon_generated = TRUE
|
||||
update_icon()
|
||||
|
||||
/obj/item/canvas/proc/get_data_string()
|
||||
var/list/data = list()
|
||||
for(var/y in 1 to height)
|
||||
for(var/x in 1 to width)
|
||||
data += grid[x][y]
|
||||
return data.Join("")
|
||||
|
||||
//Todo make this element ?
|
||||
/obj/item/canvas/proc/get_paint_tool_color(obj/item/I)
|
||||
if(!I)
|
||||
return
|
||||
if(istype(I, /obj/item/toy/crayon))
|
||||
var/obj/item/toy/crayon/C = I
|
||||
return C.paint_color
|
||||
else if(istype(I, /obj/item/pen))
|
||||
var/obj/item/pen/P = I
|
||||
switch(P.colour)
|
||||
if("black")
|
||||
return "#000000"
|
||||
if("blue")
|
||||
return "#0000ff"
|
||||
if("red")
|
||||
return "#ff0000"
|
||||
return P.colour
|
||||
else if(istype(I, /obj/item/soap) || istype(I, /obj/item/reagent_containers/rag))
|
||||
return canvas_color
|
||||
|
||||
/obj/item/canvas/proc/try_rename(mob/user)
|
||||
var/new_name = stripped_input(user,"What do you want to name the painting?")
|
||||
if(!painting_name && new_name && user.canUseTopic(src,BE_CLOSE))
|
||||
painting_name = new_name
|
||||
SStgui.update_uis(src)
|
||||
|
||||
/obj/item/canvas/nineteenXnineteen
|
||||
icon_state = "19x19"
|
||||
width = 19
|
||||
height = 19
|
||||
ui_x = 600
|
||||
ui_y = 600
|
||||
pixel_x = 6
|
||||
pixel_y = 9
|
||||
framed_offset_x = 8
|
||||
framed_offset_y = 9
|
||||
|
||||
/obj/item/canvas/twentythreeXnineteen
|
||||
icon_state = "23x19"
|
||||
width = 23
|
||||
height = 19
|
||||
ui_x = 800
|
||||
ui_y = 600
|
||||
pixel_x = 4
|
||||
pixel_y = 10
|
||||
framed_offset_x = 6
|
||||
framed_offset_y = 8
|
||||
|
||||
/obj/item/canvas/twentythreeXtwentythree
|
||||
icon_state = "23x23"
|
||||
width = 23
|
||||
height = 23
|
||||
ui_x = 800
|
||||
ui_y = 800
|
||||
pixel_x = 5
|
||||
pixel_y = 9
|
||||
framed_offset_x = 5
|
||||
framed_offset_y = 6
|
||||
|
||||
/obj/item/wallframe/painting
|
||||
name = "painting frame"
|
||||
desc = "The perfect showcase for your favorite deathtrap memories."
|
||||
icon = 'icons/obj/decals.dmi'
|
||||
custom_materials = null
|
||||
flags_1 = 0
|
||||
icon_state = "frame-empty"
|
||||
result_path = /obj/structure/sign/painting
|
||||
|
||||
/obj/structure/sign/painting
|
||||
name = "Painting"
|
||||
desc = "Art or \"Art\"? You decide."
|
||||
icon = 'icons/obj/decals.dmi'
|
||||
icon_state = "frame-empty"
|
||||
buildable_sign = FALSE
|
||||
var/obj/item/canvas/C
|
||||
var/persistence_id
|
||||
|
||||
/obj/structure/sign/painting/Initialize(mapload, dir, building)
|
||||
. = ..()
|
||||
SSpersistence.painting_frames += src
|
||||
AddElement(/datum/element/art, 20)
|
||||
if(dir)
|
||||
setDir(dir)
|
||||
if(building)
|
||||
pixel_x = (dir & 3)? 0 : (dir == 4 ? -30 : 30)
|
||||
pixel_y = (dir & 3)? (dir ==1 ? -30 : 30) : 0
|
||||
|
||||
/obj/structure/sign/painting/Destroy()
|
||||
. = ..()
|
||||
SSpersistence.painting_frames -= src
|
||||
|
||||
/obj/structure/sign/painting/attackby(obj/item/I, mob/user, params)
|
||||
if(!C && istype(I, /obj/item/canvas))
|
||||
frame_canvas(user,I)
|
||||
else if(C && !C.painting_name && istype(I,/obj/item/pen))
|
||||
try_rename(user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/sign/painting/examine(mob/user)
|
||||
. = ..()
|
||||
if(C)
|
||||
C.ui_interact(user,state = GLOB.physical_obscured_state)
|
||||
|
||||
/obj/structure/sign/painting/wirecutter_act(mob/living/user, obj/item/I)
|
||||
. = ..()
|
||||
if(C)
|
||||
C.forceMove(drop_location())
|
||||
C = null
|
||||
to_chat(user, "<span class='notice'>You remove the painting from the frame.</span>")
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
/obj/structure/sign/painting/proc/frame_canvas(mob/user,obj/item/canvas/new_canvas)
|
||||
if(user.transferItemToLoc(new_canvas,src))
|
||||
C = new_canvas
|
||||
if(!C.finalized)
|
||||
C.finalize(user)
|
||||
to_chat(user,"<span class='notice'>You frame [C].</span>")
|
||||
update_icon()
|
||||
|
||||
/obj/structure/sign/painting/proc/try_rename(mob/user)
|
||||
if(!C.painting_name)
|
||||
C.try_rename(user)
|
||||
|
||||
/obj/structure/sign/painting/update_icon_state()
|
||||
. = ..()
|
||||
if(C && C.generated_icon)
|
||||
icon_state = null
|
||||
else
|
||||
icon_state = "frame-empty"
|
||||
|
||||
|
||||
#undef AMT_OF_CANVASES
|
||||
/obj/structure/sign/painting/update_overlays()
|
||||
. = ..()
|
||||
if(C && C.generated_icon)
|
||||
var/mutable_appearance/MA = mutable_appearance(C.generated_icon)
|
||||
MA.pixel_x = C.framed_offset_x
|
||||
MA.pixel_y = C.framed_offset_y
|
||||
. += MA
|
||||
var/mutable_appearance/frame = mutable_appearance(C.icon,"[C.icon_state]frame")
|
||||
frame.pixel_x = C.framed_offset_x - 1
|
||||
frame.pixel_y = C.framed_offset_y - 1
|
||||
. += frame
|
||||
|
||||
/obj/structure/sign/painting/proc/load_persistent()
|
||||
if(!persistence_id)
|
||||
return
|
||||
if(!SSpersistence.paintings || !SSpersistence.paintings[persistence_id] || !length(SSpersistence.paintings[persistence_id]))
|
||||
return
|
||||
var/list/chosen = pick(SSpersistence.paintings[persistence_id])
|
||||
var/title = chosen["title"]
|
||||
var/author = chosen["ckey"]
|
||||
var/png = "data/paintings/[persistence_id]/[chosen["md5"]].png"
|
||||
if(!fexists(png))
|
||||
stack_trace("Persistent painting [chosen["md5"]].png was not found in [persistence_id] directory.")
|
||||
return
|
||||
var/icon/I = new(png)
|
||||
var/obj/item/canvas/new_canvas
|
||||
var/w = I.Width()
|
||||
var/h = I.Height()
|
||||
for(var/T in typesof(/obj/item/canvas))
|
||||
new_canvas = T
|
||||
if(initial(new_canvas.width) == w && initial(new_canvas.height) == h)
|
||||
new_canvas = new T(src)
|
||||
break
|
||||
new_canvas.fill_grid_from_icon(I)
|
||||
new_canvas.generated_icon = I
|
||||
new_canvas.icon_generated = TRUE
|
||||
new_canvas.finalized = TRUE
|
||||
new_canvas.painting_name = title
|
||||
new_canvas.author_ckey = author
|
||||
C = new_canvas
|
||||
update_icon()
|
||||
|
||||
/obj/structure/sign/painting/proc/save_persistent()
|
||||
if(!persistence_id || !C)
|
||||
return
|
||||
if(sanitize_filename(persistence_id) != persistence_id)
|
||||
stack_trace("Invalid persistence_id - [persistence_id]")
|
||||
return
|
||||
var/data = C.get_data_string()
|
||||
var/md5 = md5(data)
|
||||
var/list/current = SSpersistence.paintings[persistence_id]
|
||||
if(!current)
|
||||
current = list()
|
||||
for(var/list/entry in current)
|
||||
if(entry["md5"] == md5)
|
||||
return
|
||||
var/png_directory = "data/paintings/[persistence_id]/"
|
||||
var/png_path = png_directory + "[md5].png"
|
||||
var/result = rustg_dmi_create_png(png_path,"[C.width]","[C.height]",data)
|
||||
if(result)
|
||||
CRASH("Error saving persistent painting: [result]")
|
||||
current += list(list("title" = C.painting_name , "md5" = md5, "ckey" = C.author_ckey))
|
||||
SSpersistence.paintings[persistence_id] = current
|
||||
|
||||
/obj/item/canvas/proc/fill_grid_from_icon(icon/I)
|
||||
var/h = I.Height() + 1
|
||||
for(var/x in 1 to width)
|
||||
for(var/y in 1 to height)
|
||||
grid[x][y] = I.GetPixel(x,h-y)
|
||||
|
||||
//Presets for art gallery mapping, for paintings to be shared across stations
|
||||
/obj/structure/sign/painting/library
|
||||
persistence_id = "library"
|
||||
|
||||
/obj/structure/sign/painting/library_secure
|
||||
persistence_id = "library_secure"
|
||||
|
||||
/obj/structure/sign/painting/library_private // keep your smut away from prying eyes, or non-librarians at least
|
||||
persistence_id = "library_private"
|
||||
|
||||
/obj/structure/sign/painting/vv_get_dropdown()
|
||||
. = ..()
|
||||
VV_DROPDOWN_OPTION(VV_HK_REMOVE_PAINTING, "Remove Persistent Painting")
|
||||
|
||||
/obj/structure/sign/painting/vv_do_topic(list/href_list)
|
||||
. = ..()
|
||||
if(href_list[VV_HK_REMOVE_PAINTING])
|
||||
if(!check_rights(NONE))
|
||||
return
|
||||
var/mob/user = usr
|
||||
if(!persistence_id || !C)
|
||||
to_chat(user,"<span class='warning'>This is not a persistent painting.</span>")
|
||||
return
|
||||
var/md5 = md5(C.get_data_string())
|
||||
var/author = C.author_ckey
|
||||
var/list/current = SSpersistence.paintings[persistence_id]
|
||||
if(current)
|
||||
for(var/list/entry in current)
|
||||
if(entry["md5"] == md5)
|
||||
current -= entry
|
||||
var/png = "data/paintings/[persistence_id]/[md5].png"
|
||||
fdel(png)
|
||||
for(var/obj/structure/sign/painting/P in SSpersistence.painting_frames)
|
||||
if(P.C && md5(P.C.get_data_string()) == md5)
|
||||
QDEL_NULL(P.C)
|
||||
log_admin("[key_name(user)] has deleted a persistent painting made by [author].")
|
||||
message_admins("<span class='notice'>[key_name_admin(user)] has deleted persistent painting made by [author].</span>")
|
||||
|
||||
@@ -108,7 +108,9 @@
|
||||
if(!istype(poordude))
|
||||
return TRUE
|
||||
user.visible_message("<span class='notice'>[user] pulls [src] out from under [poordude].</span>", "<span class='notice'>You pull [src] out from under [poordude].</span>")
|
||||
var/C = new item_chair(loc)
|
||||
var/obj/item/chair/C = new item_chair(loc)
|
||||
C.set_custom_materials(custom_materials)
|
||||
TransferComponents(C)
|
||||
user.put_in_hands(C)
|
||||
poordude.DefaultCombatKnockdown(20)//rip in peace
|
||||
user.adjustStaminaLoss(5)
|
||||
@@ -153,7 +155,7 @@
|
||||
///Material chair
|
||||
/obj/structure/chair/greyscale
|
||||
icon_state = "chair_greyscale"
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS | MATERIAL_EFFECTS
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS
|
||||
item_chair = /obj/item/chair/greyscale
|
||||
buildstacktype = null //Custom mats handle this
|
||||
|
||||
@@ -382,7 +384,7 @@
|
||||
/obj/item/chair/greyscale
|
||||
icon_state = "chair_greyscale_toppled"
|
||||
item_state = "chair_greyscale"
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS | MATERIAL_EFFECTS
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS
|
||||
origin_type = /obj/structure/chair/greyscale
|
||||
|
||||
/obj/item/chair/stool
|
||||
|
||||
@@ -41,7 +41,7 @@ LINEN BINS
|
||||
return
|
||||
|
||||
/obj/item/bedsheet/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/wirecutters) || I.get_sharpness())
|
||||
if(!(flags_1 & HOLOGRAM_1) && (istype(I, /obj/item/wirecutters) || I.get_sharpness()))
|
||||
var/obj/item/stack/sheet/cloth/C = new (get_turf(src), 3)
|
||||
transfer_fingerprints_to(C)
|
||||
C.add_fingerprint(user)
|
||||
@@ -261,6 +261,11 @@ LINEN BINS
|
||||
var/list/sheets = list()
|
||||
var/obj/item/hidden = null
|
||||
|
||||
/obj/structure/bedsheetbin/empty
|
||||
amount = 0
|
||||
icon_state = "linenbin-empty"
|
||||
anchored = FALSE
|
||||
|
||||
/obj/structure/bedsheetbin/examine(mob/user)
|
||||
. = ..()
|
||||
if(amount < 1)
|
||||
@@ -364,4 +369,4 @@ LINEN BINS
|
||||
/obj/structure/bedsheetbin/color
|
||||
sheet_types = list(/obj/item/bedsheet, /obj/item/bedsheet/blue, /obj/item/bedsheet/green, /obj/item/bedsheet/orange, \
|
||||
/obj/item/bedsheet/purple, /obj/item/bedsheet/red, /obj/item/bedsheet/yellow, /obj/item/bedsheet/brown, \
|
||||
/obj/item/bedsheet/black)
|
||||
/obj/item/bedsheet/black)
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
move_delay = TRUE
|
||||
var/oldloc = loc
|
||||
step(src, direction)
|
||||
user.setDir(direction)
|
||||
if(oldloc != loc)
|
||||
addtimer(CALLBACK(src, .proc/ResetMoveDelay), (use_mob_movespeed ? user.movement_delay() : CONFIG_GET(number/movedelay/walk_delay)) * move_speed_multiplier)
|
||||
else
|
||||
@@ -42,7 +43,7 @@
|
||||
Snake = L
|
||||
break
|
||||
if(Snake)
|
||||
alerted = viewers(7,src)
|
||||
alerted = fov_viewers(world.view,src)
|
||||
..()
|
||||
if(LAZYLEN(alerted))
|
||||
egged = world.time + SNAKE_SPAM_TICKS
|
||||
|
||||
@@ -51,7 +51,6 @@
|
||||
new /obj/item/storage/backpack/satchel/leather/withwallet( src )
|
||||
new /obj/item/instrument/piano_synth(src)
|
||||
new /obj/item/radio/headset( src )
|
||||
new /obj/item/clothing/head/colour(src)
|
||||
|
||||
/obj/structure/closet/secure_closet/personal/attackby(obj/item/W, mob/user, params)
|
||||
var/obj/item/card/id/I = W.GetID()
|
||||
|
||||
@@ -6,8 +6,16 @@
|
||||
max_integrity = 250
|
||||
armor = list("melee" = 30, "bullet" = 50, "laser" = 50, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80)
|
||||
secure = TRUE
|
||||
var/melee_min_damage = 20
|
||||
|
||||
/obj/structure/closet/secure_closet/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir)
|
||||
if(damage_flag == "melee" && damage_amount < 20)
|
||||
if(damage_flag == "melee" && damage_amount < melee_min_damage)
|
||||
return 0
|
||||
. = ..()
|
||||
. = ..()
|
||||
|
||||
// Exists to work around the minimum 700 cr price for goodies / small items
|
||||
/obj/structure/closet/secure_closet/goodies
|
||||
icon_state = "goodies"
|
||||
desc = "A sturdier card-locked storage unit used for bulky shipments."
|
||||
max_integrity = 500 // Same as crates.
|
||||
melee_min_damage = 25 // Idem.
|
||||
|
||||
@@ -76,12 +76,13 @@
|
||||
new /obj/item/storage/box/flashbangs(src)
|
||||
new /obj/item/shield/riot/tele(src)
|
||||
new /obj/item/storage/belt/security/full(src)
|
||||
new /obj/item/gun/energy/e_gun/hos(src)
|
||||
new /obj/item/choice_beacon/hosgun(src)
|
||||
new /obj/item/flashlight/seclite(src)
|
||||
new /obj/item/pinpointer/nuke(src)
|
||||
new /obj/item/circuitboard/machine/techfab/department/security(src)
|
||||
new /obj/item/storage/photo_album/HoS(src)
|
||||
new /obj/item/clothing/suit/hooded/wintercoat/hos(src)
|
||||
|
||||
/obj/structure/closet/secure_closet/warden
|
||||
name = "\proper warden's locker"
|
||||
req_access = list(ACCESS_ARMORY)
|
||||
@@ -272,8 +273,8 @@
|
||||
icon_state = "tac"
|
||||
/obj/structure/closet/secure_closet/lethalshots/PopulateContents()
|
||||
..()
|
||||
new /obj/item/twohanded/electrostaff(src)
|
||||
new /obj/item/twohanded/electrostaff(src)
|
||||
new /obj/item/electrostaff(src)
|
||||
new /obj/item/electrostaff(src)
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/storage/box/lethalshot(src)
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
desc = "A small wall mounted cabinet designed to hold a fire extinguisher."
|
||||
icon = 'icons/obj/wallmounts.dmi'
|
||||
icon_state = "extinguisher_closed"
|
||||
plane = ABOVE_WALL_PLANE
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
max_integrity = 200
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
anchored = TRUE
|
||||
icon = 'icons/turf/walls/wall.dmi'
|
||||
icon_state = "wall"
|
||||
plane = WALL_PLANE
|
||||
layer = LOW_OBJ_LAYER
|
||||
density = TRUE
|
||||
opacity = 1
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
desc = "There is a small label that reads \"For Emergency use only\" along with details for safe use of the axe. As if."
|
||||
icon = 'icons/obj/wallmounts.dmi'
|
||||
icon_state = "fireaxe"
|
||||
plane = ABOVE_WALL_PLANE
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
armor = list("melee" = 50, "bullet" = 20, "laser" = 0, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 50)
|
||||
@@ -10,7 +11,7 @@
|
||||
integrity_failure = 0.33
|
||||
var/locked = TRUE
|
||||
var/open = FALSE
|
||||
var/obj/item/twohanded/fireaxe/fireaxe
|
||||
var/obj/item/fireaxe/fireaxe
|
||||
|
||||
/obj/structure/fireaxecabinet/Initialize()
|
||||
. = ..()
|
||||
@@ -49,8 +50,8 @@
|
||||
obj_integrity = max_integrity
|
||||
update_icon()
|
||||
else if(open || broken)
|
||||
if(istype(I, /obj/item/twohanded/fireaxe) && !fireaxe)
|
||||
var/obj/item/twohanded/fireaxe/F = I
|
||||
if(istype(I, /obj/item/fireaxe) && !fireaxe)
|
||||
var/obj/item/fireaxe/F = I
|
||||
if(F.wielded)
|
||||
to_chat(user, "<span class='warning'>Unwield the [F.name] first.</span>")
|
||||
return
|
||||
|
||||
@@ -288,7 +288,7 @@
|
||||
icon_state = "fullgrass_[rand(1, 3)]"
|
||||
. = ..()
|
||||
|
||||
/obj/item/twohanded/required/kirbyplants
|
||||
/obj/item/kirbyplants
|
||||
name = "potted plant"
|
||||
icon = 'icons/obj/flora/plants.dmi'
|
||||
icon_state = "plant-01"
|
||||
@@ -300,23 +300,25 @@
|
||||
throw_speed = 2
|
||||
throw_range = 4
|
||||
|
||||
/obj/item/twohanded/required/kirbyplants/Initialize()
|
||||
/obj/item/kirbyplants/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/tactical)
|
||||
AddElement(/datum/element/tactical)
|
||||
addtimer(CALLBACK(src, /datum.proc/_AddElement, list(/datum/element/beauty, 500)), 0)
|
||||
AddComponent(/datum/component/two_handed, require_twohands=TRUE, force_unwielded=10, force_wielded=10)
|
||||
|
||||
/obj/item/twohanded/required/kirbyplants/random
|
||||
/obj/item/kirbyplants/random
|
||||
icon = 'icons/obj/flora/_flora.dmi'
|
||||
icon_state = "random_plant"
|
||||
var/list/static/states
|
||||
|
||||
/obj/item/twohanded/required/kirbyplants/random/Initialize()
|
||||
/obj/item/kirbyplants/random/Initialize()
|
||||
. = ..()
|
||||
icon = 'icons/obj/flora/plants.dmi'
|
||||
if(!states)
|
||||
generate_states()
|
||||
icon_state = pick(states)
|
||||
|
||||
/obj/item/twohanded/required/kirbyplants/random/proc/generate_states()
|
||||
/obj/item/kirbyplants/random/proc/generate_states()
|
||||
states = list()
|
||||
for(var/i in 1 to 25)
|
||||
var/number
|
||||
@@ -328,12 +330,12 @@
|
||||
states += "applebush"
|
||||
|
||||
|
||||
/obj/item/twohanded/required/kirbyplants/dead
|
||||
/obj/item/kirbyplants/dead
|
||||
name = "RD's potted plant"
|
||||
desc = "A gift from the botanical staff, presented after the RD's reassignment. There's a tag on it that says \"Y'all come back now, y'hear?\"\nIt doesn't look very healthy..."
|
||||
icon_state = "plant-25"
|
||||
|
||||
/obj/item/twohanded/required/kirbyplants/photosynthetic
|
||||
/obj/item/kirbyplants/photosynthetic
|
||||
name = "photosynthetic potted plant"
|
||||
desc = "A bioluminescent plant."
|
||||
icon_state = "plant-09"
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
|
||||
|
||||
/obj/effect/mob_spawn/human/fugitive
|
||||
assignedrole = "Fugitive Hunter"
|
||||
flavour_text = "" //the flavor text will be the backstory argument called on the antagonist's greet, see hunter.dm for details
|
||||
roundstart = FALSE
|
||||
death = FALSE
|
||||
random = TRUE
|
||||
show_flavour = FALSE
|
||||
density = TRUE
|
||||
var/back_story = "error"
|
||||
|
||||
/obj/effect/mob_spawn/human/fugitive/Initialize(mapload)
|
||||
. = ..()
|
||||
notify_ghosts("Hunters are waking up looking for refugees!", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_FUGITIVE)
|
||||
|
||||
/obj/effect/mob_spawn/human/fugitive/special(mob/living/new_spawn)
|
||||
var/datum/antagonist/fugitive_hunter/fughunter = new
|
||||
fughunter.backstory = back_story
|
||||
new_spawn.mind.add_antag_datum(fughunter)
|
||||
fughunter.greet()
|
||||
message_admins("[ADMIN_LOOKUPFLW(new_spawn)] has been made into a Fugitive Hunter by an event.")
|
||||
log_game("[key_name(new_spawn)] was spawned as a Fugitive Hunter by an event.")
|
||||
|
||||
/obj/effect/mob_spawn/human/fugitive/spacepol
|
||||
name = "police pod"
|
||||
desc = "A small sleeper typically used to put people to sleep for briefing on the mission."
|
||||
mob_name = "a spacepol officer"
|
||||
flavour_text = "Justice has arrived. I am a member of the Spacepol!"
|
||||
back_story = "space cop"
|
||||
outfit = /datum/outfit/spacepol
|
||||
icon = 'icons/obj/machines/sleeper.dmi'
|
||||
icon_state = "sleeper"
|
||||
|
||||
/obj/effect/mob_spawn/human/fugitive/russian
|
||||
name = "russian pod"
|
||||
flavour_text = "Ay blyat. I am a space-russian smuggler! We were mid-flight when our cargo was beamed off our ship!"
|
||||
back_story = "russian"
|
||||
desc = "A small sleeper typically used to make long distance travel a bit more bearable."
|
||||
mob_name = "russian"
|
||||
outfit = /datum/outfit/russiancorpse/hunter
|
||||
icon = 'icons/obj/machines/sleeper.dmi'
|
||||
icon_state = "sleeper"
|
||||
|
||||
/obj/effect/mob_spawn/human/fugitive/bounty
|
||||
name = "bounty hunter pod"
|
||||
flavour_text = "We got a new bounty on some fugitives, dead or alive."
|
||||
back_story = "bounty hunters"
|
||||
desc = "A small sleeper typically used to make long distance travel a bit more bearable."
|
||||
mob_name = "bounty hunter"
|
||||
icon = 'icons/obj/machines/sleeper.dmi'
|
||||
icon_state = "sleeper"
|
||||
|
||||
/obj/effect/mob_spawn/human/fugitive/bounty/Destroy()
|
||||
var/obj/structure/fluff/empty_sleeper/S = new(drop_location())
|
||||
S.setDir(dir)
|
||||
return ..()
|
||||
|
||||
/obj/effect/mob_spawn/human/fugitive/bounty/armor
|
||||
outfit = /datum/outfit/bountyarmor
|
||||
|
||||
/obj/effect/mob_spawn/human/fugitive/bounty/hook
|
||||
outfit = /datum/outfit/bountyhook
|
||||
|
||||
/obj/effect/mob_spawn/human/fugitive/bounty/synth
|
||||
outfit = /datum/outfit/bountysynth
|
||||
@@ -581,7 +581,7 @@
|
||||
uniform = /obj/item/clothing/under/rank/rnd/scientist
|
||||
shoes = /obj/item/clothing/shoes/laceup
|
||||
id = /obj/item/card/id/away/old/sci
|
||||
l_pocket = /obj/item/stack/medical/bruise_pack
|
||||
l_pocket = /obj/item/stack/medical/suture
|
||||
assignedrole = "Ancient Crew"
|
||||
job_description = "Oldstation Crew"
|
||||
|
||||
@@ -694,15 +694,12 @@
|
||||
..()
|
||||
var/suited = !preference_source || preference_source.prefs.jumpsuit_style == PREF_SUIT
|
||||
if (CONFIG_GET(flag/grey_assistants))
|
||||
if(suited)
|
||||
uniform = /obj/item/clothing/under/color/grey
|
||||
else
|
||||
uniform = /obj/item/clothing/under/color/jumpskirt/grey
|
||||
uniform = suited ? /obj/item/clothing/under/color/grey : /obj/item/clothing/under/color/jumpskirt/grey
|
||||
else
|
||||
if(suited)
|
||||
uniform = /obj/item/clothing/under/color/random
|
||||
if(SSevents.holidays && SSevents.holidays[PRIDE_MONTH])
|
||||
uniform = suited ? /obj/item/clothing/under/color/rainbow : /obj/item/clothing/under/color/jumpskirt/rainbow
|
||||
else
|
||||
uniform = /obj/item/clothing/under/color/jumpskirt/random
|
||||
uniform = suited ? /obj/item/clothing/under/color/random : /obj/item/clothing/under/color/jumpskirt/random
|
||||
|
||||
/obj/item/storage/box/syndie_kit/chameleon/ghostcafe
|
||||
name = "ghost cafe costuming kit"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
density = TRUE
|
||||
var/state = GIRDER_NORMAL
|
||||
var/girderpasschance = 20 // percentage chance that a projectile passes through the girder.
|
||||
var/next_beep = 0 //Prevents spamming of the construction sound
|
||||
var/can_displace = TRUE //If the girder can be moved around by wrenching it
|
||||
max_integrity = 200
|
||||
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
|
||||
@@ -27,11 +28,17 @@
|
||||
. += "<span class='notice'>[src] is disassembled! You probably shouldn't be able to see this examine message.</span>"
|
||||
|
||||
/obj/structure/girder/attackby(obj/item/W, mob/user, params)
|
||||
var/platingmodifier = 1
|
||||
if(HAS_TRAIT(user, TRAIT_QUICK_BUILD))
|
||||
platingmodifier = 0.7
|
||||
if(next_beep <= world.time)
|
||||
next_beep = world.time + 10
|
||||
playsound(src, 'sound/machines/clockcult/integration_cog_install.ogg', 50, TRUE)
|
||||
add_fingerprint(user)
|
||||
|
||||
if(istype(W, /obj/item/gun/energy/plasmacutter))
|
||||
to_chat(user, "<span class='notice'>You start slicing apart the girder...</span>")
|
||||
if(W.use_tool(src, user, 40, volume=100))
|
||||
if(W.use_tool(src, user, 40*platingmodifier, volume=100))
|
||||
to_chat(user, "<span class='notice'>You slice apart the girder.</span>")
|
||||
var/obj/item/stack/sheet/metal/M = new (loc, 2)
|
||||
M.add_fingerprint(user)
|
||||
@@ -62,7 +69,7 @@
|
||||
to_chat(user, "<span class='warning'>You need at least two rods to create a false wall!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start building a reinforced false wall...</span>")
|
||||
if(do_after(user, 20, target = src))
|
||||
if(do_after(user, 20*platingmodifier, target = src))
|
||||
if(S.get_amount() < 2)
|
||||
return
|
||||
S.use(2)
|
||||
@@ -75,7 +82,7 @@
|
||||
to_chat(user, "<span class='warning'>You need at least five rods to add plating!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start adding plating...</span>")
|
||||
if(do_after(user, 40, target = src))
|
||||
if(do_after(user, 40*platingmodifier, target = src))
|
||||
if(S.get_amount() < 5)
|
||||
return
|
||||
S.use(5)
|
||||
@@ -96,7 +103,7 @@
|
||||
to_chat(user, "<span class='warning'>You need two sheets of metal to create a false wall!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start building a false wall...</span>")
|
||||
if(do_after(user, 20, target = src))
|
||||
if(do_after(user, 20*platingmodifier, target = src))
|
||||
if(S.get_amount() < 2)
|
||||
return
|
||||
S.use(2)
|
||||
@@ -109,7 +116,7 @@
|
||||
to_chat(user, "<span class='warning'>You need two sheets of metal to finish a wall!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start adding plating...</span>")
|
||||
if (do_after(user, 40, target = src))
|
||||
if (do_after(user, 40*platingmodifier, target = src))
|
||||
if(S.get_amount() < 2)
|
||||
return
|
||||
S.use(2)
|
||||
@@ -126,7 +133,7 @@
|
||||
to_chat(user, "<span class='warning'>You need at least two sheets to create a false wall!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start building a reinforced false wall...</span>")
|
||||
if(do_after(user, 20, target = src))
|
||||
if(do_after(user, 20*platingmodifier, target = src))
|
||||
if(S.get_amount() < 2)
|
||||
return
|
||||
S.use(2)
|
||||
@@ -139,7 +146,7 @@
|
||||
if(S.get_amount() < 1)
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start finalizing the reinforced wall...</span>")
|
||||
if(do_after(user, 50, target = src))
|
||||
if(do_after(user, 50*platingmodifier, target = src))
|
||||
if(S.get_amount() < 1)
|
||||
return
|
||||
S.use(1)
|
||||
@@ -153,7 +160,7 @@
|
||||
if(S.get_amount() < 1)
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start reinforcing the girder...</span>")
|
||||
if(do_after(user, 60, target = src))
|
||||
if(do_after(user, 60*platingmodifier, target = src))
|
||||
if(S.get_amount() < 1)
|
||||
return
|
||||
S.use(1)
|
||||
@@ -163,7 +170,7 @@
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if(S.sheettype && S.sheettype != "runed")
|
||||
if(S.sheettype != "runed")
|
||||
var/M = S.sheettype
|
||||
if(state == GIRDER_DISPLACED)
|
||||
var/F = text2path("/obj/structure/falsewall/[M]")
|
||||
@@ -172,7 +179,7 @@
|
||||
if(S.get_amount() < 2)
|
||||
to_chat(user, "<span class='warning'>You need at least two sheets to create a false wall!</span>")
|
||||
return
|
||||
if(do_after(user, 20, target = src))
|
||||
if(do_after(user, 20*platingmodifier, target = src))
|
||||
if(S.get_amount() < 2)
|
||||
return
|
||||
S.use(2)
|
||||
@@ -181,20 +188,26 @@
|
||||
transfer_fingerprints_to(FW)
|
||||
qdel(src)
|
||||
else
|
||||
var/F = text2path("/turf/closed/wall/mineral/[M]")
|
||||
var/list/material_list
|
||||
var/F = S.walltype
|
||||
if(!F)
|
||||
return
|
||||
F = /turf/closed/wall/material
|
||||
if(S.material_type)
|
||||
material_list = list()
|
||||
material_list[SSmaterials.GetMaterialRef(S.material_type)] = MINERAL_MATERIAL_AMOUNT * 2
|
||||
if(S.get_amount() < 2)
|
||||
to_chat(user, "<span class='warning'>You need at least two sheets to add plating!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start adding plating...</span>")
|
||||
if (do_after(user, 40, target = src))
|
||||
if (do_after(user, 40*platingmodifier, target = src))
|
||||
if(S.get_amount() < 2)
|
||||
return
|
||||
S.use(2)
|
||||
to_chat(user, "<span class='notice'>You add the plating.</span>")
|
||||
var/turf/T = get_turf(src)
|
||||
T.PlaceOnTop(F)
|
||||
var/turf/newturf = T.PlaceOnTop(F)
|
||||
if(material_list)
|
||||
newturf.set_custom_materials(material_list)
|
||||
transfer_fingerprints_to(T)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
@@ -267,7 +267,7 @@
|
||||
var/obj/structure/cable/C = T.get_cable_node()
|
||||
if(C)
|
||||
playsound(src, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5)
|
||||
tesla_zap(src, 3, C.newavail() * 0.01, TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE | TESLA_MOB_STUN | TESLA_ALLOW_DUPLICATES) //Zap for 1/100 of the amount of power. At a million watts in the grid, it will be as powerful as a tesla revolver shot.
|
||||
tesla_zap(src, 3, C.newavail() * 0.01, ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE | ZAP_MOB_STUN | ZAP_ALLOW_DUPLICATES) //Zap for 1/100 of the amount of power. At a million watts in the grid, it will be as powerful as a tesla revolver shot.
|
||||
C.add_delayedload(C.newavail() * 0.0375) // you can gain up to 3.5 via the 4x upgrades power is halved by the pole so thats 2x then 1X then .5X for 3.5x the 3 bounces shock.
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
// The crowd is pleased
|
||||
// The delay is to making large crowds have a longer laster applause
|
||||
var/delay_offset = 0
|
||||
for(var/mob/M in viewers(src, 7))
|
||||
for(var/mob/M in fov_viewers(world.view, src))
|
||||
var/mob/living/carbon/human/C = M
|
||||
if (ishuman(M))
|
||||
addtimer(CALLBACK(C, /mob/.proc/emote, "clap"), delay_offset * 0.3)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
var/bonespear = FALSE
|
||||
var/obj/item/twohanded/spear/spear
|
||||
var/obj/item/spear/spear
|
||||
var/obj/item/bodypart/head/victim
|
||||
|
||||
/obj/structure/headpike/bone //for bone spears
|
||||
@@ -20,9 +20,9 @@
|
||||
name = "[victim.name] on a spear"
|
||||
update_icon()
|
||||
if(bonespear)
|
||||
spear = locate(/obj/item/twohanded/bonespear) in parts_list
|
||||
spear = locate(/obj/item/spear/bonespear) in parts_list
|
||||
else
|
||||
spear = locate(/obj/item/twohanded/spear) in parts_list
|
||||
spear = locate(/obj/item/spear) in parts_list
|
||||
|
||||
/obj/structure/headpike/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
//copypaste sorry
|
||||
var/obj/item/storage/bag/trash/mybag
|
||||
var/obj/item/mop/mymop
|
||||
var/obj/item/twohanded/broom/mybroom
|
||||
var/obj/item/broom/mybroom
|
||||
var/obj/item/reagent_containers/spray/cleaner/myspray
|
||||
var/obj/item/lightreplacer/myreplacer
|
||||
var/signs = 0
|
||||
@@ -48,9 +48,9 @@
|
||||
m.janicart_insert(user, src)
|
||||
else
|
||||
to_chat(user, fail_msg)
|
||||
else if(istype(I, /obj/item/twohanded/broom))
|
||||
else if(istype(I, /obj/item/broom))
|
||||
if(!mybroom)
|
||||
var/obj/item/twohanded/broom/b=I
|
||||
var/obj/item/broom/b=I
|
||||
b.janicart_insert(user,src)
|
||||
else
|
||||
to_chat(user, fail_msg)
|
||||
|
||||
@@ -149,3 +149,30 @@
|
||||
pixel_x = 0
|
||||
pixel_y = 0
|
||||
return TRUE
|
||||
|
||||
/obj/structure/lattice/lava
|
||||
name = "heatproof support lattice"
|
||||
desc = "A specialized support beam for building across lava. Watch your step."
|
||||
icon = 'icons/obj/smooth_structures/catwalk.dmi'
|
||||
icon_state = "catwalk"
|
||||
number_of_rods = 1
|
||||
color = "#5286b9ff"
|
||||
smooth = SMOOTH_TRUE
|
||||
canSmoothWith = null
|
||||
obj_flags = CAN_BE_HIT | BLOCK_Z_FALL
|
||||
resistance_flags = FIRE_PROOF | LAVA_PROOF
|
||||
|
||||
/obj/structure/lattice/lava/deconstruction_hints(mob/user)
|
||||
return "<span class='notice'>The rods look like they could be <b>cut</b>, but the <i>heat treatment will shatter off</i>. There's space for a <i>tile</i>.</span>"
|
||||
|
||||
/obj/structure/lattice/lava/attackby(obj/item/C, mob/user, params)
|
||||
. = ..()
|
||||
if(istype(C, /obj/item/stack/tile/plasteel))
|
||||
var/obj/item/stack/tile/plasteel/P = C
|
||||
if(P.use(1))
|
||||
to_chat(user, "<span class='notice'>You construct a floor plating, as lava settles around the rods.</span>")
|
||||
playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE)
|
||||
new /turf/open/floor/plating(locate(x, y, z))
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need one floor tile to build atop [src].</span>")
|
||||
return
|
||||
|
||||
@@ -21,21 +21,21 @@
|
||||
return TRUE
|
||||
|
||||
///Handles the weaving.
|
||||
/obj/structure/loom/proc/weave(obj/item/stack/sheet/S, mob/user)
|
||||
if(!istype(S) || !S.is_fabric)
|
||||
/obj/structure/loom/proc/weave(obj/item/stack/sheet/cotton/W, mob/user)
|
||||
if(!istype(W))
|
||||
return FALSE
|
||||
if(!anchored)
|
||||
user.show_message("<span class='notice'>The loom needs to be wrenched down.</span>", MSG_VISUAL)
|
||||
return FALSE
|
||||
if(S.amount < FABRIC_PER_SHEET)
|
||||
user.show_message("<span class='notice'>You need at least [FABRIC_PER_SHEET] units of fabric before using this.</span>", 1)
|
||||
if(W.amount < FABRIC_PER_SHEET)
|
||||
user.show_message("<span class='notice'>You need at least [FABRIC_PER_SHEET] units of fabric before using this.</span>", MSG_VISUAL)
|
||||
return FALSE
|
||||
user.show_message("<span class='notice'>You start weaving \the [S.name] through the loom..</span>", MSG_VISUAL)
|
||||
if(S.use_tool(src, user, S.pull_effort))
|
||||
if(S.amount >= FABRIC_PER_SHEET)
|
||||
new S.loom_result(drop_location())
|
||||
S.use(FABRIC_PER_SHEET)
|
||||
user.show_message("<span class='notice'>You weave \the [S.name] into a workable fabric.</span>", MSG_VISUAL)
|
||||
user.show_message("<span class='notice'>You start weaving \the [W.name] through the loom..</span>", MSG_VISUAL)
|
||||
if(W.use_tool(src, user, W.pull_effort))
|
||||
if(W.amount >= FABRIC_PER_SHEET)
|
||||
new W.loom_result(drop_location())
|
||||
W.use(FABRIC_PER_SHEET)
|
||||
user.show_message("<span class='notice'>You weave \the [W.name] into a workable fabric.</span>", MSG_VISUAL)
|
||||
return TRUE
|
||||
|
||||
#undef FABRIC_PER_SHEET
|
||||
@@ -4,6 +4,7 @@
|
||||
desc = "Mirror mirror on the wall, who's the most robust of them all?"
|
||||
icon = 'icons/obj/watercloset.dmi'
|
||||
icon_state = "mirror"
|
||||
plane = ABOVE_WALL_PLANE
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
max_integrity = 200
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
desc = "A board for pinning important notices upon."
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "nboard00"
|
||||
plane = ABOVE_WALL_PLANE
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
max_integrity = 150
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
icon_state = "human_male"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
flags_1 = PREVENT_CONTENTS_EXPLOSION_1
|
||||
max_integrity = 200
|
||||
var/timer = 240 //eventually the person will be freed
|
||||
var/timer = 8 MINUTES //eventually the person will be freed
|
||||
var/mob/living/petrified_mob
|
||||
|
||||
/obj/structure/statue/petrified/New(loc, mob/living/L, statue_timer)
|
||||
/obj/structure/statue/petrified/Initialize(mapload, mob/living/L, statue_timer)
|
||||
. = ..()
|
||||
if(statue_timer)
|
||||
timer = statue_timer
|
||||
if(L)
|
||||
@@ -17,25 +19,18 @@
|
||||
L.buckled.unbuckle_mob(L,force=1)
|
||||
L.visible_message("<span class='warning'>[L]'s skin rapidly turns to marble!</span>", "<span class='userdanger'>Your body freezes up! Can't... move... can't... think...</span>")
|
||||
L.forceMove(src)
|
||||
ADD_TRAIT(L, TRAIT_MUTE, STATUE_MUTE)
|
||||
ADD_TRAIT(L, TRAIT_MUTE, STATUE_TRAIT)
|
||||
ADD_TRAIT(L, TRAIT_EMOTEMUTE, STATUE_TRAIT)
|
||||
ADD_TRAIT(L, TRAIT_LOOC_MUTE, STATUE_TRAIT)
|
||||
ADD_TRAIT(L, TRAIT_AOOC_MUTE, STATUE_TRAIT)
|
||||
ADD_TRAIT(L, TRAIT_MOBILITY_NOMOVE, STATUE_TRAIT)
|
||||
ADD_TRAIT(L, TRAIT_MOBILITY_NOPICKUP, STATUE_TRAIT)
|
||||
ADD_TRAIT(L, TRAIT_MOBILITY_NOUSE, STATUE_TRAIT)
|
||||
L.faction += "mimic" //Stops mimics from instaqdeling people in statues
|
||||
L.status_flags |= GODMODE
|
||||
obj_integrity = L.health + 100 //stoning damaged mobs will result in easier to shatter statues
|
||||
max_integrity = obj_integrity
|
||||
START_PROCESSING(SSobj, src)
|
||||
..()
|
||||
|
||||
/obj/structure/statue/petrified/process()
|
||||
if(!petrified_mob)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
timer--
|
||||
petrified_mob.Stun(40) //So they can't do anything while petrified
|
||||
if(timer <= 0)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/statue/petrified/contents_explosion(severity, target)
|
||||
return
|
||||
QDEL_IN(src, timer)
|
||||
|
||||
/obj/structure/statue/petrified/handle_atom_del(atom/A)
|
||||
if(A == petrified_mob)
|
||||
@@ -59,7 +54,13 @@
|
||||
if(petrified_mob)
|
||||
petrified_mob.status_flags &= ~GODMODE
|
||||
petrified_mob.forceMove(loc)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_MUTE, STATUE_MUTE)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_MUTE, STATUE_TRAIT)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_EMOTEMUTE, STATUE_TRAIT)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_LOOC_MUTE, STATUE_TRAIT)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_AOOC_MUTE, STATUE_TRAIT)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_MOBILITY_NOMOVE, STATUE_TRAIT)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_MOBILITY_NOPICKUP, STATUE_TRAIT)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_MOBILITY_NOUSE, STATUE_TRAIT)
|
||||
petrified_mob.take_overall_damage((petrified_mob.health - obj_integrity + 100)) //any new damage the statue incurred is transfered to the mob
|
||||
petrified_mob.faction -= "mimic"
|
||||
petrified_mob = null
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
anchored = TRUE
|
||||
opacity = 0
|
||||
density = FALSE
|
||||
plane = ABOVE_WALL_PLANE
|
||||
layer = SIGN_LAYER
|
||||
max_integrity = 100
|
||||
armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
|
||||
@@ -35,6 +36,7 @@
|
||||
"<span class='notice'>You unfasten [src].</span>")
|
||||
var/obj/item/sign_backing/SB = new (get_turf(user))
|
||||
SB.icon_state = icon_state
|
||||
SB.set_custom_materials(custom_materials) //This is here so picture frames and wooden things don't get messed up.
|
||||
SB.sign_path = type
|
||||
SB.setDir(dir)
|
||||
qdel(src)
|
||||
|
||||
@@ -46,3 +46,4 @@
|
||||
name = "Mr. Deempisi portrait"
|
||||
desc = "Under the painting a plaque reads: 'While the meat grinder may not have spared you, fear not. Not one part of you has gone to waste... You were delicious.'"
|
||||
icon_state = "monkey_painting"
|
||||
custom_materials = list(/datum/material/wood = 2000) //The same as /obj/structure/sign/picture_frame
|
||||
|
||||
@@ -73,3 +73,8 @@
|
||||
name = "\improper ENGINEERING SAFETY"
|
||||
desc = "A sign detailing the various safety protocols when working on-site to ensure a safe shift."
|
||||
icon_state = "safety"
|
||||
|
||||
/obj/structure/sign/warning/explosives
|
||||
name = "\improper HIGH EXPLOSIVES sign"
|
||||
desc = "A warning sign which reads 'HIGH EXPLOSIVES'."
|
||||
icon_state = "explosives"
|
||||
|
||||
@@ -8,12 +8,17 @@
|
||||
max_integrity = 100
|
||||
var/oreAmount = 5
|
||||
var/material_drop_type = /obj/item/stack/sheet/metal
|
||||
var/impressiveness = 15
|
||||
CanAtmosPass = ATMOS_PASS_DENSITY
|
||||
|
||||
|
||||
/obj/structure/statue/Initialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/art, impressiveness)
|
||||
addtimer(CALLBACK(src, /datum.proc/_AddElement, list(/datum/element/beauty, impressiveness * 75)), 0)
|
||||
|
||||
/obj/structure/statue/attackby(obj/item/W, mob/living/user, params)
|
||||
add_fingerprint(user)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
if(default_unfasten_wrench(user, W))
|
||||
return
|
||||
@@ -30,15 +35,6 @@
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/structure/statue/attack_hand(mob/living/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
add_fingerprint(user)
|
||||
user.visible_message("[user] rubs some dust off from the [name]'s surface.", \
|
||||
"<span class='notice'>You rub some dust off from the [name]'s surface.</span>")
|
||||
|
||||
/obj/structure/statue/deconstruct(disassembled = TRUE)
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
if(material_drop_type)
|
||||
@@ -58,6 +54,7 @@
|
||||
material_drop_type = /obj/item/stack/sheet/mineral/uranium
|
||||
var/last_event = 0
|
||||
var/active = null
|
||||
impressiveness = 25 // radiation makes an impression
|
||||
|
||||
/obj/structure/statue/uranium/nuke
|
||||
name = "statue of a nuclear fission explosive"
|
||||
@@ -101,6 +98,7 @@
|
||||
max_integrity = 200
|
||||
material_drop_type = /obj/item/stack/sheet/mineral/plasma
|
||||
desc = "This statue is suitably made from plasma."
|
||||
impressiveness = 20
|
||||
|
||||
/obj/structure/statue/plasma/scientist
|
||||
name = "statue of a scientist"
|
||||
@@ -151,6 +149,7 @@
|
||||
max_integrity = 300
|
||||
material_drop_type = /obj/item/stack/sheet/mineral/gold
|
||||
desc = "This is a highly valuable statue made from gold."
|
||||
impressiveness = 30
|
||||
|
||||
/obj/structure/statue/gold/hos
|
||||
name = "statue of the head of security"
|
||||
@@ -178,6 +177,7 @@
|
||||
max_integrity = 300
|
||||
material_drop_type = /obj/item/stack/sheet/mineral/silver
|
||||
desc = "This is a valuable statue made from silver."
|
||||
impressiveness = 25
|
||||
|
||||
/obj/structure/statue/silver/md
|
||||
name = "statue of a medical officer"
|
||||
@@ -205,6 +205,7 @@
|
||||
max_integrity = 1000
|
||||
material_drop_type = /obj/item/stack/sheet/mineral/diamond
|
||||
desc = "This is a very expensive diamond statue."
|
||||
impressiveness = 60
|
||||
|
||||
/obj/structure/statue/diamond/captain
|
||||
name = "statue of THE captain."
|
||||
@@ -225,6 +226,7 @@
|
||||
material_drop_type = /obj/item/stack/sheet/mineral/bananium
|
||||
desc = "A bananium statue with a small engraving:'HOOOOOOONK'."
|
||||
var/spam_flag = 0
|
||||
impressiveness = 65
|
||||
|
||||
/obj/structure/statue/bananium/clown
|
||||
name = "statue of a clown"
|
||||
|
||||
@@ -134,6 +134,8 @@
|
||||
if(!ishuman(pushed_mob))
|
||||
return
|
||||
var/mob/living/carbon/human/H = pushed_mob
|
||||
if(iscatperson(H))
|
||||
H.emote("nya")
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "table", /datum/mood_event/table)
|
||||
|
||||
/obj/structure/table/shove_act(mob/living/target, mob/living/user)
|
||||
@@ -163,6 +165,9 @@
|
||||
if(istype(I, /obj/item/storage/bag/tray))
|
||||
var/obj/item/storage/bag/tray/T = I
|
||||
if(T.contents.len > 0) // If the tray isn't empty
|
||||
for(var/x in T.contents)
|
||||
var/obj/item/item = x
|
||||
AfterPutItemOnTable(item, user)
|
||||
SEND_SIGNAL(I, COMSIG_TRY_STORAGE_QUICK_EMPTY, drop_location())
|
||||
user.visible_message("[user] empties [I] on [src].")
|
||||
return
|
||||
@@ -177,13 +182,17 @@
|
||||
//Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf)
|
||||
I.pixel_x = clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2)
|
||||
I.pixel_y = clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2)
|
||||
return 1
|
||||
AfterPutItemOnTable(I, user)
|
||||
return TRUE
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/table/proc/AfterPutItemOnTable(obj/item/I, mob/living/user)
|
||||
return
|
||||
|
||||
/obj/structure/table/alt_attack_hand(mob/user)
|
||||
if(user && Adjacent(user) && !user.incapacitated())
|
||||
user.setClickCooldown(4)
|
||||
user.changeNext_move(CLICK_CD_MELEE*0.5)
|
||||
if(istype(user) && user.a_intent == INTENT_HARM)
|
||||
user.visible_message("<span class='warning'>[user] slams [user.p_their()] palms down on [src].</span>", "<span class='warning'>You slam your palms down on [src].</span>")
|
||||
playsound(src, 'sound/weapons/sonic_jackhammer.ogg', 50, 1)
|
||||
@@ -211,9 +220,40 @@
|
||||
/obj/structure/table/greyscale
|
||||
icon = 'icons/obj/smooth_structures/table_greyscale.dmi'
|
||||
icon_state = "table"
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS | MATERIAL_EFFECTS
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS
|
||||
buildstack = null //No buildstack, so generate from mat datums
|
||||
|
||||
///Table on wheels
|
||||
/obj/structure/table/rolling
|
||||
name = "Rolling table"
|
||||
desc = "A NT brand \"Rolly poly\" rolling table. It can and will move."
|
||||
anchored = FALSE
|
||||
smooth = SMOOTH_FALSE
|
||||
canSmoothWith = list()
|
||||
icon = 'icons/obj/smooth_structures/rollingtable.dmi'
|
||||
icon_state = "rollingtable"
|
||||
var/list/attached_items = list()
|
||||
|
||||
/obj/structure/table/rolling/AfterPutItemOnTable(obj/item/I, mob/living/user)
|
||||
. = ..()
|
||||
attached_items += I
|
||||
RegisterSignal(I, COMSIG_MOVABLE_MOVED, .proc/RemoveItemFromTable) //Listen for the pickup event, unregister on pick-up so we aren't moved
|
||||
|
||||
/obj/structure/table/rolling/proc/RemoveItemFromTable(datum/source, newloc, dir)
|
||||
if(newloc != loc) //Did we not move with the table? because that shit's ok
|
||||
return FALSE
|
||||
attached_items -= source
|
||||
UnregisterSignal(source, COMSIG_MOVABLE_MOVED)
|
||||
|
||||
/obj/structure/table/rolling/Moved(atom/OldLoc, Dir)
|
||||
for(var/mob/M in OldLoc.contents)//Kidnap everyone on top
|
||||
M.forceMove(loc)
|
||||
for(var/x in attached_items)
|
||||
var/atom/movable/AM = x
|
||||
if(!AM.Move(loc))
|
||||
RemoveItemFromTable(AM, AM.loc)
|
||||
return TRUE
|
||||
|
||||
/*
|
||||
* Glass tables
|
||||
*/
|
||||
|
||||
@@ -80,10 +80,11 @@
|
||||
name = "shock trap"
|
||||
desc = "A trap that will shock and render you immobile. You'd better avoid it."
|
||||
icon_state = "trap-shock"
|
||||
var/stun_time = 100
|
||||
|
||||
/obj/structure/trap/stun/trap_effect(mob/living/L)
|
||||
L.electrocute_act(30, src, flags = SHOCK_NOGLOVES) // electrocute act does a message.
|
||||
L.DefaultCombatKnockdown(100)
|
||||
L.Paralyze(stun_time)
|
||||
|
||||
/obj/structure/trap/fire
|
||||
name = "flame trap"
|
||||
@@ -151,3 +152,75 @@
|
||||
new /mob/living/simple_animal/hostile/construct/proteon/hostile(loc)
|
||||
new /mob/living/simple_animal/hostile/construct/proteon/hostile(loc)
|
||||
QDEL_IN(src, 30)
|
||||
|
||||
//fugitive traps
|
||||
/obj/structure/trap/stun/hunter
|
||||
name = "bounty trap"
|
||||
desc = "A trap that only goes off when a fugitive steps on it, announcing the location and stunning the target. You'd better avoid it."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "bounty_trap_on"
|
||||
stun_time = 200
|
||||
var/obj/item/bountytrap/stored_item
|
||||
var/caught = FALSE
|
||||
|
||||
/obj/structure/trap/stun/hunter/Initialize(mapload)
|
||||
. = ..()
|
||||
time_between_triggers = 10
|
||||
|
||||
/obj/structure/trap/stun/hunter/Crossed(atom/movable/AM)
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(!L.mind?.has_antag_datum(/datum/antagonist/fugitive))
|
||||
return
|
||||
caught = TRUE
|
||||
. = ..()
|
||||
|
||||
/obj/structure/trap/stun/hunter/flare()
|
||||
..()
|
||||
stored_item.forceMove(get_turf(src))
|
||||
forceMove(stored_item)
|
||||
if(caught)
|
||||
stored_item.announce_fugitive()
|
||||
caught = FALSE
|
||||
|
||||
/obj/item/bountytrap
|
||||
name = "bounty trap"
|
||||
desc = "A trap that only goes off when a fugitive steps on it, announcing the location and stunning the target. It's currently inactive."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "bounty_trap_off"
|
||||
var/obj/structure/trap/stun/hunter/stored_trap
|
||||
var/obj/item/radio/radio
|
||||
var/datum/effect_system/spark_spread/spark_system
|
||||
|
||||
/obj/item/bountytrap/Initialize(mapload)
|
||||
. = ..()
|
||||
radio = new(src)
|
||||
radio.subspace_transmission = TRUE
|
||||
radio.canhear_range = 0
|
||||
radio.recalculateChannels()
|
||||
spark_system = new
|
||||
spark_system.set_up(4,1,src)
|
||||
spark_system.attach(src)
|
||||
name = "[name] #[rand(1, 999)]"
|
||||
stored_trap = new(src)
|
||||
stored_trap.name = name
|
||||
stored_trap.stored_item = src
|
||||
|
||||
/obj/item/bountytrap/proc/announce_fugitive()
|
||||
spark_system.start()
|
||||
playsound(src, 'sound/machines/ding.ogg', 50, TRUE)
|
||||
radio.talk_into(src, "Fugitive has triggered this trap in the [get_area_name(src)]!", RADIO_CHANNEL_COMMON)
|
||||
|
||||
/obj/item/bountytrap/attack_self(mob/living/user)
|
||||
var/turf/T = get_turf(src)
|
||||
if(!user || !user.transferItemToLoc(src, T))//visibly unequips
|
||||
return
|
||||
to_chat(user, "<span class=notice>You set up [src]. Examine while close to disarm it.</span>")
|
||||
stored_trap.forceMove(T)//moves trap to ground
|
||||
forceMove(stored_trap)//moves item into trap
|
||||
|
||||
/obj/item/bountytrap/Destroy()
|
||||
qdel(stored_trap)
|
||||
QDEL_NULL(radio)
|
||||
QDEL_NULL(spark_system)
|
||||
. = ..()
|
||||
|
||||
@@ -11,12 +11,21 @@
|
||||
var/cistern = 0 //if the cistern bit is open
|
||||
var/w_items = 0 //the combined w_class of all the items in the cistern
|
||||
var/mob/living/swirlie = null //the mob being given a swirlie
|
||||
var/buildstacktype = /obj/item/stack/sheet/metal //they're metal now, shut up
|
||||
var/buildstackamount = 1
|
||||
|
||||
/obj/structure/toilet/Initialize()
|
||||
. = ..()
|
||||
open = round(rand(0, 1))
|
||||
update_icon()
|
||||
|
||||
/obj/structure/toilet/Destroy()
|
||||
if(loc)
|
||||
for(var/A in contents)
|
||||
var/atom/movable/AM = A
|
||||
AM.forceMove(loc)
|
||||
return ..()
|
||||
|
||||
/obj/structure/toilet/attack_hand(mob/living/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
@@ -72,7 +81,18 @@
|
||||
/obj/structure/toilet/update_icon_state()
|
||||
icon_state = "toilet[open][cistern]"
|
||||
|
||||
/obj/structure/toilet/deconstruct()
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
if(buildstacktype)
|
||||
new buildstacktype(loc,buildstackamount)
|
||||
else
|
||||
for(var/i in custom_materials)
|
||||
var/datum/material/M = i
|
||||
new M.sheet_type(loc, FLOOR(custom_materials[M] / MINERAL_MATERIAL_AMOUNT, 1))
|
||||
..()
|
||||
|
||||
/obj/structure/toilet/attackby(obj/item/I, mob/living/user, params)
|
||||
add_fingerprint(user)
|
||||
if(istype(I, /obj/item/crowbar))
|
||||
to_chat(user, "<span class='notice'>You start to [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"]...</span>")
|
||||
playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 50, 1)
|
||||
@@ -80,7 +100,9 @@
|
||||
user.visible_message("[user] [cistern ? "replaces the lid on the cistern" : "lifts the lid off the cistern"]!", "<span class='notice'>You [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"]!</span>", "<span class='italics'>You hear grinding porcelain.</span>")
|
||||
cistern = !cistern
|
||||
update_icon()
|
||||
|
||||
else if(I.tool_behaviour == TOOL_WRENCH && !(flags_1&NODECONSTRUCT_1))
|
||||
I.play_tool_sound(src)
|
||||
deconstruct()
|
||||
else if(cistern)
|
||||
if(user.a_intent != INTENT_HARM)
|
||||
if(I.w_class > WEIGHT_CLASS_NORMAL)
|
||||
@@ -95,6 +117,10 @@
|
||||
w_items += I.w_class
|
||||
to_chat(user, "<span class='notice'>You carefully place [I] into the cistern.</span>")
|
||||
|
||||
if(istype(I, /obj/item/reagent_containers/food/snacks/cube))
|
||||
var/obj/item/reagent_containers/food/snacks/cube/cube = I
|
||||
cube.Expand()
|
||||
return
|
||||
else if(istype(I, /obj/item/reagent_containers))
|
||||
if (!open)
|
||||
return
|
||||
@@ -130,6 +156,10 @@
|
||||
/obj/structure/toilet/secret/prison
|
||||
secret_type = /obj/effect/spawner/lootdrop/prison_loot_toilet
|
||||
|
||||
/obj/structure/toilet/greyscale
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR
|
||||
buildstacktype = null
|
||||
|
||||
/obj/structure/urinal
|
||||
name = "urinal"
|
||||
desc = "The HU-452, an experimental urinal. Comes complete with experimental urinal cake."
|
||||
@@ -459,6 +489,8 @@
|
||||
anchored = TRUE
|
||||
var/busy = FALSE //Something's being washed at the moment
|
||||
var/dispensedreagent = /datum/reagent/water // for whenever plumbing happens
|
||||
var/buildstacktype = /obj/item/stack/sheet/metal
|
||||
var/buildstackamount = 1
|
||||
|
||||
/obj/structure/sink/attack_hand(mob/living/user)
|
||||
. = ..()
|
||||
@@ -520,7 +552,7 @@
|
||||
if(istype(O, /obj/item/melee/baton))
|
||||
var/obj/item/melee/baton/B = O
|
||||
if(B.cell)
|
||||
if(B.cell.charge > 0 && B.status == 1)
|
||||
if(B.cell.charge > 0 && B.turned_on)
|
||||
flick("baton_active", src)
|
||||
var/stunforce = B.stamforce
|
||||
user.DefaultCombatKnockdown(stunforce * 2)
|
||||
@@ -537,6 +569,11 @@
|
||||
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
|
||||
return
|
||||
|
||||
if(O.tool_behaviour == TOOL_WRENCH && !(flags_1&NODECONSTRUCT_1))
|
||||
O.play_tool_sound(src)
|
||||
deconstruct()
|
||||
return
|
||||
|
||||
if(istype(O, /obj/item/stack/medical/gauze))
|
||||
var/obj/item/stack/medical/gauze/G = O
|
||||
new /obj/item/reagent_containers/rag(src.loc)
|
||||
@@ -544,6 +581,12 @@
|
||||
G.use(1)
|
||||
return
|
||||
|
||||
if(istype(O, /obj/item/stack/ore/glass))
|
||||
new /obj/item/stack/sheet/sandblock(loc)
|
||||
to_chat(user, "<span class='notice'>You wet the sand in the sink and form it into a block.</span>")
|
||||
O.use(1)
|
||||
return
|
||||
|
||||
if(!istype(O))
|
||||
return
|
||||
if(O.item_flags & ABSTRACT) //Abstract items like grabs won't wash. No-drop items will though because it's still technically an item in your hand.
|
||||
@@ -568,9 +611,18 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/sink/deconstruct(disassembled = TRUE)
|
||||
new /obj/item/stack/sheet/metal (loc, 3)
|
||||
qdel(src)
|
||||
/obj/structure/sink/deconstruct()
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
drop_materials()
|
||||
..()
|
||||
|
||||
/obj/structure/sink/proc/drop_materials()
|
||||
if(buildstacktype)
|
||||
new buildstacktype(loc,buildstackamount)
|
||||
else
|
||||
for(var/i in custom_materials)
|
||||
var/datum/material/M = i
|
||||
new M.sheet_type(loc, FLOOR(custom_materials[M] / MINERAL_MATERIAL_AMOUNT, 1))
|
||||
|
||||
/obj/structure/sink/kitchen
|
||||
name = "kitchen sink"
|
||||
@@ -626,7 +678,7 @@
|
||||
if(steps == 4 && istype(S, /obj/item/stack/sheet/mineral/wood))
|
||||
if(S.use(3))
|
||||
steps = 5
|
||||
desc = "A dug out well, A dug out well with out rope. Just add some cloth!"
|
||||
desc = "A dug out well, A dug out well without rope. Just add some cloth!"
|
||||
icon_state = "well_4"
|
||||
return TRUE
|
||||
else
|
||||
@@ -669,6 +721,11 @@
|
||||
/obj/structure/sink/puddle/deconstruct(disassembled = TRUE)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/sink/greyscale
|
||||
icon_state = "sink_greyscale"
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR
|
||||
buildstacktype = null
|
||||
|
||||
//Shower Curtains//
|
||||
//Defines used are pre-existing in layers.dm//
|
||||
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
#define NOT_ELECTROCHROMATIC 0
|
||||
#define ELECTROCHROMATIC_OFF 1
|
||||
#define ELECTROCHROMATIC_DIMMED 2
|
||||
|
||||
GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
|
||||
/proc/do_electrochromatic_toggle(new_status, id)
|
||||
@@ -42,6 +38,8 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
var/hitsound = 'sound/effects/Glasshit.ogg'
|
||||
rad_insulation = RAD_VERY_LIGHT_INSULATION
|
||||
rad_flags = RAD_PROTECT_CONTENTS
|
||||
flags_ricochet = RICOCHET_HARD
|
||||
ricochet_chance_mod = 0.4
|
||||
|
||||
/// Electrochromatic status
|
||||
var/electrochromatic_status = NOT_ELECTROCHROMATIC
|
||||
@@ -74,9 +72,8 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
if(reinf && anchored)
|
||||
state = WINDOW_SCREWED_TO_FRAME
|
||||
|
||||
if(mapload && electrochromatic_id)
|
||||
if(copytext(electrochromatic_id, 1, 2) == "!")
|
||||
electrochromatic_id = SSmapping.get_obfuscated_id(electrochromatic_id)
|
||||
if(mapload && electrochromatic_id && electrochromatic_id[1] == "!")
|
||||
electrochromatic_id = SSmapping.get_obfuscated_id(electrochromatic_id)
|
||||
|
||||
ini_dir = dir
|
||||
air_update_turf(1)
|
||||
@@ -274,29 +271,27 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
air_update_turf(TRUE)
|
||||
update_nearby_icons()
|
||||
|
||||
/obj/structure/window/proc/spraycan_paint(paint_color)
|
||||
if(color_hex2num(paint_color) < 255)
|
||||
set_opacity(255)
|
||||
else
|
||||
set_opacity(initial(opacity))
|
||||
add_atom_colour(paint_color, WASHABLE_COLOUR_PRIORITY)
|
||||
|
||||
/obj/structure/window/proc/electrochromatic_dim()
|
||||
if(electrochromatic_status == ELECTROCHROMATIC_DIMMED)
|
||||
return
|
||||
electrochromatic_status = ELECTROCHROMATIC_DIMMED
|
||||
animate(src, color = "#222222", time = 2)
|
||||
set_opacity(TRUE)
|
||||
var/current = color
|
||||
add_atom_colour("#222222", FIXED_COLOUR_PRIORITY)
|
||||
var/newcolor = color
|
||||
if(color != current)
|
||||
color = current
|
||||
animate(src, color = newcolor, time = 2)
|
||||
|
||||
/obj/structure/window/proc/electrochromatic_off()
|
||||
if(electrochromatic_status == ELECTROCHROMATIC_OFF)
|
||||
return
|
||||
electrochromatic_status = ELECTROCHROMATIC_OFF
|
||||
var/current = color
|
||||
update_atom_colour()
|
||||
remove_atom_colour(FIXED_COLOUR_PRIORITY, "#222222")
|
||||
var/newcolor = color
|
||||
color = current
|
||||
animate(src, color = newcolor, time = 2)
|
||||
if(color != current)
|
||||
color = current
|
||||
animate(src, color = newcolor, time = 2)
|
||||
|
||||
/obj/structure/window/proc/remove_electrochromatic()
|
||||
electrochromatic_off()
|
||||
@@ -351,11 +346,9 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
GLOB.electrochromatic_window_lookup[electrochromatic_id] |= src
|
||||
|
||||
/obj/structure/window/update_atom_colour()
|
||||
if((electrochromatic_status != ELECTROCHROMATIC_OFF) && (electrochromatic_status != ELECTROCHROMATIC_DIMMED))
|
||||
return FALSE
|
||||
. = ..()
|
||||
if(color && (color_hex2num(color) < 255))
|
||||
set_opacity(255)
|
||||
if(electrochromatic_status == ELECTROCHROMATIC_DIMMED || (color && (color_hex2num(color) < 255)))
|
||||
set_opacity(TRUE)
|
||||
else
|
||||
set_opacity(FALSE)
|
||||
|
||||
@@ -530,6 +523,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
explosion_block = 1
|
||||
glass_type = /obj/item/stack/sheet/rglass
|
||||
rad_insulation = RAD_HEAVY_INSULATION
|
||||
ricochet_chance_mod = 0.8
|
||||
|
||||
/obj/structure/window/reinforced/spawner/east
|
||||
dir = EAST
|
||||
@@ -695,6 +689,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
level = 3
|
||||
glass_type = /obj/item/stack/sheet/titaniumglass
|
||||
glass_amount = 2
|
||||
ricochet_chance_mod = 0.9
|
||||
|
||||
/obj/structure/window/shuttle/narsie_act()
|
||||
add_atom_colour("#3C3434", FIXED_COLOUR_PRIORITY)
|
||||
@@ -885,7 +880,3 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
return
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
#undef NOT_ELECTROCHROMATIC
|
||||
#undef ELECTROCHROMATIC_OFF
|
||||
#undef ELECTROCHROMATIC_DIMMED
|
||||
|
||||
Reference in New Issue
Block a user