allows for deconstruction of kitchen appliances

should also hopefully allow for kitchen appliances to be upgraded
This commit is contained in:
MeepleMuncher
2022-09-14 15:14:44 +03:00
committed by GitHub
parent bc2886f4c5
commit dcc780f36e
7 changed files with 519 additions and 464 deletions

View File

@@ -42,3 +42,12 @@
/obj/machinery/appliance/mixer/candy/change_product_appearance(var/obj/item/weapon/reagent_containers/food/snacks/product)
food_color = get_random_colour(1)
. = ..()
/obj/machinery/appliance/mixer/candy/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(default_deconstruction_screwdriver(user, O)) //CHOMPedit - Allows for deconstruction
return
if(default_deconstruction_crowbar(user, O))
return
if(default_part_replacement(user, O))
return

View File

@@ -84,3 +84,12 @@
result.color = result.filling_color
for (var/i in images)
result.overlays += images[i]
/obj/machinery/appliance/mixer/cereal/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(default_deconstruction_screwdriver(user, O)) //CHOMPedit - Allows for deconstruction
return
if(default_deconstruction_crowbar(user, O))
return
if(default_part_replacement(user, O))
return

View File

@@ -1,269 +1,275 @@
/obj/machinery/appliance/cooker/fryer
name = "deep fryer"
desc = "Deep fried <i>everything</i>."
icon_state = "fryer_off"
can_cook_mobs = 1
cook_type = "deep fried"
on_icon = "fryer_on"
off_icon = "fryer_off"
food_color = "#FFAD33"
cooked_sound = 'sound/machines/ding.ogg'
var/datum/looping_sound/deep_fryer/fry_loop
circuit = /obj/item/weapon/circuitboard/fryer
appliancetype = FRYER
active_power_usage = 12 KILOWATTS
heating_power = 12 KILOWATTS
light_y = 15
min_temp = 140 + T0C // Same as above, increasing this to just under 2x to make the % increase on efficiency not quite so painful as it would be at 80.
optimal_temp = 400 + T0C // Increasing this to be 2x Oven to allow for a much higher/realistic frying temperatures. Doesn't really do anything but make heating the fryer take a bit longer.
optimal_power = 0.95 // .35 higher than the default to give fryers faster cooking speed.
idle_power_usage = 3.6 KILOWATTS
// Power used to maintain temperature once it's heated.
// Going with 25% of the active power. This is a somewhat arbitrary value.
resistance = 10 KILOWATTS // Approx. 10 minutes to heat up.
max_contents = 2
container_type = /obj/item/weapon/reagent_containers/cooking_container/fryer
stat = POWEROFF // Starts turned off
var/datum/reagents/oil
var/optimal_oil = 9000 //90 litres of cooking oil
/obj/machinery/appliance/cooker/fryer/Initialize()
. = ..()
fry_loop = new(list(src), FALSE)
oil = new/datum/reagents(optimal_oil * 1.25, src)
var/variance = rand()*0.15
// Fryer is always a little below full, but its usually negligible
if(prob(20))
// Sometimes the fryer will start with much less than full oil, significantly impacting efficiency until filled
variance = rand()*0.5
oil.add_reagent("cookingoil", optimal_oil*(1 - variance))
/obj/machinery/appliance/cooker/fryer/Destroy()
QDEL_NULL(fry_loop)
QDEL_NULL(oil)
return ..()
/obj/machinery/appliance/cooker/fryer/examine(var/mob/user)
. = ..()
if(Adjacent(user))
to_chat(user, "Oil Level: [oil.total_volume]/[optimal_oil]")
/obj/machinery/appliance/cooker/fryer/update_icon() // We add our own version of the proc to use the special fryer double-lights.
cut_overlays()
var/image/light
if(use_power == 1 && !stat)
light = image(icon, "fryer_light_idle")
else if(use_power == 2 && !stat)
light = image(icon, "fryer_light_preheating")
else
light = image(icon, "fryer_light_off")
light.pixel_x = light_x
light.pixel_y = light_y
add_overlay(light)
/obj/machinery/appliance/cooker/fryer/heat_up()
if (..())
//Set temperature of oil reagent
var/datum/reagent/nutriment/triglyceride/oil/OL = oil.get_master_reagent()
if (OL && istype(OL))
OL.data["temperature"] = temperature
/obj/machinery/appliance/cooker/fryer/equalize_temperature()
if (..())
//Set temperature of oil reagent
var/datum/reagent/nutriment/triglyceride/oil/OL = oil.get_master_reagent()
if (OL && istype(OL))
OL.data["temperature"] = temperature
/obj/machinery/appliance/cooker/fryer/update_cooking_power()
..()//In addition to parent temperature calculation
//Fryer efficiency also drops when oil levels arent optimal
var/oil_level = 0
var/datum/reagent/nutriment/triglyceride/oil/OL = oil.get_master_reagent()
if(OL && istype(OL))
oil_level = OL.volume
var/oil_efficiency = 0
if(oil_level)
oil_efficiency = oil_level / optimal_oil
if(oil_efficiency > 1)
//We're above optimal, efficiency goes down as we pass too much over it
oil_efficiency = 1 - (oil_efficiency - 1)
cooking_power *= oil_efficiency
/obj/machinery/appliance/cooker/fryer/update_icon()
if(!stat)
..()
if(cooking == TRUE)
icon_state = on_icon
if(fry_loop)
fry_loop.start(src)
else
icon_state = off_icon
if(fry_loop)
fry_loop.stop(src)
else
icon_state = off_icon
if(fry_loop)
fry_loop.stop(src)
..()
//Fryer gradually infuses any cooked food with oil. Moar calories
//This causes a slow drop in oil levels, encouraging refill after extended use
/obj/machinery/appliance/cooker/fryer/do_cooking_tick(var/datum/cooking_item/CI)
if(..() && (CI.oil < CI.max_oil) && prob(20))
var/datum/reagents/buffer = new /datum/reagents(2)
oil.trans_to_holder(buffer, min(0.5, CI.max_oil - CI.oil))
CI.oil += buffer.total_volume
CI.container.soak_reagent(buffer)
//To solve any odd logic problems with results having oil as part of their compiletime ingredients.
//Upon finishing a recipe the fryer will analyse any oils in the result, and replace them with our oil
//As well as capping the total to the max oil
/obj/machinery/appliance/cooker/fryer/finish_cooking(var/datum/cooking_item/CI)
..()
var/total_oil = 0
var/total_our_oil = 0
var/total_removed = 0
var/datum/reagent/our_oil = oil.get_master_reagent()
for (var/obj/item/I in CI.container)
if (I.reagents && I.reagents.total_volume)
for (var/datum/reagent/R in I.reagents.reagent_list)
if (istype(R, /datum/reagent/nutriment/triglyceride/oil))
total_oil += R.volume
if (R.id != our_oil.id)
total_removed += R.volume
I.reagents.remove_reagent(R.id, R.volume)
else
total_our_oil += R.volume
if (total_removed > 0 || total_oil != CI.max_oil)
total_oil = min(total_oil, CI.max_oil)
if (total_our_oil < total_oil)
//If we have less than the combined total, then top up from our reservoir
var/datum/reagents/buffer = new /datum/reagents(INFINITY)
oil.trans_to_holder(buffer, total_oil - total_our_oil)
CI.container.soak_reagent(buffer)
else if (total_our_oil > total_oil)
//If we have more than the maximum allowed then we delete some.
//This could only happen if one of the objects spawns with the same type of oil as ours
var/portion = 1 - (total_oil / total_our_oil) //find the percentage to remove
for (var/obj/item/I in CI.container)
if (I.reagents && I.reagents.total_volume)
for (var/datum/reagent/R in I.reagents.reagent_list)
if (R.id == our_oil.id)
I.reagents.remove_reagent(R.id, R.volume*portion)
/obj/machinery/appliance/cooker/fryer/cook_mob(var/mob/living/victim, var/mob/user)
if(!istype(victim))
return
// user.visible_message("<span class='danger'>\The [user] starts pushing \the [victim] into \the [src]!</span>")
//Removed delay on this action in favour of a cooldown after it
//If you can lure someone close to the fryer and grab them then you deserve success.
//And a delay on this kind of niche action just ensures it never happens
//Cooldown ensures it can't be spammed to instakill someone
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN*3)
fry_loop.start(src)
if(!do_mob(user, victim, 20))
cooking = FALSE
icon_state = off_icon
fry_loop.stop(src)
return
if(!victim || !victim.Adjacent(user))
to_chat(user, "<span class='danger'>Your victim slipped free!</span>")
cooking = FALSE
icon_state = off_icon
fry_loop.stop(src)
return
var/damage = rand(7,13) // Though this damage seems reduced, some hot oil is transferred to the victim and will burn them for a while after
var/datum/reagent/nutriment/triglyceride/oil/OL = oil.get_master_reagent()
damage *= OL.heatdamage(victim)
var/obj/item/organ/external/E
var/nopain
if(ishuman(victim) && user.zone_sel.selecting != BP_GROIN && user.zone_sel.selecting != BP_TORSO)
var/mob/living/carbon/human/H = victim
E = H.get_organ(user.zone_sel.selecting)
if(!E || E.species.flags & NO_PAIN)
nopain = 2
else if(E.robotic >= ORGAN_ROBOT)
nopain = 1
user.visible_message("<span class='danger'>\The [user] shoves \the [victim][E ? "'s [E.name]" : ""] into \the [src]!</span>")
if (damage > 0)
if(E)
if(E.children && E.children.len)
for(var/obj/item/organ/external/child in E.children)
if(nopain && nopain < 2 && !(child.robotic >= ORGAN_ROBOT))
nopain = 0
child.take_damage(0, damage)
damage -= (damage*0.5)//IF someone's arm is plunged in, the hand should take most of it
E.take_damage(0, damage)
else
victim.apply_damage(damage, BURN, user.zone_sel.selecting)
if(!nopain)
to_chat(victim, "<span class='danger'>Agony consumes you as searing hot oil scorches your [E ? E.name : "flesh"] horribly!</span>")
victim.emote("scream")
else
to_chat(victim, "<span class='danger'>Searing hot oil scorches your [E ? E.name : "flesh"]!</span>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Has [cook_type] \the [victim] ([victim.ckey]) in \a [src]</font>")
victim.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been [cook_type] in \a [src] by [user.name] ([user.ckey])</font>")
msg_admin_attack("[key_name_admin(user)] [cook_type] \the [victim] ([victim.ckey]) in \a [src]. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
//Coat the victim in some oil
oil.trans_to(victim, 40)
fry_loop.stop()
/obj/machinery/appliance/cooker/fryer/attackby(var/obj/item/I, var/mob/user)
if(istype(I, /obj/item/weapon/reagent_containers/glass) && I.reagents)
if (I.reagents.total_volume <= 0 && oil)
//Its empty, handle scooping some hot oil out of the fryer
oil.trans_to(I, I.reagents.maximum_volume)
user.visible_message("[user] scoops some oil out of \the [src].", span("notice","You scoop some oil out of \the [src]."))
return 1
else
//It contains stuff, handle pouring any oil into the fryer
//Possibly in future allow pouring non-oil reagents in, in order to sabotage it and poison food.
//That would really require coding some sort of filter or better replacement mechanism first
//So for now, restrict to oil only
var/amount = 0
for (var/datum/reagent/R in I.reagents.reagent_list)
if (istype(R, /datum/reagent/nutriment/triglyceride/oil))
var/delta = oil.get_free_space()
delta = min(delta, R.volume)
oil.add_reagent(R.id, delta)
I.reagents.remove_reagent(R.id, delta)
amount += delta
if (amount > 0)
user.visible_message("[user] pours some oil into \the [src].", span("notice","You pour [amount]u of oil into \the [src]."), "<span class='notice'>You hear something viscous being poured into a metal container.</span>")
return 1
//If neither of the above returned, then call parent as normal
..()
/obj/machinery/appliance/cooker/fryer
name = "deep fryer"
desc = "Deep fried <i>everything</i>."
icon_state = "fryer_off"
can_cook_mobs = 1
cook_type = "deep fried"
on_icon = "fryer_on"
off_icon = "fryer_off"
food_color = "#FFAD33"
cooked_sound = 'sound/machines/ding.ogg'
var/datum/looping_sound/deep_fryer/fry_loop
circuit = /obj/item/weapon/circuitboard/fryer
appliancetype = FRYER
active_power_usage = 12 KILOWATTS
heating_power = 12 KILOWATTS
light_y = 15
min_temp = 140 + T0C // Same as above, increasing this to just under 2x to make the % increase on efficiency not quite so painful as it would be at 80.
optimal_temp = 400 + T0C // Increasing this to be 2x Oven to allow for a much higher/realistic frying temperatures. Doesn't really do anything but make heating the fryer take a bit longer.
optimal_power = 0.95 // .35 higher than the default to give fryers faster cooking speed.
idle_power_usage = 3.6 KILOWATTS
// Power used to maintain temperature once it's heated.
// Going with 25% of the active power. This is a somewhat arbitrary value.
resistance = 10 KILOWATTS // Approx. 10 minutes to heat up.
max_contents = 2
container_type = /obj/item/weapon/reagent_containers/cooking_container/fryer
stat = POWEROFF // Starts turned off
var/datum/reagents/oil
var/optimal_oil = 9000 //90 litres of cooking oil
/obj/machinery/appliance/cooker/fryer/Initialize()
. = ..()
fry_loop = new(list(src), FALSE)
oil = new/datum/reagents(optimal_oil * 1.25, src)
var/variance = rand()*0.15
// Fryer is always a little below full, but its usually negligible
if(prob(20))
// Sometimes the fryer will start with much less than full oil, significantly impacting efficiency until filled
variance = rand()*0.5
oil.add_reagent("cookingoil", optimal_oil*(1 - variance))
/obj/machinery/appliance/cooker/fryer/Destroy()
QDEL_NULL(fry_loop)
QDEL_NULL(oil)
return ..()
/obj/machinery/appliance/cooker/fryer/examine(var/mob/user)
. = ..()
if(Adjacent(user))
to_chat(user, "Oil Level: [oil.total_volume]/[optimal_oil]")
/obj/machinery/appliance/cooker/fryer/update_icon() // We add our own version of the proc to use the special fryer double-lights.
cut_overlays()
var/image/light
if(use_power == 1 && !stat)
light = image(icon, "fryer_light_idle")
else if(use_power == 2 && !stat)
light = image(icon, "fryer_light_preheating")
else
light = image(icon, "fryer_light_off")
light.pixel_x = light_x
light.pixel_y = light_y
add_overlay(light)
/obj/machinery/appliance/cooker/fryer/heat_up()
if (..())
//Set temperature of oil reagent
var/datum/reagent/nutriment/triglyceride/oil/OL = oil.get_master_reagent()
if (OL && istype(OL))
OL.data["temperature"] = temperature
/obj/machinery/appliance/cooker/fryer/equalize_temperature()
if (..())
//Set temperature of oil reagent
var/datum/reagent/nutriment/triglyceride/oil/OL = oil.get_master_reagent()
if (OL && istype(OL))
OL.data["temperature"] = temperature
/obj/machinery/appliance/cooker/fryer/update_cooking_power()
..()//In addition to parent temperature calculation
//Fryer efficiency also drops when oil levels arent optimal
var/oil_level = 0
var/datum/reagent/nutriment/triglyceride/oil/OL = oil.get_master_reagent()
if(OL && istype(OL))
oil_level = OL.volume
var/oil_efficiency = 0
if(oil_level)
oil_efficiency = oil_level / optimal_oil
if(oil_efficiency > 1)
//We're above optimal, efficiency goes down as we pass too much over it
oil_efficiency = 1 - (oil_efficiency - 1)
cooking_power *= oil_efficiency
/obj/machinery/appliance/cooker/fryer/update_icon()
if(!stat)
..()
if(cooking == TRUE)
icon_state = on_icon
if(fry_loop)
fry_loop.start(src)
else
icon_state = off_icon
if(fry_loop)
fry_loop.stop(src)
else
icon_state = off_icon
if(fry_loop)
fry_loop.stop(src)
..()
//Fryer gradually infuses any cooked food with oil. Moar calories
//This causes a slow drop in oil levels, encouraging refill after extended use
/obj/machinery/appliance/cooker/fryer/do_cooking_tick(var/datum/cooking_item/CI)
if(..() && (CI.oil < CI.max_oil) && prob(20))
var/datum/reagents/buffer = new /datum/reagents(2)
oil.trans_to_holder(buffer, min(0.5, CI.max_oil - CI.oil))
CI.oil += buffer.total_volume
CI.container.soak_reagent(buffer)
//To solve any odd logic problems with results having oil as part of their compiletime ingredients.
//Upon finishing a recipe the fryer will analyse any oils in the result, and replace them with our oil
//As well as capping the total to the max oil
/obj/machinery/appliance/cooker/fryer/finish_cooking(var/datum/cooking_item/CI)
..()
var/total_oil = 0
var/total_our_oil = 0
var/total_removed = 0
var/datum/reagent/our_oil = oil.get_master_reagent()
for (var/obj/item/I in CI.container)
if (I.reagents && I.reagents.total_volume)
for (var/datum/reagent/R in I.reagents.reagent_list)
if (istype(R, /datum/reagent/nutriment/triglyceride/oil))
total_oil += R.volume
if (R.id != our_oil.id)
total_removed += R.volume
I.reagents.remove_reagent(R.id, R.volume)
else
total_our_oil += R.volume
if (total_removed > 0 || total_oil != CI.max_oil)
total_oil = min(total_oil, CI.max_oil)
if (total_our_oil < total_oil)
//If we have less than the combined total, then top up from our reservoir
var/datum/reagents/buffer = new /datum/reagents(INFINITY)
oil.trans_to_holder(buffer, total_oil - total_our_oil)
CI.container.soak_reagent(buffer)
else if (total_our_oil > total_oil)
//If we have more than the maximum allowed then we delete some.
//This could only happen if one of the objects spawns with the same type of oil as ours
var/portion = 1 - (total_oil / total_our_oil) //find the percentage to remove
for (var/obj/item/I in CI.container)
if (I.reagents && I.reagents.total_volume)
for (var/datum/reagent/R in I.reagents.reagent_list)
if (R.id == our_oil.id)
I.reagents.remove_reagent(R.id, R.volume*portion)
/obj/machinery/appliance/cooker/fryer/cook_mob(var/mob/living/victim, var/mob/user)
if(!istype(victim))
return
// user.visible_message("<span class='danger'>\The [user] starts pushing \the [victim] into \the [src]!</span>")
//Removed delay on this action in favour of a cooldown after it
//If you can lure someone close to the fryer and grab them then you deserve success.
//And a delay on this kind of niche action just ensures it never happens
//Cooldown ensures it can't be spammed to instakill someone
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN*3)
fry_loop.start(src)
if(!do_mob(user, victim, 20))
cooking = FALSE
icon_state = off_icon
fry_loop.stop(src)
return
if(!victim || !victim.Adjacent(user))
to_chat(user, "<span class='danger'>Your victim slipped free!</span>")
cooking = FALSE
icon_state = off_icon
fry_loop.stop(src)
return
var/damage = rand(7,13) // Though this damage seems reduced, some hot oil is transferred to the victim and will burn them for a while after
var/datum/reagent/nutriment/triglyceride/oil/OL = oil.get_master_reagent()
damage *= OL.heatdamage(victim)
var/obj/item/organ/external/E
var/nopain
if(ishuman(victim) && user.zone_sel.selecting != BP_GROIN && user.zone_sel.selecting != BP_TORSO)
var/mob/living/carbon/human/H = victim
E = H.get_organ(user.zone_sel.selecting)
if(!E || E.species.flags & NO_PAIN)
nopain = 2
else if(E.robotic >= ORGAN_ROBOT)
nopain = 1
user.visible_message("<span class='danger'>\The [user] shoves \the [victim][E ? "'s [E.name]" : ""] into \the [src]!</span>")
if (damage > 0)
if(E)
if(E.children && E.children.len)
for(var/obj/item/organ/external/child in E.children)
if(nopain && nopain < 2 && !(child.robotic >= ORGAN_ROBOT))
nopain = 0
child.take_damage(0, damage)
damage -= (damage*0.5)//IF someone's arm is plunged in, the hand should take most of it
E.take_damage(0, damage)
else
victim.apply_damage(damage, BURN, user.zone_sel.selecting)
if(!nopain)
to_chat(victim, "<span class='danger'>Agony consumes you as searing hot oil scorches your [E ? E.name : "flesh"] horribly!</span>")
victim.emote("scream")
else
to_chat(victim, "<span class='danger'>Searing hot oil scorches your [E ? E.name : "flesh"]!</span>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Has [cook_type] \the [victim] ([victim.ckey]) in \a [src]</font>")
victim.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been [cook_type] in \a [src] by [user.name] ([user.ckey])</font>")
msg_admin_attack("[key_name_admin(user)] [cook_type] \the [victim] ([victim.ckey]) in \a [src]. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
//Coat the victim in some oil
oil.trans_to(victim, 40)
fry_loop.stop()
/obj/machinery/appliance/cooker/fryer/attackby(var/obj/item/I, var/mob/user)
if(default_deconstruction_screwdriver(user, O)) //CHOMPedit - Allows for deconstruction
return
if(default_deconstruction_crowbar(user, O))
return
if(default_part_replacement(user, O))
return
if(istype(I, /obj/item/weapon/reagent_containers/glass) && I.reagents)
if (I.reagents.total_volume <= 0 && oil)
//Its empty, handle scooping some hot oil out of the fryer
oil.trans_to(I, I.reagents.maximum_volume)
user.visible_message("[user] scoops some oil out of \the [src].", span("notice","You scoop some oil out of \the [src]."))
return 1
else
//It contains stuff, handle pouring any oil into the fryer
//Possibly in future allow pouring non-oil reagents in, in order to sabotage it and poison food.
//That would really require coding some sort of filter or better replacement mechanism first
//So for now, restrict to oil only
var/amount = 0
for (var/datum/reagent/R in I.reagents.reagent_list)
if (istype(R, /datum/reagent/nutriment/triglyceride/oil))
var/delta = oil.get_free_space()
delta = min(delta, R.volume)
oil.add_reagent(R.id, delta)
I.reagents.remove_reagent(R.id, delta)
amount += delta
if (amount > 0)
user.visible_message("[user] pours some oil into \the [src].", span("notice","You pour [amount]u of oil into \the [src]."), "<span class='notice'>You hear something viscous being poured into a metal container.</span>")
return 1
//If neither of the above returned, then call parent as normal
..()

View File

@@ -47,3 +47,11 @@
icon_state = off_icon
if(grill_loop)
grill_loop.stop(src)
/obj/machinery/appliance/cooker/grill/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(default_deconstruction_screwdriver(user, O))
return
if(default_deconstruction_crowbar(user, O))
return
if(default_part_replacement(user, O))
return

View File

@@ -153,3 +153,13 @@
return
else
..()
/obj/machinery/appliance/cooker/oven/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(default_deconstruction_screwdriver(user, O)) //CHOMPedit - Allows for deconstruction
return
if(default_deconstruction_crowbar(user, O))
return
if(default_part_replacement(user, O))
return

View File

@@ -99,6 +99,13 @@
/obj/machinery/gibber/attackby(var/obj/item/W, var/mob/user)
var/obj/item/weapon/grab/G = W
if(default_deconstruction_screwdriver(user, O)) //CHOMPedit - Allows for deconstruction
return
if(default_deconstruction_crowbar(user, O))
return
if(default_part_replacement(user, O))
return
if(default_unfasten_wrench(user, W, 40))
return

View File

@@ -1,195 +1,201 @@
#define ICECREAM_VANILLA 1
#define ICECREAM_CHOCOLATE 2
#define ICECREAM_STRAWBERRY 3
#define ICECREAM_BLUE 4
#define CONE_WAFFLE 5
#define CONE_CHOC 6
// Ported wholesale from Apollo Station.
/obj/machinery/icecream_vat
name = "icecream vat"
desc = "Ding-aling ding dong. Get your NanoTrasen-approved ice cream!"
icon = 'icons/obj/kitchen.dmi'
icon_state = "icecream_vat"
density = TRUE
anchored = FALSE
use_power = USE_POWER_OFF
flags = OPENCONTAINER | NOREACT
var/list/product_types = list()
var/dispense_flavour = ICECREAM_VANILLA
var/flavour_name = "vanilla"
/obj/machinery/icecream_vat/proc/get_ingredient_list(var/type)
switch(type)
if(ICECREAM_CHOCOLATE)
return list("milk", "ice", "coco")
if(ICECREAM_STRAWBERRY)
return list("milk", "ice", "berryjuice")
if(ICECREAM_BLUE)
return list("milk", "ice", "singulo")
if(CONE_WAFFLE)
return list("flour", "sugar")
if(CONE_CHOC)
return list("flour", "sugar", "coco")
else
return list("milk", "ice")
/obj/machinery/icecream_vat/proc/get_flavour_name(var/flavour_type)
switch(flavour_type)
if(ICECREAM_CHOCOLATE)
return "chocolate"
if(ICECREAM_STRAWBERRY)
return "strawberry"
if(ICECREAM_BLUE)
return "blue"
if(CONE_WAFFLE)
return "waffle"
if(CONE_CHOC)
return "chocolate"
else
return "vanilla"
/obj/machinery/icecream_vat/Initialize()
. = ..()
create_reagents(100)
while(product_types.len < 6)
product_types.Add(5)
reagents.add_reagent("milk", 5)
reagents.add_reagent("flour", 5)
reagents.add_reagent("sugar", 5)
reagents.add_reagent("ice", 5)
/obj/machinery/icecream_vat/attack_hand(mob/user as mob)
user.set_machine(src)
interact(user)
/obj/machinery/icecream_vat/interact(mob/user as mob)
var/dat
dat += "<b>ICECREAM</b><br><div class='statusDisplay'>"
dat += "<b>Dispensing: [flavour_name] icecream </b> <br><br>"
dat += "<b>Vanilla icecream:</b> <a href='?src=\ref[src];select=[ICECREAM_VANILLA]'><b>Select</b></a> <a href='?src=\ref[src];make=[ICECREAM_VANILLA];amount=1'><b>Make</b></a> <a href='?src=\ref[src];make=[ICECREAM_VANILLA];amount=5'><b>x5</b></a> [product_types[ICECREAM_VANILLA]] scoops left. (Ingredients: milk, ice)<br>"
dat += "<b>Strawberry icecream:</b> <a href='?src=\ref[src];select=[ICECREAM_STRAWBERRY]'><b>Select</b></a> <a href='?src=\ref[src];make=[ICECREAM_STRAWBERRY];amount=1'><b>Make</b></a> <a href='?src=\ref[src];make=[ICECREAM_STRAWBERRY];amount=5'><b>x5</b></a> [product_types[ICECREAM_STRAWBERRY]] dollops left. (Ingredients: milk, ice, berry juice)<br>"
dat += "<b>Chocolate icecream:</b> <a href='?src=\ref[src];select=[ICECREAM_CHOCOLATE]'><b>Select</b></a> <a href='?src=\ref[src];make=[ICECREAM_CHOCOLATE];amount=1'><b>Make</b></a> <a href='?src=\ref[src];make=[ICECREAM_CHOCOLATE];amount=5'><b>x5</b></a> [product_types[ICECREAM_CHOCOLATE]] dollops left. (Ingredients: milk, ice, coco powder)<br>"
dat += "<b>Blue icecream:</b> <a href='?src=\ref[src];select=[ICECREAM_BLUE]'><b>Select</b></a> <a href='?src=\ref[src];make=[ICECREAM_BLUE];amount=1'><b>Make</b></a> <a href='?src=\ref[src];make=[ICECREAM_BLUE];amount=5'><b>x5</b></a> [product_types[ICECREAM_BLUE]] dollops left. (Ingredients: milk, ice, singulo)<br></div>"
dat += "<br><b>CONES</b><br><div class='statusDisplay'>"
dat += "<b>Waffle cones:</b> <a href='?src=\ref[src];cone=[CONE_WAFFLE]'><b>Dispense</b></a> <a href='?src=\ref[src];make=[CONE_WAFFLE];amount=1'><b>Make</b></a> <a href='?src=\ref[src];make=[CONE_WAFFLE];amount=5'><b>x5</b></a> [product_types[CONE_WAFFLE]] cones left. (Ingredients: flour, sugar)<br>"
dat += "<b>Chocolate cones:</b> <a href='?src=\ref[src];cone=[CONE_CHOC]'><b>Dispense</b></a> <a href='?src=\ref[src];make=[CONE_CHOC];amount=1'><b>Make</b></a> <a href='?src=\ref[src];make=[CONE_CHOC];amount=5'><b>x5</b></a> [product_types[CONE_CHOC]] cones left. (Ingredients: flour, sugar, coco powder)<br></div>"
dat += "<br>"
dat += "<b>VAT CONTENT</b><br>"
for(var/datum/reagent/R in reagents.reagent_list)
dat += "[R.name]: [R.volume]"
dat += "<A href='?src=\ref[src];disposeI=[R.id]'>Purge</A><BR>"
dat += "<a href='?src=\ref[src];refresh=1'>Refresh</a> <a href='?src=\ref[src];close=1'>Close</a>"
var/datum/browser/popup = new(user, "icecreamvat","Icecream Vat", 700, 500, src)
popup.set_content(dat)
popup.open()
/obj/machinery/icecream_vat/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/icecream))
var/obj/item/weapon/reagent_containers/food/snacks/icecream/I = O
if(!I.ice_creamed)
if(product_types[dispense_flavour] > 0)
src.visible_message("\icon[src][bicon(src)] <span class='info'>[user] scoops delicious [flavour_name] icecream into [I].</span>")
product_types[dispense_flavour] -= 1
I.add_ice_cream(flavour_name)
// if(beaker)
// beaker.reagents.trans_to(I, 10)
if(I.reagents.total_volume < 10)
I.reagents.add_reagent("sugar", 10 - I.reagents.total_volume)
else
to_chat(user, "<span class='warning'>There is not enough icecream left!</span>")
else
to_chat(user, "<span class='notice'>[O] already has icecream in it.</span>")
return 1
else if(O.is_open_container())
return
else
..()
/obj/machinery/icecream_vat/proc/make(var/mob/user, var/make_type, var/amount)
for(var/R in get_ingredient_list(make_type))
if(reagents.has_reagent(R, amount))
continue
amount = 0
break
if(amount)
for(var/R in get_ingredient_list(make_type))
reagents.remove_reagent(R, amount)
product_types[make_type] += amount
var/flavour = get_flavour_name(make_type)
if(make_type > 4)
src.visible_message("<span class='info'>[user] cooks up some [flavour] cones.</span>")
else
src.visible_message("<span class='info'>[user] whips up some [flavour] icecream.</span>")
else
to_chat(user, "<span class='warning'>You don't have the ingredients to make this.</span>")
/obj/machinery/icecream_vat/Topic(href, href_list)
if(..())
return
if(href_list["select"])
dispense_flavour = text2num(href_list["select"])
flavour_name = get_flavour_name(dispense_flavour)
src.visible_message("<span class='notice'>[usr] sets [src] to dispense [flavour_name] flavoured icecream.</span>")
if(href_list["cone"])
var/dispense_cone = text2num(href_list["cone"])
var/cone_name = get_flavour_name(dispense_cone)
if(product_types[dispense_cone] >= 1)
product_types[dispense_cone] -= 1
var/obj/item/weapon/reagent_containers/food/snacks/icecream/I = new(src.loc)
I.cone_type = cone_name
I.icon_state = "icecream_cone_[cone_name]"
I.desc = "Delicious [cone_name] cone, but no ice cream."
src.visible_message("<span class='info'>[usr] dispenses a crunchy [cone_name] cone from [src].</span>")
else
to_chat(usr, "<span class='warning'>There are no [cone_name] cones left!</span>")
if(href_list["make"])
var/amount = (text2num(href_list["amount"]))
var/C = text2num(href_list["make"])
make(usr, C, amount)
if(href_list["disposeI"])
reagents.del_reagent(href_list["disposeI"])
updateDialog()
if(href_list["refresh"])
updateDialog()
if(href_list["close"])
usr.unset_machine()
usr << browse(null,"window=icecreamvat")
return
/obj/item/weapon/reagent_containers/food/snacks/icecream
name = "ice cream cone"
desc = "Delicious waffle cone, but no ice cream."
icon_state = "icecream_cone_waffle" //default for admin-spawned cones, href_list["cone"] should overwrite this all the time
bitesize = 3
var/ice_creamed = 0
var/cone_type
/obj/item/weapon/reagent_containers/food/snacks/icecream/New()
create_reagents(20)
reagents.add_reagent("nutriment", 5)
/obj/item/weapon/reagent_containers/food/snacks/icecream/proc/add_ice_cream(var/flavour_name)
name = "[flavour_name] icecream"
add_overlay("icecream_[flavour_name]")
desc = "Delicious [cone_type] cone with a dollop of [flavour_name] ice cream."
ice_creamed = 1
#undef ICECREAM_VANILLA
#undef ICECREAM_CHOCOLATE
#undef ICECREAM_STRAWBERRY
#undef ICECREAM_BLUE
#undef CONE_WAFFLE
#undef CONE_CHOC
#define ICECREAM_VANILLA 1
#define ICECREAM_CHOCOLATE 2
#define ICECREAM_STRAWBERRY 3
#define ICECREAM_BLUE 4
#define CONE_WAFFLE 5
#define CONE_CHOC 6
// Ported wholesale from Apollo Station.
/obj/machinery/icecream_vat
name = "icecream vat"
desc = "Ding-aling ding dong. Get your NanoTrasen-approved ice cream!"
icon = 'icons/obj/kitchen.dmi'
icon_state = "icecream_vat"
density = TRUE
anchored = FALSE
use_power = USE_POWER_OFF
flags = OPENCONTAINER | NOREACT
var/list/product_types = list()
var/dispense_flavour = ICECREAM_VANILLA
var/flavour_name = "vanilla"
/obj/machinery/icecream_vat/proc/get_ingredient_list(var/type)
switch(type)
if(ICECREAM_CHOCOLATE)
return list("milk", "ice", "coco")
if(ICECREAM_STRAWBERRY)
return list("milk", "ice", "berryjuice")
if(ICECREAM_BLUE)
return list("milk", "ice", "singulo")
if(CONE_WAFFLE)
return list("flour", "sugar")
if(CONE_CHOC)
return list("flour", "sugar", "coco")
else
return list("milk", "ice")
/obj/machinery/icecream_vat/proc/get_flavour_name(var/flavour_type)
switch(flavour_type)
if(ICECREAM_CHOCOLATE)
return "chocolate"
if(ICECREAM_STRAWBERRY)
return "strawberry"
if(ICECREAM_BLUE)
return "blue"
if(CONE_WAFFLE)
return "waffle"
if(CONE_CHOC)
return "chocolate"
else
return "vanilla"
/obj/machinery/icecream_vat/Initialize()
. = ..()
create_reagents(100)
while(product_types.len < 6)
product_types.Add(5)
reagents.add_reagent("milk", 5)
reagents.add_reagent("flour", 5)
reagents.add_reagent("sugar", 5)
reagents.add_reagent("ice", 5)
/obj/machinery/icecream_vat/attack_hand(mob/user as mob)
user.set_machine(src)
interact(user)
/obj/machinery/icecream_vat/interact(mob/user as mob)
var/dat
dat += "<b>ICECREAM</b><br><div class='statusDisplay'>"
dat += "<b>Dispensing: [flavour_name] icecream </b> <br><br>"
dat += "<b>Vanilla icecream:</b> <a href='?src=\ref[src];select=[ICECREAM_VANILLA]'><b>Select</b></a> <a href='?src=\ref[src];make=[ICECREAM_VANILLA];amount=1'><b>Make</b></a> <a href='?src=\ref[src];make=[ICECREAM_VANILLA];amount=5'><b>x5</b></a> [product_types[ICECREAM_VANILLA]] scoops left. (Ingredients: milk, ice)<br>"
dat += "<b>Strawberry icecream:</b> <a href='?src=\ref[src];select=[ICECREAM_STRAWBERRY]'><b>Select</b></a> <a href='?src=\ref[src];make=[ICECREAM_STRAWBERRY];amount=1'><b>Make</b></a> <a href='?src=\ref[src];make=[ICECREAM_STRAWBERRY];amount=5'><b>x5</b></a> [product_types[ICECREAM_STRAWBERRY]] dollops left. (Ingredients: milk, ice, berry juice)<br>"
dat += "<b>Chocolate icecream:</b> <a href='?src=\ref[src];select=[ICECREAM_CHOCOLATE]'><b>Select</b></a> <a href='?src=\ref[src];make=[ICECREAM_CHOCOLATE];amount=1'><b>Make</b></a> <a href='?src=\ref[src];make=[ICECREAM_CHOCOLATE];amount=5'><b>x5</b></a> [product_types[ICECREAM_CHOCOLATE]] dollops left. (Ingredients: milk, ice, coco powder)<br>"
dat += "<b>Blue icecream:</b> <a href='?src=\ref[src];select=[ICECREAM_BLUE]'><b>Select</b></a> <a href='?src=\ref[src];make=[ICECREAM_BLUE];amount=1'><b>Make</b></a> <a href='?src=\ref[src];make=[ICECREAM_BLUE];amount=5'><b>x5</b></a> [product_types[ICECREAM_BLUE]] dollops left. (Ingredients: milk, ice, singulo)<br></div>"
dat += "<br><b>CONES</b><br><div class='statusDisplay'>"
dat += "<b>Waffle cones:</b> <a href='?src=\ref[src];cone=[CONE_WAFFLE]'><b>Dispense</b></a> <a href='?src=\ref[src];make=[CONE_WAFFLE];amount=1'><b>Make</b></a> <a href='?src=\ref[src];make=[CONE_WAFFLE];amount=5'><b>x5</b></a> [product_types[CONE_WAFFLE]] cones left. (Ingredients: flour, sugar)<br>"
dat += "<b>Chocolate cones:</b> <a href='?src=\ref[src];cone=[CONE_CHOC]'><b>Dispense</b></a> <a href='?src=\ref[src];make=[CONE_CHOC];amount=1'><b>Make</b></a> <a href='?src=\ref[src];make=[CONE_CHOC];amount=5'><b>x5</b></a> [product_types[CONE_CHOC]] cones left. (Ingredients: flour, sugar, coco powder)<br></div>"
dat += "<br>"
dat += "<b>VAT CONTENT</b><br>"
for(var/datum/reagent/R in reagents.reagent_list)
dat += "[R.name]: [R.volume]"
dat += "<A href='?src=\ref[src];disposeI=[R.id]'>Purge</A><BR>"
dat += "<a href='?src=\ref[src];refresh=1'>Refresh</a> <a href='?src=\ref[src];close=1'>Close</a>"
var/datum/browser/popup = new(user, "icecreamvat","Icecream Vat", 700, 500, src)
popup.set_content(dat)
popup.open()
/obj/machinery/icecream_vat/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(default_deconstruction_screwdriver(user, O)) //CHOMPedit - Allows for deconstruction
return
if(default_deconstruction_crowbar(user, O))
return
if(default_part_replacement(user, O))
return
if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/icecream))
var/obj/item/weapon/reagent_containers/food/snacks/icecream/I = O
if(!I.ice_creamed)
if(product_types[dispense_flavour] > 0)
src.visible_message("\icon[src][bicon(src)] <span class='info'>[user] scoops delicious [flavour_name] icecream into [I].</span>")
product_types[dispense_flavour] -= 1
I.add_ice_cream(flavour_name)
// if(beaker)
// beaker.reagents.trans_to(I, 10)
if(I.reagents.total_volume < 10)
I.reagents.add_reagent("sugar", 10 - I.reagents.total_volume)
else
to_chat(user, "<span class='warning'>There is not enough icecream left!</span>")
else
to_chat(user, "<span class='notice'>[O] already has icecream in it.</span>")
return 1
else if(O.is_open_container())
return
else
..()
/obj/machinery/icecream_vat/proc/make(var/mob/user, var/make_type, var/amount)
for(var/R in get_ingredient_list(make_type))
if(reagents.has_reagent(R, amount))
continue
amount = 0
break
if(amount)
for(var/R in get_ingredient_list(make_type))
reagents.remove_reagent(R, amount)
product_types[make_type] += amount
var/flavour = get_flavour_name(make_type)
if(make_type > 4)
src.visible_message("<span class='info'>[user] cooks up some [flavour] cones.</span>")
else
src.visible_message("<span class='info'>[user] whips up some [flavour] icecream.</span>")
else
to_chat(user, "<span class='warning'>You don't have the ingredients to make this.</span>")
/obj/machinery/icecream_vat/Topic(href, href_list)
if(..())
return
if(href_list["select"])
dispense_flavour = text2num(href_list["select"])
flavour_name = get_flavour_name(dispense_flavour)
src.visible_message("<span class='notice'>[usr] sets [src] to dispense [flavour_name] flavoured icecream.</span>")
if(href_list["cone"])
var/dispense_cone = text2num(href_list["cone"])
var/cone_name = get_flavour_name(dispense_cone)
if(product_types[dispense_cone] >= 1)
product_types[dispense_cone] -= 1
var/obj/item/weapon/reagent_containers/food/snacks/icecream/I = new(src.loc)
I.cone_type = cone_name
I.icon_state = "icecream_cone_[cone_name]"
I.desc = "Delicious [cone_name] cone, but no ice cream."
src.visible_message("<span class='info'>[usr] dispenses a crunchy [cone_name] cone from [src].</span>")
else
to_chat(usr, "<span class='warning'>There are no [cone_name] cones left!</span>")
if(href_list["make"])
var/amount = (text2num(href_list["amount"]))
var/C = text2num(href_list["make"])
make(usr, C, amount)
if(href_list["disposeI"])
reagents.del_reagent(href_list["disposeI"])
updateDialog()
if(href_list["refresh"])
updateDialog()
if(href_list["close"])
usr.unset_machine()
usr << browse(null,"window=icecreamvat")
return
/obj/item/weapon/reagent_containers/food/snacks/icecream
name = "ice cream cone"
desc = "Delicious waffle cone, but no ice cream."
icon_state = "icecream_cone_waffle" //default for admin-spawned cones, href_list["cone"] should overwrite this all the time
bitesize = 3
var/ice_creamed = 0
var/cone_type
/obj/item/weapon/reagent_containers/food/snacks/icecream/New()
create_reagents(20)
reagents.add_reagent("nutriment", 5)
/obj/item/weapon/reagent_containers/food/snacks/icecream/proc/add_ice_cream(var/flavour_name)
name = "[flavour_name] icecream"
add_overlay("icecream_[flavour_name]")
desc = "Delicious [cone_type] cone with a dollop of [flavour_name] ice cream."
ice_creamed = 1
#undef ICECREAM_VANILLA
#undef ICECREAM_CHOCOLATE
#undef ICECREAM_STRAWBERRY
#undef ICECREAM_BLUE
#undef CONE_WAFFLE
#undef CONE_CHOC