Merge branch 'master' into food-quality
This commit is contained in:
@@ -188,7 +188,7 @@
|
||||
|
||||
/datum/component/personal_crafting/proc/construct_item(mob/user, datum/crafting_recipe/R)
|
||||
var/list/contents = get_surroundings(user)
|
||||
var/send_feedback = 1
|
||||
var/send_feedback = TRUE
|
||||
if(check_contents(user, R, contents))
|
||||
if(check_tools(user, R, contents))
|
||||
if(do_after(user, R.time, target = user))
|
||||
@@ -217,7 +217,7 @@
|
||||
if(send_feedback)
|
||||
SSblackbox.record_feedback("tally", "object_crafted", 1, I.type)
|
||||
log_craft("[I] crafted by [user] at [loc_name(I.loc)]")
|
||||
return 0
|
||||
return FALSE
|
||||
return "."
|
||||
return ", missing tool."
|
||||
return ", missing component."
|
||||
@@ -420,8 +420,11 @@
|
||||
switch(action)
|
||||
if("make")
|
||||
var/datum/crafting_recipe/TR = locate(params["recipe"]) in GLOB.crafting_recipes
|
||||
busy = TRUE
|
||||
ui_interact(usr)
|
||||
if(busy)
|
||||
to_chat(usr, "<span class='warning'>You are already making something!</span>")
|
||||
return
|
||||
busy = TRUE
|
||||
var/fail_msg = construct_item(usr, TR)
|
||||
if(!fail_msg)
|
||||
to_chat(usr, "<span class='notice'>[TR.name] constructed.</span>")
|
||||
|
||||
+212
-57
@@ -14,26 +14,32 @@
|
||||
name = "Glass working tools"
|
||||
desc = "A lovely belt of most the tools you will need to shape, mold, and refine glass into more advanced shapes."
|
||||
icon_state = "glass_tools"
|
||||
tool_behaviour = TOOL_GLASS_CUT
|
||||
tool_behaviour = TOOL_GLASS_CUT //Cutting takes 20 ticks
|
||||
|
||||
/obj/item/glasswork/blowing_rod
|
||||
name = "Glass working blow rod"
|
||||
desc = "A hollow metal stick made for glass blowing."
|
||||
icon_state = "blowing_rods_unused"
|
||||
tool_behaviour = TOOL_BLOW
|
||||
tool_behaviour = TOOL_BLOW //Rods take 5 ticks
|
||||
|
||||
/obj/item/glasswork/glass_base
|
||||
/obj/item/glasswork/glass_base //Welding takes 30 ticks
|
||||
name = "Glass fodder sheet"
|
||||
desc = "A sheet of glass set aside for glass working"
|
||||
icon_state = "glass_base"
|
||||
var/next_step = null
|
||||
var/rod = /obj/item/glasswork/blowing_rod
|
||||
|
||||
/obj/item/lens
|
||||
name = "Optical lens"
|
||||
desc = "Good for selling or crafting, by itself its useless"
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "glass_optics"
|
||||
/obj/item/tea_plate
|
||||
name = "Tea Plate"
|
||||
desc = "A polished plate for a tea cup. How fancy!"
|
||||
icon = 'icons/obj/glass_ware.dmi'
|
||||
icon_state = "tea_plate"
|
||||
|
||||
/obj/item/tea_cup
|
||||
name = "Tea Cup"
|
||||
desc = "A glass cup made for fake tea!"
|
||||
icon = 'icons/obj/glass_ware.dmi'
|
||||
icon_state = "tea_plate"
|
||||
|
||||
//////////////////////Chem Disk/////////////////////
|
||||
//Two Steps //
|
||||
@@ -49,8 +55,9 @@
|
||||
/obj/item/glasswork/glass_base/dish/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_GLASS_CUT)
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
if(do_after(user,20, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/dish_part1
|
||||
name = "Half chem dish sheet"
|
||||
@@ -61,8 +68,9 @@
|
||||
/obj/item/glasswork/glass_base/dish_part1/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_GLASS_CUT)
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
if(do_after(user,20, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
//////////////////////Lens//////////////////////////
|
||||
//Six Steps //
|
||||
@@ -78,8 +86,9 @@
|
||||
/obj/item/glasswork/glass_base/glass_lens/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_GLASS_CUT)
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
if(do_after(user,20, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/glass_lens_part1
|
||||
name = "Glass fodder sheet"
|
||||
@@ -90,8 +99,9 @@
|
||||
/obj/item/glasswork/glass_base/glass_lens_part1/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_WELDER)
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
if(do_after(user,30, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/glass_lens_part2
|
||||
name = "Glass fodder sheet"
|
||||
@@ -102,8 +112,9 @@
|
||||
/obj/item/glasswork/glass_base/glass_lens_part2/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_WELDER)
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
if(do_after(user,30, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/glass_lens_part3
|
||||
name = "Glass fodder sheet"
|
||||
@@ -114,9 +125,10 @@
|
||||
/obj/item/glasswork/glass_base/glass_lens_part3/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_BLOW)
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
qdel(I)
|
||||
if(do_after(user,5, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
qdel(I)
|
||||
|
||||
/obj/item/glasswork/glass_base/glass_lens_part4
|
||||
name = "Glass fodder sheet"
|
||||
@@ -127,29 +139,31 @@
|
||||
/obj/item/glasswork/glass_base/glass_lens_part4/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_GLASS_CUT)
|
||||
new next_step(user.loc, 1)
|
||||
new rod(user.loc, 1)
|
||||
qdel(src)
|
||||
if(do_after(user,20, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
new rod(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/glass_lens_part5
|
||||
name = "Unpolished glass lens"
|
||||
desc = "A small unpolished glass lens. Could be polished with some cloth."
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
desc = "A small unpolished glass lens. Could be polished with some silk."
|
||||
icon = 'icons/obj/glass_ware.dmi'
|
||||
icon_state = "glass_optics"
|
||||
next_step = /obj/item/glasswork/glass_base/glass_lens_part6
|
||||
|
||||
/obj/item/glasswork/glass_base/glass_lens_part5/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(istype(I, /obj/item/stack/sheet/cloth))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
if(istype(I, /obj/item/stack/sheet/silk))
|
||||
if(do_after(user,10, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/glass_lens_part6
|
||||
name = "Unrefined glass lens"
|
||||
desc = "A small polished glass lens. Just needs to be refined with some sandstone."
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon = 'icons/obj/glass_ware.dmi'
|
||||
icon_state = "glass_optics"
|
||||
next_step = /obj/item/lens
|
||||
next_step = /obj/item/glasswork/glass_base/lens
|
||||
|
||||
/obj/item/glasswork/glass_base/glass_lens_part6/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
@@ -171,8 +185,9 @@
|
||||
/obj/item/glasswork/glass_base/spouty/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_GLASS_CUT)
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
if(do_after(user,20, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/spouty_part2
|
||||
name = "Glass fodder sheet"
|
||||
@@ -183,8 +198,9 @@
|
||||
/obj/item/glasswork/glass_base/spouty_part2/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_WELDER)
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
if(do_after(user,30, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/spouty_part3
|
||||
name = "Glass fodder sheet"
|
||||
@@ -195,9 +211,10 @@
|
||||
/obj/item/glasswork/glass_base/spouty_part3/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_BLOW)
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
qdel(I)
|
||||
if(do_after(user,5, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
qdel(I)
|
||||
|
||||
/obj/item/glasswork/glass_base/spouty_part4
|
||||
name = "Glass fodder sheet"
|
||||
@@ -208,9 +225,10 @@
|
||||
/obj/item/glasswork/glass_base/spouty_part4/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_GLASS_CUT)
|
||||
new next_step(user.loc, 1)
|
||||
new rod(user.loc, 1)
|
||||
qdel(src)
|
||||
if(do_after(user,20, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
new rod(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
//////////////////////Small Bulb Flask//////////////
|
||||
//Two Steps //
|
||||
@@ -226,8 +244,9 @@
|
||||
/obj/item/glasswork/glass_base/flask_small/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_WELDER)
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
if(do_after(user,30, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/flask_small_part1
|
||||
name = "Metled glass"
|
||||
@@ -238,9 +257,10 @@
|
||||
/obj/item/glasswork/glass_base/flask_small_part1/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_BLOW)
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
qdel(I)
|
||||
if(do_after(user,5, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
qdel(I)
|
||||
|
||||
/obj/item/glasswork/glass_base/flask_small_part2
|
||||
name = "Metled glass"
|
||||
@@ -251,9 +271,10 @@
|
||||
/obj/item/glasswork/glass_base/flask_small_part2/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_GLASS_CUT)
|
||||
new next_step(user.loc, 1)
|
||||
new rod(user.loc, 1)
|
||||
qdel(src)
|
||||
if(do_after(user,20, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
new rod(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
//////////////////////Large Bulb Flask//////////////
|
||||
//Two Steps //
|
||||
@@ -269,8 +290,9 @@
|
||||
/obj/item/glasswork/glass_base/flask_large/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_WELDER)
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
if(do_after(user,30, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/flask_large_part1
|
||||
name = "Metled glass"
|
||||
@@ -281,9 +303,10 @@
|
||||
/obj/item/glasswork/glass_base/flask_large_part1/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_BLOW)
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
qdel(I)
|
||||
if(do_after(user,5, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
qdel(I)
|
||||
|
||||
/obj/item/glasswork/glass_base/flask_large_part2
|
||||
name = "Metled glass"
|
||||
@@ -294,6 +317,138 @@
|
||||
/obj/item/glasswork/glass_base/flask_large_part2/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_GLASS_CUT)
|
||||
new next_step(user.loc, 1)
|
||||
new rod(user.loc, 1)
|
||||
qdel(src)
|
||||
if(do_after(user,20, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
new rod(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
//////////////////////Tea Plates////////////////////
|
||||
//Three Steps //
|
||||
//Sells for 1200 cr, takes 5 glass shets //
|
||||
//Usefull for selling and chemical things //
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
/obj/item/glasswork/glass_base/tea_plate
|
||||
name = "Glass fodder sheet"
|
||||
desc = "A set of glass sheets set aside for glass working, this one is ideal for a tea plate, how fancy! Needs to be heated with some tools."
|
||||
next_step = /obj/item/glasswork/glass_base/tea_plate1
|
||||
|
||||
/obj/item/glasswork/glass_base/tea_plate/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_WELDER)
|
||||
if(do_after(user,30, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/tea_plate1
|
||||
name = "Metled glass"
|
||||
desc = "A blob of metled glass, this one is ideal for a tea plate. Needs to be blown with some tools."
|
||||
icon_state = "glass_base_molding"
|
||||
next_step = /obj/item/glasswork/glass_base/tea_plate2
|
||||
|
||||
/obj/item/glasswork/glass_base/tea_plate1/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_BLOW)
|
||||
if(do_after(user,5, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
qdel(I)
|
||||
|
||||
/obj/item/glasswork/glass_base/tea_plate2
|
||||
name = "Metled glass"
|
||||
desc = "A blob of metled glass on the end of a blowing rod. Needs to be cut off with some tools."
|
||||
icon_state = "blowing_rods_inuse"
|
||||
next_step = /obj/item/glasswork/glass_base/tea_plate3
|
||||
|
||||
/obj/item/glasswork/glass_base/tea_plate2/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_GLASS_CUT)
|
||||
if(do_after(user,20, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
new rod(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/tea_plate3
|
||||
name = "Disk of glass"
|
||||
desc = "A disk of glass that can be cant be used for much. Needs to be polished with some silk."
|
||||
icon_state = "glass_base_half"
|
||||
next_step = /obj/item/tea_plate
|
||||
|
||||
/obj/item/glasswork/glass_base/tea_plate3/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(istype(I, /obj/item/stack/sheet/silk))
|
||||
if(do_after(user,10, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
//////////////////////Tea Cup///////////////////////
|
||||
//Four Steps //
|
||||
//Sells for 1800 cr, takes 6 glass shets //
|
||||
//Usefull for selling and chemical things //
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
/obj/item/glasswork/glass_base/tea_cup
|
||||
name = "Glass fodder sheet"
|
||||
desc = "A set of glass sheets set aside for glass working, this one is ideal for a tea cup, how fancy! Needs to be heated with some tools."
|
||||
next_step = /obj/item/glasswork/glass_base/tea_cup1
|
||||
|
||||
/obj/item/glasswork/glass_base/tea_cup/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_WELDER)
|
||||
if(do_after(user,30, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/tea_cup1
|
||||
name = "Metled glass"
|
||||
desc = "A blob of metled glass, this one is ideal for a tea cup. Needs to be blown with some tools."
|
||||
icon_state = "glass_base_molding"
|
||||
next_step = /obj/item/glasswork/glass_base/tea_cup2
|
||||
|
||||
/obj/item/glasswork/glass_base/tea_cup1/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_BLOW)
|
||||
if(do_after(user,5, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
qdel(I)
|
||||
|
||||
/obj/item/glasswork/glass_base/tea_cupe2
|
||||
name = "Metled glass"
|
||||
desc = "A blob of metled glass on the end of a blowing rod. Needs to be cut off with some tools."
|
||||
icon_state = "blowing_rods_inuse"
|
||||
next_step = /obj/item/glasswork/glass_base/tea_cup3
|
||||
|
||||
/obj/item/glasswork/glass_base/tea_cup2/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_GLASS_CUT)
|
||||
if(do_after(user,20, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
new rod(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/tea_cup3
|
||||
name = "Disk of glass"
|
||||
desc = "A bowl of glass that can be cant be used for much. Needs to be polished with some silk."
|
||||
icon_state = "glass_base_half"
|
||||
next_step = /obj/item/glasswork/glass_base/tea_cup4
|
||||
|
||||
/obj/item/glasswork/glass_base/cup3/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(istype(I, /obj/item/stack/sheet/silk))
|
||||
if(do_after(user,10, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/tea_cup4
|
||||
name = "Disk of glass"
|
||||
desc = "A bowl of polished glass that can be cant be used for much. Needs some more glass to make a handle."
|
||||
icon_state = "glass_base_half"
|
||||
next_step = /obj/item/tea_cup
|
||||
|
||||
/obj/item/glasswork/glass_base/cup4/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(istype(I, /obj/item/stack/sheet/glass))
|
||||
if(do_after(user,10, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
@@ -0,0 +1,98 @@
|
||||
//This file is for crafting using a lens!
|
||||
|
||||
/obj/item/glasswork/glass_base/lens
|
||||
name = "Optical lens"
|
||||
desc = "Good for selling or crafting, by itself its useless"
|
||||
icon = 'icons/obj/glass_ware.dmi'
|
||||
icon_state = "glass_optics"
|
||||
|
||||
//Laser pointers - 2600
|
||||
/obj/item/glasswork/glass_base/laserpointer_shell
|
||||
name = "Laser pointer assembly"
|
||||
desc = "Good for selling or crafting, by itself its useless. Needs a power capactor."
|
||||
icon_state = "laser_case"
|
||||
icon = 'icons/obj/glass_ware.dmi'
|
||||
next_step = /obj/item/glasswork/glass_base/laserpointer_shell_1
|
||||
|
||||
/obj/item/glasswork/glass_base/laserpointer_shell/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(istype(I, /obj/item/stock_parts/capacitor))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/laserpointer_shell_1
|
||||
name = "Laser pointer assembly"
|
||||
desc = "Good for selling or crafting, by itself its useless. Needs a glass lens."
|
||||
icon_state = "laser_wire"
|
||||
icon_state = "laser_case"
|
||||
next_step = /obj/item/glasswork/glass_base/laserpointer_shell_2
|
||||
|
||||
/obj/item/glasswork/glass_base/laserpointer_shell_1/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(istype(I, /obj/item/glasswork/glass_base/lens))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/laserpointer_shell_2
|
||||
name = "Laser pointer assembly"
|
||||
desc = "Good for selling or crafting, by itself its useless. Needs to be screwed together."
|
||||
icon_state = "laser_wire"
|
||||
icon_state = "laser_case"
|
||||
next_step = /obj/item/laser_pointer/blue/handmade
|
||||
|
||||
/obj/item/glasswork/glass_base/laserpointer_shell_2/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
if(do_after(user,260, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
//NERD SHIT - 5000
|
||||
|
||||
/obj/item/glasswork/glass_base/glasses_frame
|
||||
name = "Glasses Frame"
|
||||
desc = "Good for crafting a pare of glasses, by itself its useless. Just add a pare of lens."
|
||||
icon = 'icons/obj/glass_ware.dmi'
|
||||
icon_state = "frames"
|
||||
next_step = /obj/item/glasswork/glass_base/glasses_frame_1
|
||||
|
||||
/obj/item/glasswork/glass_base/glasses_frame/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(istype(I, /obj/item/glasswork/glass_base/lens))
|
||||
if(do_after(user,60, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/glasses_frame_1
|
||||
name = "Glasses Frame"
|
||||
desc = "Good for crafting a pare of glasses, by itself its useless. Just add a the other lens."
|
||||
icon = 'icons/obj/glass_ware.dmi'
|
||||
icon_state = "frames_1"
|
||||
next_step = /obj/item/glasswork/glass_base/glasses_frame_2
|
||||
|
||||
/obj/item/glasswork/glass_base/glasses_frame_1/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(istype(I, /obj/item/glasswork/glass_base/lens))
|
||||
if(do_after(user,60, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glass_base/glasses_frame_2
|
||||
name = "Glasses Frame"
|
||||
desc = "Good for crafting a pare of glasses, by itself its useless. Just adjust the pices into the frame with a screwdriver."
|
||||
icon = 'icons/obj/glass_ware.dmi'
|
||||
icon_state = "frames_2"
|
||||
next_step = /obj/item/glasswork/glasses
|
||||
|
||||
/obj/item/glasswork/glass_base/glasses_frame_2/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(I.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
if(do_after(user,180, target = src))
|
||||
new next_step(user.loc, 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/glasswork/glasses
|
||||
name = "Hand Made Glasses"
|
||||
desc = "Hande made glasses that have not been polished at all making them useless. Selling them could still be worth a bit of credits."
|
||||
icon = 'icons/obj/glass_ware.dmi'
|
||||
icon_state = "frames_2"
|
||||
@@ -39,6 +39,30 @@
|
||||
time = 10
|
||||
reqs = list(/obj/item/paper = 20)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/armwraps
|
||||
name = "armwraps"
|
||||
result = /obj/item/clothing/gloves/fingerless/pugilist
|
||||
time = 60
|
||||
tools = list(TOOL_WIRECUTTER)
|
||||
reqs = list(/obj/item/stack/sheet/cloth = 4,
|
||||
/obj/item/stack/sheet/silk = 2,
|
||||
/obj/item/stack/sheet/leather = 2)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/armwrapsplusone
|
||||
name = "armwraps of mighty fists"
|
||||
result = /obj/item/clothing/gloves/fingerless/pugilist/magic
|
||||
time = 300
|
||||
tools = list(TOOL_WIRECUTTER, /obj/item/book/codex_gigas, /obj/item/clothing/head/wizard, /obj/item/clothing/suit/wizrobe)
|
||||
reqs = list(/obj/item/stack/sheet/cloth = 2,
|
||||
/obj/item/stack/sheet/leather = 2,
|
||||
/obj/item/stack/sheet/durathread = 2,
|
||||
/datum/reagent/consumable/ethanol/sake = 100,
|
||||
/datum/reagent/consumable/ethanol/wizz_fizz = 100,
|
||||
/obj/item/stack/sheet/sinew = 1,
|
||||
/obj/item/stack/sheet/mineral/gold = 50)
|
||||
category = CAT_CLOTHING
|
||||
|
||||
////////
|
||||
//Huds//
|
||||
@@ -294,3 +318,12 @@
|
||||
/obj/item/bedsheet/cosmos = 1)
|
||||
time = 60
|
||||
category = CAT_CLOTHING
|
||||
|
||||
|
||||
/datum/crafting_recipe/garlic_necklace
|
||||
name = "Garlic Necklace"
|
||||
result = /obj/item/clothing/neck/garlic_necklace
|
||||
reqs = list(/obj/item/reagent_containers/food/snacks/grown/garlic = 15,
|
||||
/obj/item/stack/cable_coil = 10)
|
||||
time = 100 //Takes awhile to put all the garlics on the coil and knot it.
|
||||
category = CAT_CLOTHING
|
||||
|
||||
@@ -298,7 +298,7 @@
|
||||
subcategory = CAT_AMMO
|
||||
|
||||
/datum/crafting_recipe/ashen_arrow
|
||||
name = "Fire Hardened Arrow"
|
||||
name = "Ashen Arrow"
|
||||
result = /obj/item/ammo_casing/caseless/arrow/ash
|
||||
tools = list(TOOL_WELDER)
|
||||
time = 30
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
//This component applies a customizable drop_shadow filter to its wearer when they toggle combat mode on or off. This can stack.
|
||||
|
||||
/datum/component/wearertargeting/phantomthief
|
||||
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
|
||||
signals = list(COMSIG_LIVING_COMBAT_ENABLED)
|
||||
dupe_mode = COMPONENT_DUPE_ALLOWED
|
||||
signals = list(COMSIG_LIVING_COMBAT_ENABLED, COMSIG_LIVING_COMBAT_DISABLED)
|
||||
proctype = .proc/handlefilterstuff
|
||||
var/filter_x
|
||||
var/filter_y
|
||||
@@ -19,8 +19,8 @@
|
||||
filter_color = _color
|
||||
valid_slots = _valid_slots
|
||||
|
||||
/datum/component/wearertargeting/phantomthief/proc/handlefilterstuff(datum/source, mob/user, combatmodestate)
|
||||
if(!combatmodestate)
|
||||
/datum/component/wearertargeting/phantomthief/proc/handlefilterstuff(mob/living/user, was_forced = FALSE)
|
||||
if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
user.remove_filter("phantomthief")
|
||||
else
|
||||
user.add_filter("phantomthief", 4, list(type = "drop_shadow", x = filter_x, y = filter_y, size = filter_size, color = filter_color))
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
RegisterSignal(parent, COMSIG_ITEM_ATTACK_OBJ, .proc/rad_attack)
|
||||
else
|
||||
CRASH("Something that wasn't an atom was given /datum/component/radioactive")
|
||||
return
|
||||
|
||||
if(strength > RAD_MINIMUM_CONTAMINATION)
|
||||
SSradiation.warn(src)
|
||||
@@ -84,4 +83,4 @@
|
||||
#undef RAD_AMOUNT_LOW
|
||||
#undef RAD_AMOUNT_MEDIUM
|
||||
#undef RAD_AMOUNT_HIGH
|
||||
#undef RAD_AMOUNT_EXTREME
|
||||
#undef RAD_AMOUNT_EXTREME
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_BUCKLE, .proc/vehicle_mob_buckle)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_UNBUCKLE, .proc/vehicle_mob_unbuckle)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/vehicle_moved)
|
||||
RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, .proc/vehicle_dir_changed)
|
||||
|
||||
/datum/component/riding/proc/vehicle_mob_unbuckle(datum/source, mob/living/M, force = FALSE)
|
||||
restore_position(M)
|
||||
@@ -47,6 +48,11 @@
|
||||
/datum/component/riding/proc/set_vehicle_dir_layer(dir, layer)
|
||||
directional_vehicle_layers["[dir]"] = layer
|
||||
|
||||
/datum/component/riding/proc/vehicle_dir_changed(from_dir, to_dir)
|
||||
spawn
|
||||
handle_vehicle_offsets()
|
||||
handle_vehicle_layer()
|
||||
|
||||
/datum/component/riding/proc/vehicle_moved(datum/source)
|
||||
var/atom/movable/AM = parent
|
||||
for(var/i in AM.buckled_mobs)
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
_contents_limbo = null
|
||||
if(_user_limbo)
|
||||
for(var/i in _user_limbo)
|
||||
show_to(i)
|
||||
ui_show(i)
|
||||
_user_limbo = null
|
||||
|
||||
/datum/component/storage/concrete/_insert_physical_item(obj/item/I, override = FALSE)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
return
|
||||
. = COMPONENT_NO_ATTACK_HAND
|
||||
if(!check_locked(source, user, TRUE))
|
||||
show_to(user)
|
||||
ui_show(user)
|
||||
A.do_jiggle()
|
||||
if(rustle_sound)
|
||||
playsound(A, "rustle", 50, 1, -5)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
allow_quick_gather = TRUE
|
||||
allow_quick_empty = TRUE
|
||||
click_gather = TRUE
|
||||
storage_flags = STORAGE_FLAGS_LEGACY_DEFAULT
|
||||
max_w_class = WEIGHT_CLASS_NORMAL
|
||||
max_combined_w_class = 100
|
||||
max_items = 100
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//Stack-only storage.
|
||||
/datum/component/storage/concrete/stack
|
||||
display_numerical_stacking = TRUE
|
||||
storage_flags = STORAGE_FLAGS_LEGACY_DEFAULT
|
||||
var/max_combined_stack_amount = 300
|
||||
max_w_class = WEIGHT_CLASS_NORMAL
|
||||
max_combined_w_class = WEIGHT_CLASS_NORMAL * 14
|
||||
|
||||
@@ -21,9 +21,16 @@
|
||||
|
||||
var/locked = FALSE //when locked nothing can see inside or use it.
|
||||
|
||||
var/max_w_class = WEIGHT_CLASS_SMALL //max size of objects that will fit.
|
||||
var/max_combined_w_class = 14 //max combined sizes of objects that will fit.
|
||||
var/max_items = 7 //max number of objects that will fit.
|
||||
/// Storage flags, including what kinds of limiters we use for how many items we can hold
|
||||
var/storage_flags = STORAGE_FLAGS_LEGACY_DEFAULT
|
||||
/// Max w_class we can hold. Applies to [STORAGE_LIMIT_COMBINED_W_CLASS] and [STORAGE_LIMIT_VOLUME]
|
||||
var/max_w_class = WEIGHT_CLASS_SMALL
|
||||
/// Max combined w_class. Applies to [STORAGE_LIMIT_COMBINED_W_CLASS]
|
||||
var/max_combined_w_class = WEIGHT_CLASS_SMALL * 7
|
||||
/// Max items we can hold. Applies to [STORAGE_LIMIT_MAX_ITEMS]
|
||||
var/max_items = 7
|
||||
/// Max volume we can hold. Applies to [STORAGE_LIMIT_VOLUME]. Auto scaled on New() if unset.
|
||||
var/max_volume
|
||||
|
||||
var/emp_shielded = FALSE
|
||||
|
||||
@@ -39,8 +46,17 @@
|
||||
|
||||
var/display_numerical_stacking = FALSE //stack things of the same type and show as a single object with a number.
|
||||
|
||||
var/obj/screen/storage/boxes //storage display object
|
||||
var/obj/screen/close/closer //close button object
|
||||
/// "legacy"/default view mode's storage "boxes"
|
||||
var/obj/screen/storage/boxes/ui_boxes
|
||||
/// New volumetric storage display mode's left side
|
||||
var/obj/screen/storage/left/ui_left
|
||||
/// New volumetric storage display mode's center 'blocks'
|
||||
var/obj/screen/storage/continuous/ui_continuous
|
||||
/// The close button, used in all modes. Frames right side in volumetric mode.
|
||||
var/obj/screen/storage/close/ui_close
|
||||
/// Associative list of list(item = screen object) for volumetric storage item screen blocks
|
||||
var/list/ui_item_blocks
|
||||
|
||||
var/current_maxscreensize
|
||||
|
||||
var/allow_big_nesting = FALSE //allow storage objects of the same or greater size.
|
||||
@@ -68,9 +84,6 @@
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
if(master)
|
||||
change_master(master)
|
||||
boxes = new(null, src)
|
||||
closer = new(null, src)
|
||||
orient2hud()
|
||||
|
||||
RegisterSignal(parent, COMSIG_CONTAINS_STORAGE, .proc/on_check)
|
||||
RegisterSignal(parent, COMSIG_IS_STORAGE_LOCKED, .proc/check_locked)
|
||||
@@ -111,8 +124,15 @@
|
||||
|
||||
/datum/component/storage/Destroy()
|
||||
close_all()
|
||||
QDEL_NULL(boxes)
|
||||
QDEL_NULL(closer)
|
||||
QDEL_NULL(ui_boxes)
|
||||
QDEL_NULL(ui_close)
|
||||
QDEL_NULL(ui_continuous)
|
||||
QDEL_NULL(ui_left)
|
||||
// DO NOT USE QDEL_LIST_ASSOC.
|
||||
if(ui_item_blocks)
|
||||
for(var/i in ui_item_blocks)
|
||||
qdel(ui_item_blocks[i]) //qdel the screen object not the item
|
||||
ui_item_blocks.Cut()
|
||||
LAZYCLEARLIST(is_using)
|
||||
return ..()
|
||||
|
||||
@@ -286,7 +306,7 @@
|
||||
if(!_target)
|
||||
_target = get_turf(parent)
|
||||
if(usr)
|
||||
hide_from(usr)
|
||||
ui_hide(usr)
|
||||
var/list/contents = contents()
|
||||
var/atom/real_location = real_location()
|
||||
for(var/obj/item/I in contents)
|
||||
@@ -300,106 +320,8 @@
|
||||
if(check_locked())
|
||||
close_all()
|
||||
|
||||
/datum/component/storage/proc/_process_numerical_display()
|
||||
. = list()
|
||||
for(var/obj/item/I in accessible_items())
|
||||
if(QDELETED(I))
|
||||
continue
|
||||
if(!.[I.type])
|
||||
.[I.type] = new /datum/numbered_display(I, 1)
|
||||
else
|
||||
var/datum/numbered_display/ND = .[I.type]
|
||||
ND.number++
|
||||
. = sortTim(., /proc/cmp_numbered_displays_name_asc, associative = TRUE)
|
||||
|
||||
//This proc determines the size of the inventory to be displayed. Please touch it only if you know what you're doing.
|
||||
/datum/component/storage/proc/orient2hud(mob/user, maxcolumns)
|
||||
var/list/accessible_contents = accessible_items()
|
||||
var/adjusted_contents = length(accessible_contents)
|
||||
|
||||
//Numbered contents display
|
||||
var/list/datum/numbered_display/numbered_contents
|
||||
if(display_numerical_stacking)
|
||||
numbered_contents = _process_numerical_display()
|
||||
adjusted_contents = numbered_contents.len
|
||||
|
||||
var/columns = CLAMP(max_items, 1, maxcolumns ? maxcolumns : screen_max_columns)
|
||||
var/rows = CLAMP(CEILING(adjusted_contents / columns, 1), 1, screen_max_rows)
|
||||
standard_orient_objs(rows, columns, numbered_contents)
|
||||
|
||||
//This proc draws out the inventory and places the items on it. It uses the standard position.
|
||||
/datum/component/storage/proc/standard_orient_objs(rows, cols, list/obj/item/numerical_display_contents)
|
||||
boxes.screen_loc = "[screen_start_x]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x+cols-1]:[screen_pixel_x],[screen_start_y+rows-1]:[screen_pixel_y]"
|
||||
var/cx = screen_start_x
|
||||
var/cy = screen_start_y
|
||||
if(islist(numerical_display_contents))
|
||||
for(var/type in numerical_display_contents)
|
||||
var/datum/numbered_display/ND = numerical_display_contents[type]
|
||||
ND.sample_object.mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
ND.sample_object.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]"
|
||||
ND.sample_object.maptext = "<font color='white'>[(ND.number > 1)? "[ND.number]" : ""]</font>"
|
||||
ND.sample_object.layer = ABOVE_HUD_LAYER
|
||||
ND.sample_object.plane = ABOVE_HUD_PLANE
|
||||
cx++
|
||||
if(cx - screen_start_x >= cols)
|
||||
cx = screen_start_x
|
||||
cy++
|
||||
if(cy - screen_start_y >= rows)
|
||||
break
|
||||
else
|
||||
for(var/obj/O in accessible_items())
|
||||
if(QDELETED(O))
|
||||
continue
|
||||
O.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip"
|
||||
O.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]"
|
||||
O.maptext = ""
|
||||
O.layer = ABOVE_HUD_LAYER
|
||||
O.plane = ABOVE_HUD_PLANE
|
||||
cx++
|
||||
if(cx - screen_start_x >= cols)
|
||||
cx = screen_start_x
|
||||
cy++
|
||||
if(cy - screen_start_y >= rows)
|
||||
break
|
||||
closer.screen_loc = "[screen_start_x + cols]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y]"
|
||||
|
||||
/datum/component/storage/proc/show_to(mob/M, set_screen_size = TRUE)
|
||||
if(!M.client)
|
||||
return FALSE
|
||||
var/list/cview = getviewsize(M.client.view)
|
||||
var/maxallowedscreensize = cview[1]-8
|
||||
if(set_screen_size)
|
||||
current_maxscreensize = maxallowedscreensize
|
||||
else if(current_maxscreensize)
|
||||
maxallowedscreensize = current_maxscreensize
|
||||
if(M.active_storage != src && (M.stat == CONSCIOUS))
|
||||
for(var/obj/item/I in accessible_items())
|
||||
if(I.on_found(M))
|
||||
return FALSE
|
||||
if(M.active_storage)
|
||||
M.active_storage.hide_from(M)
|
||||
orient2hud(M, (isliving(M) ? maxallowedscreensize : 7))
|
||||
M.client.screen |= boxes
|
||||
M.client.screen |= closer
|
||||
M.client.screen |= accessible_items()
|
||||
M.active_storage = src
|
||||
LAZYOR(is_using, M)
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/hide_from(mob/M)
|
||||
if(!M.client)
|
||||
return TRUE
|
||||
var/atom/real_location = real_location()
|
||||
M.client.screen -= boxes
|
||||
M.client.screen -= closer
|
||||
M.client.screen -= real_location.contents
|
||||
if(M.active_storage == src)
|
||||
M.active_storage = null
|
||||
LAZYREMOVE(is_using, M)
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/close(mob/M)
|
||||
hide_from(M)
|
||||
ui_hide(M)
|
||||
|
||||
/datum/component/storage/proc/close_all()
|
||||
. = FALSE
|
||||
@@ -418,25 +340,6 @@
|
||||
var/datum/component/storage/concrete/master = master()
|
||||
master.emp_act(source, severity)
|
||||
|
||||
//This proc draws out the inventory and places the items on it. tx and ty are the upper left tile and mx, my are the bottm right.
|
||||
//The numbers are calculated from the bottom-left The bottom-left slot being 1,1.
|
||||
/datum/component/storage/proc/orient_objs(tx, ty, mx, my)
|
||||
var/atom/real_location = real_location()
|
||||
var/cx = tx
|
||||
var/cy = ty
|
||||
boxes.screen_loc = "[tx]:,[ty] to [mx],[my]"
|
||||
for(var/obj/O in real_location)
|
||||
if(QDELETED(O))
|
||||
continue
|
||||
O.screen_loc = "[cx],[cy]"
|
||||
O.layer = ABOVE_HUD_LAYER
|
||||
O.plane = ABOVE_HUD_PLANE
|
||||
cx++
|
||||
if(cx > mx)
|
||||
cx = tx
|
||||
cy--
|
||||
closer.screen_loc = "[mx+1],[my]"
|
||||
|
||||
//Resets something that is being removed from storage.
|
||||
/datum/component/storage/proc/_removal_reset(atom/movable/thing)
|
||||
if(!istype(thing))
|
||||
@@ -448,6 +351,9 @@
|
||||
|
||||
/datum/component/storage/proc/_remove_and_refresh(datum/source, atom/movable/thing)
|
||||
_removal_reset(thing)
|
||||
if(LAZYACCESS(ui_item_blocks, thing))
|
||||
qdel(ui_item_blocks[thing])
|
||||
ui_item_blocks -= thing
|
||||
refresh_mob_views()
|
||||
|
||||
//Call this proc to handle the removal of an item from the storage item. The item will be moved to the new_location target, if that is null it's being deleted
|
||||
@@ -462,7 +368,7 @@
|
||||
/datum/component/storage/proc/refresh_mob_views()
|
||||
var/list/seeing = can_see_contents()
|
||||
for(var/i in seeing)
|
||||
show_to(i)
|
||||
ui_show(i)
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/can_see_contents()
|
||||
@@ -559,7 +465,7 @@
|
||||
A.add_fingerprint(M)
|
||||
if(!force && (check_locked(null, M) || !M.CanReach(parent, view_only = TRUE)))
|
||||
return FALSE
|
||||
show_to(M, !ghost)
|
||||
ui_show(M, !ghost)
|
||||
|
||||
/datum/component/storage/proc/mousedrop_receive(datum/source, atom/movable/O, mob/M)
|
||||
if(isitem(O))
|
||||
@@ -587,10 +493,6 @@
|
||||
if(M && !stop_messages)
|
||||
host.add_fingerprint(M)
|
||||
return FALSE
|
||||
if(real_location.contents.len >= max_items)
|
||||
if(!stop_messages)
|
||||
to_chat(M, "<span class='warning'>[host] is full, make some space!</span>")
|
||||
return FALSE //Storage item is full
|
||||
if(length(can_hold))
|
||||
if(!is_type_in_typecache(I, can_hold))
|
||||
if(!stop_messages)
|
||||
@@ -600,17 +502,34 @@
|
||||
if(!stop_messages)
|
||||
to_chat(M, "<span class='warning'>[host] cannot hold [I]!</span>")
|
||||
return FALSE
|
||||
if(I.w_class > max_w_class)
|
||||
if(!stop_messages)
|
||||
to_chat(M, "<span class='warning'>[I] is too big for [host]!</span>")
|
||||
return FALSE
|
||||
var/sum_w_class = I.w_class
|
||||
for(var/obj/item/_I in real_location)
|
||||
sum_w_class += _I.w_class //Adds up the combined w_classes which will be in the storage item if the item is added to it.
|
||||
if(sum_w_class > max_combined_w_class)
|
||||
if(!stop_messages)
|
||||
to_chat(M, "<span class='warning'>[I] won't fit in [host], make some space!</span>")
|
||||
return FALSE
|
||||
// STORAGE LIMITS
|
||||
if(storage_flags & STORAGE_LIMIT_MAX_ITEMS)
|
||||
if(real_location.contents.len >= max_items)
|
||||
if(!stop_messages)
|
||||
to_chat(M, "<span class='warning'>[host] has too many things in it, make some space!</span>")
|
||||
return FALSE //Storage item is full
|
||||
if(storage_flags & STORAGE_LIMIT_MAX_W_CLASS)
|
||||
if(I.w_class > max_w_class)
|
||||
if(!stop_messages)
|
||||
to_chat(M, "<span class='warning'>[I] is too long for [host]!</span>")
|
||||
return FALSE
|
||||
if(storage_flags & STORAGE_LIMIT_COMBINED_W_CLASS)
|
||||
var/sum_w_class = I.w_class
|
||||
for(var/obj/item/_I in real_location)
|
||||
sum_w_class += _I.w_class //Adds up the combined w_classes which will be in the storage item if the item is added to it.
|
||||
if(sum_w_class > max_combined_w_class)
|
||||
if(!stop_messages)
|
||||
to_chat(M, "<span class='warning'>[I] won't fit in [host], make some space!</span>")
|
||||
return FALSE
|
||||
if(storage_flags & STORAGE_LIMIT_VOLUME)
|
||||
var/sum_volume = I.get_w_volume()
|
||||
for(var/obj/item/_I in real_location)
|
||||
sum_volume += _I.get_w_volume()
|
||||
if(sum_volume > get_max_volume())
|
||||
if(!stop_messages)
|
||||
to_chat(M, "<span class='warning'>[I] is too spacious to fit in [host], make some space!</span>")
|
||||
return FALSE
|
||||
/////////////////
|
||||
if(isitem(host))
|
||||
var/obj/item/IP = host
|
||||
var/datum/component/storage/STR_I = I.GetComponent(/datum/component/storage)
|
||||
@@ -742,7 +661,7 @@
|
||||
if(A.loc == user)
|
||||
. = COMPONENT_NO_ATTACK_HAND
|
||||
if(!check_locked(source, user, TRUE))
|
||||
show_to(user)
|
||||
ui_show(user)
|
||||
A.do_jiggle()
|
||||
|
||||
/datum/component/storage/proc/signal_on_pickup(datum/source, mob/user)
|
||||
@@ -761,7 +680,7 @@
|
||||
return do_quick_empty(loctarget)
|
||||
|
||||
/datum/component/storage/proc/signal_hide_attempt(datum/source, mob/target)
|
||||
return hide_from(target)
|
||||
return ui_hide(target)
|
||||
|
||||
/datum/component/storage/proc/on_alt_click(datum/source, mob/user)
|
||||
if(!isliving(user) || !user.CanReach(parent))
|
||||
@@ -790,7 +709,7 @@
|
||||
user.visible_message("<span class='warning'>[user] draws [I] from [parent]!</span>", "<span class='notice'>You draw [I] from [parent].</span>")
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/action_trigger(datum/signal_source, datum/action/source)
|
||||
/datum/component/storage/proc/action_trigger(datum/action/source, obj/target)
|
||||
gather_mode_switch(source.owner)
|
||||
return COMPONENT_ACTION_BLOCK_TRIGGER
|
||||
|
||||
@@ -803,3 +722,9 @@
|
||||
to_chat(user, "[parent] now picks up all items in a tile at once.")
|
||||
if(COLLECT_ONE)
|
||||
to_chat(user, "[parent] now picks up one item at a time.")
|
||||
|
||||
/**
|
||||
* Gets our max volume
|
||||
*/
|
||||
/datum/component/storage/proc/get_max_volume()
|
||||
return max_volume || AUTO_SCALE_STORAGE_VOLUME(max_w_class, max_combined_w_class)
|
||||
|
||||
@@ -0,0 +1,293 @@
|
||||
/**
|
||||
* Generates a list of numbered_display datums for the numerical display system.
|
||||
*/
|
||||
/datum/component/storage/proc/_process_numerical_display()
|
||||
. = list()
|
||||
for(var/obj/item/I in accessible_items())
|
||||
if(QDELETED(I))
|
||||
continue
|
||||
if(!.[I.type])
|
||||
.[I.type] = new /datum/numbered_display(I, 1)
|
||||
else
|
||||
var/datum/numbered_display/ND = .[I.type]
|
||||
ND.number++
|
||||
. = sortTim(., /proc/cmp_numbered_displays_name_asc, associative = TRUE)
|
||||
|
||||
/**
|
||||
* Orients all objects in legacy mode, and returns the objects to show to the user.
|
||||
*/
|
||||
/datum/component/storage/proc/orient2hud_legacy(mob/user, maxcolumns)
|
||||
. = list()
|
||||
var/list/accessible_contents = accessible_items()
|
||||
var/adjusted_contents = length(accessible_contents)
|
||||
|
||||
//Numbered contents display
|
||||
var/list/datum/numbered_display/numbered_contents
|
||||
if(display_numerical_stacking)
|
||||
numbered_contents = _process_numerical_display()
|
||||
adjusted_contents = numbered_contents.len
|
||||
|
||||
var/columns = CLAMP(max_items, 1, maxcolumns ? maxcolumns : screen_max_columns)
|
||||
var/rows = CLAMP(CEILING(adjusted_contents / columns, 1), 1, screen_max_rows)
|
||||
|
||||
// First, boxes.
|
||||
ui_boxes = get_ui_boxes()
|
||||
ui_boxes.screen_loc = "[screen_start_x]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x+columns-1]:[screen_pixel_x],[screen_start_y+rows-1]:[screen_pixel_y]"
|
||||
. += ui_boxes
|
||||
// Then, closer.
|
||||
ui_close = get_ui_close()
|
||||
ui_close.screen_loc = "[screen_start_x + columns]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y]"
|
||||
. += ui_close
|
||||
// Then orient the actual items.
|
||||
var/cx = screen_start_x
|
||||
var/cy = screen_start_y
|
||||
if(islist(numbered_contents))
|
||||
for(var/type in numbered_contents)
|
||||
var/datum/numbered_display/ND = numbered_contents[type]
|
||||
ND.sample_object.mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
ND.sample_object.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]"
|
||||
ND.sample_object.maptext = "<font color='white'>[(ND.number > 1)? "[ND.number]" : ""]</font>"
|
||||
ND.sample_object.layer = ABOVE_HUD_LAYER
|
||||
ND.sample_object.plane = ABOVE_HUD_PLANE
|
||||
. += ND.sample_object
|
||||
cx++
|
||||
if(cx - screen_start_x >= columns)
|
||||
cx = screen_start_x
|
||||
cy++
|
||||
if(cy - screen_start_y >= rows)
|
||||
break
|
||||
else
|
||||
for(var/obj/O in accessible_items())
|
||||
if(QDELETED(O))
|
||||
continue
|
||||
O.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip"
|
||||
O.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]"
|
||||
O.maptext = ""
|
||||
O.layer = ABOVE_HUD_LAYER
|
||||
O.plane = ABOVE_HUD_PLANE
|
||||
. += O
|
||||
cx++
|
||||
if(cx - screen_start_x >= columns)
|
||||
cx = screen_start_x
|
||||
cy++
|
||||
if(cy - screen_start_y >= rows)
|
||||
break
|
||||
|
||||
/**
|
||||
* Orients all objects in .. volumetric mode. Does not support numerical display!
|
||||
*/
|
||||
/datum/component/storage/proc/orient2hud_volumetric(mob/user, maxcolumns)
|
||||
. = list()
|
||||
|
||||
// Generate ui_item_blocks for missing ones and render+orient.
|
||||
var/list/atom/contents = accessible_items()
|
||||
// our volume
|
||||
var/our_volume = get_max_volume()
|
||||
var/horizontal_pixels = (maxcolumns * world.icon_size) - (VOLUMETRIC_STORAGE_EDGE_PADDING * 2)
|
||||
var/max_horizontal_pixels = horizontal_pixels * screen_max_rows
|
||||
// sigh loopmania time
|
||||
var/used = 0
|
||||
// define outside for performance
|
||||
var/volume
|
||||
var/list/volume_by_item = list()
|
||||
var/list/percentage_by_item = list()
|
||||
for(var/obj/item/I in contents)
|
||||
volume = I.get_w_volume()
|
||||
used += volume
|
||||
volume_by_item[I] = volume
|
||||
percentage_by_item[I] = volume / get_max_volume()
|
||||
var/padding_pixels = ((length(percentage_by_item) - 1) * VOLUMETRIC_STORAGE_ITEM_PADDING) + VOLUMETRIC_STORAGE_EDGE_PADDING * 2
|
||||
var/min_pixels = (MINIMUM_PIXELS_PER_ITEM * length(percentage_by_item)) + padding_pixels
|
||||
// do the check for fallback for when someone has too much gamer gear
|
||||
if((min_pixels) > (max_horizontal_pixels + 4)) // 4 pixel grace zone
|
||||
to_chat(user, "<span class='warning'>[parent] was showed to you in legacy mode due to your items overrunning the three row limit! Consider not carrying too much or bugging a maintainer to raise this limit!</span>")
|
||||
return orient2hud_legacy(user, maxcolumns)
|
||||
// after this point we are sure we can somehow fit all items into our max number of rows.
|
||||
|
||||
// determine rows
|
||||
var/rows = CLAMP(CEILING(min_pixels / horizontal_pixels, 1), 1, screen_max_rows)
|
||||
|
||||
var/overrun = FALSE
|
||||
if(used > our_volume)
|
||||
// congratulations we are now in overrun mode. everything will be crammed to minimum storage pixels.
|
||||
to_chat(user, "<span class='warning'>[parent] rendered in overrun mode due to more items inside than the maximum volume supports.</span>")
|
||||
overrun = TRUE
|
||||
|
||||
// how much we are using
|
||||
var/using_horizontal_pixels = horizontal_pixels * rows
|
||||
|
||||
// item padding
|
||||
using_horizontal_pixels -= padding_pixels
|
||||
|
||||
// define outside for marginal performance boost
|
||||
var/obj/item/I
|
||||
// start at this pixel from screen_start_x.
|
||||
var/current_pixel = VOLUMETRIC_STORAGE_EDGE_PADDING
|
||||
var/row = 1
|
||||
|
||||
LAZYINITLIST(ui_item_blocks)
|
||||
|
||||
for(var/i in percentage_by_item)
|
||||
I = i
|
||||
var/percent = percentage_by_item[I]
|
||||
if(!ui_item_blocks[I])
|
||||
ui_item_blocks[I] = new /obj/screen/storage/volumetric_box/center(null, src, I)
|
||||
var/obj/screen/storage/volumetric_box/center/B = ui_item_blocks[I]
|
||||
var/pixels_to_use = overrun? MINIMUM_PIXELS_PER_ITEM : max(using_horizontal_pixels * percent, MINIMUM_PIXELS_PER_ITEM)
|
||||
var/addrow = FALSE
|
||||
if(CEILING(pixels_to_use, 1) >= FLOOR(horizontal_pixels - current_pixel - VOLUMETRIC_STORAGE_EDGE_PADDING, 1))
|
||||
pixels_to_use = horizontal_pixels - current_pixel - VOLUMETRIC_STORAGE_EDGE_PADDING
|
||||
addrow = TRUE
|
||||
|
||||
// now that we have pixels_to_use, place our thing and add it to the returned list.
|
||||
|
||||
B.screen_loc = I.screen_loc = "[screen_start_x]:[round(current_pixel + (pixels_to_use * 0.5) + VOLUMETRIC_STORAGE_ITEM_PADDING, 1)],[screen_start_y+row-1]:[screen_pixel_y]"
|
||||
// add the used pixels to pixel after we place the object
|
||||
current_pixel += pixels_to_use + VOLUMETRIC_STORAGE_ITEM_PADDING
|
||||
|
||||
// set various things
|
||||
B.set_pixel_size(pixels_to_use)
|
||||
B.layer = VOLUMETRIC_STORAGE_BOX_LAYER
|
||||
B.plane = VOLUMETRIC_STORAGE_BOX_PLANE
|
||||
B.name = I.name
|
||||
|
||||
I.mouse_opacity = MOUSE_OPACITY_ICON
|
||||
I.maptext = ""
|
||||
I.layer = VOLUMETRIC_STORAGE_ITEM_LAYER
|
||||
I.plane = VOLUMETRIC_STORAGE_ITEM_PLANE
|
||||
|
||||
// finally add our things.
|
||||
. += B.on_screen_objects()
|
||||
. += I
|
||||
|
||||
// go up a row if needed
|
||||
if(addrow)
|
||||
row++
|
||||
current_pixel = VOLUMETRIC_STORAGE_EDGE_PADDING
|
||||
|
||||
// Then, continuous section.
|
||||
ui_continuous = get_ui_continuous()
|
||||
ui_continuous.screen_loc = "[screen_start_x]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x+maxcolumns-1]:[screen_pixel_x],[screen_start_y+rows-1]:[screen_pixel_y]"
|
||||
. += ui_continuous
|
||||
// Then, left.
|
||||
ui_left = get_ui_left()
|
||||
ui_left.screen_loc = "[screen_start_x]:[screen_pixel_x - 2],[screen_start_y]:[screen_pixel_y] to [screen_start_x]:[screen_pixel_x - 2],[screen_start_y+rows-1]:[screen_pixel_y]"
|
||||
. += ui_left
|
||||
// Then, closer, which is also our right element.
|
||||
ui_close = get_ui_close()
|
||||
ui_close.screen_loc = "[screen_start_x + maxcolumns]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x + maxcolumns]:[screen_pixel_x],[screen_start_y + row - 1]:[screen_pixel_y]"
|
||||
. += ui_close
|
||||
|
||||
/**
|
||||
* Shows our UI to a mob.
|
||||
*/
|
||||
/datum/component/storage/proc/ui_show(mob/M, set_screen_size = TRUE)
|
||||
if(!M.client)
|
||||
return FALSE
|
||||
var/list/cview = getviewsize(M.client.view)
|
||||
// in tiles
|
||||
var/maxallowedscreensize = cview[1]-8
|
||||
if(set_screen_size)
|
||||
current_maxscreensize = maxallowedscreensize
|
||||
else if(current_maxscreensize)
|
||||
maxallowedscreensize = current_maxscreensize
|
||||
// we got screen size, register signal
|
||||
RegisterSignal(M, COMSIG_MOB_CLIENT_LOGOUT, .proc/on_logout, override = TRUE)
|
||||
if(M.active_storage != src)
|
||||
if(M.active_storage)
|
||||
M.active_storage.ui_hide(M)
|
||||
M.active_storage = src
|
||||
LAZYOR(is_using, M)
|
||||
if(volumetric_ui())
|
||||
//new volumetric ui bay-style
|
||||
M.client.screen |= orient2hud_volumetric(M, maxallowedscreensize)
|
||||
else
|
||||
//old ui
|
||||
M.client.screen |= orient2hud_legacy(M, maxallowedscreensize)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* VV hooked to ensure no lingering screen objects.
|
||||
*/
|
||||
/datum/component/storage/vv_edit_var(var_name, var_value)
|
||||
var/list/old
|
||||
if(var_name == NAMEOF(src, storage_flags))
|
||||
old = is_using.Copy()
|
||||
for(var/i in is_using)
|
||||
ui_hide(i)
|
||||
. = ..()
|
||||
if(old)
|
||||
for(var/i in old)
|
||||
ui_show(i)
|
||||
|
||||
/**
|
||||
* Proc triggered by signal to ensure logging out clients don't linger.
|
||||
*/
|
||||
/datum/component/storage/proc/on_logout(datum/source, client/C)
|
||||
ui_hide(source)
|
||||
|
||||
/**
|
||||
* Hides our UI from a mob
|
||||
*/
|
||||
/datum/component/storage/proc/ui_hide(mob/M)
|
||||
if(!M.client)
|
||||
return TRUE
|
||||
UnregisterSignal(M, COMSIG_MOB_CLIENT_LOGOUT)
|
||||
M.client.screen -= list(ui_boxes, ui_close, ui_left, ui_continuous) + get_ui_item_objects_hide()
|
||||
if(M.active_storage == src)
|
||||
M.active_storage = null
|
||||
LAZYREMOVE(is_using, M)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Returns TRUE if we are using volumetric UI instead of box UI
|
||||
*/
|
||||
/datum/component/storage/proc/volumetric_ui()
|
||||
var/atom/real_location = real_location()
|
||||
return (storage_flags & STORAGE_LIMIT_VOLUME) && (length(real_location.contents) <= MAXIMUM_VOLUMETRIC_ITEMS) && !display_numerical_stacking
|
||||
|
||||
/**
|
||||
* Gets the ui item objects to ui_hide.
|
||||
*/
|
||||
/datum/component/storage/proc/get_ui_item_objects_hide()
|
||||
if(!volumetric_ui())
|
||||
var/atom/real_location = real_location()
|
||||
return real_location.contents
|
||||
else
|
||||
. = list()
|
||||
for(var/i in ui_item_blocks)
|
||||
// get both the box and the item
|
||||
. += ui_item_blocks[i]
|
||||
. += i
|
||||
|
||||
/**
|
||||
* Gets our ui_boxes, making it if it doesn't exist.
|
||||
*/
|
||||
/datum/component/storage/proc/get_ui_boxes()
|
||||
if(!ui_boxes)
|
||||
ui_boxes = new(null, src)
|
||||
return ui_boxes
|
||||
|
||||
/**
|
||||
* Gets our ui_left, making it if it doesn't exist.
|
||||
*/
|
||||
/datum/component/storage/proc/get_ui_left()
|
||||
if(!ui_left)
|
||||
ui_left = new(null, src)
|
||||
return ui_left
|
||||
|
||||
/**
|
||||
* Gets our ui_close, making it if it doesn't exist.
|
||||
*/
|
||||
/datum/component/storage/proc/get_ui_close()
|
||||
if(!ui_close)
|
||||
ui_close = new(null, src)
|
||||
return ui_close
|
||||
|
||||
/**
|
||||
* Gets our ui_continuous, making it if it doesn't exist.
|
||||
*/
|
||||
/datum/component/storage/proc/get_ui_continuous()
|
||||
if(!ui_continuous)
|
||||
ui_continuous = new(null, src)
|
||||
return ui_continuous
|
||||
@@ -176,7 +176,7 @@
|
||||
/**
|
||||
*The following procs simply acts as hooks for quit(), since components do not use callbacks anymore
|
||||
*/
|
||||
/datum/component/virtual_reality/proc/action_trigger(datum/signal_source, datum/action/source)
|
||||
/datum/component/virtual_reality/proc/action_trigger(datum/action/source, obj/target)
|
||||
quit()
|
||||
return COMPONENT_ACTION_BLOCK_TRIGGER
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
var/datum/component/wet_floor/WF = newcomp //Lets make an assumption
|
||||
if(WF.gc()) //See if it's even valid, still. Also does LAZYLEN and stuff for us.
|
||||
CRASH("Wet floor component tried to inherit another, but the other was able to garbage collect while being inherited! What a waste of time!")
|
||||
return
|
||||
for(var/i in WF.time_left_list)
|
||||
add_wet(text2num(i), WF.time_left_list[i])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user