mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-24 04:27:35 +01:00
[TGUI] Stack Craft 3: Rebirth (#26443)
* Initial commit * Back to JS (Skill Issue & lazyness) * Update UI please * No need that * Uhhh... documentation?
This commit is contained in:
@@ -556,7 +556,6 @@ GLOBAL_LIST_INIT(cult_recipes, list (
|
||||
item_state = "sheet-runed"
|
||||
sheettype = "runed"
|
||||
merge_type = /obj/item/stack/sheet/runed_metal
|
||||
recipe_width = 700
|
||||
|
||||
/obj/item/stack/sheet/runed_metal/examine_more(mob/user)
|
||||
. = ..()
|
||||
|
||||
@@ -20,42 +20,49 @@
|
||||
var/cost = 1
|
||||
/// A list of recipes buildable with this stack.
|
||||
var/list/recipes = list()
|
||||
/// The singular name of this stack.
|
||||
var/singular_name
|
||||
/// The current amount of this stack.
|
||||
var/amount = 1
|
||||
var/to_transfer = 0
|
||||
var/max_amount = 50 //also see stack recipes initialisation, param "max_res_amount" must be equal to this max_amount
|
||||
/// This path and its children should merge with this stack, defaults to src.type
|
||||
var/merge_type = null
|
||||
var/recipe_width = 400 //Width of the recipe popup
|
||||
var/recipe_height = 400 //Height of the recipe popup
|
||||
/// What sort of table is made when applying this stack to a frame?
|
||||
/// The maximum amount of this stack. Also see stack recipes initialisation, param "max_res_amount" must be equal to this max_amount
|
||||
var/max_amount = 50
|
||||
/// The path and its children that should merge with this stack, defaults to src.type.
|
||||
var/merge_type
|
||||
/// The type of table that is made when applying this stack to a frame.
|
||||
var/table_type
|
||||
/// If this stack has a dynamic icon_state based on amount / max_amount
|
||||
/// Whether this stack has a dynamic icon_state based on amount / max_amount.
|
||||
var/dynamic_icon_state = FALSE
|
||||
/// if true, then this item can't stack with subtypes
|
||||
/// Whether this stack can't stack with subtypes.
|
||||
var/parent_stack = FALSE
|
||||
|
||||
/obj/item/stack/Initialize(mapload, new_amount, merge = TRUE)
|
||||
. = ..()
|
||||
if(dynamic_icon_state) //If we have a dynamic icon state, we don't want item states to follow the same pattern.
|
||||
item_state = initial(icon_state)
|
||||
|
||||
if(new_amount != null)
|
||||
amount = new_amount
|
||||
|
||||
while(amount > max_amount)
|
||||
amount -= max_amount
|
||||
new type(loc, max_amount, FALSE)
|
||||
|
||||
if(!merge_type)
|
||||
merge_type = type
|
||||
|
||||
if(merge && !(amount >= max_amount))
|
||||
for(var/obj/item/stack/S in loc)
|
||||
if(S.merge_type == merge_type)
|
||||
merge(S)
|
||||
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
|
||||
/obj/item/stack/update_icon_state()
|
||||
. = ..()
|
||||
if(!dynamic_icon_state)
|
||||
return
|
||||
|
||||
var/state = CEILING((amount/max_amount) * 3, 1)
|
||||
if(state <= 1)
|
||||
icon_state = initial(icon_state)
|
||||
@@ -66,8 +73,10 @@
|
||||
/obj/item/stack/Crossed(obj/O, oldloc)
|
||||
if(amount >= max_amount || ismob(loc)) // Prevents unnecessary call. Also prevents merging stack automatically in a mob's inventory
|
||||
return
|
||||
|
||||
if(istype(O, merge_type) && !O.throwing)
|
||||
merge(O)
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/stack/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
|
||||
@@ -75,11 +84,6 @@
|
||||
merge(AM)
|
||||
. = ..()
|
||||
|
||||
/obj/item/stack/Destroy()
|
||||
if(usr && usr.machine == src)
|
||||
usr << browse(null, "window=stack")
|
||||
return ..()
|
||||
|
||||
/obj/item/stack/examine(mob/user)
|
||||
. = ..()
|
||||
if(!in_range(user, src))
|
||||
@@ -106,151 +110,151 @@
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
|
||||
/obj/item/stack/attack_self(mob/user)
|
||||
list_recipes(user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/item/stack/attack_self_tk(mob/user)
|
||||
list_recipes(user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/item/stack/attack_tk(mob/user)
|
||||
if(user.stat || !isturf(loc)) return
|
||||
if(user.stat || !isturf(loc))
|
||||
return
|
||||
// Allow remote stack splitting, because telekinetic inventory managing
|
||||
// is really cool
|
||||
if(src in user.tkgrabbed_objects)
|
||||
var/obj/item/stack/F = split(user, 1)
|
||||
F.attack_tk(user)
|
||||
if(src && user.machine == src)
|
||||
spawn(0)
|
||||
interact(user)
|
||||
else
|
||||
if(!(src in user.tkgrabbed_objects))
|
||||
..()
|
||||
return
|
||||
|
||||
var/obj/item/stack/material = split(user, 1)
|
||||
material.attack_tk(user)
|
||||
if(src && user.machine == src)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/item/stack/attack_hand(mob/user)
|
||||
if(!user.is_in_inactive_hand(src) && get_amount() > 1)
|
||||
..()
|
||||
return
|
||||
|
||||
change_stack(user, 1)
|
||||
if(src && user.machine == src)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/item/stack/attackby(obj/item/thing, mob/user, params)
|
||||
if((parent_stack && !istype(thing, merge_type)) || !(parent_stack && thing.type == type))
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/stack/proc/list_recipes(mob/user, recipes_sublist)
|
||||
if(!recipes)
|
||||
return
|
||||
|
||||
if(get_amount() <= 0)
|
||||
user << browse(null, "window=stack")
|
||||
if(is_cyborg)
|
||||
to_chat(user, "<span class='warning'>You don't have enough energy to dispense more [name]!</span>")
|
||||
return
|
||||
|
||||
user.set_machine(src) //for correct work of onclose
|
||||
|
||||
var/list/recipe_list = recipes
|
||||
if(recipes_sublist && recipe_list[recipes_sublist] && istype(recipe_list[recipes_sublist], /datum/stack_recipe_list))
|
||||
var/datum/stack_recipe_list/srl = recipe_list[recipes_sublist]
|
||||
recipe_list = srl.recipes
|
||||
|
||||
var/t1 = "Amount Left: [get_amount()]<br>"
|
||||
for(var/i in 1 to length(recipe_list))
|
||||
var/E = recipe_list[i]
|
||||
if(isnull(E))
|
||||
t1 += "<hr>"
|
||||
continue
|
||||
|
||||
if(i > 1 && !isnull(recipe_list[i - 1]))
|
||||
t1 += "<br>"
|
||||
|
||||
if(istype(E, /datum/stack_recipe_list))
|
||||
var/datum/stack_recipe_list/srl = E
|
||||
t1 += "<a href='byond://?src=[UID()];sublist=[i]'>[srl.title]</a>"
|
||||
|
||||
if(istype(E, /datum/stack_recipe))
|
||||
var/datum/stack_recipe/R = E
|
||||
var/max_multiplier = round(get_amount() / R.req_amount)
|
||||
var/title
|
||||
var/can_build = 1
|
||||
can_build = can_build && (max_multiplier > 0)
|
||||
|
||||
if(R.res_amount > 1)
|
||||
title += "[R.res_amount]x [R.title]\s"
|
||||
else
|
||||
title += "[R.title]"
|
||||
title += " ([R.req_amount] [src.singular_name]\s)"
|
||||
if(can_build)
|
||||
t1 += "<a href='byond://?src=[UID()];sublist=[recipes_sublist];make=[i]'>[title]</a> "
|
||||
else
|
||||
t1 += "[title]"
|
||||
continue
|
||||
if(R.max_res_amount > 1 && max_multiplier > 1)
|
||||
max_multiplier = min(max_multiplier, round(R.max_res_amount / R.res_amount))
|
||||
t1 += " |"
|
||||
|
||||
var/list/multipliers = list(5, 10, 25)
|
||||
for(var/n in multipliers)
|
||||
if(max_multiplier >= n)
|
||||
t1 += " <a href='byond://?src=[UID()];sublist=[recipes_sublist];make=[i];multiplier=[n]'>[n * R.res_amount]x</a>"
|
||||
if(!(max_multiplier in multipliers))
|
||||
t1 += " <a href='byond://?src=[UID()];sublist=[recipes_sublist];make=[i];multiplier=[max_multiplier]'>[max_multiplier * R.res_amount]x</a>"
|
||||
|
||||
var/datum/browser/popup = new(user, "stack", name, recipe_width, recipe_height)
|
||||
popup.set_content(t1)
|
||||
popup.open(0)
|
||||
onclose(user, "stack")
|
||||
|
||||
/obj/item/stack/Topic(href, href_list)
|
||||
..()
|
||||
if(usr.incapacitated() || !usr.is_in_active_hand(src))
|
||||
return 0
|
||||
|
||||
if(href_list["sublist"] && !href_list["make"])
|
||||
list_recipes(usr, text2num(href_list["sublist"]))
|
||||
|
||||
if(href_list["make"])
|
||||
if(amount < 0 && !is_cyborg)
|
||||
qdel(src) //Never should happen
|
||||
|
||||
var/list/recipes_list = recipes
|
||||
if(href_list["sublist"])
|
||||
var/datum/stack_recipe_list/srl = recipes_list[text2num(href_list["sublist"])]
|
||||
recipes_list = srl.recipes
|
||||
|
||||
var/datum/stack_recipe/R = recipes_list[text2num(href_list["make"])]
|
||||
var/multiplier = text2num(href_list["multiplier"])
|
||||
if(!multiplier || multiplier <= 0 || multiplier > 50 || !IS_INT(multiplier)) // Href exploit checks
|
||||
if(multiplier) // It existed but they tried to fuck with it
|
||||
message_admins("[key_name_admin(usr)] just attempted to href exploit sheet crafting with an invalid multiplier. Ban highly advised.")
|
||||
multiplier = 1
|
||||
|
||||
if(!R.try_build(usr, src, multiplier))
|
||||
return
|
||||
var/obj/O
|
||||
O = R.do_build(usr, src, multiplier, O)
|
||||
if(!O)
|
||||
return
|
||||
R.post_build(usr, src, O)
|
||||
|
||||
if(amount < 1) // Just in case a stack's amount ends up fractional somehow
|
||||
var/oldsrc = src
|
||||
src = null //dont kill proc after qdel()
|
||||
usr.unEquip(oldsrc, 1)
|
||||
qdel(oldsrc)
|
||||
|
||||
if(src && usr.machine == src) //do not reopen closed window
|
||||
spawn(0)
|
||||
interact(usr)
|
||||
return
|
||||
var/obj/item/stack/material = thing
|
||||
merge(material)
|
||||
to_chat(user, "<span class='notice'>Your [material.name] stack now contains [material.get_amount()] [material.singular_name]\s.</span>")
|
||||
|
||||
/obj/item/stack/use(used, check = TRUE)
|
||||
if(check && zero_amount())
|
||||
return FALSE
|
||||
|
||||
if(is_cyborg)
|
||||
return source.use_charge(used * cost)
|
||||
|
||||
if(amount < used)
|
||||
return FALSE
|
||||
|
||||
amount -= used
|
||||
if(check)
|
||||
zero_amount()
|
||||
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
return TRUE
|
||||
|
||||
/obj/item/stack/AltClick(mob/living/user)
|
||||
if(!istype(user) || user.incapacitated())
|
||||
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
|
||||
return
|
||||
|
||||
if(!in_range(src, user) || !ishuman(usr) || amount < 1 || is_cyborg)
|
||||
return
|
||||
|
||||
// Get amount from user
|
||||
var/min = 0
|
||||
var/max = get_amount()
|
||||
var/stackmaterial = tgui_input_number(user, "How many sheets do you wish to take out of this stack? (Max: [max])", "Stack Split", max_value = max)
|
||||
if(isnull(stackmaterial) || stackmaterial <= min || stackmaterial > get_amount())
|
||||
return
|
||||
|
||||
if(!Adjacent(user, 1))
|
||||
return
|
||||
|
||||
change_stack(user,stackmaterial)
|
||||
to_chat(user, "<span class='notice'>You take [stackmaterial] sheets out of the stack.</span>")
|
||||
|
||||
/obj/item/stack/ui_state(mob/user)
|
||||
return GLOB.hands_state
|
||||
|
||||
/obj/item/stack/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "StackCraft", name)
|
||||
ui.set_autoupdate(FALSE)
|
||||
ui.open()
|
||||
|
||||
/obj/item/stack/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["amount"] = get_amount()
|
||||
return data
|
||||
|
||||
/obj/item/stack/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["recipes"] = recursively_build_recipes(recipes)
|
||||
return data
|
||||
|
||||
/obj/item/stack/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
if(..())
|
||||
return FALSE
|
||||
|
||||
var/mob/living/user = usr
|
||||
var/obj/item/stack/material = src
|
||||
switch(action)
|
||||
if("make")
|
||||
var/datum/stack_recipe/recipe = locateUID(params["recipe_uid"])
|
||||
var/multiplier = text2num(params["multiplier"])
|
||||
if(!recipe.try_build(user, material, multiplier))
|
||||
return
|
||||
return recipe.do_build(user, material, multiplier)
|
||||
|
||||
|
||||
/**
|
||||
* Recursively builds the recipes data for the given list of recipes, iterating through each recipe.
|
||||
* If recipe is of type /datum/stack_recipe, it adds the recipe data to the recipes_data list with the title as the key.
|
||||
* If recipe is of type /datum/stack_recipe_list, it recursively calls itself, scanning the entire list and adding each recipe to its category.
|
||||
*/
|
||||
/obj/item/stack/proc/recursively_build_recipes(list/recipes_to_iterate)
|
||||
var/list/recipes_data = list()
|
||||
for(var/recipe in recipes_to_iterate)
|
||||
if(istype(recipe, /datum/stack_recipe))
|
||||
var/datum/stack_recipe/single_recipe = recipe
|
||||
recipes_data["[single_recipe.title]"] = build_recipe_data(single_recipe)
|
||||
|
||||
else if(istype(recipe, /datum/stack_recipe_list))
|
||||
var/datum/stack_recipe_list/recipe_list = recipe
|
||||
recipes_data["[recipe_list.title]"] = recursively_build_recipes(recipe_list.recipes)
|
||||
|
||||
return recipes_data
|
||||
|
||||
/obj/item/stack/proc/build_recipe_data(datum/stack_recipe/recipe)
|
||||
var/list/data = list()
|
||||
|
||||
data["uid"] = recipe.UID()
|
||||
data["required_amount"] = recipe.req_amount
|
||||
data["result_amount"] = recipe.res_amount
|
||||
data["max_result_amount"] = recipe.max_res_amount
|
||||
data["image"] = recipe.image
|
||||
|
||||
return data
|
||||
|
||||
/obj/item/stack/proc/get_amount()
|
||||
if(!is_cyborg)
|
||||
return amount
|
||||
|
||||
if(!source) // The energy source has not yet been initializied
|
||||
return FALSE
|
||||
|
||||
return round(source.amount / cost)
|
||||
|
||||
/obj/item/stack/proc/get_max_amount()
|
||||
@@ -259,69 +263,32 @@
|
||||
/obj/item/stack/proc/get_amount_transferred()
|
||||
return to_transfer
|
||||
|
||||
/obj/item/stack/proc/split(mob/user, amt)
|
||||
var/obj/item/stack/F = new type(loc, amt)
|
||||
F.copy_evidences(src)
|
||||
/obj/item/stack/proc/split(mob/user, amount)
|
||||
var/obj/item/stack/material = new type(loc, amount)
|
||||
material.copy_evidences(src)
|
||||
if(isliving(user))
|
||||
add_fingerprint(user)
|
||||
F.add_fingerprint(user)
|
||||
use(amt)
|
||||
return F
|
||||
material.add_fingerprint(user)
|
||||
|
||||
/obj/item/stack/attack_hand(mob/user)
|
||||
if(user.is_in_inactive_hand(src) && get_amount() > 1)
|
||||
change_stack(user, 1)
|
||||
if(src && usr.machine == src)
|
||||
spawn(0)
|
||||
interact(usr)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/stack/AltClick(mob/living/user)
|
||||
if(!istype(user) || user.incapacitated())
|
||||
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
|
||||
return
|
||||
if(!in_range(src, user))
|
||||
return
|
||||
if(is_cyborg)
|
||||
return
|
||||
if(!ishuman(usr))
|
||||
return
|
||||
if(amount < 1)
|
||||
return
|
||||
//get amount from user
|
||||
var/min = 0
|
||||
var/max = get_amount()
|
||||
var/stackmaterial = tgui_input_number(user, "How many sheets do you wish to take out of this stack? (Max: [max])", "Stack Split", max_value = max)
|
||||
if(isnull(stackmaterial) || stackmaterial <= min || stackmaterial > get_amount())
|
||||
return
|
||||
if(!Adjacent(user, 1))
|
||||
return
|
||||
change_stack(user,stackmaterial)
|
||||
to_chat(user, "<span class='notice'>You take [stackmaterial] sheets out of the stack.</span>")
|
||||
use(amount)
|
||||
return material
|
||||
|
||||
/obj/item/stack/proc/change_stack(mob/user,amount)
|
||||
var/obj/item/stack/F = new type(user, amount, FALSE)
|
||||
. = F
|
||||
F.copy_evidences(src)
|
||||
user.put_in_hands(F)
|
||||
var/obj/item/stack/material = new type(user, amount, FALSE)
|
||||
. = material
|
||||
material.copy_evidences(src)
|
||||
user.put_in_hands(material)
|
||||
add_fingerprint(user)
|
||||
F.add_fingerprint(user)
|
||||
material.add_fingerprint(user)
|
||||
use(amount)
|
||||
|
||||
/obj/item/stack/attackby(obj/item/W, mob/user, params)
|
||||
if((!parent_stack && istype(W, merge_type)) || (parent_stack && W.type == type))
|
||||
var/obj/item/stack/S = W
|
||||
merge(S)
|
||||
to_chat(user, "<span class='notice'>Your [S.name] stack now contains [S.get_amount()] [S.singular_name]\s.</span>")
|
||||
else
|
||||
return ..()
|
||||
SStgui.update_uis(src)
|
||||
|
||||
// Returns TRUE if the stack amount is zero.
|
||||
// Also qdels the stack gracefully if it is.
|
||||
/obj/item/stack/proc/zero_amount()
|
||||
if(is_cyborg)
|
||||
return source.amount < cost
|
||||
|
||||
if(amount < 1)
|
||||
if(ismob(loc))
|
||||
var/mob/living/L = loc // At this stage, stack code is so horrible and atrocious, I wouldn't be all surprised ghosts can somehow have stacks. If this happens, then the world deserves to burn.
|
||||
@@ -334,25 +301,30 @@
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/stack/proc/merge(obj/item/stack/S) //Merge src into S, as much as possible
|
||||
if(QDELETED(S) || QDELETED(src) || S == src) //amusingly this can cause a stack to consume itself, let's not allow that.
|
||||
/obj/item/stack/proc/merge(obj/item/stack/material) //Merge src into S, as much as possible
|
||||
if(QDELETED(material) || QDELETED(src) || material == src) //amusingly this can cause a stack to consume itself, let's not allow that.
|
||||
return FALSE
|
||||
|
||||
var/transfer = get_amount()
|
||||
if(S.is_cyborg)
|
||||
transfer = min(transfer, round((S.source.max_amount - S.source.amount) / S.cost))
|
||||
if(material.is_cyborg)
|
||||
transfer = min(transfer, round((material.source.max_amount - material.source.amount) / material.cost))
|
||||
else
|
||||
transfer = min(transfer, S.max_amount - S.amount)
|
||||
transfer = min(transfer, material.max_amount - material.amount)
|
||||
|
||||
if(transfer <= 0)
|
||||
return
|
||||
|
||||
if(pulledby)
|
||||
pulledby.start_pulling(S)
|
||||
S.copy_evidences(src)
|
||||
S.add(transfer)
|
||||
pulledby.start_pulling(material)
|
||||
|
||||
material.copy_evidences(src)
|
||||
material.add(transfer)
|
||||
use(transfer)
|
||||
SStgui.update_uis(material)
|
||||
return transfer
|
||||
|
||||
/obj/item/stack/proc/copy_evidences(obj/item/stack/from)
|
||||
blood_DNA = from.blood_DNA
|
||||
fingerprints = from.fingerprints
|
||||
fingerprintshidden = from.fingerprintshidden
|
||||
fingerprintslast = from.fingerprintslast
|
||||
/obj/item/stack/proc/copy_evidences(obj/item/stack/material)
|
||||
blood_DNA = material.blood_DNA
|
||||
fingerprints = material.fingerprints
|
||||
fingerprintshidden = material.fingerprintshidden
|
||||
fingerprintslast = material.fingerprintslast
|
||||
|
||||
@@ -1,42 +1,45 @@
|
||||
|
||||
/*
|
||||
* Recipe datum
|
||||
*/
|
||||
/datum/stack_recipe
|
||||
/// Visible title of recipe
|
||||
var/title = "ERROR"
|
||||
|
||||
/// Cached recipe result base64 image
|
||||
var/image
|
||||
/// Resulting typepath of crafted atom
|
||||
var/result_type
|
||||
|
||||
/// Required stack amount to make
|
||||
var/req_amount = 1
|
||||
|
||||
/// Amount of atoms made
|
||||
var/res_amount = 1
|
||||
|
||||
/// Maximum amount of atoms made
|
||||
var/max_res_amount = 1
|
||||
|
||||
/// Time to make
|
||||
var/time = 0
|
||||
|
||||
/// Only one resulting atom is allowed per turf
|
||||
var/one_per_turf = FALSE
|
||||
|
||||
/// Requires a floor underneath to make
|
||||
var/on_floor = FALSE
|
||||
|
||||
/// Requires a floor OR lattice underneath to make
|
||||
var/on_floor_or_lattice = FALSE
|
||||
|
||||
/// Requires a valid window location to make
|
||||
var/window_checks = FALSE
|
||||
|
||||
/// Resulting atom is a cult structure
|
||||
var/cult_structure = FALSE
|
||||
|
||||
/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1, time = 0, one_per_turf = FALSE, on_floor = FALSE, on_floor_or_lattice = FALSE, window_checks = FALSE, cult_structure = FALSE)
|
||||
/datum/stack_recipe/New(
|
||||
title,
|
||||
result_type,
|
||||
req_amount = 1,
|
||||
res_amount = 1,
|
||||
max_res_amount = 1,
|
||||
time = 0,
|
||||
one_per_turf = FALSE,
|
||||
on_floor = FALSE,
|
||||
on_floor_or_lattice = FALSE,
|
||||
window_checks = FALSE,
|
||||
cult_structure = FALSE
|
||||
)
|
||||
src.title = title
|
||||
src.result_type = result_type
|
||||
src.req_amount = req_amount
|
||||
@@ -49,6 +52,16 @@
|
||||
src.window_checks = window_checks
|
||||
src.cult_structure = cult_structure
|
||||
|
||||
var/obj/item/result = result_type
|
||||
var/icon/result_icon = icon(result::icon, result::icon_state, SOUTH, 1)
|
||||
var/paint = result::color
|
||||
|
||||
result_icon.Scale(32, 32)
|
||||
if(!isnull(paint) && paint != COLOR_WHITE)
|
||||
result_icon.Blend(paint, ICON_MULTIPLY)
|
||||
|
||||
src.image = "[icon2base64(result_icon)]"
|
||||
|
||||
/// Returns TRUE if the recipe can be built, otherwise returns FALSE. This proc is only meant as a series of tests to check if construction is possible; the actual creation of the resulting atom should be handled in do_build()
|
||||
/datum/stack_recipe/proc/try_build(mob/user, obj/item/stack/S, multiplier)
|
||||
if(S.get_amount() < req_amount * multiplier)
|
||||
|
||||
Reference in New Issue
Block a user