diff --git a/_maps/map_files/IceBoxStation/IcemoonUnderground_Above.dmm b/_maps/map_files/IceBoxStation/IcemoonUnderground_Above.dmm index 2ce78a09a71..193c1938477 100644 --- a/_maps/map_files/IceBoxStation/IcemoonUnderground_Above.dmm +++ b/_maps/map_files/IceBoxStation/IcemoonUnderground_Above.dmm @@ -3162,9 +3162,9 @@ /turf/open/floor/iron/dark, /area/service/hydroponics) "rN" = ( -/obj/structure/closet/crate/freezer, /obj/machinery/power/apc/auto_name/east, /obj/structure/cable, +/obj/structure/closet/crate/secure/freezer/pizza, /turf/open/floor/iron, /area/cargo/warehouse) "rS" = ( diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index a6f64518d82..2d3b9865d2d 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -203,6 +203,7 @@ //2. Gets a number between 1 and that total //3. For each element in the list, subtracts its weighting from that number //4. If that makes the number 0 or less, return that element. +//Will output null sometimes if you use decimals (e.g. 0.1 instead of 10) as rand() uses integers, not floats /proc/pickweight(list/L) var/total = 0 var/item diff --git a/code/game/objects/items/food/pizza.dm b/code/game/objects/items/food/pizza.dm index 537faaa292e..6072923b769 100644 --- a/code/game/objects/items/food/pizza.dm +++ b/code/game/objects/items/food/pizza.dm @@ -8,6 +8,8 @@ foodtypes = GRAIN | DAIRY | VEGETABLES /// type is spawned 6 at a time and replaces this pizza when processed by cutting tool var/obj/item/food/pizzaslice/slice_type + ///What label pizza boxes use if this pizza spawns in them. + var/boxtag = "" /obj/item/food/pizza/MakeProcessable() if (slice_type) @@ -35,9 +37,9 @@ icon_state = "pizzamargherita" food_reagents = list(/datum/reagent/consumable/nutriment = 25, /datum/reagent/consumable/nutriment/protein = 8, /datum/reagent/consumable/tomatojuice = 6, /datum/reagent/consumable/nutriment/vitamin = 5) tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1) - tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1) foodtypes = GRAIN | VEGETABLES | DAIRY slice_type = /obj/item/food/pizzaslice/margherita + boxtag = "Margherita Deluxe" /obj/item/food/pizza/margherita/robo food_reagents = list(/datum/reagent/nanomachines = 70, /datum/reagent/consumable/nutriment = 25, /datum/reagent/consumable/nutriment/protein = 8, /datum/reagent/consumable/tomatojuice = 6, /datum/reagent/consumable/nutriment/vitamin = 5) @@ -60,6 +62,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 25, /datum/reagent/consumable/nutriment/protein = 8, /datum/reagent/consumable/tomatojuice = 6, /datum/reagent/consumable/nutriment/vitamin = 8) foodtypes = GRAIN | VEGETABLES| DAIRY | MEAT slice_type = /obj/item/food/pizzaslice/meat + boxtag = "Meatlovers' Supreme" /obj/item/food/pizzaslice/meat name = "meatpizza slice" @@ -77,6 +80,7 @@ tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "mushroom" = 1) foodtypes = GRAIN | VEGETABLES | DAIRY slice_type = /obj/item/food/pizzaslice/mushroom + boxtag = "Mushroom Special" /obj/item/food/pizzaslice/mushroom name = "mushroom pizza slice" @@ -94,6 +98,7 @@ tastes = list("crust" = 1, "tomato" = 2, "cheese" = 1, "carrot" = 1) foodtypes = GRAIN | VEGETABLES | DAIRY slice_type = /obj/item/food/pizzaslice/vegetable + boxtag = "Gourmet Vegetable" /obj/item/food/pizzaslice/vegetable name = "vegetable pizza slice" @@ -111,6 +116,7 @@ tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "meat" = 1, "laziness" = 1) foodtypes = GRAIN | VEGETABLES | DAIRY | MEAT | JUNKFOOD slice_type = /obj/item/food/pizzaslice/donkpocket + boxtag = "Bangin' Donk" /obj/item/food/pizzaslice/donkpocket name = "donkpocket pizza slice" @@ -128,6 +134,7 @@ tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "meat" = 1) foodtypes = GRAIN | VEGETABLES | DAIRY slice_type = /obj/item/food/pizzaslice/dank + boxtag = "Fresh Herb" /obj/item/food/pizzaslice/dank name = "dank pizza slice" @@ -139,12 +146,13 @@ /obj/item/food/pizza/sassysage name = "sassysage pizza" - desc = "You can really smell the sassiness." + desc = "You can almost taste the sassiness." icon_state = "sassysagepizza" food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/protein = 15, /datum/reagent/consumable/tomatojuice = 6, /datum/reagent/consumable/nutriment/vitamin = 6) tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "meat" = 1) foodtypes = GRAIN | VEGETABLES | DAIRY slice_type = /obj/item/food/pizzaslice/sassysage + boxtag = "Sausage Lovers" /obj/item/food/pizzaslice/sassysage name = "sassysage pizza slice" @@ -162,6 +170,7 @@ tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "pineapple" = 2, "ham" = 2) foodtypes = GRAIN | VEGETABLES | DAIRY | MEAT | FRUIT | PINEAPPLE slice_type = /obj/item/food/pizzaslice/pineapple + boxtag = "Honolulu Chew" /obj/item/food/pizzaslice/pineapple name = "\improper Hawaiian pizza slice" @@ -195,6 +204,7 @@ food_reagents = list(/datum/reagent/consumable/nutriment = 25, /datum/reagent/consumable/nutriment/protein = 9, /datum/reagent/consumable/nutriment/vitamin = 6, /datum/reagent/iron = 10, /datum/reagent/medicine/omnizine = 30) tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "pepperoni" = 2, "9 millimeter bullets" = 2) slice_type = /obj/item/food/pizzaslice/arnold + boxtag = "9mm Pepperoni" //fuck it, i will leave this at the food level for now. /obj/item/food/proc/try_break_off(mob/living/M, mob/living/user) //maybe i give you a pizza maybe i break off your arm diff --git a/code/game/objects/structures/crates_lockers/crates/secure.dm b/code/game/objects/structures/crates_lockers/crates/secure.dm index d12b5944c45..82439bb13a4 100644 --- a/code/game/objects/structures/crates_lockers/crates/secure.dm +++ b/code/game/objects/structures/crates_lockers/crates/secure.dm @@ -54,6 +54,21 @@ name = "secure hydroponics crate" icon_state = "hydrosecurecrate" +/obj/structure/closet/crate/secure/freezer //for consistency with other "freezer" closets/crates + desc = "An insulated crate with a lock on it, used to secure perishables." + name = "secure kitchen crate" + icon_state = "kitchen_secure_crate" + +/obj/structure/closet/crate/secure/freezer/pizza + name = "secure pizza crate" + desc = "An insulated crate with a lock on it, used to secure pizza." + req_access = list(28) + tamperproof = 10 + +/obj/structure/closet/crate/secure/freezer/pizza/PopulateContents() + . = ..() + new /obj/effect/spawner/lootdrop/pizzaparty(src) + /obj/structure/closet/crate/secure/engineering desc = "A crate with a lock on it, painted in the scheme of the station's engineers." name = "secure engineering crate" diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm index 0a5d4ec5c66..b1a8e307c0a 100644 --- a/code/modules/cargo/packs.dm +++ b/code/modules/cargo/packs.dm @@ -1801,7 +1801,8 @@ /datum/supply_pack/organic/pizza name = "Pizza Crate" - desc = "Best prices on this side of the galaxy. All deliveries are guaranteed to be 99% anomaly-free!" + desc = "Why visit the kitchen when you can have five random pizzas in a fraction of the time? \ + Best prices this side of the galaxy! All deliveries are guaranteed to be 99% anomaly-free." cost = CARGO_CRATE_VALUE * 10 // Best prices this side of the galaxy. contains = list(/obj/item/pizzabox/margherita, /obj/item/pizzabox/mushroom, @@ -1809,15 +1810,37 @@ /obj/item/pizzabox/vegetable, /obj/item/pizzabox/pineapple) crate_name = "pizza crate" + ///Whether we've provided an infinite pizza box already this shift or not. var/static/anomalous_box_provided = FALSE + ///The percentage chance (per pizza) of this supply pack to spawn an anomalous pizza box. + var/anna_molly_box_chance = 1 + ///Total tickets in our figurative lottery (per pizza) to decide if we create a bomb box, and if so what type. 1 to 3 create a bomb. The rest do nothing. + var/boombox_tickets = 100 + ///Whether we've provided a bomb pizza box already this shift or not. + var/boombox_provided = FALSE /datum/supply_pack/organic/pizza/fill(obj/structure/closet/crate/C) . = ..() - if(!anomalous_box_provided) - for(var/obj/item/pizzabox/P in C) - if(prob(1)) //1% chance for each box, so 4% total chance per order + + var/list/pizza_types = list( + /obj/item/food/pizza/margherita = 10, + /obj/item/food/pizza/meat = 10, + /obj/item/food/pizza/mushroom = 10, + /obj/item/food/pizza/vegetable = 10, + /obj/item/food/pizza/donkpocket = 10, + /obj/item/food/pizza/dank = 7, + /obj/item/food/pizza/sassysage = 10, + /obj/item/food/pizza/pineapple = 10, + /obj/item/food/pizza/arnold = 3 + ) //weighted by chance to disrupt eaters' rounds + + for(var/obj/item/pizzabox/P in C) + if(!anomalous_box_provided) + if(prob(anna_molly_box_chance)) //1% chance for each box, so 4% total chance per order var/obj/item/pizzabox/infinite/fourfiveeight = new(C) fourfiveeight.boxtag = P.boxtag + fourfiveeight.boxtag_set = TRUE + fourfiveeight.update_icon() qdel(P) anomalous_box_provided = TRUE log_game("An anomalous pizza box was provided in a pizza crate at during cargo delivery") @@ -1825,7 +1848,34 @@ addtimer(CALLBACK(src, .proc/anomalous_pizza_report), rand(300, 1800)) else message_admins("An anomalous pizza box was silently created with no command report in a pizza crate delivery.") - break + continue + + if(!boombox_provided) + var/boombox_lottery = rand(1,boombox_tickets) + var/boombox_type + switch(boombox_lottery) + if(1 to 2) + boombox_type = /obj/item/pizzabox/bomb/armed //explodes after opening + if(3) + boombox_type = /obj/item/pizzabox/bomb //free bomb + + if(boombox_type) + new boombox_type(C) + qdel(P) + boombox_provided = TRUE + log_game("A bomb pizza box was created by a pizza crate delivery.") + message_admins("A bomb pizza box has arrived in a pizza crate delivery.") + continue + + //here we randomly replace our pizzas for a chance at the full range + var/obj/item/food/pizza/replacement_type = pickweight(pizza_types) + pizza_types -= replacement_type + if(replacement_type && !istype(P.pizza, replacement_type)) + QDEL_NULL(P.pizza) + P.pizza = new replacement_type + P.boxtag = P.pizza.boxtag + P.boxtag_set = TRUE + P.update_icon() /datum/supply_pack/organic/pizza/proc/anomalous_pizza_report() print_command_report("[station_name()], our anomalous materials divison has reported a missing object that is highly likely to have been sent to your station during a routine cargo \ diff --git a/code/modules/food_and_drinks/pizzabox.dm b/code/modules/food_and_drinks/pizzabox.dm index 0492ba1db27..99b8f6c38ab 100644 --- a/code/modules/food_and_drinks/pizzabox.dm +++ b/code/modules/food_and_drinks/pizzabox.dm @@ -19,6 +19,8 @@ var/open = FALSE var/can_open_on_fall = TRUE //if FALSE, this pizza box will never open if it falls from a stack var/boxtag = "" + ///Used to make sure artisinal box tags aren't overwritten. + var/boxtag_set = FALSE var/list/boxes = list() var/obj/item/food/pizza/pizza @@ -34,6 +36,8 @@ /obj/item/pizzabox/Initialize() . = ..() + if(pizza) + pizza = new pizza update_icon() @@ -44,6 +48,9 @@ /obj/item/pizzabox/update_icon() // Description desc = initial(desc) + if(pizza && pizza.boxtag && !boxtag_set) + boxtag = pizza.boxtag + boxtag_set = TRUE if(open) if(pizza) desc = "[desc] It appears to have \a [pizza] inside. Use your other hand to take it out." @@ -211,6 +218,7 @@ if(!user.canUseTopic(src, BE_CLOSE)) return to_chat(user, "You write with [I] on [src].") + boxtag_set = TRUE update_icon() return else if(is_wire_tool(I)) @@ -245,6 +253,14 @@ if(boxes.len >= 2 && prob(20 * boxes.len)) disperse_pizzas() +/obj/item/pizzabox/examine(mob/user) + . = ..() + if(isobserver(user)) + if(bomb) + . += "This pizza box contains [bomb_defused ? "an unarmed bomb" : "an armed bomb"]." + if(pizza && istype(pizza, /obj/item/food/pizza/margherita/robo)) + . += "The pizza in this pizza box contains nanomachines." + /obj/item/pizzabox/proc/disperse_pizzas() visible_message("The pizzas fall everywhere!") for(var/V in boxes) @@ -272,56 +288,54 @@ /obj/item/pizzabox/bomb/Initialize() . = ..() - var/randompizza = pick(subtypesof(/obj/item/food/pizza)) - pizza = new randompizza(src) + if(!pizza) + var/randompizza = pick(subtypesof(/obj/item/food/pizza)) + pizza = new randompizza(src) bomb = new(src) wires = new /datum/wires/explosive/pizza(src) -/obj/item/pizzabox/margherita/Initialize() - . = ..() - AddPizza() - boxtag = "Margherita Deluxe" +/obj/item/pizzabox/bomb/armed + bomb_timer = 5 + bomb_defused = FALSE + boxtag = "Meat Explosion" + boxtag_set = TRUE + pizza = /obj/item/food/pizza/meat -/obj/item/pizzabox/margherita/proc/AddPizza() - pizza = new /obj/item/food/pizza/margherita(src) +/obj/item/pizzabox/margherita + pizza = /obj/item/food/pizza/margherita -/obj/item/pizzabox/margherita/robo/AddPizza() - pizza = new /obj/item/food/pizza/margherita/robo(src) +/obj/item/pizzabox/margherita/robo + pizza = /obj/item/food/pizza/margherita/robo -/obj/item/pizzabox/vegetable/Initialize() - . = ..() - pizza = new /obj/item/food/pizza/vegetable(src) - boxtag = "Gourmet Vegatable" +/obj/item/pizzabox/vegetable + pizza = /obj/item/food/pizza/vegetable -/obj/item/pizzabox/mushroom/Initialize() - . = ..() - pizza = new /obj/item/food/pizza/mushroom(src) - boxtag = "Mushroom Special" +/obj/item/pizzabox/mushroom + pizza = /obj/item/food/pizza/mushroom -/obj/item/pizzabox/meat/Initialize() - . = ..() - pizza = new /obj/item/food/pizza/meat(src) - boxtag = "Meatlover's Supreme" +/obj/item/pizzabox/meat + pizza = /obj/item/food/pizza/meat -/obj/item/pizzabox/pineapple/Initialize() - . = ..() - pizza = new /obj/item/food/pizza/pineapple(src) - boxtag = "Honolulu Chew" +/obj/item/pizzabox/pineapple + pizza = /obj/item/food/pizza/pineapple //An anomalous pizza box that, when opened, produces the opener's favorite kind of pizza. /obj/item/pizzabox/infinite resistance_flags = FIRE_PROOF | LAVA_PROOF | ACID_PROOF //hard to destroy can_open_on_fall = FALSE + boxtag = "Your Favourite" //used to give it a tag overlay, shouldn't be seen by players + ///List of pizzas this box can spawn. Weighted by chance to be someone's favorite. var/list/pizza_types = list( - /obj/item/food/pizza/meat = 1, - /obj/item/food/pizza/mushroom = 1, - /obj/item/food/pizza/margherita = 1, - /obj/item/food/pizza/sassysage = 0.8, - /obj/item/food/pizza/vegetable = 0.8, - /obj/item/food/pizza/pineapple = 0.5, - /obj/item/food/pizza/donkpocket = 0.3, - /obj/item/food/pizza/dank = 0.1, - ) //pizzas here are weighted by chance to be someone's favorite + /obj/item/food/pizza/meat = 10, + /obj/item/food/pizza/mushroom = 10, + /obj/item/food/pizza/margherita = 10, + /obj/item/food/pizza/sassysage = 8, + /obj/item/food/pizza/vegetable = 8, + /obj/item/food/pizza/pineapple = 5, + /obj/item/food/pizza/donkpocket = 3, + /obj/item/food/pizza/dank = 1, + ) + ///List of ckeys and their favourite pizzas. e.g. pizza_preferences[ckey] = /obj/item/food/pizza/meat var/static/list/pizza_preferences /obj/item/pizzabox/infinite/Initialize() @@ -330,28 +344,43 @@ pizza_preferences = list() /obj/item/pizzabox/infinite/examine(mob/user) + if(!open && ishuman(user)) + attune_pizza(user) //pizza tag changes based on examiner . = ..() if(isobserver(user)) . += "This pizza box is anomalous, and will produce infinite pizza." /obj/item/pizzabox/infinite/attack_self(mob/living/user) - QDEL_NULL(pizza) if(ishuman(user)) attune_pizza(user) - . = ..() + return ..() -/obj/item/pizzabox/infinite/proc/attune_pizza(mob/living/carbon/human/noms) //tonight on "proc names I never thought I'd type" - if(!pizza_preferences[noms.ckey]) - pizza_preferences[noms.ckey] = pickweight(pizza_types) - if(noms.has_quirk(/datum/quirk/pineapple_liker)) - pizza_preferences[noms.ckey] = /obj/item/food/pizza/pineapple - else if(noms.has_quirk(/datum/quirk/pineapple_hater)) +/obj/item/pizzabox/infinite/proc/attune_pizza(mob/living/carbon/human/nommer) //tonight on "proc names I never thought I'd type" + if(!nommer.ckey) + return + + //list our ckey and assign it a favourite pizza + if(!pizza_preferences[nommer.ckey]) + if(nommer.has_quirk(/datum/quirk/pineapple_liker)) + pizza_preferences[nommer.ckey] = /obj/item/food/pizza/pineapple + else if(nommer.has_quirk(/datum/quirk/pineapple_hater)) var/list/pineapple_pizza_liker = pizza_types.Copy() pineapple_pizza_liker -= /obj/item/food/pizza/pineapple - pizza_preferences[noms.ckey] = pickweight(pineapple_pizza_liker) - else if(noms.mind && noms.mind.assigned_role == "Botanist") - pizza_preferences[noms.ckey] = /obj/item/food/pizza/dank + pizza_preferences[nommer.ckey] = pickweight(pineapple_pizza_liker) + else if(nommer.mind && nommer.mind.assigned_role == "Botanist") + pizza_preferences[nommer.ckey] = /obj/item/food/pizza/dank + else + pizza_preferences[nommer.ckey] = pickweight(pizza_types) + if(pizza) + //if the pizza isn't our favourite, delete it + if(pizza.type != pizza_preferences[nommer.ckey]) + QDEL_NULL(pizza) + else + pizza.foodtypes = nommer.dna.species.liked_food //make sure it's our favourite + return - var/obj/item/pizza_type = pizza_preferences[noms.ckey] - pizza = new pizza_type (src) - pizza.foodtypes = noms.dna.species.liked_food //it's our favorite! + var/obj/item/food/pizza/favourite_pizza_type = pizza_preferences[nommer.ckey] + pizza = new favourite_pizza_type + boxtag_set = FALSE + update_icon() //update our boxtag to match our new pizza + pizza.foodtypes = nommer.dna.species.liked_food //it's our favorite! diff --git a/code/modules/ruins/lavalandruin_code/pizzaparty.dm b/code/modules/ruins/lavalandruin_code/pizzaparty.dm index a7776f4e6a8..590994451b5 100644 --- a/code/modules/ruins/lavalandruin_code/pizzaparty.dm +++ b/code/modules/ruins/lavalandruin_code/pizzaparty.dm @@ -5,5 +5,5 @@ loot = list(/obj/item/pizzabox/margherita = 3, /obj/item/pizzabox/meat = 3, /obj/item/pizzabox/mushroom = 3, - /obj/item/pizzabox/bomb = 1) + /obj/item/pizzabox/bomb/armed = 1) lootdoubles = FALSE diff --git a/icons/obj/crates.dmi b/icons/obj/crates.dmi index 3f15cc67b22..98ccc6b2ff1 100644 Binary files a/icons/obj/crates.dmi and b/icons/obj/crates.dmi differ