mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 21:48:39 +01:00
+37






![tgstation-ci[bot] <179393467+tgstation-ci[bot]@users.noreply.github.com>](/assets/img/avatar_default.png)


Alexis
GitHub
tgstation-ci[bot] <179393467+tgstation-ci[bot]@users.noreply.github.com>
ArcaneMusic
MrMelbert
Rhials
rageguy505
LemonInTheDark
John Willard
Aliceee2ch
Time-Green
Tsar-Salat
SmArtKar
Maxipat
SyncIt21
deltanedas
SimplyLogan
loganuk
Leland Kemble
FalloutFalcon
Roxy
Lucy
siliconOpossum
Isratosh
TheRyeGuyWhoWillNowDie
Neocloudy
Alexander V.
ElGitificador
Twaticus
dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bloop
Cameron Lennox
Tim
Iamgoofball
Layzu666
Arturlang
_0Steven
mrmanlikesbt
Ben10Omintrix
John F. Kennedy
Cursor
Josh
Josh Powell
Yobrocharlie
Hardly3D
shayoki
LT3
21b4095dfd
Upstream 04/17/2026 fixes https://github.com/Bubberstation/Bubberstation/issues/5549 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: tgstation-ci[bot] <179393467+tgstation-ci[bot]@users.noreply.github.com> Co-authored-by: ArcaneMusic <41715314+ArcaneMusic@users.noreply.github.com> Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Co-authored-by: Rhials <28870487+Rhials@users.noreply.github.com> Co-authored-by: rageguy505 <54517726+rageguy505@users.noreply.github.com> Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com> Co-authored-by: Aliceee2ch <160794176+Aliceee2ch@users.noreply.github.com> Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com> Co-authored-by: Tsar-Salat <62388554+Tsar-Salat@users.noreply.github.com> Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Co-authored-by: Maxipat <108554989+Maxipat112@users.noreply.github.com> Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Co-authored-by: deltanedas <39013340+deltanedas@users.noreply.github.com> Co-authored-by: SimplyLogan <47579821+loganuk@users.noreply.github.com> Co-authored-by: loganuk <fakeemail123@aol.com> Co-authored-by: Leland Kemble <70413276+lelandkemble@users.noreply.github.com> Co-authored-by: FalloutFalcon <86381784+FalloutFalcon@users.noreply.github.com> Co-authored-by: Roxy <75404941+TealSeer@users.noreply.github.com> Co-authored-by: Lucy <lucy@absolucy.moe> Co-authored-by: siliconOpossum <138069572+siliconOpossum@users.noreply.github.com> Co-authored-by: Isratosh <Isratosh@hotmail.com> Co-authored-by: TheRyeGuyWhoWillNowDie <70169560+TheRyeGuyWhoWillNowDie@users.noreply.github.com> Co-authored-by: Neocloudy <88008002+Neocloudy@users.noreply.github.com> Co-authored-by: Alexander V. <volas@ya.ru> Co-authored-by: ElGitificador <168473461+ElGitificador@users.noreply.github.com> Co-authored-by: Twaticus <46540570+Twaticus@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> Co-authored-by: Cameron Lennox <killer65311@gmail.com> Co-authored-by: Tim <timothymtorres@gmail.com> Co-authored-by: Iamgoofball <iamgoofball@gmail.com> Co-authored-by: Layzu666 <121319428+Layzu666@users.noreply.github.com> Co-authored-by: Arturlang <24881678+Arturlang@users.noreply.github.com> Co-authored-by: _0Steven <42909981+00-Steven@users.noreply.github.com> Co-authored-by: mrmanlikesbt <99309552+mrmanlikesbt@users.noreply.github.com> Co-authored-by: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com> Co-authored-by: John F. Kennedy <54908920+MacaroniCritter@users.noreply.github.com> Co-authored-by: Cursor <102828457+theselfish@users.noreply.github.com> Co-authored-by: Josh <josh.adam.powell@gmail.com> Co-authored-by: Josh Powell <josh.powell@softwire.com> Co-authored-by: Yobrocharlie <Charliemiller5617@gmail.com> Co-authored-by: Hardly3D <66234359+Hardly3D@users.noreply.github.com> Co-authored-by: shayoki <96078776+shayoki@users.noreply.github.com> Co-authored-by: LT3 <83487515+lessthnthree@users.noreply.github.com>
962 lines
35 KiB
Plaintext
962 lines
35 KiB
Plaintext
/// The baseline time to take for doing actions with the forge, like heating glass, setting ceramics, etc.
|
|
#define BASELINE_ACTION_TIME (4 SECONDS)
|
|
|
|
/// The basline for how long an item such as molten glass will be kept workable after heating
|
|
#define BASELINE_HEATING_DURATION (25 SECONDS)
|
|
|
|
/// The amount the forge's temperature will change per process
|
|
#define FORGE_DEFAULT_TEMPERATURE_CHANGE 5
|
|
/// The maximum temperature the forge can reach
|
|
#define MAX_FORGE_TEMP 100
|
|
/// The minimum temperature for using the forge
|
|
#define MIN_FORGE_TEMP 50
|
|
/// The duration that objects heated in the forge are heated for
|
|
#define FORGE_HEATING_DURATION (1 MINUTES)
|
|
|
|
/// Defines for different levels of the forge, ranging from no level (you play like a noob) to legendary
|
|
#define FORGE_LEVEL_YOU_PLAY_LIKE_A_NOOB 1
|
|
#define FORGE_LEVEL_NOVICE 2
|
|
#define FORGE_LEVEL_APPRENTICE 3
|
|
#define FORGE_LEVEL_JOURNEYMAN 4
|
|
#define FORGE_LEVEL_EXPERT 5
|
|
#define FORGE_LEVEL_MASTER 6
|
|
#define FORGE_LEVEL_LEGENDARY 7
|
|
|
|
/// The maximum amount of temperature loss decrease that upgrades can give the forge
|
|
#define MAX_TEMPERATURE_LOSS_DECREASE 5
|
|
|
|
/// The chance per piece of wood added that charcoal will form later
|
|
#define CHARCOAL_CHANCE 45
|
|
|
|
/// The minimum units of a reagent rerquired to imbue it into a weapon
|
|
#define MINIMUM_IMBUING_REAGENT_AMOUNT 100
|
|
|
|
/// Defines for the different levels of smoke coming out of the forge, (good, neutral, bad) are all used for baking, (not cooking) is used for when there is no tray in the forge
|
|
#define SMOKE_STATE_NONE 0
|
|
#define SMOKE_STATE_GOOD 1
|
|
#define SMOKE_STATE_NEUTRAL 2
|
|
#define SMOKE_STATE_BAD 3
|
|
#define SMOKE_STATE_NOT_COOKING 4
|
|
|
|
/obj/structure/reagent_forge
|
|
name = "forge"
|
|
desc = "A structure built out of bricks, for heating up metal, or glass, or ceramic, or food, or anything really."
|
|
icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_structures.dmi'
|
|
icon_state = "forge_inactive"
|
|
|
|
anchored = TRUE
|
|
density = TRUE
|
|
custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 10)
|
|
|
|
/// What the current internal temperature of the forge is
|
|
var/forge_temperature = 0
|
|
/// What temperature the forge is moving towards
|
|
var/target_temperature = 0
|
|
/// What the minimum target temperature is, used for upgrades
|
|
var/minimum_target_temperature = 0
|
|
/// What is the current reduction for temperature decrease
|
|
var/temperature_loss_reduction = 0
|
|
/// How many seconds of weak fuel (wood) does the forge have left
|
|
var/forge_fuel_weak = 0
|
|
/// How many seconds of strong fuel (coal) does the forge have left
|
|
var/forge_fuel_strong = 0
|
|
/// If the forge is capable of reagent forging or not
|
|
var/reagent_forging = FALSE
|
|
/// Cooldown time for processing on the forge
|
|
COOLDOWN_DECLARE(forging_cooldown)
|
|
/// Is the forge in use or not? If true, prevents most interactions with the forge
|
|
var/in_use = FALSE
|
|
/// The current 'level' of the forge, how upgraded is it from zero to three
|
|
var/forge_level = FORGE_LEVEL_YOU_PLAY_LIKE_A_NOOB
|
|
/// What smoke particles should be coming out of the forge
|
|
var/smoke_state = SMOKE_STATE_NONE
|
|
/// Tracks any oven tray placed inside of the forge
|
|
var/obj/item/plate/oven_tray/used_tray
|
|
/// The list of possible things to make with materials used on the forge
|
|
var/static/list/choice_list = list(
|
|
"Chain" = /obj/item/forging/incomplete/chain,
|
|
"Plate" = /obj/item/forging/incomplete/plate,
|
|
"Sword" = /obj/item/forging/incomplete/sword,
|
|
"Katana" = /obj/item/forging/incomplete/katana,
|
|
"Dagger" = /obj/item/forging/incomplete/dagger,
|
|
"Rapier" = /obj/item/forging/incomplete/rapier,
|
|
"Staff" = /obj/item/forging/incomplete/staff,
|
|
"Spear" = /obj/item/forging/incomplete/spear,
|
|
"Axe" = /obj/item/forging/incomplete/axe,
|
|
"Hammer" = /obj/item/forging/incomplete/hammer,
|
|
"Pickaxe" = /obj/item/forging/incomplete/pickaxe,
|
|
"Shovel" = /obj/item/forging/incomplete/shovel,
|
|
"Arrowhead" = /obj/item/forging/incomplete/arrowhead,
|
|
"Rail Nail" = /obj/item/forging/incomplete/rail_nail,
|
|
"Rail Cart" = /obj/item/forging/incomplete/rail_cart,
|
|
)
|
|
/// List of possible choices for the selection radial
|
|
var/list/radial_choice_list = list()
|
|
|
|
/obj/structure/reagent_forge/examine(mob/user)
|
|
. = ..()
|
|
|
|
if(used_tray)
|
|
. += span_notice("It has [used_tray] in it, which can be removed with an <b>empty hand</b>.")
|
|
else
|
|
. += span_notice("You can place an <b>oven tray</b> in this to <b>bake</b> any items on it.")
|
|
|
|
if(forge_level < FORGE_LEVEL_LEGENDARY)
|
|
. += span_notice("Using an <b>empty hand</b> on [src] will upgrade it, if your forging skill level is above the current upgrade's level.")
|
|
|
|
switch(forge_level)
|
|
if(FORGE_LEVEL_YOU_PLAY_LIKE_A_NOOB)
|
|
. += span_notice("This forge has not been upgraded yet.")
|
|
|
|
if(FORGE_LEVEL_NOVICE)
|
|
. += span_notice("This forge has been upgraded by a novice smith.")
|
|
|
|
if(FORGE_LEVEL_APPRENTICE)
|
|
. += span_notice("This forge has been upgraded by an apprentice smith.")
|
|
|
|
if(FORGE_LEVEL_JOURNEYMAN)
|
|
. += span_notice("This forge has been upgraded by a journeyman smith.")
|
|
|
|
if(FORGE_LEVEL_EXPERT)
|
|
. += span_notice("This forge has been upgraded by an expert smith.")
|
|
|
|
if(FORGE_LEVEL_MASTER)
|
|
. += span_notice("This forge has been upgraded by a master smith.")
|
|
|
|
if(FORGE_LEVEL_LEGENDARY)
|
|
. += span_hierophant("This forge has been upgraded by a legendary smith.") // Legendary skills give you the greatest gift of all, cool text
|
|
|
|
switch(temperature_loss_reduction)
|
|
if(0)
|
|
. += span_notice("[src] will lose heat at a normal rate.")
|
|
if(1)
|
|
. += span_notice("[src] will lose heat slightly slower than usual.")
|
|
if(2)
|
|
. += span_notice("[src] will lose heat a bit slower than usual.")
|
|
if(3)
|
|
. += span_notice("[src] will lose heat much slower than usual.")
|
|
if(4)
|
|
. += span_notice("[src] will lose heat signficantly slower than usual.")
|
|
if(5)
|
|
. += span_notice("[src] will lose heat at a practically negligible rate.")
|
|
|
|
. += span_notice("<br>[src] is currently [forge_temperature] degrees hot, going towards [target_temperature] degrees.<br>")
|
|
|
|
if(reagent_forging)
|
|
. += span_warning("[src] has a fine gold trim, it is ready to imbue chemicals into reagent objects.")
|
|
|
|
return .
|
|
|
|
/obj/structure/reagent_forge/Initialize(mapload)
|
|
. = ..()
|
|
START_PROCESSING(SSobj, src)
|
|
populate_radial_choice_list()
|
|
update_appearance()
|
|
upgrade_forge(forced = TRUE)
|
|
|
|
/// Fills out the radial choice list with everything in the choice_list's contents
|
|
/obj/structure/reagent_forge/proc/populate_radial_choice_list()
|
|
if(!length(choice_list))
|
|
return
|
|
|
|
if(length(radial_choice_list))
|
|
return
|
|
|
|
for(var/forge_option in choice_list)
|
|
var/obj/resulting_item = choice_list[forge_option]
|
|
radial_choice_list[forge_option] = image(icon = initial(resulting_item.icon), icon_state = initial(resulting_item.icon_state))
|
|
|
|
/obj/structure/reagent_forge/Destroy()
|
|
STOP_PROCESSING(SSobj, src)
|
|
QDEL_NULL(particles)
|
|
if(used_tray)
|
|
QDEL_NULL(used_tray)
|
|
. = ..()
|
|
|
|
/obj/structure/reagent_forge/update_appearance(updates)
|
|
. = ..()
|
|
cut_overlays()
|
|
|
|
if(reagent_forging) // If we can do reagent forging, give the forge the gold trim
|
|
var/image/gold_overlay = image(icon = icon, icon_state = "forge_masterwork_trim")
|
|
add_overlay(gold_overlay)
|
|
|
|
if(used_tray) // If we have a tray inside, check if the forge is on or not, then give the corresponding tray overlay
|
|
var/image/tray_overlay = image(icon = icon, icon_state = "forge_tray_[check_fuel(just_checking = TRUE) ? "active" : "inactive"]")
|
|
add_overlay(tray_overlay)
|
|
|
|
/// Checks if the forge has fuel, if so what type. If it has either type of fuel, returns TRUE, otherwise returns FALSE. just_checking will check if there is fuel without taking actions
|
|
/obj/structure/reagent_forge/proc/check_fuel(just_checking = FALSE)
|
|
if(forge_fuel_strong) // Check for strong fuel (coal) first, as it has more power over weaker fuels
|
|
if(just_checking)
|
|
return TRUE
|
|
|
|
forge_fuel_strong -= 5 SECONDS
|
|
target_temperature = 100
|
|
return TRUE
|
|
|
|
if(forge_fuel_weak) // If there's no strong fuel, maybe we have weak fuel (wood)
|
|
if(just_checking)
|
|
return TRUE
|
|
|
|
forge_fuel_weak -= 5 SECONDS
|
|
target_temperature = 50
|
|
return TRUE
|
|
|
|
if(just_checking)
|
|
return FALSE
|
|
|
|
target_temperature = minimum_target_temperature // If the forge has no fuel, then we should lowly return to the minimum lowest temp we can do
|
|
return FALSE
|
|
|
|
/// Gives the forge the ability to imbue reagents into things
|
|
/obj/structure/reagent_forge/proc/create_reagent_forge()
|
|
if(reagent_forging) // If the forge can already do reagent forging, then we can skip the rest of this
|
|
return
|
|
reagent_forging = TRUE
|
|
update_appearance()
|
|
|
|
/// Creates both a fail message balloon alert, and sets in_use to false
|
|
/obj/structure/reagent_forge/proc/fail_message(mob/living/user, message)
|
|
balloon_alert(user, message)
|
|
in_use = FALSE
|
|
|
|
/// Adjust the temperature to head towards the target temperature, changing icon and creating light if the temperature is rising
|
|
/obj/structure/reagent_forge/proc/check_temp()
|
|
if(forge_temperature > target_temperature) // Being above the target temperature will cause the forge to cool down
|
|
forge_temperature -= (FORGE_DEFAULT_TEMPERATURE_CHANGE - temperature_loss_reduction)
|
|
return
|
|
|
|
else if((forge_temperature < target_temperature) && (forge_fuel_weak || forge_fuel_strong)) // Being below the target temp, and having fuel, will cause the temp to rise
|
|
forge_temperature += FORGE_DEFAULT_TEMPERATURE_CHANGE
|
|
return
|
|
|
|
/// If the forge is in use, checks if there is an oven tray, then if there are any mobs actually in use range. If not sets the forge to not be in use.
|
|
/obj/structure/reagent_forge/proc/check_in_use()
|
|
if(!in_use)
|
|
return
|
|
|
|
if(used_tray) // We check if there's a tray because trays inside of the forge count as it being in use, even if nobody is around
|
|
return
|
|
|
|
for(var/mob/living/living_mob in range(1,src))
|
|
if(!living_mob)
|
|
in_use = FALSE
|
|
|
|
/// Spawns a piece of coal at the forge and renames it to charcoal
|
|
/obj/structure/reagent_forge/proc/spawn_coal()
|
|
var/obj/item/stack/sheet/mineral/coal/spawn_coal = new(get_turf(src))
|
|
spawn_coal.name = "charcoal"
|
|
|
|
/obj/structure/reagent_forge/process(seconds_per_tick)
|
|
if(!COOLDOWN_FINISHED(src, forging_cooldown))
|
|
return
|
|
|
|
COOLDOWN_START(src, forging_cooldown, 5 SECONDS)
|
|
check_fuel()
|
|
check_temp()
|
|
check_in_use() // This is here to ensure the forge doesn't remain in_use if it really isn't
|
|
|
|
|
|
|
|
if(!used_tray && check_fuel(just_checking = TRUE))
|
|
set_smoke_state(SMOKE_STATE_NOT_COOKING) // If there is no tray but we have fuel, use the not cooking smoke state
|
|
return
|
|
|
|
if(!check_fuel(just_checking = TRUE)) // If there's no fuel, remove it all
|
|
set_smoke_state(SMOKE_STATE_NONE)
|
|
return
|
|
|
|
handle_baking_things(seconds_per_tick)
|
|
|
|
/// Sends signals to bake and items on the used tray, setting the smoke state of the forge according to the most cooked item in it
|
|
/obj/structure/reagent_forge/proc/handle_baking_things(seconds_per_tick)
|
|
if(forge_temperature < MIN_FORGE_TEMP) // If we are below minimum forge temp, don't continue on to cooking
|
|
return
|
|
|
|
/// The worst off item being baked in our forge right now, to ensure people know when gordon ramsay is gonna be upset at them
|
|
var/worst_cooked_food_state = 0
|
|
for(var/obj/item/baked_item as anything in used_tray.contents)
|
|
|
|
var/signal_result = SEND_SIGNAL(baked_item, COMSIG_ITEM_OVEN_PROCESS, src, seconds_per_tick)
|
|
|
|
if(signal_result & COMPONENT_HANDLED_BAKING)
|
|
if(signal_result & COMPONENT_BAKING_GOOD_RESULT && worst_cooked_food_state < SMOKE_STATE_GOOD)
|
|
worst_cooked_food_state = SMOKE_STATE_GOOD
|
|
else if(signal_result & COMPONENT_BAKING_BAD_RESULT && worst_cooked_food_state < SMOKE_STATE_NEUTRAL)
|
|
worst_cooked_food_state = SMOKE_STATE_NEUTRAL
|
|
continue
|
|
|
|
worst_cooked_food_state = SMOKE_STATE_BAD
|
|
baked_item.fire_act(1000) // Overcooked food really does burn, hot hot hot!
|
|
|
|
if(SPT_PROB(10, seconds_per_tick))
|
|
visible_message(span_danger("You smell a burnt smell coming from [src]!")) // Give indication that something is burning in the oven
|
|
set_smoke_state(worst_cooked_food_state)
|
|
|
|
/// Sets the type of particles that the forge should be generating
|
|
/obj/structure/reagent_forge/proc/set_smoke_state(new_state)
|
|
if(new_state == smoke_state)
|
|
return
|
|
|
|
smoke_state = new_state
|
|
|
|
QDEL_NULL(particles)
|
|
|
|
switch(smoke_state)
|
|
if(SMOKE_STATE_NONE)
|
|
icon_state = "forge_inactive"
|
|
set_light(0, 0) // If we aren't heating up and thus not on fire, turn the fire light off
|
|
return
|
|
|
|
if(SMOKE_STATE_BAD)
|
|
particles = new /particles/smoke()
|
|
particles.position = list(6, 4, 0)
|
|
|
|
if(SMOKE_STATE_NEUTRAL)
|
|
particles = new /particles/smoke/steam()
|
|
particles.position = list(6, 4, 0)
|
|
|
|
if(SMOKE_STATE_GOOD)
|
|
particles = new /particles/smoke/steam/mild()
|
|
particles.position = list(6, 4, 0)
|
|
|
|
if(SMOKE_STATE_NOT_COOKING)
|
|
particles = new /particles/smoke/mild()
|
|
particles.position = list(6, 4, 0)
|
|
|
|
icon_state = "forge_active"
|
|
set_light(3, 1, LIGHT_COLOR_FIRE)
|
|
|
|
/obj/structure/reagent_forge/attack_hand(mob/living/user, list/modifiers)
|
|
. = ..()
|
|
if(used_tray)
|
|
remove_tray_from_forge(user)
|
|
return
|
|
|
|
upgrade_forge(user)
|
|
|
|
/obj/structure/reagent_forge/attack_robot(mob/living/user)
|
|
. = ..()
|
|
upgrade_forge(user)
|
|
|
|
/obj/structure/reagent_forge/proc/upgrade_forge(mob/living/user, forced = FALSE)
|
|
var/level_to_upgrade_to
|
|
|
|
if(forced || !user) // This is to make sure the ready subtype of forge still works
|
|
level_to_upgrade_to = forge_level
|
|
else
|
|
level_to_upgrade_to = user.mind.get_skill_level(/datum/skill/smithing)
|
|
|
|
if((forge_level == level_to_upgrade_to) && !forced)
|
|
to_chat(user, span_notice("[src] was already upgraded by your level of expertise!"))
|
|
return
|
|
|
|
switch(level_to_upgrade_to) // Remember to carry things over from past levels in case someone skips levels in upgrading
|
|
if(SKILL_LEVEL_NONE)
|
|
if(!forced)
|
|
to_chat(user, span_notice("You'll need some forging skills to really understand how to upgrade [src]."))
|
|
return
|
|
|
|
if(SKILL_LEVEL_NOVICE)
|
|
if(!forced)
|
|
to_chat(user, span_notice("With some experience, you've come to realize there are some easily fixable spots with poor insulation..."))
|
|
temperature_loss_reduction = 1
|
|
forge_level = FORGE_LEVEL_NOVICE
|
|
|
|
if(SKILL_LEVEL_APPRENTICE)
|
|
if(!forced)
|
|
to_chat(user, span_notice("Further insulation and protection of the thinner areas means [src] will lose heat just that little bit slower."))
|
|
temperature_loss_reduction = 2
|
|
forge_level = FORGE_LEVEL_APPRENTICE
|
|
|
|
if(SKILL_LEVEL_JOURNEYMAN)
|
|
if(!forced)
|
|
to_chat(user, span_notice("Some careful placement and stoking of the flame will allow you to keep at least the embers burning..."))
|
|
minimum_target_temperature = 25 // Will allow quicker reheating from having no fuel
|
|
temperature_loss_reduction = 3
|
|
forge_level = FORGE_LEVEL_JOURNEYMAN
|
|
|
|
if(SKILL_LEVEL_EXPERT)
|
|
if(!forced)
|
|
to_chat(user, span_notice("[src] has become nearly perfect, able to hold heat for long enough that even a piece of wood can outmatch the longevity of lesser forges."))
|
|
temperature_loss_reduction = 4
|
|
minimum_target_temperature = 25
|
|
forge_level = FORGE_LEVEL_EXPERT
|
|
|
|
if(SKILL_LEVEL_MASTER)
|
|
if(!forced)
|
|
to_chat(user, span_notice("The perfect forge for a perfect metalsmith, with your knowledge it should bleed heat so slowly, that not even you will live to see [src] cool."))
|
|
temperature_loss_reduction = MAX_TEMPERATURE_LOSS_DECREASE
|
|
minimum_target_temperature = 25
|
|
forge_level = FORGE_LEVEL_MASTER
|
|
|
|
if(SKILL_LEVEL_LEGENDARY)
|
|
if(!forced)
|
|
to_chat(user, span_notice("With just the right heat treating technique, metal could be made to accept reagents..."))
|
|
create_reagent_forge()
|
|
temperature_loss_reduction = MAX_TEMPERATURE_LOSS_DECREASE
|
|
minimum_target_temperature = 25 // This won't matter except in a few cases here, but we still need to cover those few cases
|
|
forge_level = FORGE_LEVEL_LEGENDARY
|
|
|
|
playsound(src, 'sound/items/weapons/parry.ogg', 50, TRUE) // Play a feedback sound to really let players know we just did an upgrade
|
|
|
|
//this will allow click dragging certain items
|
|
/obj/structure/reagent_forge/mouse_drop_receive(atom/attacking_item, mob/user, params)
|
|
. = ..()
|
|
if(!isliving(user))
|
|
return
|
|
|
|
if(!isobj(attacking_item))
|
|
return
|
|
|
|
if(istype(attacking_item, /obj/item/stack/sheet/mineral/wood)) // Wood is a weak fuel, and will only get the forge up to 50 temperature
|
|
refuel(attacking_item, user)
|
|
return
|
|
|
|
if(istype(attacking_item, /obj/item/stack/sheet/mineral/coal)) // Coal is a strong fuel that doesn't need bellows to heat up properly
|
|
refuel(attacking_item, user, TRUE)
|
|
return
|
|
|
|
if(istype(attacking_item, /obj/item/stack/ore))
|
|
smelt_ore(attacking_item, user)
|
|
return
|
|
|
|
if(attacking_item.GetComponent(/datum/component/reagent_weapon))
|
|
handle_weapon_imbue(attacking_item, user)
|
|
return
|
|
|
|
if(attacking_item.GetComponent(/datum/component/reagent_clothing))
|
|
handle_clothing_imbue(attacking_item, user)
|
|
return
|
|
|
|
/obj/structure/reagent_forge/attackby(obj/item/attacking_item, mob/living/user, params)
|
|
if(!used_tray && istype(attacking_item, /obj/item/plate/oven_tray))
|
|
add_tray_to_forge(user, attacking_item)
|
|
return TRUE
|
|
|
|
if(in_use) // If the forge is currently in use by someone (or there is a tray in it) then we cannot use it
|
|
if(used_tray)
|
|
balloon_alert(user, "remove [used_tray] first")
|
|
balloon_alert(user, "forge busy")
|
|
return TRUE
|
|
|
|
if(istype(attacking_item, /obj/item/stack/sheet/mineral/wood)) // Wood is a weak fuel, and will only get the forge up to 50 temperature
|
|
refuel(attacking_item, user)
|
|
return TRUE
|
|
|
|
if(istype(attacking_item, /obj/item/stack/sheet/mineral/coal)) // Coal is a strong fuel that doesn't need bellows to heat up properly
|
|
refuel(attacking_item, user, TRUE)
|
|
return TRUE
|
|
|
|
if(istype(attacking_item, /obj/item/stack/ore))
|
|
smelt_ore(attacking_item, user)
|
|
return TRUE
|
|
|
|
if(attacking_item.GetComponent(/datum/component/reagent_weapon))
|
|
handle_weapon_imbue(attacking_item, user)
|
|
return TRUE
|
|
|
|
if(attacking_item.GetComponent(/datum/component/reagent_clothing))
|
|
handle_clothing_imbue(attacking_item, user)
|
|
return TRUE
|
|
|
|
if(istype(attacking_item, /obj/item/ceramic))
|
|
handle_ceramics(attacking_item, user)
|
|
return TRUE
|
|
|
|
if(istype(attacking_item, /obj/item/stack/sheet/glass))
|
|
handle_glass_sheet_melting(attacking_item, user)
|
|
return TRUE
|
|
|
|
if(istype(attacking_item, /obj/item/glassblowing/metal_cup))
|
|
handle_metal_cup_melting(attacking_item, user)
|
|
return TRUE
|
|
|
|
return ..()
|
|
|
|
/// Take the given tray and place it inside the forge, updating everything relevant to that
|
|
/obj/structure/reagent_forge/proc/add_tray_to_forge(mob/living/user, obj/item/plate/oven_tray/tray)
|
|
if(used_tray) // This shouldn't be able to happen but just to be safe
|
|
balloon_alert_to_viewers("already has tray")
|
|
return
|
|
|
|
if(!user.transferItemToLoc(tray, src, silent = FALSE))
|
|
return
|
|
|
|
// need to send the right signal for each item in the tray
|
|
for(var/obj/item/baked_item in tray.contents)
|
|
SEND_SIGNAL(baked_item, COMSIG_ITEM_OVEN_PLACED_IN, src, user)
|
|
|
|
balloon_alert_to_viewers("put [tray] in [src]")
|
|
used_tray = tray
|
|
in_use = TRUE // You can't use the forge if there's a tray sitting in it
|
|
update_appearance()
|
|
|
|
/// Take the used_tray and spit it out, updating everything relevant to that
|
|
/obj/structure/reagent_forge/proc/remove_tray_from_forge(mob/living/carbon/user)
|
|
if(!used_tray)
|
|
if(user)
|
|
balloon_alert_to_viewers("no tray")
|
|
return
|
|
|
|
if(user)
|
|
user.put_in_hands(used_tray)
|
|
balloon_alert_to_viewers("removed [used_tray]")
|
|
else
|
|
used_tray.forceMove(get_turf(src))
|
|
used_tray = null
|
|
in_use = FALSE
|
|
|
|
/// Adds to either the strong or weak fuel timers from the given stack
|
|
/obj/structure/reagent_forge/proc/refuel(obj/item/stack/refueling_stack, mob/living/user, is_strong_fuel = FALSE)
|
|
in_use = TRUE
|
|
|
|
if(is_strong_fuel)
|
|
if(forge_fuel_strong >= 5 MINUTES)
|
|
fail_message(user, "[src] is full on coal")
|
|
return
|
|
if(forge_fuel_weak >= 5 MINUTES)
|
|
fail_message(user, "[src] is full on wood")
|
|
return
|
|
|
|
balloon_alert_to_viewers("refueling...")
|
|
|
|
var/obj/item/stack/sheet/stack_sheet = refueling_stack
|
|
if(!do_after(user, 3 SECONDS, target = src) || !stack_sheet.use(1))
|
|
fail_message(user, "stopped fueling")
|
|
return
|
|
|
|
if(is_strong_fuel)
|
|
forge_fuel_strong += 5 MINUTES
|
|
else
|
|
forge_fuel_weak += 5 MINUTES
|
|
in_use = FALSE
|
|
balloon_alert(user, "fueled [src]")
|
|
user.mind.adjust_experience(/datum/skill/smithing, 5) // You gain small amounts of experience from useful fueling
|
|
|
|
if(prob(CHARCOAL_CHANCE) && !is_strong_fuel)
|
|
to_chat(user, span_notice("[src]'s fuel is packed densely enough to have made some charcoal!"))
|
|
addtimer(CALLBACK(src, PROC_REF(spawn_coal)), 1 MINUTES)
|
|
|
|
/// Takes given ore and smelts it, possibly producing extra sheets if upgraded
|
|
/obj/structure/reagent_forge/proc/smelt_ore(obj/item/stack/ore/ore_item, mob/living/user)
|
|
in_use = TRUE
|
|
|
|
if(forge_temperature < MIN_FORGE_TEMP)
|
|
fail_message(user, "forge too cool")
|
|
return
|
|
|
|
var/skill_modifier = user.mind.get_skill_modifier(/datum/skill/smithing, SKILL_SPEED_MODIFIER)
|
|
|
|
if(!ore_item.refined_type)
|
|
fail_message(user, "cannot smelt [ore_item]")
|
|
return
|
|
|
|
balloon_alert_to_viewers("smelting...")
|
|
|
|
if(!do_after(user, skill_modifier * 3 SECONDS, target = src))
|
|
fail_message(user, "stopped smelting [ore_item]")
|
|
return
|
|
|
|
var/src_turf = get_turf(src)
|
|
var/spawning_item = ore_item.refined_type
|
|
var/ore_to_sheet_amount = ore_item.amount
|
|
|
|
for(var/spawn_ore in 1 to ore_to_sheet_amount)
|
|
new spawning_item(src_turf)
|
|
|
|
in_use = FALSE
|
|
qdel(ore_item)
|
|
return
|
|
|
|
/// Handles weapon reagent imbuing
|
|
/obj/structure/reagent_forge/proc/handle_weapon_imbue(obj/attacking_item, mob/living/user)
|
|
if(user.mind.get_skill_level(/datum/skill/smithing) < SKILL_LEVEL_MASTER)
|
|
to_chat(user, span_danger("You need more experience to understand the fine workings of imbuing!"))
|
|
return
|
|
//This code will refuse all non-ashwalkers & non-icecats from imbuing
|
|
if(!ishuman(user))
|
|
to_chat(user, span_danger("It is impossible for you to imbue!")) //maybe remove (ashwalkers & icecats only) after some time
|
|
return
|
|
|
|
in_use = TRUE
|
|
balloon_alert_to_viewers("imbuing...")
|
|
|
|
var/obj/item/attacking_weapon = attacking_item
|
|
|
|
var/datum/component/reagent_weapon/weapon_component = attacking_weapon.GetComponent(/datum/component/reagent_weapon)
|
|
if(!weapon_component)
|
|
fail_message(user, "cannot imbue")
|
|
return
|
|
|
|
if(length(weapon_component.imbued_reagent))
|
|
fail_message(user, "already imbued")
|
|
return
|
|
|
|
if(!do_after(user, 10 SECONDS, target = src))
|
|
fail_message(user, "stopped imbuing")
|
|
return
|
|
|
|
for(var/datum/reagent/weapon_reagent as anything in attacking_weapon.reagents.reagent_list)
|
|
if(weapon_reagent.volume < MINIMUM_IMBUING_REAGENT_AMOUNT)
|
|
attacking_weapon.reagents.remove_reagent(weapon_reagent.type)
|
|
continue
|
|
|
|
weapon_component.imbued_reagent += weapon_reagent.type
|
|
attacking_weapon.name = "[weapon_reagent.name] [attacking_weapon.name]"
|
|
|
|
attacking_weapon.color = mix_color_from_reagents(attacking_weapon.reagents.reagent_list)
|
|
if(attacking_weapon.armour_penetration < 10)
|
|
attacking_weapon.armour_penetration = 0
|
|
else
|
|
attacking_weapon.armour_penetration -= 10
|
|
balloon_alert_to_viewers("imbued [attacking_weapon]")
|
|
user.mind.adjust_experience(/datum/skill/smithing, 60)
|
|
playsound(src, 'sound/effects/magic/demon_consume.ogg', 50, TRUE)
|
|
in_use = FALSE
|
|
return TRUE
|
|
|
|
/// Handles clothing imbuing, extremely similar to weapon imbuing but not in the same proc because of how uhh... goofy the way this has to be done is
|
|
/obj/structure/reagent_forge/proc/handle_clothing_imbue(obj/attacking_item, mob/living/user)
|
|
if(user.mind.get_skill_level(/datum/skill/smithing) < SKILL_LEVEL_MASTER)
|
|
to_chat(user, span_danger("You need more experience to understand the fine workings of imbuing!"))
|
|
return
|
|
//This code will refuse all non-ashwalkers & non-icecats from imbuing
|
|
if(!ishuman(user))
|
|
to_chat(user, span_danger("It is impossible for you to imbue!")) //maybe remove (ashwalkers & icecats only) after some time
|
|
return
|
|
|
|
in_use = TRUE
|
|
balloon_alert_to_viewers("imbuing...")
|
|
|
|
var/obj/item/attacking_clothing = attacking_item
|
|
|
|
var/datum/component/reagent_clothing/clothing_component = attacking_clothing.GetComponent(/datum/component/reagent_clothing)
|
|
if(!clothing_component)
|
|
fail_message(user, "cannot imbue")
|
|
return
|
|
|
|
if(length(clothing_component.imbued_reagent))
|
|
fail_message(user, "already imbued")
|
|
return
|
|
|
|
if(!do_after(user, 10 SECONDS, target = src))
|
|
fail_message(user, "stopped imbuing")
|
|
return
|
|
|
|
for(var/datum/reagent/clothing_reagent as anything in attacking_clothing.reagents.reagent_list)
|
|
if(clothing_reagent.volume < MINIMUM_IMBUING_REAGENT_AMOUNT)
|
|
attacking_clothing.reagents.remove_reagent(clothing_reagent.type, include_subtypes = TRUE)
|
|
continue
|
|
|
|
clothing_component.imbued_reagent += clothing_reagent.type
|
|
attacking_clothing.name = "[clothing_reagent.name] [attacking_clothing.name]"
|
|
|
|
attacking_clothing.color = mix_color_from_reagents(attacking_clothing.reagents.reagent_list)
|
|
balloon_alert_to_viewers("imbued [attacking_clothing]")
|
|
user.mind.adjust_experience(/datum/skill/smithing, 60)
|
|
playsound(src, 'sound/effects/magic/demon_consume.ogg', 50, TRUE)
|
|
in_use = FALSE
|
|
return TRUE
|
|
|
|
/// Sets ceramic items from their unusable state into their finished form
|
|
/obj/structure/reagent_forge/proc/handle_ceramics(obj/attacking_item, mob/living/user)
|
|
in_use = TRUE
|
|
|
|
if(forge_temperature < MIN_FORGE_TEMP)
|
|
fail_message(user, "forge too cool")
|
|
return
|
|
|
|
var/obj/item/ceramic/ceramic_item = attacking_item
|
|
var/ceramic_speed = user.mind.get_skill_modifier(/datum/skill/production, SKILL_SPEED_MODIFIER) * BASELINE_ACTION_TIME
|
|
|
|
if(!ceramic_item.forge_item)
|
|
fail_message(user, "cannot set [ceramic_item]")
|
|
return
|
|
|
|
balloon_alert_to_viewers("setting [ceramic_item]")
|
|
|
|
if(!do_after(user, ceramic_speed, target = src))
|
|
fail_message("stopped setting [ceramic_item]")
|
|
return
|
|
|
|
balloon_alert(user, "finished setting [ceramic_item]")
|
|
var/obj/item/ceramic/spawned_ceramic = new ceramic_item.forge_item(get_turf(src))
|
|
user.mind.adjust_experience(/datum/skill/production, 50)
|
|
spawned_ceramic.color = ceramic_item.color
|
|
qdel(ceramic_item)
|
|
in_use = FALSE
|
|
|
|
/// Handles the creation of molten glass from glass sheets
|
|
/obj/structure/reagent_forge/proc/handle_glass_sheet_melting(obj/attacking_item, mob/living/user)
|
|
in_use = TRUE
|
|
|
|
if(forge_temperature < MIN_FORGE_TEMP)
|
|
fail_message(user, "forge too cool")
|
|
return
|
|
|
|
var/obj/item/stack/sheet/glass/glass_item = attacking_item
|
|
var/glassblowing_speed = user.mind.get_skill_modifier(/datum/skill/production, SKILL_SPEED_MODIFIER) * BASELINE_ACTION_TIME
|
|
var/glassblowing_amount = BASELINE_HEATING_DURATION / user.mind.get_skill_modifier(/datum/skill/production, SKILL_SPEED_MODIFIER)
|
|
|
|
balloon_alert_to_viewers("heating...")
|
|
|
|
if(!do_after(user, glassblowing_speed, target = src) || !glass_item.use(1))
|
|
fail_message(user, "stopped heating [glass_item]")
|
|
return
|
|
|
|
in_use = FALSE
|
|
var/obj/item/glassblowing/molten_glass/spawned_glass = new /obj/item/glassblowing/molten_glass(get_turf(src))
|
|
user.mind.adjust_experience(/datum/skill/production, 10)
|
|
COOLDOWN_START(spawned_glass, remaining_heat, glassblowing_amount)
|
|
spawned_glass.total_time = glassblowing_amount
|
|
|
|
/// Handles creating molten glass from a metal cup filled with sand
|
|
/obj/structure/reagent_forge/proc/handle_metal_cup_melting(obj/attacking_item, mob/living/user)
|
|
in_use = TRUE
|
|
|
|
if(forge_temperature < MIN_FORGE_TEMP)
|
|
fail_message(user, "forge too cool")
|
|
return
|
|
|
|
var/obj/item/glassblowing/metal_cup/metal_item = attacking_item
|
|
var/glassblowing_speed = user.mind.get_skill_modifier(/datum/skill/production, SKILL_SPEED_MODIFIER) * BASELINE_ACTION_TIME
|
|
var/glassblowing_amount = BASELINE_HEATING_DURATION / user.mind.get_skill_modifier(/datum/skill/production, SKILL_SPEED_MODIFIER)
|
|
|
|
if(!metal_item.has_sand)
|
|
fail_message(user, "[metal_item] has no sand")
|
|
return
|
|
|
|
balloon_alert_to_viewers("heating...")
|
|
|
|
if(!do_after(user, glassblowing_speed, target = src))
|
|
fail_message(user, "stopped heating [metal_item]")
|
|
return
|
|
|
|
in_use = FALSE
|
|
metal_item.has_sand = FALSE
|
|
metal_item.icon_state = "metal_cup_empty" // This should be handled a better way but presently this is how it works
|
|
var/obj/item/glassblowing/molten_glass/spawned_glass = new /obj/item/glassblowing/molten_glass(get_turf(src))
|
|
user.mind.adjust_experience(/datum/skill/production, 10)
|
|
COOLDOWN_START(spawned_glass, remaining_heat, glassblowing_amount)
|
|
spawned_glass.total_time = glassblowing_amount
|
|
|
|
/obj/structure/reagent_forge/billow_act(mob/living/user, obj/item/tool)
|
|
if(in_use) // Preventing billow use if the forge is in use to prevent spam
|
|
fail_message(user, "forge busy")
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
var/skill_modifier = user.mind.get_skill_modifier(/datum/skill/smithing, SKILL_SPEED_MODIFIER)
|
|
var/obj/item/forging/forge_item = tool
|
|
|
|
in_use = TRUE
|
|
|
|
if(!forge_fuel_strong && !forge_fuel_weak)
|
|
fail_message(user, "no fuel in [src]")
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
if(forge_temperature >= MAX_FORGE_TEMP)
|
|
fail_message(user, "[src] cannot heat further")
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
balloon_alert_to_viewers("billowing...")
|
|
|
|
while(forge_temperature < 91)
|
|
if(!do_after(user, skill_modifier * forge_item.toolspeed, target = src))
|
|
balloon_alert_to_viewers("stopped billowing")
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
forge_temperature += 10
|
|
user.mind.adjust_experience(/datum/skill/smithing, 5) // Billowing, like fueling, gives you some experience in forging
|
|
|
|
in_use = FALSE
|
|
balloon_alert(user, "successfully heated [src]")
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/structure/reagent_forge/tong_act(mob/living/user, obj/item/tool)
|
|
var/skill_modifier = user.mind.get_skill_modifier(/datum/skill/smithing, SKILL_SPEED_MODIFIER)
|
|
var/obj/item/forging/forge_item = tool
|
|
|
|
if(in_use || forge_item.in_use)
|
|
fail_message(user, "forge busy")
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
in_use = TRUE
|
|
forge_item.in_use = TRUE
|
|
|
|
if(forge_temperature < MIN_FORGE_TEMP)
|
|
fail_message(user, "forge too cool")
|
|
forge_item.in_use = FALSE
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
// Here we check the item used on us (tongs) for an incomplete forge item of some kind to heat
|
|
var/obj/item/forging/incomplete/search_incomplete = locate(/obj/item/forging/incomplete) in forge_item.contents
|
|
if(search_incomplete)
|
|
balloon_alert_to_viewers("heating [search_incomplete]")
|
|
|
|
if(!do_after(user, skill_modifier * forge_item.toolspeed, target = src))
|
|
balloon_alert_to_viewers("stopped heating [search_incomplete]")
|
|
forge_item.in_use = FALSE
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
COOLDOWN_START(search_incomplete, heating_remainder, FORGE_HEATING_DURATION)
|
|
in_use = FALSE
|
|
forge_item.in_use = FALSE
|
|
user.mind.adjust_experience(/datum/skill/smithing, 5) // Heating up forge items grants some experience
|
|
balloon_alert(user, "successfully heated [search_incomplete]")
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
// Here we check the item used on us (tongs) for a stack of some kind to create an object from
|
|
var/obj/item/stack/search_stack = locate(/obj/item/stack) in forge_item.contents
|
|
if(search_stack)
|
|
var/user_choice = show_radial_menu(user, src, radial_choice_list, radius = 38, require_near = TRUE, tooltips = TRUE)
|
|
if(!user_choice)
|
|
fail_message(user, "nothing chosen")
|
|
forge_item.in_use = FALSE
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
// Sets up a list of the materials to give to the item later
|
|
var/list/material_list = list()
|
|
|
|
if(search_stack.material_type)
|
|
material_list[SSmaterials.get_material(search_stack.material_type)] = SHEET_MATERIAL_AMOUNT
|
|
|
|
else
|
|
for(var/material in search_stack.custom_materials)
|
|
material_list[material] = SHEET_MATERIAL_AMOUNT
|
|
|
|
if(!search_stack.use(1))
|
|
fail_message(user, "not enough of [search_stack]")
|
|
forge_item.in_use = FALSE
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
balloon_alert_to_viewers("heating [search_stack]")
|
|
|
|
if(!do_after(user, skill_modifier * forge_item.toolspeed, target = src))
|
|
balloon_alert_to_viewers("stopped heating [search_stack]")
|
|
forge_item.in_use = FALSE
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
var/spawn_item = choice_list[user_choice]
|
|
var/obj/item/forging/incomplete/incomplete_item = new spawn_item(get_turf(src))
|
|
|
|
if(material_list)
|
|
incomplete_item.set_custom_materials(material_list)
|
|
|
|
COOLDOWN_START(incomplete_item, heating_remainder, FORGE_HEATING_DURATION)
|
|
in_use = FALSE
|
|
forge_item.in_use = FALSE
|
|
balloon_alert(user, "prepared [search_incomplete] into [user_choice]")
|
|
search_stack = locate(/obj/item/stack) in forge_item.contents
|
|
|
|
if(!search_stack)
|
|
forge_item.icon_state = "tong_empty"
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
in_use = FALSE
|
|
forge_item.in_use = FALSE
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/structure/reagent_forge/blowrod_act(mob/living/user, obj/item/tool)
|
|
var/obj/item/glassblowing/blowing_rod/blowing_item = tool
|
|
var/glassblowing_speed = user.mind.get_skill_modifier(/datum/skill/production, SKILL_SPEED_MODIFIER) * BASELINE_ACTION_TIME
|
|
var/glassblowing_amount = BASELINE_HEATING_DURATION / user.mind.get_skill_modifier(/datum/skill/production, SKILL_SPEED_MODIFIER)
|
|
|
|
if(in_use)
|
|
to_chat(user, span_warning("You cannot do multiple things at the same time!"))
|
|
return ITEM_INTERACT_SUCCESS
|
|
in_use = TRUE
|
|
|
|
if(forge_temperature < MIN_FORGE_TEMP)
|
|
fail_message(user, "The temperature is not hot enough to start heating [blowing_item].")
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
var/obj/item/glassblowing/molten_glass/find_glass = locate() in blowing_item.contents
|
|
if(!find_glass)
|
|
fail_message(user, "[blowing_item] does not have any glass to heat up.")
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
if(!COOLDOWN_FINISHED(find_glass, remaining_heat))
|
|
fail_message(user, "[find_glass] is still has remaining heat.")
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
to_chat(user, span_notice("You begin heating up [blowing_item]."))
|
|
|
|
if(!do_after(user, glassblowing_speed, target = src))
|
|
fail_message(user, "[blowing_item] is interrupted in its heating process.")
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
COOLDOWN_START(find_glass, remaining_heat, glassblowing_amount)
|
|
find_glass.total_time = glassblowing_amount
|
|
to_chat(user, span_notice("You finish heating up [blowing_item]."))
|
|
user.mind.adjust_experience(/datum/skill/smithing, 5)
|
|
user.mind.adjust_experience(/datum/skill/production, 10)
|
|
in_use = FALSE
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/structure/reagent_forge/wrench_act(mob/living/user, obj/item/tool)
|
|
tool.play_tool_sound(src)
|
|
deconstruct(TRUE)
|
|
return TRUE
|
|
|
|
/obj/structure/reagent_forge/atom_deconstruct(disassembled)
|
|
new /obj/item/stack/sheet/iron/ten(get_turf(src))
|
|
return ..()
|
|
|
|
/obj/structure/reagent_forge/tier2
|
|
forge_level = FORGE_LEVEL_NOVICE
|
|
|
|
/obj/structure/reagent_forge/tier3
|
|
forge_level = FORGE_LEVEL_APPRENTICE
|
|
|
|
/obj/structure/reagent_forge/tier4
|
|
forge_level = FORGE_LEVEL_JOURNEYMAN
|
|
|
|
/obj/structure/reagent_forge/tier5
|
|
forge_level = FORGE_LEVEL_EXPERT
|
|
|
|
/obj/structure/reagent_forge/tier6
|
|
forge_level = FORGE_LEVEL_MASTER
|
|
|
|
/obj/structure/reagent_forge/tier7
|
|
forge_level = FORGE_LEVEL_LEGENDARY
|
|
|
|
/obj/structure/reagent_forge/tier7/imbuing/Initialize(mapload)
|
|
. = ..()
|
|
create_reagent_forge()
|
|
|
|
/particles/smoke/mild
|
|
spawning = 1
|
|
velocity = list(0, 0.3, 0)
|
|
friction = 0.25
|
|
|
|
#undef BASELINE_ACTION_TIME
|
|
|
|
#undef BASELINE_HEATING_DURATION
|
|
|
|
#undef FORGE_DEFAULT_TEMPERATURE_CHANGE
|
|
#undef MAX_FORGE_TEMP
|
|
#undef MIN_FORGE_TEMP
|
|
#undef FORGE_HEATING_DURATION
|
|
|
|
#undef FORGE_LEVEL_YOU_PLAY_LIKE_A_NOOB
|
|
#undef FORGE_LEVEL_NOVICE
|
|
#undef FORGE_LEVEL_APPRENTICE
|
|
#undef FORGE_LEVEL_JOURNEYMAN
|
|
#undef FORGE_LEVEL_EXPERT
|
|
#undef FORGE_LEVEL_MASTER
|
|
#undef FORGE_LEVEL_LEGENDARY
|
|
|
|
#undef MAX_TEMPERATURE_LOSS_DECREASE
|
|
|
|
#undef CHARCOAL_CHANCE
|
|
|
|
#undef MINIMUM_IMBUING_REAGENT_AMOUNT
|
|
|
|
#undef SMOKE_STATE_NONE
|
|
#undef SMOKE_STATE_GOOD
|
|
#undef SMOKE_STATE_NEUTRAL
|
|
#undef SMOKE_STATE_BAD
|
|
#undef SMOKE_STATE_NOT_COOKING
|