slice a pizza into slices without it turning into a pile of slices (#89621)

## About The Pull Request



https://github.com/user-attachments/assets/3a620eba-b9c7-464e-a4e4-6c98c1506b2f

use a cutting tool on a pizza or a pizza in a pizza box to do this
afterwards the pizza can only be picked up like a paper bin - click drag
to self
slice again to turn into pile of slices
works on plates

pizza boxes that start with pizza arrive pre-sliced

also makes it use item_interaction

## Why It's Good For The Game

it makes more sense

## Changelog
🆑
add: you may now take out individual slices of pizza
/🆑
This commit is contained in:
possiblepossibility
2025-03-06 20:27:52 +00:00
committed by GitHub
parent 28a14b9792
commit d514b1a9fe
3 changed files with 149 additions and 43 deletions
+93 -8
View File
@@ -16,11 +16,102 @@
venue_value = FOOD_PRICE_CHEAP
crafting_complexity = FOOD_COMPLEXITY_2
/// type is spawned 6 at a time and replaces this pizza when processed by cutting tool
var/obj/item/food/pizzaslice/slice_type
slice_type = /obj/item/food/pizzaslice
var/obj/item/food/pizzaslice/slice_type = /obj/item/food/pizzaslice
///What label pizza boxes use if this pizza spawns in them.
var/boxtag = ""
/// how many slices left
var/slices_left = 6
/// have we been sliced? like sliced and you can take it apart by hand
var/sliced = FALSE
/// cutting tools
var/list/cutting_tools = list(TOOL_KNIFE, TOOL_SAW, TOOL_SCALPEL)
/obj/item/food/pizza/Initialize(mapload)
. = ..()
AddElement(/datum/element/drag_pickup)
register_context()
/obj/item/food/pizza/add_context(atom/source, list/context, obj/item/held_item, mob/user)
. = ..()
if(istype(held_item) && (held_item.tool_behaviour in cutting_tools))
context[SCREENTIP_CONTEXT_LMB] = "Slice"
context[SCREENTIP_CONTEXT_RMB] = "Slice apart"
return TRUE
if(sliced)
context[SCREENTIP_CONTEXT_LMB] = "Take Slice"
return TRUE
/obj/item/food/pizza/examine(mob/user)
. = ..()
if(isnull(slice_type) || !sliced)
return
. += span_notice("You can slice this to make it possible to take out slices with an empty hand!")
/obj/item/food/pizza/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
. = NONE
if(isnull(slice_type) || !(tool.tool_behaviour in cutting_tools))
return
if(!sliced)
slice(user, tool)
return ITEM_INTERACT_SUCCESS
user.visible_message(span_notice("[user] seperates [src] into individual slices with [tool]."))
cut_apart()
return ITEM_INTERACT_SUCCESS
/obj/item/food/pizza/item_interaction_secondary(mob/living/user, obj/item/tool, list/modifiers)
. = NONE
if(isnull(slice_type) || !(tool.tool_behaviour in cutting_tools))
return
visible_message(span_notice("[user] seperates [src] into individual slices with [tool]."))
cut_apart()
return ITEM_INTERACT_SUCCESS
/obj/item/food/pizza/attack_hand(mob/user, list/modifiers)
. = ..()
if(!sliced)
return
user.visible_message(span_notice("You take a slice of [src]."), span_notice("[user] takes a slice of [src]."))
produce_slice(user)
/obj/item/food/pizza/proc/get_slices_filter() //to not repeat code
return alpha_mask_filter(icon = icon('icons/obj/food/pizza.dmi', "[slices_left]slices"))
/// slices this pizza. all arguments optional.
/obj/item/food/pizza/proc/slice(mob/user, obj/item/tool)
if(sliced)
return
tool?.play_tool_sound(src)
sliced = TRUE
user?.visible_message(span_notice("[user] cuts [src] into 6 slices with [tool]."))
interaction_flags_item &= ~INTERACT_ITEM_ATTACK_HAND_PICKUP
/obj/item/food/pizza/proc/cut_apart()
for(var/_ in 1 to slices_left)
produce_slice(no_update = TRUE)
/// make a slice and give it to user. no_update means no filter work is done. user is optional
/obj/item/food/pizza/proc/produce_slice(mob/user, no_update = FALSE)
var/turf/our_turf = get_turf(src)
var/obj/item/food/pizzaslice/slice = new slice_type(our_turf)
if(HAS_TRAIT(src, TRAIT_FOOD_SILVER))
ADD_TRAIT(slice, TRAIT_FOOD_SILVER, INNATE_TRAIT)
if(HAS_TRAIT(src, TRAIT_FOOD_CHEF_MADE))
ADD_TRAIT(slice, TRAIT_FOOD_CHEF_MADE, GET_TRAIT_SOURCES(src, TRAIT_FOOD_CHEF_MADE)[1]) // wack thing to inherit first source
slice.pixel_x += rand(-6, 6)
slice.pixel_y += rand(-6, 6)
user?.put_in_active_hand(slice)
slices_left--
if(slices_left <= 0)
qdel(src)
return
if(no_update)
return
remove_filter("pizzaslices")
add_filter("pizzaslices", 1, get_slices_filter())
// Raw Pizza
/obj/item/food/pizza/raw
foodtypes = GRAIN | RAW
slice_type = null
@@ -29,12 +120,6 @@
/obj/item/food/pizza/raw/make_bakeable()
AddComponent(/datum/component/bakeable, /obj/item/food/pizza, rand(70 SECONDS, 80 SECONDS), TRUE, TRUE)
/obj/item/food/pizza/make_processable()
if (slice_type)
AddElement(/datum/element/processable, TOOL_KNIFE, slice_type, 6, 3 SECONDS, table_required = TRUE, screentip_verb = "Slice")
AddElement(/datum/element/processable, TOOL_SAW, slice_type, 6, 4.5 SECONDS, table_required = TRUE, screentip_verb = "Slice")
AddElement(/datum/element/processable, TOOL_SCALPEL, slice_type, 6, 6 SECONDS, table_required = TRUE, screentip_verb = "Slice")
// Pizza Slice
/obj/item/food/pizzaslice
name = "pizza slice"
+56 -35
View File
@@ -40,7 +40,8 @@
/obj/item/pizzabox/Initialize(mapload)
. = ..()
if(pizza)
pizza = new pizza
pizza = new pizza(src)
pizza.slice()
update_appearance()
register_context()
@@ -69,7 +70,7 @@
boxtag_set = TRUE
if(open)
if(pizza)
desc = "[desc] It appears to have \a [pizza] inside. Use your other hand to take it out."
desc = "[desc] It appears to have \a [pizza] inside[pizza.sliced ? ". It is sliced" : ""]. Use your other hand to take it out."
if(bomb)
desc = "[desc] Wait, what?! It has \a [bomb] inside!"
if(bomb_defused)
@@ -97,6 +98,8 @@
if(open)
if(pizza)
var/mutable_appearance/pizza_overlay = mutable_appearance(pizza.icon, pizza.icon_state)
if(pizza.slices_left != initial(pizza.slices_left))
pizza_overlay.add_filter("pizzaslices", 1, pizza.get_slices_filter())
pizza_overlay.pixel_y = -2
. += pizza_overlay
if(bomb)
@@ -154,6 +157,10 @@
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/item/pizzabox/attack_hand(mob/user, list/modifiers)
if(user.get_inactive_held_item() != src)
if(open && pizza?.sliced && !isobj(loc))
pizza.produce_slice(user)
update_appearance()
return
return ..()
if(open)
if(pizza)
@@ -184,15 +191,16 @@
update_appearance()
user.regenerate_icons()
/obj/item/pizzabox/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/pizzabox))
var/obj/item/pizzabox/newbox = I
/obj/item/pizzabox/item_interaction(mob/living/user, obj/item/used_item, list/modifiers)
. = NONE
if(istype(used_item, /obj/item/pizzabox))
var/obj/item/pizzabox/newbox = used_item
if(!open && !newbox.open)
var/list/add = list()
add += newbox
add += newbox.boxes
if(!user.transferItemToLoc(newbox, src))
return
return ITEM_INTERACT_FAILURE
boxes += add
newbox.boxes.Cut()
newbox.update_appearance()
@@ -204,47 +212,53 @@
disperse_pizzas()
else
balloon_alert(user, "looks unstable...")
return
return ITEM_INTERACT_SUCCESS
else
balloon_alert(user, "close it first!")
else if(istype(I, /obj/item/food/pizza))
return ITEM_INTERACT_FAILURE
else if(istype(used_item, /obj/item/food/pizza))
if(open)
if(pizza)
balloon_alert(user, "it's full!")
return
if(!user.transferItemToLoc(I, src))
return
pizza = I
return ITEM_INTERACT_FAILURE
if(!user.transferItemToLoc(used_item, src))
return ITEM_INTERACT_FAILURE
pizza = used_item
update_appearance()
return
else if(istype(I, /obj/item/bombcore/miniature/pizza))
return ITEM_INTERACT_SUCCESS
else if(istype(used_item, /obj/item/bombcore/miniature/pizza))
if(open && !bomb)
if(!user.transferItemToLoc(I, src))
return
if(!user.transferItemToLoc(used_item, src))
return ITEM_INTERACT_FAILURE
set_wires(new /datum/wires/explosive/pizza(src))
register_bomb(I)
register_bomb(used_item)
balloon_alert(user, "bomb placed")
update_appearance()
return
return ITEM_INTERACT_SUCCESS
else if(bomb)
balloon_alert(user, "already rigged!")
else if(IS_WRITING_UTENSIL(I))
if(!open)
if(!user.can_write(I))
return
var/obj/item/pizzabox/box = length(boxes) ? boxes[length(boxes)] : src
box.boxtag += tgui_input_text(user, "Write on [box]'s tag:", box, max_length = 30)
if(!user.can_perform_action(src))
return
balloon_alert(user, "writing box tag...")
playsound(src, SFX_WRITING_PEN, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, SOUND_FALLOFF_EXPONENT + 3, ignore_walls = FALSE)
boxtag_set = TRUE
update_appearance()
return
else if(is_wire_tool(I))
if(wires && bomb)
wires.interact(user)
..()
return ITEM_INTERACT_FAILURE
else if(IS_WRITING_UTENSIL(used_item))
if(open)
return ITEM_INTERACT_FAILURE
if(!user.can_write(used_item))
return ITEM_INTERACT_FAILURE
var/obj/item/pizzabox/box = length(boxes) ? boxes[length(boxes)] : src
box.boxtag += tgui_input_text(user, "Write on [box]'s tag:", box, max_length = 30)
if(!user.can_perform_action(src))
return ITEM_INTERACT_FAILURE
balloon_alert(user, "writing box tag...")
playsound(src, SFX_WRITING_PEN, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, SOUND_FALLOFF_EXPONENT + 3, ignore_walls = FALSE)
boxtag_set = TRUE
update_appearance()
return ITEM_INTERACT_SUCCESS
else if(is_wire_tool(used_item) && wires && bomb)
wires.interact(user)
return ITEM_INTERACT_SUCCESS
else if(istype(used_item, /obj/item/knife) && !isnull(pizza) && open && !pizza.sliced)
pizza.slice(user, used_item)
return ITEM_INTERACT_SUCCESS
/obj/item/pizzabox/process(seconds_per_tick)
if(bomb_active && !bomb_defused && (bomb_timer > 0))
@@ -298,6 +312,13 @@
var/mob/living/L = loc
L.regenerate_icons()
/obj/item/pizzabox/Exited(atom/movable/gone, direction)
. = ..()
if(gone != pizza)
return
pizza = null
update_appearance()
/obj/item/pizzabox/proc/unprocess()
STOP_PROCESSING(SSobj, src)
qdel(wires)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 14 KiB