mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2026-08-26 06:39:22 +01:00
Collapsing fireplace logic into bonfire.
This commit is contained in:
@@ -1,454 +0,0 @@
|
||||
/obj/structure/bonfire
|
||||
name = "bonfire"
|
||||
desc = "For grilling, broiling, charring, smoking, heating, roasting, toasting, simmering, searing, melting, and occasionally burning things."
|
||||
icon = 'icons/obj/structures.dmi'
|
||||
icon_state = "bonfire"
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
buckle_lying = FALSE
|
||||
layer = TURF_LAYER + 0.5 // We want it to layer underneath food and things on top of it.
|
||||
|
||||
var/burning = FALSE
|
||||
var/next_fuel_consumption = 0 // world.time of when next item in fuel list gets eatten to sustain the fire.
|
||||
var/grill = FALSE
|
||||
var/datum/material/material
|
||||
var/set_temperature = T0C + 30 //K
|
||||
var/heating_power = 80000
|
||||
var/datum/looping_sound/fire_crackles/fire_loop
|
||||
var/datum/looping_sound/grill/grill_loop // Used when food is cooking on the fire.
|
||||
|
||||
/obj/structure/bonfire/Initialize(var/ml, material_name)
|
||||
. = ..()
|
||||
fire_loop = new(list(src), FALSE)
|
||||
grill_loop = new(list(src), FALSE)
|
||||
if(!material_name)
|
||||
material_name = MAT_WOOD
|
||||
material = get_material_by_name("[material_name]")
|
||||
if(!material)
|
||||
qdel(src)
|
||||
return
|
||||
color = material.icon_colour
|
||||
|
||||
/obj/structure/bonfire/sifwood/Destroy()
|
||||
QDEL_NULL(fire_loop)
|
||||
QDEL_NULL(grill_loop)
|
||||
return ..()
|
||||
|
||||
// Blue wood.
|
||||
/obj/structure/bonfire/sifwood/Initialize(var/ml, material_name)
|
||||
. = ..(ml, MAT_SIFWOOD)
|
||||
|
||||
/obj/structure/bonfire/permanent/Initialize(var/ml, material_name)
|
||||
. = ..()
|
||||
ignite()
|
||||
|
||||
/obj/structure/bonfire/permanent/sifwood/Initialize(var/ml, material_name)
|
||||
. = ..(ml, MAT_SIFWOOD)
|
||||
|
||||
/obj/structure/bonfire/attackby(obj/item/W, mob/user)
|
||||
|
||||
// Place food on the grill.
|
||||
if(istype(W, /obj/item/reagent_containers/food/snacks) && grill)
|
||||
if(user.unEquip(W))
|
||||
W.dropInto(loc)
|
||||
// Place it on top of the grill.
|
||||
W.pixel_x = 0
|
||||
W.pixel_y = 12
|
||||
return TRUE
|
||||
|
||||
if(istype(W, /obj/item/stack/rods) && !can_buckle && !grill)
|
||||
var/obj/item/stack/rods/R = W
|
||||
var/choice = input(user, "What would you like to construct?", "Bonfire") as null|anything in list("Stake","Grill")
|
||||
if(!choice || user.incapacitated() || !Adjacent(user))
|
||||
return TRUE
|
||||
switch(choice)
|
||||
if("Stake")
|
||||
R.use(1)
|
||||
can_buckle = TRUE
|
||||
buckle_require_restraints = TRUE
|
||||
to_chat(user, "<span class='notice'>You add a rod to \the [src].</span>")
|
||||
var/mutable_appearance/rod_underlay = mutable_appearance('icons/obj/structures.dmi', "bonfire_rod")
|
||||
rod_underlay.pixel_y = 16
|
||||
rod_underlay.appearance_flags = RESET_COLOR | PIXEL_SCALE | TILE_BOUND | KEEP_APART
|
||||
underlays += rod_underlay
|
||||
if("Grill")
|
||||
R.use(1)
|
||||
grill = TRUE
|
||||
to_chat(user, "<span class='notice'>You add a grill to \the [src].</span>")
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
if(istype(W, /obj/item/stack/material/fuel/wood) || istype(W, /obj/item/stack/material/fuel/log) )
|
||||
add_fuel(W, user)
|
||||
return TRUE
|
||||
|
||||
if(W.is_hot())
|
||||
ignite()
|
||||
return TRUE
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/structure/bonfire/attack_hand(mob/user)
|
||||
if(has_buckled_mobs())
|
||||
return ..()
|
||||
|
||||
if(get_fuel_amount())
|
||||
remove_fuel(user)
|
||||
else
|
||||
dismantle(user)
|
||||
|
||||
|
||||
/obj/structure/bonfire/proc/dismantle(mob/user)
|
||||
if(!burning)
|
||||
user.visible_message("[user] starts dismantling \the [src].", "You start dismantling \the [src].")
|
||||
if(do_after(user, 5 SECONDS))
|
||||
for(var/i = 1 to 5)
|
||||
material.place_dismantled_product(get_turf(src))
|
||||
user.visible_message("[user] dismantles down \the [src].", "You dismantle \the [src].")
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>\The [src] is still burning. Extinguish it first if you want to dismantle it.</span>")
|
||||
|
||||
/obj/structure/bonfire/proc/get_fuel_amount()
|
||||
var/F = 0
|
||||
for(var/A in contents)
|
||||
if(istype(A, /obj/item/stack/material/fuel/wood))
|
||||
F += 0.5
|
||||
if(istype(A, /obj/item/stack/material/fuel/log))
|
||||
F += 1.0
|
||||
return F
|
||||
|
||||
/obj/structure/bonfire/permanent/get_fuel_amount()
|
||||
return 10
|
||||
|
||||
/obj/structure/bonfire/proc/remove_fuel(mob/user)
|
||||
if(get_fuel_amount())
|
||||
var/atom/movable/AM = pop(contents)
|
||||
AM.forceMove(get_turf(src))
|
||||
to_chat(user, "<span class='notice'>You take \the [AM] out of \the [src] before it has a chance to burn away.</span>")
|
||||
update_icon()
|
||||
|
||||
/obj/structure/bonfire/permanent/remove_fuel(mob/user)
|
||||
dismantle(user)
|
||||
|
||||
/obj/structure/bonfire/proc/add_fuel(atom/movable/new_fuel, mob/user)
|
||||
if(get_fuel_amount() >= 10)
|
||||
to_chat(user, "<span class='warning'>\The [src] already has enough fuel!</span>")
|
||||
return FALSE
|
||||
if(istype(new_fuel, /obj/item/stack/material/fuel/wood) || istype(new_fuel, /obj/item/stack/material/fuel/log) )
|
||||
var/obj/item/stack/F = new_fuel
|
||||
var/obj/item/stack/S = F.split(1)
|
||||
if(S)
|
||||
S.forceMove(src)
|
||||
to_chat(user, "<span class='warning'>You add \the [new_fuel] to \the [src].</span>")
|
||||
update_icon()
|
||||
return TRUE
|
||||
return FALSE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>\The [src] needs raw wood to burn, \a [new_fuel] won't work.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/structure/bonfire/permanent/add_fuel(mob/user)
|
||||
to_chat(user, "<span class='warning'>\The [src] has plenty of fuel and doesn't need more fuel.</span>")
|
||||
|
||||
/obj/structure/bonfire/proc/consume_fuel(var/obj/item/stack/consumed_fuel)
|
||||
if(!istype(consumed_fuel))
|
||||
qdel(consumed_fuel) // Don't know, don't care.
|
||||
return FALSE
|
||||
|
||||
if(istype(consumed_fuel, /obj/item/stack/material/fuel/log))
|
||||
next_fuel_consumption = world.time + 2 MINUTES
|
||||
qdel(consumed_fuel)
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
else if(istype(consumed_fuel, /obj/item/stack/material/fuel/wood)) // One log makes two planks of wood.
|
||||
next_fuel_consumption = world.time + 1 MINUTE
|
||||
qdel(consumed_fuel)
|
||||
update_icon()
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/structure/bonfire/permanent/consume_fuel()
|
||||
return TRUE
|
||||
|
||||
/obj/structure/bonfire/proc/check_oxygen()
|
||||
var/datum/gas_mixture/G = loc.return_air()
|
||||
if(G.gas["oxygen"] < 1)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/structure/bonfire/proc/extinguish()
|
||||
if(burning)
|
||||
burning = FALSE
|
||||
update_icon()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
visible_message("<span class='notice'>\The [src] stops burning.</span>")
|
||||
if(fire_loop?.started)
|
||||
fire_loop.stop(src)
|
||||
|
||||
/obj/structure/bonfire/proc/ignite()
|
||||
if(!burning && get_fuel_amount())
|
||||
burning = TRUE
|
||||
update_icon()
|
||||
START_PROCESSING(SSobj, src)
|
||||
visible_message("<span class='warning'>\The [src] starts burning!</span>")
|
||||
if(fire_loop && !fire_loop.started)
|
||||
fire_loop.start(src)
|
||||
|
||||
/obj/structure/bonfire/proc/burn()
|
||||
var/turf/current_location = get_turf(src)
|
||||
current_location.hotspot_expose(1000, 500)
|
||||
for(var/A in current_location)
|
||||
if(A == src)
|
||||
continue
|
||||
if(isobj(A))
|
||||
var/obj/O = A
|
||||
O.fire_act(null, 1000, 500)
|
||||
else if(isliving(A) && get_fuel_amount() > 4)
|
||||
var/mob/living/L = A
|
||||
L.adjust_fire_stacks(get_fuel_amount() / 4)
|
||||
L.IgniteMob()
|
||||
|
||||
/obj/structure/bonfire/update_icon()
|
||||
cut_overlays()
|
||||
if(burning)
|
||||
var/state
|
||||
switch(get_fuel_amount())
|
||||
if(0 to 4.5)
|
||||
state = "bonfire_warm"
|
||||
if(4.6 to 10)
|
||||
state = "bonfire_hot"
|
||||
var/image/I = image(icon, state)
|
||||
I.appearance_flags = RESET_COLOR | KEEP_APART
|
||||
add_overlay(I)
|
||||
|
||||
if(has_buckled_mobs() && get_fuel_amount() >= 5)
|
||||
I = image(icon, "bonfire_intense")
|
||||
I.pixel_y = 13
|
||||
I.layer = MOB_LAYER + 0.1
|
||||
I.appearance_flags = RESET_COLOR | KEEP_APART
|
||||
add_overlay(I)
|
||||
|
||||
var/light_strength = max(get_fuel_amount() / 2, 2)
|
||||
set_light(light_strength, light_strength, "#FF9933")
|
||||
else
|
||||
set_light(0)
|
||||
|
||||
if(grill)
|
||||
var/image/grille_image = image(icon, "bonfire_grill")
|
||||
grille_image.appearance_flags = RESET_COLOR | KEEP_APART
|
||||
add_overlay(grille_image)
|
||||
|
||||
/obj/structure/bonfire/process()
|
||||
if(!check_oxygen())
|
||||
extinguish()
|
||||
return
|
||||
if(world.time >= next_fuel_consumption)
|
||||
if(!consume_fuel(pop(contents)))
|
||||
extinguish()
|
||||
return
|
||||
|
||||
var/do_grill_sound = FALSE
|
||||
if(grill)
|
||||
for(var/obj/item/thing in view(2, src))
|
||||
if(thing.dry_out(src, 3 - get_dist(thing, src), (thing.loc == loc), silent = TRUE))
|
||||
do_grill_sound = TRUE
|
||||
else
|
||||
burn()
|
||||
|
||||
if(grill_loop)
|
||||
if(do_grill_sound)
|
||||
if(!grill_loop.started)
|
||||
grill_loop.start(src)
|
||||
else
|
||||
if(grill_loop.started)
|
||||
grill_loop.stop(src)
|
||||
|
||||
|
||||
if(!burning)
|
||||
return
|
||||
var/W = get_fuel_amount()
|
||||
if(W < 5)
|
||||
return
|
||||
var/datum/gas_mixture/env = loc.return_air()
|
||||
if(!env || abs(env.temperature - set_temperature) <= 0.1)
|
||||
return
|
||||
var/transfer_moles = 0.25 * env.total_moles
|
||||
var/datum/gas_mixture/removed = env.remove(transfer_moles)
|
||||
var/heat_transfer = removed?.get_thermal_energy_change(set_temperature)
|
||||
if(heat_transfer > 0)
|
||||
heat_transfer = min(heat_transfer, heating_power)
|
||||
removed.add_thermal_energy(heat_transfer)
|
||||
for(var/mob/living/L in view(3, src))
|
||||
L.add_modifier(/datum/modifier/endothermic, 10 SECONDS, null, TRUE)
|
||||
env.merge(removed)
|
||||
|
||||
/obj/structure/bonfire/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
ignite()
|
||||
|
||||
/obj/structure/bonfire/water_act(amount)
|
||||
if(prob(amount * 10))
|
||||
extinguish()
|
||||
|
||||
/obj/structure/bonfire/post_buckle_mob(mob/living/M)
|
||||
if(M.buckled == src) // Just buckled someone
|
||||
M.pixel_y += 13
|
||||
else // Just unbuckled someone
|
||||
M.pixel_y -= 13
|
||||
update_icon()
|
||||
|
||||
/obj/structure/fireplace //more like a space heater than a bonfire. A cozier alternative to both.
|
||||
name = "fireplace"
|
||||
desc = "The sound of the crackling hearth reminds you of home."
|
||||
icon = 'icons/obj/structures.dmi'
|
||||
icon_state = "fireplace"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
var/burning = FALSE
|
||||
var/next_fuel_consumption = 0
|
||||
var/set_temperature = T0C + 20 //K
|
||||
var/heating_power = 40000
|
||||
|
||||
/obj/structure/fireplace/attackby(obj/item/W, mob/user)
|
||||
if(istype(W, /obj/item/stack/material/fuel/wood) || istype(W, /obj/item/stack/material/fuel/log) )
|
||||
add_fuel(W, user)
|
||||
|
||||
else if(W.is_hot())
|
||||
ignite()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/fireplace/attack_hand(mob/user)
|
||||
if(get_fuel_amount())
|
||||
remove_fuel(user)
|
||||
|
||||
/obj/structure/fireplace/proc/get_fuel_amount()
|
||||
var/F = 0
|
||||
for(var/A in contents)
|
||||
if(istype(A, /obj/item/stack/material/fuel/wood))
|
||||
F += 0.5
|
||||
if(istype(A, /obj/item/stack/material/fuel/log))
|
||||
F += 1.0
|
||||
return F
|
||||
|
||||
/obj/structure/fireplace/proc/remove_fuel(mob/user)
|
||||
if(get_fuel_amount())
|
||||
var/atom/movable/AM = pop(contents)
|
||||
AM.forceMove(get_turf(src))
|
||||
to_chat(user, "<span class='notice'>You take \the [AM] out of \the [src] before it has a chance to burn away.</span>")
|
||||
update_icon()
|
||||
|
||||
/obj/structure/fireplace/proc/add_fuel(atom/movable/new_fuel, mob/user)
|
||||
if(get_fuel_amount() >= 10)
|
||||
to_chat(user, "<span class='warning'>\The [src] already has enough fuel!</span>")
|
||||
return FALSE
|
||||
if(istype(new_fuel, /obj/item/stack/material/fuel/wood) || istype(new_fuel, /obj/item/stack/material/fuel/log) )
|
||||
var/obj/item/stack/F = new_fuel
|
||||
var/obj/item/stack/S = F.split(1)
|
||||
if(S)
|
||||
S.forceMove(src)
|
||||
to_chat(user, "<span class='warning'>You add \the [new_fuel] to \the [src].</span>")
|
||||
update_icon()
|
||||
return TRUE
|
||||
return FALSE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>\The [src] needs raw wood to burn, \a [new_fuel] won't work.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/structure/fireplace/proc/consume_fuel(var/obj/item/stack/consumed_fuel)
|
||||
|
||||
if(!istype(consumed_fuel, /obj/item/stack/material/fuel))
|
||||
qdel(consumed_fuel) // Don't know, don't care.
|
||||
return FALSE
|
||||
|
||||
var/obj/item/stack/material/fuel/fuel_stack = consumed_fuel
|
||||
next_fuel_consumption = world.time + max(1 MINUTE, fuel_stack + bonfire_fuel_time)
|
||||
fuel_stack.use(1)
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/structure/fireplace/proc/check_oxygen()
|
||||
var/datum/gas_mixture/G = loc.return_air()
|
||||
if(G.gas["oxygen"] < 1)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/structure/fireplace/proc/extinguish()
|
||||
if(burning)
|
||||
burning = FALSE
|
||||
update_icon()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
visible_message("<span class='notice'>\The [src] stops burning.</span>")
|
||||
|
||||
/obj/structure/fireplace/proc/ignite()
|
||||
if(!burning && get_fuel_amount())
|
||||
burning = TRUE
|
||||
update_icon()
|
||||
START_PROCESSING(SSobj, src)
|
||||
visible_message("<span class='warning'>\The [src] starts burning!</span>")
|
||||
|
||||
/obj/structure/fireplace/proc/burn()
|
||||
var/turf/current_location = get_turf(src)
|
||||
current_location.hotspot_expose(1000, 500)
|
||||
for(var/A in current_location)
|
||||
if(A == src)
|
||||
continue
|
||||
if(isobj(A))
|
||||
var/obj/O = A
|
||||
O.fire_act(null, 1000, 500)
|
||||
|
||||
/obj/structure/fireplace/update_icon()
|
||||
cut_overlays()
|
||||
if(burning)
|
||||
var/state
|
||||
switch(get_fuel_amount())
|
||||
if(0 to 3.5)
|
||||
state = "fireplace_warm"
|
||||
if(3.6 to 6.5)
|
||||
state = "fireplace_hot"
|
||||
if(6.6 to 10)
|
||||
state = "fireplace_intense" //don't need to throw a corpse inside to make it burn hotter.
|
||||
var/image/I = image(icon, state)
|
||||
I.appearance_flags = RESET_COLOR | KEEP_APART
|
||||
add_overlay(I)
|
||||
|
||||
var/light_strength = max(get_fuel_amount() / 2, 2)
|
||||
set_light(light_strength, light_strength, "#FF9933")
|
||||
else
|
||||
set_light(0)
|
||||
|
||||
/obj/structure/fireplace/process()
|
||||
if(!check_oxygen())
|
||||
extinguish()
|
||||
return
|
||||
if(world.time >= next_fuel_consumption)
|
||||
if(!consume_fuel(pop(contents)))
|
||||
extinguish()
|
||||
return
|
||||
|
||||
if(burning)
|
||||
var/W = get_fuel_amount()
|
||||
if(W >= 5)
|
||||
var/datum/gas_mixture/env = loc.return_air()
|
||||
if(env && abs(env.temperature - set_temperature) > 0.1)
|
||||
var/transfer_moles = 0.25 * env.total_moles
|
||||
var/datum/gas_mixture/removed = env.remove(transfer_moles)
|
||||
|
||||
if(removed)
|
||||
var/heat_transfer = removed.get_thermal_energy_change(set_temperature)
|
||||
if(heat_transfer > 0)
|
||||
heat_transfer = min(heat_transfer , heating_power)
|
||||
|
||||
removed.add_thermal_energy(heat_transfer)
|
||||
|
||||
env.merge(removed)
|
||||
|
||||
/obj/structure/fireplace/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
ignite()
|
||||
|
||||
/obj/structure/fireplace/water_act(amount)
|
||||
if(prob(amount * 10))
|
||||
extinguish()
|
||||
@@ -603,3 +603,10 @@
|
||||
|
||||
/obj/structure/bed/chair/sofa/orange/corner
|
||||
icon_state = "sofacorner"
|
||||
|
||||
// Sivian wood subtype for mapping.
|
||||
/obj/structure/bed/chair/sifwood/Initialize(var/ml, var/newmaterial)
|
||||
. = ..(ml, MAT_SIFWOOD)
|
||||
|
||||
/obj/structure/bed/chair/sifwood/wings
|
||||
icon_state = "wooden_chair_wings"
|
||||
|
||||
@@ -0,0 +1,389 @@
|
||||
/obj/structure/wood_fire // abstract type, do not use
|
||||
|
||||
icon = 'icons/obj/wood_fire.dmi'
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
buckle_lying = FALSE
|
||||
layer = TURF_LAYER + 0.5 // We want it to layer underneath food and things on top of it.
|
||||
|
||||
var/base_icon_state = "bonfire"
|
||||
var/can_dismantle = TRUE
|
||||
var/burning = FALSE
|
||||
var/next_fuel_consumption = 0 // world.time of when next item in fuel list gets eatten to sustain the fire.
|
||||
var/grill = FALSE
|
||||
var/set_temperature = T0C + 30 //K
|
||||
var/heating_power = 80000
|
||||
var/datum/looping_sound/fire_crackles/fire_loop
|
||||
var/datum/looping_sound/grill/grill_loop // Used when food is cooking on the fire.
|
||||
|
||||
/obj/structure/wood_fire/Initialize()
|
||||
. = ..()
|
||||
fire_loop = new(list(src), FALSE)
|
||||
grill_loop = new(list(src), FALSE)
|
||||
|
||||
/obj/structure/wood_fire/Destroy()
|
||||
QDEL_NULL(fire_loop)
|
||||
QDEL_NULL(grill_loop)
|
||||
return ..()
|
||||
|
||||
/obj/structure/wood_fire/proc/get_upgrade_options()
|
||||
if(!grill)
|
||||
LAZYADD(., "Grill")
|
||||
else if(!can_buckle)
|
||||
LAZYADD(., "Stake")
|
||||
|
||||
/obj/structure/wood_fire/proc/try_build_feature(var/mob/user, var/obj/item/stack/rods/rods)
|
||||
if(!istype(rods))
|
||||
return FALSE
|
||||
|
||||
var/list/upgrade_options = get_upgrade_options()
|
||||
var/choice
|
||||
if(!length(upgrade_options))
|
||||
return FALSE
|
||||
|
||||
if(length(upgrade_options) == 1)
|
||||
choice = upgrade_options[1]
|
||||
else
|
||||
choice = input(user, "What would you like to construct?", "Constructing Grill") as null|anything in upgrade_options
|
||||
if(QDELETED(rods) || rods.get_amount() < 1 || user.incapacitated() || !Adjacent(user))
|
||||
return TRUE
|
||||
|
||||
switch(choice)
|
||||
if("Stake")
|
||||
rods.use(1)
|
||||
can_buckle = TRUE
|
||||
buckle_require_restraints = TRUE
|
||||
to_chat(user, SPAN_NOTICE("You add a rod to \the [src]."))
|
||||
if("Grill")
|
||||
rods.use(1)
|
||||
grill = TRUE
|
||||
to_chat(user, SPAN_NOTICE("You add a grill to \the [src]."))
|
||||
else
|
||||
return TRUE
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
/obj/structure/wood_fire/attackby(obj/item/W, mob/user)
|
||||
|
||||
// Place food on the grill.
|
||||
if(istype(W, /obj/item/reagent_containers/food/snacks) && grill)
|
||||
if(user.unEquip(W))
|
||||
W.dropInto(loc)
|
||||
// Place it on top of the grill.
|
||||
W.pixel_x = 0
|
||||
W.pixel_y = 12
|
||||
return TRUE
|
||||
|
||||
if(try_build_feature(user, W))
|
||||
return TRUE
|
||||
|
||||
if(istype(W, /obj/item/stack/material/fuel))
|
||||
add_fuel(W, user)
|
||||
return TRUE
|
||||
|
||||
if(W.is_hot())
|
||||
ignite()
|
||||
return TRUE
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/structure/wood_fire/attack_hand(mob/user)
|
||||
if(!has_buckled_mobs())
|
||||
if(get_fuel_amount())
|
||||
remove_fuel(user)
|
||||
return TRUE
|
||||
if(can_dismantle)
|
||||
dismantle(user)
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/obj/structure/wood_fire/proc/dismantle(mob/user)
|
||||
if(!burning)
|
||||
user.visible_message("[user] starts dismantling \the [src].", "You start dismantling \the [src].")
|
||||
if(do_after(user, 5 SECONDS))
|
||||
for(var/obj/item/thing in contents)
|
||||
thing.dropInto(loc)
|
||||
user.visible_message("[user] dismantles down \the [src].", "You dismantle \the [src].")
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, SPAN_WARNING("\The [src] is still burning. Extinguish it first if you want to dismantle it."))
|
||||
|
||||
/obj/structure/wood_fire/proc/get_fuel_amount()
|
||||
. = 0
|
||||
for(var/obj/item/stack/material/fuel/fuel in contents)
|
||||
. += (fuel.amount * fuel.bonfire_fuel_time) / (2 MINUTES)
|
||||
|
||||
/obj/structure/wood_fire/proc/remove_fuel(mob/user)
|
||||
if(!get_fuel_amount())
|
||||
return
|
||||
var/atom/movable/AM = pop(contents)
|
||||
if(!istype(AM))
|
||||
return
|
||||
AM.forceMove(get_turf(src))
|
||||
to_chat(user, SPAN_NOTICE("You take \the [AM] out of \the [src] before it has a chance to burn away."))
|
||||
update_icon()
|
||||
|
||||
/obj/structure/wood_fire/proc/add_fuel(atom/movable/new_fuel, mob/user)
|
||||
if(get_fuel_amount() >= 10)
|
||||
to_chat(user, SPAN_WARNING("\The [src] already has enough fuel!"))
|
||||
return FALSE
|
||||
if(istype(new_fuel, /obj/item/stack/material/fuel/wood) || istype(new_fuel, /obj/item/stack/material/fuel/log) )
|
||||
var/obj/item/stack/F = new_fuel
|
||||
var/obj/item/stack/S = F.split(1)
|
||||
if(S)
|
||||
S.forceMove(src)
|
||||
to_chat(user, SPAN_WARNING("You add \the [new_fuel] to \the [src]."))
|
||||
update_icon()
|
||||
return TRUE
|
||||
return FALSE
|
||||
else
|
||||
to_chat(user, SPAN_WARNING("\The [src] needs raw wood to burn, \a [new_fuel] won't work."))
|
||||
return FALSE
|
||||
|
||||
/obj/structure/wood_fire/proc/consume_fuel()
|
||||
var/obj/item/stack/consumed_fuel
|
||||
for(var/atom/movable/thing in contents)
|
||||
if(!thing.simulated)
|
||||
continue
|
||||
consumed_fuel = thing
|
||||
break
|
||||
if(!istype(consumed_fuel, /obj/item/stack/material/fuel))
|
||||
if(consumed_fuel)
|
||||
qdel(consumed_fuel) // Don't know, don't care.
|
||||
return FALSE
|
||||
var/obj/item/stack/material/fuel/fuel_stack = consumed_fuel
|
||||
next_fuel_consumption = world.time + max(1 MINUTE, fuel_stack.bonfire_fuel_time)
|
||||
fuel_stack.use(1)
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
/obj/structure/wood_fire/proc/extinguish()
|
||||
if(!burning)
|
||||
return
|
||||
burning = FALSE
|
||||
update_icon()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
visible_message(SPAN_NOTICE("\The [src] stops burning."))
|
||||
if(fire_loop?.started)
|
||||
fire_loop.stop(src)
|
||||
|
||||
/obj/structure/wood_fire/proc/ignite()
|
||||
if(burning || !get_fuel_amount())
|
||||
return
|
||||
burning = TRUE
|
||||
update_icon()
|
||||
START_PROCESSING(SSobj, src)
|
||||
visible_message(SPAN_NOTICE("\The [src] starts burning!"))
|
||||
if(fire_loop && !fire_loop.started)
|
||||
fire_loop.start(src)
|
||||
|
||||
/obj/structure/wood_fire/proc/get_fuel_overlay(var/fuel_amount)
|
||||
if(fuel_amount)
|
||||
var/image/I = image(icon, "[base_icon_state]_fuelled")
|
||||
I.appearance_flags = RESET_COLOR | KEEP_APART
|
||||
var/obj/item/stack/material/fuel/fuel = locate() in contents
|
||||
I.color = fuel?.material?.icon_colour
|
||||
return I
|
||||
|
||||
/obj/structure/wood_fire/update_icon()
|
||||
|
||||
cut_overlays()
|
||||
|
||||
// Draw our fuel overlay and colour it based on fuel material.
|
||||
var/fuel_amount = get_fuel_amount()
|
||||
var/fuel_overlay = get_fuel_overlay(fuel_amount)
|
||||
if(fuel_overlay)
|
||||
if(islist(fuel_overlay))
|
||||
for(var/overlay in fuel_overlay)
|
||||
add_overlay(overlay)
|
||||
else
|
||||
add_overlay(fuel_overlay)
|
||||
|
||||
if(burning)
|
||||
|
||||
// Draw our actual fire icon.
|
||||
var/fire_state
|
||||
if(fuel_amount >= 10)
|
||||
fire_state = "[base_icon_state]_intense"
|
||||
else if(fuel_amount >= 5)
|
||||
fire_state = "[base_icon_state]_hot"
|
||||
else
|
||||
fire_state = "[base_icon_state]_warm"
|
||||
var/image/I = image(icon, fire_state)
|
||||
I.appearance_flags = RESET_COLOR | KEEP_APART
|
||||
add_overlay(I)
|
||||
|
||||
// If we're capable of burning buckled mobs (usually via a stake),
|
||||
// draw a second intense fire overlay and offset it to cover the mob.
|
||||
if(fire_is_burning_mobs())
|
||||
I = image(icon, "[base_icon_state]_intense")
|
||||
I.pixel_y = 13
|
||||
I.layer = MOB_LAYER + 0.1
|
||||
I.appearance_flags = RESET_COLOR | KEEP_APART
|
||||
add_overlay(I)
|
||||
|
||||
// Update our lights.
|
||||
var/light_strength = max(fuel_amount / 2, 2)
|
||||
set_light(light_strength, light_strength, COLOR_FIRE_ORANGE)
|
||||
else
|
||||
set_light(0)
|
||||
|
||||
if(grill)
|
||||
var/image/grille_image = image(icon, "[base_icon_state]_grill")
|
||||
grille_image.appearance_flags = RESET_COLOR | KEEP_APART
|
||||
add_overlay(grille_image)
|
||||
|
||||
underlays.Cut()
|
||||
if(can_buckle)
|
||||
var/mutable_appearance/rod_underlay = mutable_appearance('icons/obj/structures.dmi', "[base_icon_state]_rod")
|
||||
rod_underlay.pixel_y = 16
|
||||
rod_underlay.appearance_flags = RESET_COLOR | PIXEL_SCALE | TILE_BOUND | KEEP_APART
|
||||
underlays += rod_underlay
|
||||
|
||||
|
||||
/obj/structure/wood_fire/proc/fire_is_burning_mobs()
|
||||
return has_buckled_mobs() && get_fuel_amount() >= 5
|
||||
|
||||
/obj/structure/wood_fire/process()
|
||||
|
||||
// Are we even alight?
|
||||
if(!burning)
|
||||
return
|
||||
|
||||
// Should we even be alight?
|
||||
var/datum/gas_mixture/env = loc?.return_air()
|
||||
if(env?.gas["oxygen"] < 1 || (world.time >= next_fuel_consumption && !consume_fuel()))
|
||||
extinguish()
|
||||
return
|
||||
|
||||
// Ignite anything sitting on the same turf as us.
|
||||
if(isturf(loc))
|
||||
var/turf/current_turf = loc
|
||||
current_turf.hotspot_expose(1000, 500)
|
||||
|
||||
// See if we can dry out anything around us, or cook any food.
|
||||
var/grilling = FALSE
|
||||
for(var/obj/item/thing in view(2, src))
|
||||
var/on_top_of_fire = thing.loc == loc
|
||||
if(on_top_of_fire)
|
||||
if(!grilling && istype(thing, /obj/item/reagent_containers/food/snacks))
|
||||
grilling = TRUE
|
||||
if(!grill)
|
||||
thing.fire_act(null, 1000, 500)
|
||||
continue
|
||||
thing.dry_out(src, max(1, 3 - get_dist(thing, src)), on_top_of_fire)
|
||||
|
||||
// If we're cooking food, play a food cooking souond.
|
||||
if(grilling)
|
||||
if(grill_loop)
|
||||
if(locate(/obj/item/reagent_containers/food/snacks) in contents)
|
||||
if(!grill_loop.started)
|
||||
grill_loop.start(src)
|
||||
else
|
||||
if(grill_loop.started)
|
||||
grill_loop.stop(src)
|
||||
|
||||
// If we're low enough, don't burn anything or put out
|
||||
// any significant heat, they need to refuel the fire.
|
||||
var/fuel_amount = get_fuel_amount()
|
||||
if(fuel_amount < 5)
|
||||
return
|
||||
|
||||
// Burn anything standing on our turf.
|
||||
var/adj_fuel_amount = fuel_amount / 4
|
||||
for(var/mob/living/victim in loc)
|
||||
victim.adjust_fire_stacks(adj_fuel_amount / 4)
|
||||
victim.IgniteMob()
|
||||
|
||||
// Heat up our environment.
|
||||
if(!env || abs(env.temperature - set_temperature) <= 0.1)
|
||||
return
|
||||
var/transfer_moles = 0.25 * env.total_moles
|
||||
var/datum/gas_mixture/removed = env.remove(transfer_moles)
|
||||
var/heat_transfer = removed?.get_thermal_energy_change(set_temperature)
|
||||
if(heat_transfer > 0)
|
||||
heat_transfer = min(heat_transfer, heating_power)
|
||||
removed.add_thermal_energy(heat_transfer)
|
||||
for(var/mob/living/L in view(3, src))
|
||||
L.add_modifier(/datum/modifier/endothermic, 10 SECONDS, null, TRUE)
|
||||
env.merge(removed)
|
||||
|
||||
/obj/structure/wood_fire/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
ignite()
|
||||
|
||||
/obj/structure/wood_fire/water_act(amount)
|
||||
if(prob(amount * 10))
|
||||
extinguish()
|
||||
|
||||
/obj/structure/wood_fire/post_buckle_mob(mob/living/M)
|
||||
if(M.buckled == src) // Just buckled someone
|
||||
M.pixel_y += 13
|
||||
else // Just unbuckled someone
|
||||
M.pixel_y -= 13
|
||||
update_icon()
|
||||
|
||||
// A freestanding fire for cooking food on.
|
||||
/obj/structure/wood_fire/bonfire
|
||||
name = "bonfire"
|
||||
desc = "For grilling, broiling, charring, smoking, heating, roasting, toasting, simmering, searing, melting, and occasionally burning things."
|
||||
icon_state = "bonfire"
|
||||
|
||||
// Pre-fuelled for recipes/maps.
|
||||
/obj/structure/wood_fire/bonfire/fuelled/Initialize()
|
||||
. = ..()
|
||||
for(var/i = 1 to 5)
|
||||
new /obj/item/stack/material/fuel/log(src)
|
||||
update_icon()
|
||||
|
||||
// Blue wood.
|
||||
/obj/structure/wood_fire/bonfire/sifwood/Initialize()
|
||||
. = ..()
|
||||
for(var/i = 1 to 5)
|
||||
new /obj/item/stack/material/fuel/log/sif(src)
|
||||
update_icon()
|
||||
|
||||
// A smaller bonfire.
|
||||
/obj/structure/wood_fire/campfire
|
||||
name = "campfire"
|
||||
desc = "A small firepit for camping. Did anyone bring the marshmallows?"
|
||||
icon_state = "campfire"
|
||||
base_icon_state = "campfire"
|
||||
can_dismantle = FALSE
|
||||
can_buckle = FALSE
|
||||
set_temperature = T0C + 20 //K
|
||||
heating_power = 40000
|
||||
|
||||
/obj/structure/wood_fire/campfire/get_upgrade_options()
|
||||
if(!grill)
|
||||
return list("Grill")
|
||||
|
||||
// more like a space heater than a bonfire. A cozier alternative to both.
|
||||
/obj/structure/wood_fire/fireplace
|
||||
name = "fireplace"
|
||||
desc = "The sound of the crackling hearth reminds you of home."
|
||||
icon_state = "fireplace"
|
||||
base_icon_state = "fireplace"
|
||||
density = TRUE
|
||||
set_temperature = T0C + 20 //K
|
||||
heating_power = 40000
|
||||
can_dismantle = FALSE
|
||||
can_buckle = FALSE
|
||||
grill = TRUE
|
||||
|
||||
/obj/structure/wood_fire/fireplace/get_upgrade_options()
|
||||
if(!grill)
|
||||
return list("Grill")
|
||||
|
||||
/obj/structure/wood_fire/fireplace/stove
|
||||
name = "stove"
|
||||
desc = "A rustic, soot-stained wood-fired stove. Better check your CO detector."
|
||||
grill = FALSE
|
||||
icon_state = "stove"
|
||||
base_icon_state = "stove"
|
||||
|
||||
/obj/structure/wood_fire/fireplace/stove/get_upgrade_options()
|
||||
return
|
||||
|
||||
/obj/structure/wood_fire/fireplace/stove/get_fuel_overlay(var/fuel_amount)
|
||||
. = ..()
|
||||
LAZYADD(., "[base_icon_state]_cover")
|
||||
Reference in New Issue
Block a user