diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index f0ab8e7ac93..0f652808833 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -1017,3 +1017,24 @@
/// from /obj/structure/cursed_slot_machine/determine_victor() when someone finally wins.
#define COMSIG_GLOB_CURSED_SLOT_MACHINE_WON "cursed_slot_machine_won"
+
+// Signal types for the cargo shuttle
+
+// Sent before the shuttle scans its contents.
+// Use to initialize data that will be needed during the scan.
+#define COMSIG_CARGO_BEGIN_SCAN "begin_scan"
+// Sent as the shuttle scans its contents.
+// Can return sell flags (see code/__DEFINES/supply_defines.dm).
+#define COMSIG_CARGO_CHECK_SELL "check_sell"
+// Sent as the shuttle begins selling off its contents.
+// Use to initialize data that will be needed during the sale.
+#define COMSIG_CARGO_BEGIN_SELL "begin_sell"
+// Sent during sales for items marked with COMSIG_CARGO_SELL_PRIORITY.
+#define COMSIG_CARGO_DO_PRIORITY_SELL "do_priority_sell"
+// Sent during sales for items marked with COMSIG_CARGO_SELL_NORMAL.
+#define COMSIG_CARGO_DO_SELL "do_sell"
+// Sent during sales for items marked with COMSIG_CARGO_SELL_WRONG.
+#define COMSIG_CARGO_SEND_ERROR "send_error"
+// Sent when sales are completed.
+// Use to send summary messages for items that sell in bulk.
+#define COMSIG_CARGO_END_SELL "end_sell"
diff --git a/code/__DEFINES/food_defines.dm b/code/__DEFINES/food_defines.dm
new file mode 100644
index 00000000000..83d378400e1
--- /dev/null
+++ b/code/__DEFINES/food_defines.dm
@@ -0,0 +1,5 @@
+// Used for secondary goals.
+#define FOOD_GOAL_SKIP 0
+#define FOOD_GOAL_EASY 1
+#define FOOD_GOAL_NORMAL 2
+#define FOOD_GOAL_HARD 3
diff --git a/code/__DEFINES/reagents_defines.dm b/code/__DEFINES/reagents_defines.dm
index 3b31509b4c7..45bc2fafd1d 100644
--- a/code/__DEFINES/reagents_defines.dm
+++ b/code/__DEFINES/reagents_defines.dm
@@ -32,3 +32,9 @@
/// Like O- blood but doesn't contribute to blood_volume or vampire nutrition
#define BLOOD_TYPE_FAKE_BLOOD "Vh Null"
+
+/// Used for secondary goals.
+#define REAGENT_GOAL_SKIP 0
+#define REAGENT_GOAL_EASY 1
+#define REAGENT_GOAL_NORMAL 2
+#define REAGENT_GOAL_HARD 3
diff --git a/code/__DEFINES/station_goals.dm b/code/__DEFINES/station_goals.dm
index 0c19da7b5f1..01922b2132c 100644
--- a/code/__DEFINES/station_goals.dm
+++ b/code/__DEFINES/station_goals.dm
@@ -1,2 +1,9 @@
#define BSA_SIZE_FRONT 4
#define BSA_SIZE_BACK 6
+
+// Secondary goals
+
+/// How many units can be missing from a reagent and still count to the goal.
+/// Prevents floationg point rounding from making you fail even though you
+/// seemed to have sent enough.
+#define REAGENT_GOAL_FORGIVENESS 0.1
diff --git a/code/__DEFINES/supply_defines.dm b/code/__DEFINES/supply_defines.dm
new file mode 100644
index 00000000000..f47fdaf111e
--- /dev/null
+++ b/code/__DEFINES/supply_defines.dm
@@ -0,0 +1,14 @@
+// Cargo sell flags
+
+// Priorities
+// Each priority blocks all lower priorities.
+// Any priority (even WRONG) prevents items from being considered trash.
+#define COMSIG_CARGO_SELL_PRIORITY (1<<0)
+#define COMSIG_CARGO_SELL_NORMAL (1<<1)
+#define COMSIG_CARGO_SELL_WRONG (1<<2)
+#define COMSIG_CARGO_SELL_SKIP (1<<3)
+#define COMSIG_CARGO_MESS (1<<4)
+
+// Functional markers
+// Marks the item as safe for the shuttle floor (e.g. crates)
+#define COMSIG_CARGO_IS_SECURED (1<<5)
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 3c1bc5fb997..50a5df5f38d 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1596,17 +1596,18 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
closest_atom = A
return closest_atom
-/proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types())
- if(!value) //nothing should be calling us with a number, so this is safe
- value = input("Enter type to find (blank for all, cancel to cancel)", "Search for type") as null|text
- if(isnull(value))
- return
- value = trim(value)
- if(!isnull(value) && value != "")
- matches = filter_fancy_list(matches, value)
+/proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types(), skip_filter = FALSE)
+ if(!skip_filter)
+ if(!value) //nothing should be calling us with a number, so this is safe
+ value = input("Enter type to find (blank for all, cancel to cancel)", "Search for type") as null|text
+ if(isnull(value))
+ return
+ value = trim(value)
+ if(!isnull(value) && value != "")
+ matches = filter_fancy_list(matches, value)
- if(!length(matches))
- return
+ if(!length(matches))
+ return
var/chosen
if(length(matches) == 1)
@@ -1702,6 +1703,8 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
/obj/structure = "STRUCTURE",
/obj/vehicle = "VEHICLE",
/obj = "O",
+ /datum/station_goal/secondary = "S_GOAL",
+ /datum/station_goal = "GOAL",
/datum = "D",
/turf/simulated/floor = "SIM_FLOOR",
/turf/simulated/wall = "SIM_WALL",
diff --git a/code/controllers/subsystem/SSeconomy.dm b/code/controllers/subsystem/SSeconomy.dm
index db104e779dc..c261d7f963a 100644
--- a/code/controllers/subsystem/SSeconomy.dm
+++ b/code/controllers/subsystem/SSeconomy.dm
@@ -48,14 +48,34 @@ SUBSYSTEM_DEF(economy)
///Current Order number
var/ordernum = 1
- /// points gained per slip returned
+ /// credits gained per slip returned
var/credits_per_manifest = 5
- /// points gained per intel returned
+ /// credits gained per intel sold
var/credits_per_intel = 750
- /// points gained per plasma returned
+ /// credits gained per plasma sold
var/credits_per_plasma = 10
- /// points gained per research design returned
+ /// credits gained per research design sold
var/credits_per_design = 20
+ /// credits gained per working mech sold
+ var/credits_per_mech = 100
+ /// credits gained for each secondary goal completed
+ /// These get split in 3, one part for Cargo, one for the department,
+ /// and one part for the person who requested the goal.
+ var/credits_per_easy_reagent_goal = 150
+ var/credits_per_normal_reagent_goal = 300
+ var/credits_per_hard_reagent_goal = 450
+ var/credits_per_variety_reagent_goal = 300
+ var/credits_per_easy_food_goal = 300
+ var/credits_per_normal_food_goal = 450
+ var/credits_per_hard_food_goal = 600
+ var/credits_per_ripley_goal = 600
+ var/credits_per_kudzu_goal = 600
+ /// credits lost for sending unsecured cargo
+ var/fine_for_loose_cargo = -100
+ /// credits lost for sending a messy shuttle
+ var/fine_for_messy_shuttle = -100
+ /// credits lost for sending unwanted items
+ var/fine_for_selling_trash = -100
/// points gained per virology goal
var/credits_per_virology_goal = 200
@@ -150,8 +170,7 @@ SUBSYSTEM_DEF(economy)
next_paycheck_delay = 30 MINUTES + world.time
next_mail_delay = 15 MINUTES + world.time
- for(var/obj/machinery/computer/pandemic/P in GLOB.pandemics)
- P.print_goal_orders()
+ check_total_virology_goals_completion()
/datum/controller/subsystem/economy/fire()
if(next_paycheck_delay <= world.time)
diff --git a/code/datums/components/label.dm b/code/datums/components/label.dm
index 0a8c50cdf71..eba55631c5a 100644
--- a/code/datums/components/label.dm
+++ b/code/datums/components/label.dm
@@ -52,8 +52,8 @@
* user: The mob who is wielding the attacking object.
*/
/datum/component/label/proc/OnAttackby(datum/source, obj/item/attacker, mob/user)
- // If the attacking object is not a hand labeler or its mode is 1 (has a label ready to apply), return.
- // The hand labeler should be off (mode is 0), in order to remove a label.
+ // If the attacking object is not a hand labeler or it's not off (has a label ready to apply), return.
+ // The hand labeler should be off in order to remove a label.
var/obj/item/hand_labeler/labeler = attacker
if(!istype(labeler) || labeler.mode)
return
@@ -85,3 +85,28 @@
var/atom/owner = parent
owner.name = replacetext(owner.name, "([label_name])", "") // Remove the label text from the parent's name, wherever it's located.
owner.name = trim(owner.name) // Shave off any white space from the beginning or end of the parent's name.
+
+/// A verson of the label component specific to labelling goal items.
+/datum/component/label/goal
+
+/datum/component/label/goal/Initialize(_label_name)
+ if(istype(parent, /obj/item))
+ // Can only be attached to things that won't go in a crate.
+ return COMPONENT_INCOMPATIBLE
+ return ..()
+
+/// Adds detailed information to the examine text.
+/datum/component/label/goal/Examine(datum/source, mob/user, list/examine_list)
+ examine_list += "It has a label on it, marking it as part of a secondary goal for [label_name]. Use a hand labeler to remove it."
+
+/// Applies a static label to the parent's name.
+/// We do this instead of using label_name so it's easier to identify goal objects at a glance.
+/datum/component/label/goal/apply_label()
+ var/atom/owner = parent
+ owner.name += " (Secondary Goal)"
+
+/// Removes the label from the parent's name
+/datum/component/label/goal/remove_label()
+ var/atom/owner = parent
+ owner.name = replacetext(owner.name, "(Secondary Goal)", "") // Remove the label text from the parent's name, wherever it's located.
+ owner.name = trim(owner.name) // Shave off any white space from the beginning or end of the parent's name.
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 6aa34a1d3b3..ae13b97766d 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -40,6 +40,7 @@
var/list/blob_overminds = list()
var/list/datum/station_goal/station_goals = list() // A list of all station goals for this game mode
+ var/list/datum/station_goal/secondary/secondary_goals = list() // A list of all secondary goals issued
/// Each item in this list can only be rolled once on average.
var/list/single_antag_positions = list("Head of Personnel", "Chief Engineer", "Research Director", "Chief Medical Officer", "Quartermaster")
@@ -177,6 +178,8 @@
SSblackbox.record_feedback("nested tally", "round_end_stats", escaped_on_pod_3, list("escapees", "on_pod_3"))
if(escaped_on_pod_5)
SSblackbox.record_feedback("nested tally", "round_end_stats", escaped_on_pod_5, list("escapees", "on_pod_5"))
+ for(var/tech_id in SSeconomy.tech_levels)
+ SSblackbox.record_feedback("tally", "cargo max tech level sold", SSeconomy.tech_levels[tech_id], tech_id)
GLOB.discord_manager.send2discord_simple(DISCORD_WEBHOOK_PRIMARY, "A round of [name] has ended - [surviving_total] survivors, [ghosts] ghosts.")
if(SSredis.connected)
@@ -466,12 +469,14 @@
/datum/game_mode/proc/generate_station_goals()
var/list/possible = list()
for(var/T in subtypesof(/datum/station_goal))
+ if(ispath(T, /datum/station_goal/secondary))
+ continue
var/datum/station_goal/G = T
if(config_tag in initial(G.gamemode_blacklist))
continue
- possible += T
+ possible += G
var/goal_weights = 0
- while(possible.len && goal_weights < STATION_GOAL_BUDGET)
+ while(length(possible) && goal_weights < STATION_GOAL_BUDGET)
var/datum/station_goal/picked = pick_n_take(possible)
goal_weights += initial(picked.weight)
station_goals += new picked
@@ -492,9 +497,24 @@
print_command_report(message_text, "NAS Trurl Orders", FALSE)
/datum/game_mode/proc/declare_station_goal_completion()
- for(var/V in station_goals)
- var/datum/station_goal/G = V
- G.print_result()
+ for(var/datum/station_goal/goal in station_goals)
+ goal.print_result()
+
+ var/departments = list()
+ for(var/datum/station_goal/secondary/goal in secondary_goals)
+ if(goal.completed)
+ if(!departments[goal.department])
+ departments[goal.department] = 0
+ departments[goal.department]++
+
+ to_chat(world, "Secondary Goals:")
+ var/any = FALSE
+ for(var/department in departments)
+ if(departments[department])
+ any = TRUE
+ to_chat(world, "[department]: [departments[department]] completed!")
+ if(!any)
+ to_chat(world, "None completed!")
/datum/game_mode/proc/generate_station_trait_report()
var/something_to_print = FALSE
diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm
index 8f8ebaa110e..560c136d45e 100644
--- a/code/game/jobs/access.dm
+++ b/code/game/jobs/access.dm
@@ -246,7 +246,7 @@
if(ACCESS_CAPTAIN)
return "Captain"
if(ACCESS_ALL_PERSONAL_LOCKERS)
- return "Personal Lockers"
+ return "Personal Lockers/Crates"
if(ACCESS_CHAPEL_OFFICE)
return "Chapel Office"
if(ACCESS_TECH_STORAGE)
diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm
index 63f3814b358..ba6682cb042 100644
--- a/code/game/machinery/requests_console.dm
+++ b/code/game/machinery/requests_console.dm
@@ -8,17 +8,18 @@
#define RC_INFO (1<<2) //Relay Info
//Request Console Screens
-#define RCS_MAINMENU 0 // Main menu
-#define RCS_RQSUPPLY 1 // Request supplies
-#define RCS_RQASSIST 2 // Request assistance
-#define RCS_SENDINFO 3 // Relay information
-#define RCS_SENTPASS 4 // Message sent successfully
-#define RCS_SENTFAIL 5 // Message sent unsuccessfully
-#define RCS_VIEWMSGS 6 // View messages
-#define RCS_MESSAUTH 7 // Authentication before sending
-#define RCS_ANNOUNCE 8 // Send announcement
-#define RCS_SHIPPING 9 // Print Shipping Labels/Packages
-#define RCS_SHIP_LOG 10 // View Shipping Label Log
+#define RCS_MAINMENU 0 // Main menu
+#define RCS_RQSUPPLY 1 // Request supplies
+#define RCS_RQASSIST 2 // Request assistance
+#define RCS_SENDINFO 3 // Relay information
+#define RCS_SENTPASS 4 // Message sent successfully
+#define RCS_SENTFAIL 5 // Message sent unsuccessfully
+#define RCS_VIEWMSGS 6 // View messages
+#define RCS_MESSAUTH 7 // Authentication before sending
+#define RCS_ANNOUNCE 8 // Send announcement
+#define RCS_SHIPPING 9 // Print Shipping Labels/Packages
+#define RCS_SHIP_LOG 10 // View Shipping Label Log
+#define RCS_SECONDARY 11 // Request secodary goal
//Radio list. For a console to announce messages on a specific radio, it's "department" variable must be in the list below.
#define ENGI_ROLES list("Atmospherics", "Engineering", "Chief Engineer's Desk")
@@ -51,21 +52,28 @@ GLOBAL_LIST_EMPTY(allRequestConsoles)
var/announcementConsole = FALSE
// FALSE = This console cannot be used to send department announcements
// TRUE = This console can send department announcementsf
- var/announceAuth = 0 //Will be set to 1 when you authenticate yourself for announcements
- var/msgVerified = "" //Will contain the name of the person who varified it
- var/msgStamped = "" //If a message is stamped, this will contain the stamp name
+ /// Will be set to TRUE when you authenticate yourself for announcements
+ var/announceAuth = FALSE
+ /// Will be set to TRUE when you authenticate yourself for requesting a secondary goal
+ var/secondaryGoalAuth = FALSE
+ /// Will contain the name of the person who verified it
+ var/msgVerified = "Not verified"
+ /// If a message is stamped, this will contain the stamp name
+ var/msgStamped = "Not stamped"
var/message = ""
var/recipient = ""; //the department which will be receiving the message
var/priority = -1 ; //Priority of the message being sent
light_range = 0
var/datum/announcer/announcer = new(config_type = /datum/announcement_configuration/requests_console)
+ /// The ID card of the person requesting a secondary goal.
+ var/goalRequester
var/list/shipping_log = list()
var/ship_tag_name = ""
var/ship_tag_index = 0
var/print_cooldown = 0 //cooldown on shipping label printer, stores the in-game time of when the printer will next be ready
var/obj/item/radio/Radio
- var/radiochannel = ""
var/reminder_timer_id = TIMER_ID_NULL
+ var/has_active_secondary_goal = FALSE
/obj/machinery/requests_console/power_change()
if(!..())
@@ -168,6 +176,8 @@ GLOBAL_LIST_EMPTY(allRequestConsoles)
data["msgStamped"] = msgStamped
data["msgVerified"] = msgVerified
data["announceAuth"] = announceAuth
+ data["secondaryGoalAuth"] = secondaryGoalAuth
+ data["secondaryGoalEnabled"] = !has_active_secondary_goal
data["shipDest"] = ship_tag_name
data["shipping_log"] = shipping_log
@@ -213,58 +223,34 @@ GLOBAL_LIST_EMPTY(allRequestConsoles)
announcer.Announce(message)
reset_message(TRUE)
- if("department")
- if(!message)
+ if("requestSecondaryGoal")
+ has_active_secondary_goal = check_for_active_secondary_goal(goalRequester)
+ if(has_active_secondary_goal || !secondaryGoalAuth)
return
- var/log_msg = message
- var/pass = FALSE
- screen = RCS_SENTFAIL
- for(var/M in GLOB.message_servers)
- var/obj/machinery/message_server/MS = M
- if(!MS.active)
- continue
- MS.send_rc_message(ckey(params["department"]), department, log_msg, msgStamped, msgVerified, priority)
- pass = TRUE
- if(pass)
+ generate_secondary_goal(department, goalRequester, usr)
+ reset_message(FALSE)
+ view_messages()
+ screen = RCS_VIEWMSGS
+
+ if("department")
+ if(send_requests_console_message(message, department, recipient, msgStamped, msgVerified, priority, Radio))
screen = RCS_SENTPASS
- if(recipient in ENGI_ROLES)
- radiochannel = "Engineering"
- else if(recipient in SEC_ROLES)
- radiochannel = "Security"
- else if(recipient in MISC_ROLES)
- radiochannel = "Service"
- else if(recipient in MED_ROLES)
- radiochannel = "Medical"
- else if(recipient in COM_ROLES)
- radiochannel = "Command"
- else if(recipient in SCI_ROLES)
- radiochannel = "Science"
- else if(recipient == "AI")
- radiochannel = "AI Private"
- else if(recipient in SUPPLY_ROLES)
- radiochannel = "Supply"
- message_log.Add(list(list("Message sent to [recipient] at [station_time_timestamp()]", "[message]")))
- Radio.autosay("Alert; a new message has been received from [department]", "[recipient] Requests Console", "[radiochannel]")
else
+ screen = RCS_SENTFAIL
atom_say("No server detected!")
//Handle screen switching
if("setScreen")
// Ensures screen cant be set higher or lower than it should be
- var/tempScreen = round(clamp(text2num(params["setScreen"]), 0, 10), 1)
+ var/tempScreen = round(clamp(text2num(params["setScreen"]), 0, 11), 1)
if(tempScreen == RCS_ANNOUNCE && !announcementConsole)
return
if(tempScreen == RCS_VIEWMSGS)
- for(var/obj/machinery/requests_console/Console in GLOB.allRequestConsoles)
- if(Console.department == department)
- Console.newmessagepriority = RQ_NONEW_MESSAGES
- Console.update_icon(UPDATE_OVERLAYS)
- Console.set_light(1)
- if(reminder_timer_id != TIMER_ID_NULL)
- deltimer(reminder_timer_id)
- reminder_timer_id = TIMER_ID_NULL
+ view_messages()
if(tempScreen == RCS_MAINMENU)
reset_message()
+ if(tempScreen == RCS_SECONDARY)
+ has_active_secondary_goal = check_for_active_secondary_goal(goalRequester)
screen = tempScreen
if("shipSelect")
@@ -303,12 +289,18 @@ GLOBAL_LIST_EMPTY(allRequestConsoles)
if(screen == RCS_ANNOUNCE)
var/obj/item/card/id/ID = I
if(ACCESS_RC_ANNOUNCE in ID.GetAccess())
- announceAuth = 1
+ announceAuth = TRUE
announcer.author = ID.assignment ? "[ID.assignment] [ID.registered_name]" : ID.registered_name
else
reset_message()
to_chat(user, "You are not authorized to send announcements.")
SStgui.update_uis(src)
+ if(screen == RCS_SECONDARY)
+ var/obj/item/card/id/ID = I
+ if(ID)
+ secondaryGoalAuth = TRUE
+ goalRequester = ID
+ has_active_secondary_goal = check_for_active_secondary_goal(goalRequester)
if(screen == RCS_SHIPPING)
var/obj/item/card/id/T = I
msgVerified = "Sender verified as [T.registered_name] ([T.assignment])"
@@ -327,16 +319,18 @@ GLOBAL_LIST_EMPTY(allRequestConsoles)
message = ""
recipient = ""
priority = RQ_NONEW_MESSAGES
- msgVerified = ""
- msgStamped = ""
+ msgVerified = "Not verified"
+ msgStamped = "Not stamped"
announceAuth = FALSE
+ secondaryGoalAuth = FALSE
announcer.author = ""
+ goalRequester = ""
ship_tag_name = ""
ship_tag_index = FALSE
if(mainmenu)
screen = RCS_MAINMENU
-/obj/machinery/requests_console/proc/createMessage(source, title, message, priority, forced = FALSE)
+/obj/machinery/requests_console/proc/createMessage(source, title, message, priority, forced = FALSE, verified = "", stamped = "")
var/linkedSender
if(inoperable() && !forced)
message_log.Add(list(list("Message lost due to console failure. Please contact [station_name()]'s system administrator or AI for technical assistance.")))
@@ -357,9 +351,9 @@ GLOBAL_LIST_EMPTY(allRequestConsoles)
switch(priority)
if(RQ_HIGHPRIORITY) // High
- message_log.Add(list(list("High Priority - From: [linkedSender]", message))) // List in a list for passing into TGUI
+ message_log.Add(list(list("High Priority - From: [linkedSender]") + message + list(verified, stamped))) // List in a list for passing into TGUI
else // Normal
- message_log.Add(list(list("From: [linkedSender]", message))) // List in a list for passing into TGUI
+ message_log.Add(list(list("From: [linkedSender]") + message + list(verified, stamped))) // List in a list for passing into TGUI
set_light(2)
/obj/machinery/requests_console/proc/remind_unread_messages()
@@ -379,6 +373,62 @@ GLOBAL_LIST_EMPTY(allRequestConsoles)
sp.update_desc()
print_cooldown = world.time + 600 //1 minute cooldown before you can print another label, but you can still configure the next one during this time
+/obj/machinery/requests_console/proc/view_messages()
+ for(var/obj/machinery/requests_console/Console in GLOB.allRequestConsoles)
+ if(Console.department == department)
+ Console.newmessagepriority = RQ_NONEW_MESSAGES
+ Console.update_icon(UPDATE_OVERLAYS)
+ Console.set_light(1)
+ if(reminder_timer_id != TIMER_ID_NULL)
+ deltimer(reminder_timer_id)
+ reminder_timer_id = TIMER_ID_NULL
+
+/obj/machinery/requests_console/proc/check_for_active_secondary_goal(obj/item/card/id/id)
+ if(!istype(id))
+ return FALSE
+ for(var/datum/station_goal/secondary/goal in SSticker.mode.secondary_goals)
+ if(goal.requester_name == id.registered_name && !goal.completed)
+ return TRUE
+ return FALSE
+
+/proc/send_requests_console_message(message, sender, recipient, stamped, verified, priority, obj/item/radio/radio)
+ if(!message)
+ return
+ var/found_message_server = FALSE
+ for(var/M in GLOB.message_servers)
+ var/obj/machinery/message_server/MS = M
+ if(!MS.active)
+ continue
+ MS.send_rc_message(ckey(recipient), sender, message, stamped, verified, priority)
+ found_message_server = TRUE
+
+ if(!found_message_server)
+ return FALSE
+
+ if(!radio)
+ return TRUE
+
+ var/radiochannel = ""
+ if(recipient in ENGI_ROLES)
+ radiochannel = "Engineering"
+ else if(recipient in SEC_ROLES)
+ radiochannel = "Security"
+ else if(recipient in MISC_ROLES)
+ radiochannel = "Service"
+ else if(recipient in MED_ROLES)
+ radiochannel = "Medical"
+ else if(recipient in COM_ROLES)
+ radiochannel = "Command"
+ else if(recipient in SCI_ROLES)
+ radiochannel = "Science"
+ else if(recipient == "AI")
+ radiochannel = "AI Private"
+ else if(recipient in SUPPLY_ROLES)
+ radiochannel = "Supply"
+ radio.autosay("Alert; a new message has been received from [sender]", "[recipient] Requests Console", "[radiochannel]")
+
+ return TRUE
+
#undef RC_ASSIST
#undef RC_SUPPLY
#undef RC_INFO
@@ -393,6 +443,7 @@ GLOBAL_LIST_EMPTY(allRequestConsoles)
#undef RCS_ANNOUNCE
#undef RCS_SHIPPING
#undef RCS_SHIP_LOG
+#undef RCS_SECONDARY
#undef ENGI_ROLES
#undef SEC_ROLES
#undef MISC_ROLES
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index d2d3050e71f..361d4d9fbd6 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -281,6 +281,58 @@
req_access += pick(get_all_accesses())
..()
+/obj/structure/closet/crate/secure/personal
+ name = "personal crate"
+ desc = "The crate version of Nanotrasen's famous personal locker, ideal for shipping booze, food, or drugs to CC without letting Cargo consume it. This one has not been configured by CC, and the first card swiped gains control."
+ req_access = list(ACCESS_ALL_PERSONAL_LOCKERS)
+ /// The name of the person this crate is registered to.
+ var/registered_name = null
+ // Unlike most secure crates, personal crates are easily obtained.
+ crate_value = DEFAULT_CRATE_VALUE
+
+/obj/structure/closet/crate/secure/personal/allowed(mob/user)
+ if(..())
+ return TRUE
+ var/obj/item/card/id/id = user.get_id_card()
+ if(is_usable_id(id))
+ return id.registered_name == registered_name
+ return FALSE
+
+/// Returns whether the object is a usable ID card (not guest pass, has name).
+/obj/structure/closet/crate/secure/personal/proc/is_usable_id(obj/item/card/id/id)
+ if(!istype(id))
+ return FALSE
+ if(istype(id, /obj/item/card/id/guest) || !id.registered_name)
+ return FALSE
+ return TRUE
+
+/obj/structure/closet/crate/secure/personal/attackby(obj/item/I, mob/user, params)
+ if(opened || !istype(I, /obj/item/card/id))
+ return ..()
+
+ if(broken)
+ to_chat(user, "It appears to be broken.")
+ return FALSE
+
+ var/obj/item/card/id/id = I
+ if(!is_usable_id(id))
+ to_chat(user, "Invalid identification card.")
+ return FALSE
+
+ if(registered_name && allowed(user))
+ return ..()
+
+ if(!registered_name)
+ registered_name = id.registered_name
+ desc = "Owned by [id.registered_name]."
+ to_chat(user, "Crate reserved")
+ return TRUE
+
+ if(registered_name == id.registered_name)
+ return ..()
+
+ return FALSE
+
/obj/structure/closet/crate/plastic
name = "plastic crate"
desc = "A rectangular plastic crate."
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 1f9256283d6..d70c4ab8ae1 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -3317,7 +3317,7 @@
else if(href_list["add_station_goal"])
if(!check_rights(R_EVENT))
return
- var/list/type_choices = typesof(/datum/station_goal)
+ var/list/type_choices = typesof(/datum/station_goal) - typesof(/datum/station_goal/secondary)
var/picked = input("Choose goal type") in type_choices|null
if(!picked)
return
@@ -3335,6 +3335,46 @@
SSticker.mode.station_goals += G
modify_goals()
+ else if(href_list["add_secondary_goal"])
+ if(!check_rights(R_EVENT))
+ return
+ var/list/type_choices = typesof(/datum/station_goal/secondary)
+ for(var/T in type_choices)
+ if(T == /datum/station_goal/secondary)
+ continue
+ var/datum/station_goal/secondary/SG = T
+ if(initial(SG.abstract))
+ type_choices -= SG
+ var/picked = pick_closest_path(FALSE, make_types_fancy(type_choices), skip_filter = TRUE)
+ if(!picked)
+ return
+ var/datum/station_goal/secondary/G = new picked()
+ if(picked == /datum/station_goal/secondary)
+ var/newname = clean_input("Enter goal name:")
+ if(!newname)
+ return
+ G.name = newname
+ var/description = input("Enter A.L.I.C.E message contents:") as message|null
+ if(!description)
+ return
+ G.report_message = description
+ var/admin_description = input("Enter description for admins:") as message|null
+ if(!admin_description)
+ return
+ G.admin_desc = admin_description
+ var/department_choices = list()
+ for(var/obj/machinery/requests_console/RC in GLOB.allRequestConsoles)
+ department_choices |= RC.department
+ var/department = input("Choose goal department") in department_choices|null
+ if(!department)
+ return
+ G.department = department
+ G.should_send_crate = alert("Send a personal crate?","Send crate","Yes","No") == "Yes"
+ G.Initialize()
+ message_admins("[key_name_admin(usr)] created \"[G.name]\" station goal. Description: [G.admin_desc]")
+ SSticker.mode.secondary_goals += G
+ modify_goals()
+
else if(href_list["showdetails"])
if(!check_rights(R_ADMIN))
return
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index 335b6bd6ea2..e14ecac5910 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -1147,11 +1147,18 @@ Traitors and the like can also be revived with the previous role mostly intact.
to_chat(usr, "This verb can only be used if the round has started.")
return
- var/dat = ""
+ var/list/dat = list()
for(var/datum/station_goal/S in SSticker.mode.station_goals)
- dat += "[S.name] - Announce | Remove
"
- dat += "
Add New Goal"
- usr << browse(dat, "window=goals;size=400x400")
+ dat += "[S.name][S.completed ? " (C)" : ""] - Announce | Remove"
+ dat += ""
+ dat += "Add New Goal"
+ dat += ""
+ dat += "Secondary goals"
+ for(var/datum/station_goal/secondary/SG in SSticker.mode.secondary_goals)
+ dat += "[SG.admin_desc][SG.completed ? " (C)" : ""] for [SG.requester_name || SG.department] - Announce | Remove | Mark complete | Reset progress"
+ dat += "Add New Secondary Goal"
+
+ usr << browse(dat.Join("
"), "window=goals;size=400x400")
/// Allow admin to add or remove traits of datum
/datum/admins/proc/modify_traits(datum/D)
diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm
index 0a1ff431e21..61f9b450ed5 100644
--- a/code/modules/events/spacevine.dm
+++ b/code/modules/events/spacevine.dm
@@ -17,11 +17,11 @@
// Make the event start fun - give the vine a random hostile mutation
if(SC.vines.len)
SV = SC.vines[1]
- var/list/mutations = SC.mutations_list.Copy()
- while(mutations.len)
+ var/list/mutations = subtypesof(/datum/spacevine_mutation)
+ while(mutations)
var/datum/spacevine_mutation/SM = pick_n_take(mutations)
- if(SM.quality == SPACEVINE_MUTATION_NEGATIVE && !SM.nofun)
- SM.add_mutation_to_vinepiece(SV)
+ if(initial(SM.quality) == SPACEVINE_MUTATION_NEGATIVE && !initial(SM.nofun))
+ SV.add_mutation(SM)
break
mutations.Cut()
mutations = null
@@ -35,19 +35,6 @@
// For stuff that isn't fun as a random-event vine
var/nofun = FALSE
-/datum/spacevine_mutation/proc/add_mutation_to_vinepiece(obj/structure/spacevine/holder)
- holder.mutations |= src
- holder.color = hue
-
-/datum/spacevine_mutation/proc/remove_mutation_from_vinepiece(obj/structure/spacevine/holder)
- holder.mutations -= src
- var/datum/spacevine_mutation/oldmutation
- if(holder.mutations.len)
- oldmutation = pick(holder.mutations)
- holder.color = oldmutation.hue
- else
- holder.color = ""
-
/datum/spacevine_mutation/proc/process_mutation(obj/structure/spacevine/holder)
return
@@ -91,11 +78,6 @@
return
-/datum/spacevine_mutation/space_covering
- name = "space protective"
- hue = "#aa77aa"
- quality = SPACEVINE_MUTATION_POSITIVE
-
/turf/simulated/floor/vines
color = "#aa77aa"
icon_state = "vinefloor"
@@ -139,6 +121,9 @@
SV.wither()
/datum/spacevine_mutation/space_covering
+ name = "space protective"
+ hue = "#aa77aa"
+ quality = SPACEVINE_MUTATION_POSITIVE
var/static/list/coverable_turfs
/datum/spacevine_mutation/space_covering/New()
@@ -181,7 +166,7 @@
// Lose bluespace upon piercing a single tile, and drop it from our own mutations too
// Representing a loss in "high potential"
// also conveniently prevents this from spreading too crazily
- remove_mutation_from_vinepiece(holder)
+ holder.remove_mutation(src.type)
holder.master.spawn_spacevine_piece(target, holder)
playsound(holder, 'sound/misc/interference.ogg', 50, 1)
. = TRUE
@@ -421,9 +406,9 @@
/obj/structure/spacevine/examine(mob/user)
. = ..()
var/text = "This one is a"
- if(mutations.len)
+ if(length(mutations))
for(var/A in mutations)
- var/datum/spacevine_mutation/SM = A
+ var/datum/spacevine_mutation/SM = mutations[A]
text += " [SM.name]"
else
text += " normal"
@@ -431,20 +416,23 @@
. += text
/obj/structure/spacevine/proc/wither()
- for(var/datum/spacevine_mutation/SM in mutations)
+ for(var/SM_type in mutations)
+ var/datum/spacevine_mutation/SM = mutations[SM_type]
SM.on_death(src)
qdel(src)
/obj/structure/spacevine/Destroy()
- for(var/datum/spacevine_mutation/SM in mutations)
+ for(var/SM_type in mutations)
+ var/datum/spacevine_mutation/SM = mutations[SM_type]
SM.on_deletion(src)
if(master)
master.vines -= src
master.growth_queue -= src
if(!master.vines.len)
var/obj/item/seeds/kudzu/KZ = new(loc)
- KZ.mutations |= mutations
+ for(var/mutation in mutations)
+ KZ.mutations += mutation
KZ.set_potency(10 ** sqrt(master.mutativeness))
KZ.set_production(10 - (master.spread_cap / 10))
qdel(master)
@@ -456,12 +444,21 @@
return ..()
/obj/structure/spacevine/proc/add_mutation(datum/spacevine_mutation/mutation)
- mutations |= mutation
- color = mutation.hue
+ if(!mutations[mutation])
+ mutations[mutation] = new mutation
+ color = mutation.hue
+
+/obj/structure/spacevine/proc/remove_mutation(datum/spacevine_mutation/mutation)
+ mutations -= mutation
+ if(length(mutations))
+ var/oldmutation_type = pick(mutations)
+ var/datum/spacevine_mutation/oldmutation = mutations[oldmutation_type]
+ color = oldmutation.hue
/obj/structure/spacevine/proc/on_chem_effect(datum/reagent/R)
var/override = 0
- for(var/datum/spacevine_mutation/SM in mutations)
+ for(var/SM_type in mutations)
+ var/datum/spacevine_mutation/SM = mutations[SM_type]
override += SM.on_chem(src, R)
if(!override && istype(R, /datum/reagent/glyphosate))
if(prob(50))
@@ -469,7 +466,8 @@
/obj/structure/spacevine/proc/eat(mob/eater)
var/override = 0
- for(var/datum/spacevine_mutation/SM in mutations)
+ for(var/SM_type in mutations)
+ var/datum/spacevine_mutation/SM = mutations[SM_type]
override += SM.on_eat(src, eater)
if(!override)
if(prob(10))
@@ -493,7 +491,8 @@
if(I.damtype == BURN)
damage_dealt *= 4
- for(var/datum/spacevine_mutation/SM in mutations)
+ for(var/SM_type in mutations)
+ var/datum/spacevine_mutation/SM = mutations[SM_type]
damage_dealt = SM.on_hit(src, user, I, damage_dealt) //on_hit now takes override damage as arg and returns new value for other mutations to permutate further
take_damage(damage_dealt, I.damtype, MELEE, 1)
@@ -512,11 +511,13 @@
/obj/structure/spacevine/Crossed(mob/crosser, oldloc)
if(isliving(crosser))
- for(var/datum/spacevine_mutation/SM in mutations)
+ for(var/SM_type in mutations)
+ var/datum/spacevine_mutation/SM = mutations[SM_type]
SM.on_cross(src, crosser)
/obj/structure/spacevine/attack_hand(mob/user)
- for(var/datum/spacevine_mutation/SM in mutations)
+ for(var/SM_type in mutations)
+ var/datum/spacevine_mutation/SM = mutations[SM_type]
SM.on_hit(src, user)
user_unbuckle_mob(user, user)
@@ -529,14 +530,12 @@
var/list/growth_queue = list()
var/spread_multiplier = 5
var/spread_cap = 30
- var/list/mutations_list = list()
var/mutativeness = 1
/obj/structure/spacevine_controller/New(loc, list/muts, potency, production)
color = "#ffffff"
spawn_spacevine_piece(loc, null, muts)
START_PROCESSING(SSobj, src)
- init_subtypes(/datum/spacevine_mutation/, mutations_list)
if(potency != null && potency > 0)
// 1 mutativeness at 10 potency
// 4 mutativeness at 100 potency
@@ -571,20 +570,21 @@
growth_queue += SV
vines += SV
SV.master = src
- if(muts && muts.len)
- for(var/datum/spacevine_mutation/M in muts)
- M.add_mutation_to_vinepiece(SV)
+ if(length(muts))
+ for(var/M in muts)
+ SV.add_mutation(M)
return
if(parent)
SV.mutations |= parent.mutations
SV.color = parent.color
if(prob(mutativeness))
- var/list/random_mutations_picked = mutations_list - SV.mutations
- if(random_mutations_picked.len)
- var/datum/spacevine_mutation/randmut = pick(random_mutations_picked)
- randmut.add_mutation_to_vinepiece(SV)
+ var/list/random_mutation_candidates = subtypesof(/datum/spacevine_mutation) - SV.mutations
+ if(length(random_mutation_candidates))
+ var/datum/spacevine_mutation/randmut = pick(random_mutation_candidates)
+ SV.add_mutation(randmut)
- for(var/datum/spacevine_mutation/SM in SV.mutations)
+ for(var/SM_type in SV.mutations)
+ var/datum/spacevine_mutation/SM = SV.mutations[SM_type]
SM.on_birth(SV)
/obj/structure/spacevine_controller/process()
@@ -607,7 +607,8 @@
i++
queue_end += SV
growth_queue -= SV
- for(var/datum/spacevine_mutation/SM in SV.mutations)
+ for(var/SM_type in SV.mutations)
+ var/datum/spacevine_mutation/SM = SV.mutations[SM_type]
SM.process_mutation(SV)
if(SV.energy < 2) //If tile isn't fully grown
if(prob(20))
@@ -631,7 +632,8 @@
icon_state = pick("Hvy1", "Hvy2", "Hvy3")
energy = 2
- for(var/datum/spacevine_mutation/SM in mutations)
+ for(var/SM_type in mutations)
+ var/datum/spacevine_mutation/SM = mutations[SM_type]
SM.on_grow(src)
/obj/structure/spacevine/proc/entangle_mob()
@@ -645,7 +647,8 @@
/obj/structure/spacevine/proc/entangle(mob/living/V)
if(!V || isvineimmune(V))
return
- for(var/datum/spacevine_mutation/SM in mutations)
+ for(var/SM_type in mutations)
+ var/datum/spacevine_mutation/SM = mutations[SM_type]
SM.on_buckle(src, V)
if((V.stat != DEAD) && (V.buckled != src)) //not dead or captured
to_chat(V, "The vines [pick("wind", "tangle", "tighten")] around you!")
@@ -654,14 +657,16 @@
/obj/structure/spacevine/proc/spread()
var/list/dir_list = GLOB.cardinal.Copy()
var/spread_search = FALSE // Whether to exhaustive search all 4 cardinal dirs for an open direction
- for(var/datum/spacevine_mutation/SM in mutations)
+ for(var/SM_type in mutations)
+ var/datum/spacevine_mutation/SM = mutations[SM_type]
spread_search |= SM.on_search(src)
while(dir_list.len)
var/direction = pick(dir_list)
dir_list -= direction
var/turf/stepturf = get_step(src,direction)
var/spread_success = FALSE
- for(var/datum/spacevine_mutation/SM in mutations)
+ for(var/SM_type in mutations)
+ var/datum/spacevine_mutation/SM = mutations[SM_type]
spread_success |= SM.on_spread(src, stepturf) // If this returns 1, spreading succeeded
if(!locate(/obj/structure/spacevine, stepturf))
// snowflake for space turf, but space turf is super common and a big deal
@@ -674,7 +679,8 @@
/obj/structure/spacevine/ex_act(severity)
var/i
- for(var/datum/spacevine_mutation/SM in mutations)
+ for(var/SM_type in mutations)
+ var/datum/spacevine_mutation/SM = mutations[SM_type]
i += SM.on_explosion(severity, src)
if(!i && prob(100/severity))
wither()
@@ -682,7 +688,8 @@
/obj/structure/spacevine/temperature_expose(null, temp, volume)
..()
var/override = 0
- for(var/datum/spacevine_mutation/SM in mutations)
+ for(var/SM_type in mutations)
+ var/datum/spacevine_mutation/SM = mutations[SM_type]
override += SM.process_temperature(src, temp, volume)
if(!override)
wither()
diff --git a/code/modules/food_and_drinks/food/foods/baked_goods.dm b/code/modules/food_and_drinks/food/foods/baked_goods.dm
index a4ab2d626ba..903e25d32db 100644
--- a/code/modules/food_and_drinks/food/foods/baked_goods.dm
+++ b/code/modules/food_and_drinks/food/foods/baked_goods.dm
@@ -25,6 +25,7 @@
trash = /obj/item/trash/plate
filling_color = "#FFD675"
tastes = list("cake" = 5, "sweetness" = 2, "carrot" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/braincake
@@ -47,6 +48,7 @@
trash = /obj/item/trash/plate
filling_color = "#E6AEDB"
tastes = list("cake" = 5, "sweetness" = 2, "brains" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/sliceable/cheesecake
name = "cheese cake"
@@ -68,6 +70,7 @@
trash = /obj/item/trash/plate
filling_color = "#FAF7AF"
tastes = list("cake" = 4, "cream cheese" = 3)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/plaincake
name = "vanilla cake"
@@ -89,6 +92,7 @@
trash = /obj/item/trash/plate
filling_color = "#F7EDD5"
tastes = list("cake" = 5, "vanilla" = 1, "sweetness" = 2)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/orangecake
name = "orange cake"
@@ -110,6 +114,7 @@
trash = /obj/item/trash/plate
filling_color = "#FADA8E"
tastes = list("cake" = 5, "sweetness" = 2, "oranges" = 2)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/bananacake
name = "banana cake"
@@ -131,6 +136,7 @@
trash = /obj/item/trash/plate
filling_color = "#FADA8E"
tastes = list("cake" = 5, "sweetness" = 2, "banana" = 2)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/limecake
name = "lime cake"
@@ -152,6 +158,7 @@
trash = /obj/item/trash/plate
filling_color = "#CBFA8E"
tastes = list("cake" = 5, "sweetness" = 2, "unbearable sourness" = 2)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/lemoncake
name = "lemon cake"
@@ -173,6 +180,7 @@
trash = /obj/item/trash/plate
filling_color = "#FAFA8E"
tastes = list("cake" = 5, "sweetness" = 2, "sourness" = 2)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/chocolatecake
name = "chocolate cake"
@@ -194,6 +202,7 @@
trash = /obj/item/trash/plate
filling_color = "#805930"
tastes = list("cake" = 5, "sweetness" = 1, "chocolate" = 4)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/birthdaycake
name = "birthday cake"
@@ -215,6 +224,7 @@
trash = /obj/item/trash/plate
filling_color = "#FFD6D6"
tastes = list("cake" = 5, "sweetness" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/sliceable/applecake
name = "apple cake"
@@ -236,6 +246,7 @@
trash = /obj/item/trash/plate
filling_color = "#EBF5B8"
tastes = list("cake" = 5, "sweetness" = 1, "apple" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
//////////////////////
@@ -251,6 +262,7 @@
filling_color = "#DBC94F"
list_reagents = list("nutriment" = 1, "sugar" = 3, "hot_coco" = 5 )
tastes = list("cookie" = 1, "crunchy chocolate" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/fortunecookie
name = "fortune cookie"
@@ -261,6 +273,7 @@
list_reagents = list("nutriment" = 3)
trash = /obj/item/paper/fortune
tastes = list("cookie" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/sugarcookie
name = "sugar cookie"
@@ -269,6 +282,7 @@
icon_state = "sugarcookie"
list_reagents = list("nutriment" = 1, "sugar" = 3)
tastes = list("sweetness" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
//////////////////////
@@ -285,6 +299,7 @@
bitesize = 3
list_reagents = list("nutriment" = 6, "banana" = 5, "vitamin" = 2)
tastes = list("pie" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/pie/throw_impact(atom/hit_atom)
..()
@@ -302,6 +317,7 @@
bitesize = 3
list_reagents = list("nutriment" = 10, "vitamin" = 2)
tastes = list("pie" = 1, "meat" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/tofupie
name = "tofu-pie"
@@ -313,6 +329,7 @@
bitesize = 3
list_reagents = list("nutriment" = 10, "vitamin" = 2)
tastes = list("pie" = 1, "tofu" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/amanita_pie
name = "amanita pie"
@@ -323,6 +340,7 @@
bitesize = 4
list_reagents = list("nutriment" = 6, "amanitin" = 3, "psilocybin" = 1, "vitamin" = 4)
tastes = list("pie" = 1, "mushroom" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/plump_pie
name = "plump pie"
@@ -333,6 +351,7 @@
bitesize = 3
list_reagents = list("nutriment" = 10, "vitamin" = 2)
tastes = list("pie" = 1, "mushroom" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/plump_pie/Initialize(mapload)
. = ..()
@@ -361,6 +380,7 @@
bitesize = 3
list_reagents = list("nutriment" = 10, "vitamin" = 2)
tastes = list("pie" = 1, "apple" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/cherrypie
@@ -372,6 +392,7 @@
bitesize = 3
list_reagents = list("nutriment" = 10, "vitamin" = 2)
tastes = list("pie" = 1, "cherries" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/sliceable/pumpkinpie
name = "pumpkin pie"
@@ -384,6 +405,7 @@
filling_color = "#F5B951"
list_reagents = list("nutriment" = 20, "vitamin" = 5)
tastes = list("pie" = 1, "pumpkin" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/pumpkinpieslice
name = "pumpkin pie slice"
@@ -393,6 +415,7 @@
trash = /obj/item/trash/plate
filling_color = "#F5B951"
tastes = list("pie" = 1, "pumpkin" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
//////////////////////
// Donuts //
@@ -433,6 +456,7 @@
desc = "Like life, it never quite tastes the same."
bitesize = 10
tastes = list("donut" = 3, "chaos" = 1)
+ goal_difficulty = FOOD_GOAL_HARD
/obj/item/food/snacks/donut/chaos/Initialize(mapload)
. = ..()
@@ -450,6 +474,7 @@
icon_state = "jdonut1"
extra_reagent = "berryjuice"
tastes = list("jelly" = 1, "donut" = 3)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/donut/jelly/Initialize(mapload)
. = ..()
@@ -467,6 +492,7 @@
desc = "You jelly?"
icon_state = "jdonut1"
extra_reagent = "slimejelly"
+ goal_difficulty = FOOD_GOAL_HARD
/obj/item/food/snacks/donut/jelly/cherryjelly
name = "jelly donut"
@@ -487,6 +513,7 @@
bitesize = 2
list_reagents = list("nutriment" = 3, "sugar" = 3)
tastes = list("sweet cake" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/pancake/attack_tk(mob/user)
if(src in user.tkgrabbed_objects)
@@ -509,6 +536,7 @@
icon_state = "berry_pancake"
list_reagents = list("nutriment" = 3, "sugar" = 3, "berryjuice" = 3)
tastes = list("sweet cake" = 2, "berries" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/pancake/choc_chip_pancake
name = "choc-chip pancake"
@@ -516,6 +544,7 @@
icon_state = "choc_chip_pancake"
list_reagents = list("nutriment" = 3, "sugar" = 3, "cocoa" = 3)
tastes = list("sweet cake" = 2, "chocolate" = 3)
+ goal_difficulty = FOOD_GOAL_NORMAL
//////////////////////
// Misc //
@@ -529,6 +558,7 @@
filling_color = "#E0CF9B"
list_reagents = list("nutriment" = 6)
tastes = list("muffin" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/berryclafoutis
name = "berry clafoutis"
@@ -539,6 +569,7 @@
bitesize = 3
list_reagents = list("nutriment" = 10, "berryjuice" = 5, "vitamin" = 2)
tastes = list("pie" = 1, "blackberries" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/poppypretzel
@@ -549,6 +580,7 @@
filling_color = "#916E36"
list_reagents = list("nutriment" = 5)
tastes = list("pretzel" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/plumphelmetbiscuit
name = "plump helmet biscuit"
@@ -558,6 +590,7 @@
filling_color = "#CFB4C4"
list_reagents = list("nutriment" = 5)
tastes = list("mushroom" = 1, "biscuit" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/plumphelmetbiscuit/Initialize(mapload)
. = ..()
@@ -576,6 +609,7 @@
bitesize = 3
list_reagents = list("nutriment" = 8, "gold" = 5, "vitamin" = 4)
tastes = list("pie" = 1, "apple" = 1, "expensive metal" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/cracker
@@ -587,6 +621,7 @@
filling_color = "#F5DEB8"
list_reagents = list("nutriment" = 1)
tastes = list("cracker" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/croissant
name = "croissant"
@@ -597,6 +632,7 @@
filling_color = "#ecb54f"
list_reagents = list("nutriment" = 4, "sugar" = 2)
tastes = list("croissant" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/croissant/throwing
throwforce = 20
diff --git a/code/modules/food_and_drinks/food/foods/bread.dm b/code/modules/food_and_drinks/food/foods/bread.dm
index c2cfd50226b..e81ee938ff9 100644
--- a/code/modules/food_and_drinks/food/foods/bread.dm
+++ b/code/modules/food_and_drinks/food/foods/bread.dm
@@ -20,6 +20,7 @@
icon = 'icons/obj/food/burgerbread.dmi'
icon_state = "meatbreadslice"
filling_color = "#FF7575"
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/xenomeatbread
name = "xenomeatbread loaf"
@@ -75,6 +76,7 @@
icon_state = "bananabreadslice"
filling_color = "#EDE5AD"
tastes = list("bread" = 10, "banana" = 5)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/tofubread
name = "tofubread"
@@ -93,6 +95,7 @@
icon = 'icons/obj/food/burgerbread.dmi'
icon_state = "tofubreadslice"
filling_color = "#F7FFE0"
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/bread
name = "bread"
@@ -113,6 +116,7 @@
filling_color = "#D27332"
list_reagents = list("nutriment" = 2, "bread" = 5)
tastes = list("bread" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/creamcheesebread
name = "cream cheese bread"
@@ -133,6 +137,7 @@
filling_color = "#FFF896"
list_reagents = list("nutriment" = 4, "vitamin" = 1)
tastes = list("bread" = 10, "cheese" = 10)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/banarnarbread
name = "banarnarbread loaf"
@@ -153,6 +158,7 @@
filling_color = "#6F0000"
list_reagents = list("nutriment" = 4, "vitamin" = 1)
tastes = list("heresy" = 10, "banana" = 10)
+ goal_difficulty = FOOD_GOAL_EASY
//////////////////////
@@ -166,6 +172,7 @@
icon_state = "bun"
list_reagents = list("nutriment" = 1)
tastes = list("bun" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/flatbread
@@ -175,6 +182,7 @@
icon_state = "flatbread"
list_reagents = list("nutriment" = 6, "vitamin" = 1)
tastes = list("bread" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/baguette
name = "baguette"
@@ -187,6 +195,7 @@
bitesize = 3
list_reagents = list("nutriment" = 6, "vitamin" = 1)
tastes = list("bread" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/baguette/combat
sharp = TRUE
@@ -205,6 +214,7 @@
bitesize = 3
list_reagents = list("nutriment" = 2, "vitamin" = 2)
tastes = list("bread" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/toast
name = "toast"
@@ -227,9 +237,11 @@
/obj/item/food/snacks/jelliedtoast/cherry
list_reagents = list("nutriment" = 1, "cherryjelly" = 5, "vitamin" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/jelliedtoast/slime
list_reagents = list("nutriment" = 1, "slimejelly" = 5, "vitamin" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/rofflewaffles
name = "roffle waffles"
@@ -241,6 +253,7 @@
bitesize = 4
list_reagents = list("nutriment" = 8, "psilocybin" = 2, "vitamin" = 2)
tastes = list("waffle" = 1, "mushrooms" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/waffles
name = "waffles"
@@ -250,3 +263,4 @@
trash = /obj/item/trash/waffles
filling_color = "#E6DEB5"
list_reagents = list("nutriment" = 8, "vitamin" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
diff --git a/code/modules/food_and_drinks/food/foods/candy.dm b/code/modules/food_and_drinks/food/foods/candy.dm
index fe3fe0ac48a..80cbfc5ee20 100644
--- a/code/modules/food_and_drinks/food/foods/candy.dm
+++ b/code/modules/food_and_drinks/food/foods/candy.dm
@@ -13,25 +13,19 @@
icon = 'icons/obj/food/candy.dmi'
icon_state = "candy"
tastes = list("candy" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
// ***********************************************************
// Candy Ingredients / Flavorings / Byproduct
// ***********************************************************
-/obj/item/food/snacks/chocolatebar
- name = "chocolate bar"
- desc = "Such sweet, fattening food."
- icon_state = "chocolatebar"
- filling_color = "#7D5F46"
- list_reagents = list("nutriment" = 2, "chocolate" = 4)
- tastes = list("chocolate" = 1)
-
/obj/item/food/snacks/candy/caramel
name = "caramel"
desc = "Chewy and dense, yet it practically melts in your mouth!"
icon_state = "caramel"
filling_color = "#DB944D"
list_reagents = list("cream" = 2, "sugar" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/toffee
@@ -40,6 +34,7 @@
icon_state = "toffee"
filling_color = "#7D5F46"
list_reagents = list("nutriment" = 3, "sugar" = 3)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/nougat
name = "nougat"
@@ -47,6 +42,7 @@
icon_state = "nougat"
filling_color = "#7D5F46"
list_reagents = list("nutriment" = 3, "sugar" = 3)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/taffy
name = "saltwater taffy"
@@ -54,6 +50,7 @@
icon_state = "candy1"
filling_color = "#7D5F46"
list_reagents = list("nutriment" = 3, "sugar" = 3)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/taffy/Initialize(mapload)
. = ..()
@@ -66,18 +63,21 @@
filling_color = "#7D5F46"
bitesize = 3
list_reagents = list("cream" = 3, "chocolate" = 6)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/fudge/peanut
name = "peanut fudge"
desc = "Chocolate fudge, with bits of peanuts mixed in. People with nut allergies shouldn't eat this."
icon_state = "fudge_peanut"
filling_color = "#7D5F46"
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/fudge/cherry
name = "chocolate cherry fudge"
desc = "Chocolate fudge surrounding sweet cherries. Good for tricking kids into eating some fruit."
icon_state = "fudge_cherry"
filling_color = "#7D5F46"
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/fudge/cookies_n_cream
name = "cookies 'n' cream fudge"
@@ -85,12 +85,14 @@
icon_state = "fudge_cookies_n_cream"
filling_color = "#7D5F46"
list_reagents = list("cream" = 6, "chocolate" = 6)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/fudge/turtle
name = "turtle fudge"
desc = "Chocolate fudge with caramel and nuts. It doesn't contain real turtles, thankfully."
icon_state = "fudge_turtle"
filling_color = "#7D5F46"
+ goal_difficulty = FOOD_GOAL_NORMAL
// ***********************************************************
// Candy Products (Pre-existing)
@@ -135,6 +137,7 @@
antable = FALSE
list_reagents = list("nutriment" = 1, "chocolate" = 1)
tastes = list("chocolate" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/candycane
@@ -143,6 +146,7 @@
icon_state = "candycane"
filling_color = "#F2F2F2"
list_reagents = list("minttoxin" = 1, "sugar" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/gummybear
name = "gummy bear"
@@ -175,6 +179,7 @@
filling_color = "#ED0758"
bitesize = 0.1 //this is gonna take a while, you'll be working at this all shift.
list_reagents = list("sugar" = 10)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/cash
name = "candy cash"
@@ -183,6 +188,7 @@
filling_color = "#302000"
list_reagents = list("nutriment" = 2, "chocolate" = 4)
tastes = list("chocolate" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/coin
@@ -193,6 +199,7 @@
bitesize = 3
list_reagents = list("nutriment" = 2, "chocolate" = 4)
tastes = list("chocolate" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/gum
@@ -203,6 +210,7 @@
filling_color = "#FF7495"
bitesize = 0.2
list_reagents = list("sugar" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/sucker
name = "sucker"
@@ -210,244 +218,273 @@
icon_state = "sucker"
filling_color = "#FFFFFF"
list_reagents = list("sugar" = 10)
+ goal_difficulty = FOOD_GOAL_NORMAL
// ***********************************************************
// Gummy Bear Flavors
// ***********************************************************
/obj/item/food/snacks/candy/gummybear/red
- name = "gummy bear"
+ name = "red gummy bear"
desc = "A small edible bear. It's red!"
icon_state = "gbear_red"
filling_color = "#801E28"
list_reagents = list("sugar" = 10, "cherryjelly" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/gummybear/blue
- name = "gummy bear"
+ name = "blue gummy bear"
desc = "A small edible bear. It's blue!"
icon_state = "gbear_blue"
filling_color = "#863333"
list_reagents = list("sugar" = 10, "berryjuice" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/gummybear/poison
- name = "gummy bear"
+ name = "blue gummy bear"
desc = "A small edible bear. It's blue!"
icon_state = "gbear_blue"
filling_color = "#863353"
list_reagents = list("poisonberryjuice" = 12)
/obj/item/food/snacks/candy/gummybear/green
- name = "gummy bear"
+ name = "green gummy bear"
desc = "A small edible bear. It's green!"
icon_state = "gbear_green"
filling_color = "#365E30"
list_reagents = list("sugar" = 10, "limejuice" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/gummybear/yellow
- name = "gummy bear"
+ name = "yellow gummy bear"
desc = "A small edible bear. It's yellow!"
icon_state = "gbear_yellow"
filling_color = "#863333"
list_reagents = list("sugar" = 10, "lemonjuice" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/gummybear/orange
- name = "gummy bear"
+ name = "orange gummy bear"
desc = "A small edible bear. It's orange!"
icon_state = "gbear_orange"
filling_color = "#E78108"
list_reagents = list("sugar" = 10, "orangejuice" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/gummybear/purple
- name = "gummy bear"
+ name = "purple gummy bear"
desc = "A small edible bear. It's purple!"
icon_state = "gbear_purple"
filling_color = "#993399"
list_reagents = list("sugar" = 10, "grapejuice" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/gummybear/wtf
- name = "gummy bear"
+ name = "rainbow gummy bear"
desc = "A small bear. Wait... what?"
icon_state = "gbear_rainbow"
filling_color = "#60A584"
list_reagents = list("sugar" = 10, "space_drugs" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
// ***********************************************************
// Gummy Worm Flavors
// ***********************************************************
/obj/item/food/snacks/candy/gummyworm/red
- name = "gummy worm"
+ name = "red gummy worm"
desc = "An edible worm, made from gelatin. It's red!"
icon_state = "gworm_red"
filling_color = "#801E28"
list_reagents = list("sugar" = 10, "cherryjelly" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/gummyworm/blue
- name = "gummy worm"
+ name = "blue gummy worm"
desc = "An edible worm, made from gelatin. It's blue!"
icon_state = "gworm_blue"
filling_color = "#863333"
list_reagents = list("sugar" = 10, "berryjuice" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/gummyworm/poison
- name = "gummy worm"
+ name = "blue gummy worm"
desc = "An edible worm, made from gelatin. It's blue!"
icon_state = "gworm_blue"
filling_color = "#863353"
list_reagents = list("poisonberryjuice" = 12)
/obj/item/food/snacks/candy/gummyworm/green
- name = "gummy worm"
+ name = "green gummy worm"
desc = "An edible worm, made from gelatin. It's green!"
icon_state = "gworm_green"
filling_color = "#365E30"
list_reagents = list("sugar" = 10, "limejuice" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/gummyworm/yellow
- name = "gummy worm"
+ name = "yellow gummy worm"
desc = "An edible worm, made from gelatin. It's yellow!"
icon_state = "gworm_yellow"
filling_color = "#863333"
list_reagents = list("sugar" = 10, "lemonjuice" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/gummyworm/orange
- name = "gummy worm"
+ name = "orange gummy worm"
desc = "An edible worm, made from gelatin. It's orange!"
icon_state = "gworm_orange"
filling_color = "#E78108"
list_reagents = list("sugar" = 10, "orangejuice" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/gummyworm/purple
- name = "gummy worm"
+ name = "purple gummy worm"
desc = "An edible worm, made from gelatin. It's purple!"
icon_state = "gworm_purple"
filling_color = "#993399"
list_reagents = list("sugar" = 10, "grapejuice" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/gummyworm/wtf
- name = "gummy worm"
+ name = "rainbow gummy worm"
desc = "An edible worm. Did it just move?"
icon_state = "gworm_rainbow"
filling_color = "#60A584"
list_reagents = list("sugar" = 10, "space_drugs" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
// ***********************************************************
// Jelly Bean Flavors
// ***********************************************************
/obj/item/food/snacks/candy/jellybean/red
- name = "jelly bean"
+ name = "red jelly bean"
desc = "A candy bean, guaranteed to not give you gas. It's red!"
icon_state = "jbean_red"
filling_color = "#801E28"
list_reagents = list("sugar" = 10, "cherryjelly" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/jellybean/blue
- name = "jelly bean"
+ name = "blue jelly bean"
desc = "A candy bean, guaranteed to not give you gas. It's blue!"
icon_state = "jbean_blue"
filling_color = "#863333"
list_reagents = list("sugar" = 10, "berryjuice" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/jellybean/poison
- name = "jelly bean"
+ name = "blue jelly bean"
desc = "A candy bean, guaranteed to not give you gas. It's blue!"
icon_state = "jbean_blue"
filling_color = "#863353"
list_reagents = list("poisonberryjuice" = 12)
/obj/item/food/snacks/candy/jellybean/green
- name = "jelly bean"
+ name = "green jelly bean"
desc = "A candy bean, guaranteed to not give you gas. It's green!"
icon_state = "jbean_green"
filling_color = "#365E30"
list_reagents = list("sugar" = 10, "limejuice" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/jellybean/yellow
- name = "jelly bean"
+ name = "yellow jelly bean"
desc = "A candy bean, guaranteed to not give you gas. It's yellow!"
icon_state = "jbean_yellow"
filling_color = "#863333"
list_reagents = list("sugar" = 10, "lemonjuice" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/jellybean/orange
- name = "jelly bean"
+ name = "orange jelly bean"
desc = "A candy bean, guaranteed to not give you gas. It's orange!"
icon_state = "jbean_orange"
filling_color = "#E78108"
list_reagents = list("sugar" = 10, "orangejuice" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/jellybean/purple
- name = "jelly bean"
+ name = "purple jelly bean"
desc = "A candy bean, guaranteed to not give you gas. It's purple!"
icon_state = "jbean_purple"
filling_color = "#993399"
list_reagents = list("sugar" = 10, "grapejuice" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/jellybean/chocolate
- name = "jelly bean"
+ name = "chocolate jelly bean"
desc = "A candy bean, guaranteed to not give you gas. It's chocolate!"
icon_state = "jbean_choc"
filling_color = "#302000"
list_reagents = list("sugar" = 10, "chocolate" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/jellybean/popcorn
- name = "jelly bean"
+ name = "popcorn jelly bean"
desc = "A candy bean, guaranteed to not give you gas. It's popcorn flavored!"
icon_state = "jbean_popcorn"
filling_color = "#664330"
list_reagents = list("sugar" = 10, "nutriment" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/jellybean/cola
- name = "jelly bean"
+ name = "cola jelly bean"
desc = "A candy bean, guaranteed to not give you gas. It's Cola flavored!"
icon_state = "jbean_cola"
filling_color = "#102000"
list_reagents = list("sugar" = 10, "cola" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/jellybean/drgibb
- name = "jelly bean"
+ name = "\improper Dr. Gibb jelly bean"
desc = "A candy bean, guaranteed to not give you gas. It's Dr. Gibb flavored!"
icon_state = "jbean_cola"
filling_color = "#102000"
list_reagents = list("sugar" = 10, "dr_gibb" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/jellybean/coffee
- name = "jelly bean"
+ name = "coffee jelly bean"
desc = "A candy bean, guaranteed to not give you gas. It's Coffee flavored!"
icon_state = "jbean_choc"
filling_color = "#482000"
list_reagents = list("sugar" = 10, "coffee" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/jellybean/wtf
- name = "jelly bean"
+ name = "rainbow jelly bean"
desc = "A candy bean, guaranteed to not give you gas. You aren't sure what color it is."
icon_state = "jbean_rainbow"
filling_color = "#60A584"
list_reagents = list("sugar" = 10, "space_drugs" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
// ***********************************************************
// Cotton Candy Flavors
// ***********************************************************
/obj/item/food/snacks/candy/cotton/red
- name = "cotton candy"
+ name = "red cotton candy"
desc = "Light and fluffy, it's like eating a cloud made from sugar!"
icon_state = "cottoncandy_red"
trash = /obj/item/c_tube
filling_color = "#801E28"
list_reagents = list("sugar" = 15, "cherryjelly" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/cotton/blue
- name = "cotton candy"
+ name = "blue cotton candy"
desc = "Light and fluffy, it's like eating a cloud made from sugar!"
icon_state = "cottoncandy_blue"
trash = /obj/item/c_tube
filling_color = "#863333"
list_reagents = list("sugar" = 15, "berryjuice" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/cotton/poison
- name = "cotton candy"
+ name = "blue cotton candy"
desc = "Light and fluffy, it's like eating a cloud made from sugar!"
icon_state = "cottoncandy_blue"
trash = /obj/item/c_tube
@@ -455,55 +492,61 @@
list_reagents = list("poisonberryjuice" = 20)
/obj/item/food/snacks/candy/cotton/green
- name = "cotton candy"
+ name = "green cotton candy"
desc = "Light and fluffy, it's like eating a cloud made from sugar!"
icon_state = "cottoncandy_green"
trash = /obj/item/c_tube
filling_color = "#365E30"
list_reagents = list("sugar" = 15, "limejuice" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/cotton/yellow
- name = "cotton candy"
+ name = "yellow cotton candy"
desc = "Light and fluffy, it's like eating a cloud made from sugar!"
icon_state = "cottoncandy_yellow"
trash = /obj/item/c_tube
filling_color = "#863333"
list_reagents = list("sugar" = 15, "lemonjuice" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/cotton/orange
- name = "cotton candy"
+ name = "orange cotton candy"
desc = "Light and fluffy, it's like eating a cloud made from sugar!"
icon_state = "cottoncandy_orange"
trash = /obj/item/c_tube
filling_color = "#E78108"
list_reagents = list("sugar" = 15, "orangejuice" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/cotton/purple
- name = "cotton candy"
+ name = "purple cotton candy"
desc = "Light and fluffy, it's like eating a cloud made from sugar!"
icon_state = "cottoncandy_purple"
trash = /obj/item/c_tube
filling_color = "#993399"
list_reagents = list("sugar" = 15, "grapejuice" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/cotton/pink
- name = "cotton candy"
+ name = "pink cotton candy"
desc = "Light and fluffy, it's like eating a cloud made from sugar!"
icon_state = "cottoncandy_pink"
trash = /obj/item/c_tube
filling_color = "#863333"
list_reagents = list("sugar" = 15, "watermelonjuice" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/cotton/rainbow
- name = "cotton candy"
+ name = "rainbow cotton candy"
desc = "Light and fluffy, it's like eating a cloud made from sugar!"
icon_state = "cottoncandy_rainbow"
trash = /obj/item/c_tube
filling_color = "#C8A5DC"
list_reagents = list("omnizine" = 20)
+ goal_difficulty = FOOD_GOAL_HARD
/obj/item/food/snacks/candy/cotton/bad_rainbow
- name = "cotton candy"
+ name = "rainbow cotton candy"
desc = "Light and fluffy, it's like eating a cloud made from sugar!"
icon_state = "cottoncandy_rainbow"
trash = /obj/item/c_tube
@@ -523,27 +566,32 @@
icon_state = "asteroidcrunch"
trash = /obj/item/trash/candy
filling_color = "#7D5F46"
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/confectionery/toffee
name = "Yum-Baton Bar"
desc = "Chocolate and toffee in the shape of a baton. Security sure knows how to pound these down!"
icon_state = "yumbaton"
filling_color = "#7D5F46"
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/confectionery/caramel
name = "Malper Bar"
desc = "A chocolate syringe filled with a caramel injection. Just what the doctor ordered!"
icon_state = "malper"
filling_color = "#7D5F46"
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/confectionery/caramel_nougat
name = "Toxins Test Bar"
desc = "An explosive combination of chocolate, caramel, and nougat. Research has never been so tasty!"
icon_state = "toxinstest"
filling_color = "#7D5F46"
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candy/confectionery/nougat
name = "Tool-erone Bar"
desc = "Chocolate-covered nougat, shaped like a wrench. Great for an engineer on the go!"
icon_state = "toolerone"
filling_color = "#7D5F46"
+ goal_difficulty = FOOD_GOAL_NORMAL
diff --git a/code/modules/food_and_drinks/food/foods/desserts.dm b/code/modules/food_and_drinks/food/foods/desserts.dm
index c68b8bc55f1..8c3517c8c66 100644
--- a/code/modules/food_and_drinks/food/foods/desserts.dm
+++ b/code/modules/food_and_drinks/food/foods/desserts.dm
@@ -7,6 +7,7 @@
desc = "Goreng Pisang, also known as fried bananas."
icon_state = "friedbanana"
list_reagents = list("sugar" = 5, "nutriment" = 8, "cornoil" = 4)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/ricepudding
name = "rice pudding"
@@ -16,6 +17,7 @@
filling_color = "#FFFBDB"
list_reagents = list("nutriment" = 7, "vitamin" = 2)
tastes = list("rice" = 1, "sweetness" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/spacylibertyduff
name = "spacy liberty duff"
@@ -26,6 +28,7 @@
bitesize = 3
list_reagents = list("nutriment" = 6, "psilocybin" = 6)
tastes = list("jelly" = 1, "mushroom" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/amanitajelly
name = "amanita jelly"
@@ -36,6 +39,7 @@
bitesize = 3
list_reagents = list("nutriment" = 6, "amanitin" = 6, "psilocybin" = 3)
tastes = list("jelly" = 1, "mushroom" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/candiedapple
name = "candied apple"
@@ -45,6 +49,7 @@
bitesize = 3
list_reagents = list("nutriment" = 3, "sugar" = 2)
tastes = list("apple" = 2, "sweetness" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/mint
name = "mint"
@@ -53,3 +58,4 @@
bitesize = 1
filling_color = "#F2F2F2"
list_reagents = list("minttoxin" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
diff --git a/code/modules/food_and_drinks/food/foods/ethnic.dm b/code/modules/food_and_drinks/food/foods/ethnic.dm
index 153dc2b7407..b620811936b 100644
--- a/code/modules/food_and_drinks/food/foods/ethnic.dm
+++ b/code/modules/food_and_drinks/food/foods/ethnic.dm
@@ -10,6 +10,7 @@
bitesize = 3
list_reagents = list("nutriment" = 7, "vitamin" = 1)
tastes = list("taco" = 4, "meat" = 2, "cheese" = 2, "lettuce" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/burrito
name = "burrito"
@@ -19,6 +20,7 @@
filling_color = "#A36A1F"
list_reagents = list("nutriment" = 4, "vitamin" = 1)
tastes = list("torilla" = 2, "meat" = 3)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/chimichanga
@@ -28,6 +30,7 @@
trash = /obj/item/trash/plate
filling_color = "#A36A1F"
list_reagents = list("omnizine" = 4, "cheese" = 2) //Deadpool reference. Deal with it.
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/enchiladas
name = "enchiladas"
@@ -38,6 +41,7 @@
bitesize = 4
list_reagents = list("nutriment" = 8, "capsaicin" = 6)
tastes = list("hot peppers" = 1, "meat" = 3, "cheese" = 1, "sour cream" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/cornchips
name = "corn chips"
@@ -47,6 +51,7 @@
trash = /obj/item/trash/chips
filling_color = "#E8C31E"
list_reagents = list("nutriment" = 3)
+ goal_difficulty = FOOD_GOAL_NORMAL
//////////////////////
@@ -113,6 +118,7 @@
filling_color = "#F0F2E4"
list_reagents = list("nutriment" = 5)
tastes = list("custard" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/yakiimo
name = "yaki imo"
@@ -122,6 +128,7 @@
list_reagents = list("nutriment" = 5, "vitamin" = 4)
filling_color = "#8B1105"
tastes = list("sweet potato" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
//////////////////////
@@ -143,6 +150,7 @@
trash = /obj/item/stack/rods
filling_color = "#A85340"
list_reagents = list("nutriment" = 8)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/tofukabob
name = "tofu-kabob"
@@ -151,6 +159,7 @@
trash = /obj/item/stack/rods
filling_color = "#FFFEE0"
list_reagents = list("nutriment" = 8)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/picoss_kabob
name = "picoss-kabob"
@@ -160,3 +169,4 @@
list_reagents = list("protein" = 8, "vitamin" = 4, "vinegar" = 1, "capsaicin" = 1)
filling_color = "#A85340"
tastes = list("fish" = 4, "acid" = 1, "onion" = 1, "heat" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
diff --git a/code/modules/food_and_drinks/food/foods/frozen.dm b/code/modules/food_and_drinks/food/foods/frozen.dm
index d00db915ed0..dd117fbaecb 100644
--- a/code/modules/food_and_drinks/food/foods/frozen.dm
+++ b/code/modules/food_and_drinks/food/foods/frozen.dm
@@ -30,13 +30,7 @@
filling_color = "#FFD675"
list_reagents = list("nutriment" = 4, "sugar" = 1, "vitamin" = 1, "banana" = 3)
tastes = list("cake" = 5, "sweetness" = 2, "sad clowns" = 1, "ice-cream" = 1)
-
-/obj/item/food/snacks/frozen/sundae
- name = "sundae"
- desc = "Portable ice cream in its own packaging."
- icon_state = "sundae"
- list_reagents = list("nutriment" = 2, "ice" = 2)
- tastes = list("ice cream" = 1, "banana" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
///////////////////
// Ice Cream //
@@ -100,6 +94,7 @@
icon_state = "icecreamsandwich"
list_reagents = list("nutriment" = 2, "ice" = 2)
tastes = list("ice cream" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/berryicecreamsandwich
name = "strawberry icecream sandwich"
@@ -107,6 +102,7 @@
icon_state = "strawberryicecreamsandwich"
list_reagents = list("nutriment" = 2, "ice" = 2)
tastes = list("ice cream" = 1, "strawberry" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/sundae
name = "sundae"
@@ -114,6 +110,7 @@
icon_state = "sundae"
list_reagents = list("nutriment" = 6, "banana" = 5, "vitamin" = 2)
tastes = list("ice cream" = 1, "banana" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/honkdae
name = "honkdae"
@@ -121,6 +118,7 @@
icon_state = "honkdae"
list_reagents = list("nutriment" = 6, "banana" = 10, "vitamin" = 4)
tastes = list("ice cream" = 1, "banana" = 1, "a bad joke" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/cornuto
name = "cornuto"
@@ -128,6 +126,7 @@
icon_state = "cornuto"
list_reagents = list("nutriment" = 6, "hot_coco" = 4, "cream" = 2, "vanilla" = 4, "sugar" = 2)
tastes = list("chopped hazelnuts" = 3, "waffle" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/peanutbuttermochi
name = "peanut butter ice cream mochi"
@@ -135,6 +134,7 @@
icon_state = "pb_ice_cream_mochi"
list_reagents = list("nutriment" = 4, "sugar" = 6, "peanutbutter" = 4, "milk" = 2)
tastes = list("peanut butter" = 1, "mochi" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/spacefreezy
name = "spacefreezy"
@@ -142,6 +142,7 @@
icon_state = "spacefreezy"
list_reagents = list("nutriment" = 8, "vitamin" = 5, "bluecherryjelly" = 5)
tastes = list("blue cherries" = 2, "ice cream" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
///////////////////
// Snow Cones //
@@ -161,6 +162,7 @@
icon_state = "amber_sc"
list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "applejuice" = 5)
tastes = list("ice" = 1, "water" = 1, "apples" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/snowcone/berry
name = "berry snowcone"
@@ -168,6 +170,7 @@
icon_state = "berry_sc"
list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "berryjuice" = 5)
tastes = list("ice" = 1, "water" = 1, "berries" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/snowcone/bluecherry
name = "bluecherry snowcone"
@@ -175,6 +178,7 @@
icon_state = "blue_sc"
list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "bluecherryjelly" = 5)
tastes = list("ice" = 1, "water" = 1, "bluecherries" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/snowcone/cherry
name = "cherry snowcone"
@@ -182,6 +186,7 @@
icon_state = "red_sc"
list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "cherryjelly" = 5)
tastes = list("ice" = 1, "water" = 1, "cherries" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/snowcone/fruitsalad
name = "fruit salad snowcone"
@@ -189,6 +194,7 @@
icon_state = "fruitsalad_sc"
list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "limejuice" = 5, "lemonjuice" = 5, "orangejuice" = 5)
tastes = list("ice" = 1, "water" = 1, "oranges" = 5, "lemons" = 5, "limes" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/snowcone/grape
name = "grape snowcone"
@@ -196,6 +202,7 @@
icon_state = "grape_sc"
list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "grapejuice" = 5)
tastes = list("ice" = 1, "water" = 1, "grapes" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/snowcone/honey
name = "honey snowcone"
@@ -203,6 +210,7 @@
icon_state = "amber_sc"
list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "honey" = 5)
tastes = list("ice" = 1, "water" = 1, "honey" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/snowcone/lemon
name = "lemon snowcone"
@@ -210,6 +218,7 @@
icon_state = "lemon_sc"
list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "lemonjuice" = 5)
tastes = list("ice" = 1, "water" = 1, "lemons" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/snowcone/lime
name = "lime snowcone"
@@ -217,6 +226,7 @@
icon_state = "lime_sc"
list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "limejuice" = 5)
tastes = list("ice" = 1, "water" = 1, "limes" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/snowcone/mime
name = "mime snowcone"
@@ -224,6 +234,7 @@
icon_state = "mime_sc"
list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "nothing" = 5)
tastes = list("ice" = 1, "water" = 1, "silence" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/snowcone/orange
name = "orange snowcone"
@@ -231,6 +242,7 @@
icon_state = "orange_sc"
list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "orangejuice" = 5)
tastes = list("ice" = 1, "water" = 1, "oranges" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/snowcone/pineapple
name = "pineapple snowcone"
@@ -238,6 +250,7 @@
icon_state = "pineapple_sc"
list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "pineapplejuice" = 5)
tastes = list("ice" = 1, "water" = 1, "pineapple" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/snowcone/rainbow
name = "rainbow snowcone"
@@ -245,6 +258,7 @@
icon_state = "rainbow_sc"
list_reagents = list("water" = 10, "ice" = 5, "colorful_reagent" = 5)
tastes = list("ice" = 1, "water" = 1, "rainbows" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/snowcone/cola
name = "space cola snowcone"
@@ -252,6 +266,7 @@
icon_state = "soda_sc"
list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "cola" = 5)
tastes = list("ice" = 1, "water" = 1, "soda" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/snowcone/spacemountain
name = "space mountain wind snowcone"
@@ -259,6 +274,7 @@
icon_state = "mountainwind_sc"
list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "spacemountainwind" = 5)
tastes = list("ice" = 1, "water" = 1, "mountain wind" = 5)
+ goal_difficulty = FOOD_GOAL_NORMAL
///////////////////
// Popsicles //
@@ -271,6 +287,7 @@
trash = /obj/item/trash/popsicle_stick
list_reagents = list("nutriment" = 4, "sugar" = 4, "chocolate" = 3)
tastes = list("ice cream" = 1, "chocolate" = 1, "vanilla" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/popsicle/bananatop
name = "banana topsicle"
@@ -278,6 +295,7 @@
icon_state = "topsicle_banana"
list_reagents = list("vitamin" = 4, "sugar" = 6, "banana" = 4)
tastes = list("bananas" = 1, "tofu" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/popsicle/berrytop
name = "berry topsicle"
@@ -285,6 +303,7 @@
icon_state = "topsicle_berry"
list_reagents = list("vitamin" = 4, "sugar" = 6, "berryjuice" = 4)
tastes = list("berries" = 1, "tofu" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/popsicle/pineappletop
name = "pineapple topsicle"
@@ -292,6 +311,7 @@
icon_state = "topsicle_pineapple"
list_reagents = list("vitamin" = 4, "sugar" = 6, "pineapplejuice" = 4)
tastes = list("pineapples" = 1, "tofu" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/popsicle/licoricecream
name = "licorice creamsicle"
@@ -299,6 +319,7 @@
icon_state = "licorice_creamsicle"
list_reagents = list("nutriment" = 4, "cream" = 2, "vanilla" = 1, "sugar" = 4, "salt" = 1)
tastes = list("salty licorice" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/popsicle/orangecream
name = "orange creamsicle"
@@ -306,6 +327,7 @@
icon_state = "creamsicle_o"
list_reagents = list("orangejuice" = 4, "cream" = 2, "vanilla" = 2, "sugar" = 4)
tastes = list("ice cream" = 1, "oranges" = 1, "vanilla" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/popsicle/berrycream
name = "berry creamsicle"
@@ -313,6 +335,7 @@
icon_state = "creamsicle_m"
list_reagents = list("berryjuice" = 4, "cream" = 2, "vanilla" = 2, "sugar" = 4)
tastes = list("ice cream" = 1, "berries" = 1, "vanilla" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/popsicle/frozenpineapple
name = "frozen pineapple pop"
@@ -320,6 +343,7 @@
icon_state = "pineapple_pop"
list_reagents = list("pineapplejuice" = 4, "sugar" = 4, "nutriment" = 2, "vitamin" = 2)
tastes = list("cold pineapple" = 1, "chocolate" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/popsicle/sea_salt
name = "sea salt ice-cream bar"
@@ -327,6 +351,7 @@
icon_state = "sea_salt_pop"
list_reagents = list("salt" = 1, "nutriment" = 2, "cream" = 2, "vanilla" = 2, "sugar"= 4,)
tastes = list("salt" = 1, "sweet" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/frozen/popsicle/ant
name = "ant popsicle"
diff --git a/code/modules/food_and_drinks/food/foods/ingredients.dm b/code/modules/food_and_drinks/food/foods/ingredients.dm
index d6331119b2c..ffb42057fad 100644
--- a/code/modules/food_and_drinks/food/foods/ingredients.dm
+++ b/code/modules/food_and_drinks/food/foods/ingredients.dm
@@ -21,6 +21,7 @@
bitesize = 3
list_reagents = list("plantmatter" = 3)
tastes = list("tofu" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/soydope
name = "soy dope"
@@ -230,6 +231,7 @@
filling_color = "#7D5F46"
list_reagents = list("nutriment" = 2, "sugar" = 2, "cocoa" = 2)
tastes = list("chocolate" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
///Chocolate crumbles/pile
/obj/item/food/snacks/chocolatebar/attackby(obj/item/I, mob/user, params)
diff --git a/code/modules/food_and_drinks/food/foods/meat.dm b/code/modules/food_and_drinks/food/foods/meat.dm
index 0a0a410807b..5cc637ba2d6 100644
--- a/code/modules/food_and_drinks/food/foods/meat.dm
+++ b/code/modules/food_and_drinks/food/foods/meat.dm
@@ -201,6 +201,7 @@
bitesize = 3
list_reagents = list("nutriment" = 5)
tastes = list("meat" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/bacon
name = "bacon"
@@ -209,6 +210,7 @@
icon_state = "bacon"
list_reagents = list("nutriment" = 4, "porktonium" = 10, "msg" = 4)
tastes = list("bacon" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/telebacon
name = "tele bacon"
@@ -218,6 +220,7 @@
var/obj/item/radio/beacon/bacon/baconbeacon
list_reagents = list("nutriment" = 4, "porktonium" = 10)
tastes = list("bacon" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/telebacon/Initialize(mapload)
. = ..()
@@ -250,6 +253,7 @@
filling_color = "#DB0000"
list_reagents = list("protein" = 6, "vitamin" = 1, "porktonium" = 10)
tastes = list("meat" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/cutlet
name = "cutlet"
@@ -258,6 +262,7 @@
icon_state = "cutlet"
list_reagents = list("protein" = 2)
tastes = list("meat" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/spidereggsham
name = "green eggs and ham"
@@ -461,6 +466,7 @@
bitesize = 1
list_reagents = list("nutriment" = 3, "egg" = 5)
tastes = list("egg" = 1, "salt" = 1, "pepper" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/boiledegg
name = "boiled egg"
@@ -469,6 +475,7 @@
icon_state = "egg"
filling_color = "#FFFFFF"
list_reagents = list("nutriment" = 2, "egg" = 5, "vitamin" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/chocolateegg
name = "chocolate egg"
@@ -477,6 +484,7 @@
icon_state = "chocolateegg"
filling_color = "#7D5F46"
list_reagents = list("nutriment" = 4, "sugar" = 2, "cocoa" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/omelette
name = "omelette du fromage"
@@ -488,6 +496,7 @@
list_reagents = list("nutriment" = 8, "vitamin" = 1)
bitesize = 1
tastes = list("egg" = 1, "cheese" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/benedict
name = "eggs benedict"
@@ -497,6 +506,7 @@
bitesize = 3
list_reagents = list("nutriment" = 6, "egg" = 3, "vitamin" = 4)
tastes = list("egg" = 1, "bacon" = 1, "bun" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
//////////////////////
@@ -511,6 +521,7 @@
bitesize = 3
list_reagents = list("nutriment" = 6, "ketchup" = 3, "vitamin" = 3)
tastes = list("bun" = 3, "meat" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/meatbun
name = "meat bun"
@@ -520,6 +531,7 @@
bitesize = 6
list_reagents = list("nutriment" = 6, "vitamin" = 2)
tastes = list("bun" = 3, "meat" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/sliceable/turkey
name = "turkey"
@@ -539,6 +551,7 @@
trash = /obj/item/trash/plate
filling_color = "#B97A57"
tastes = list("turkey" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/organ
name = "organ"
@@ -573,3 +586,4 @@
list_reagents = list("nutriment" = 3, "protein" = 10, "bbqsauce" = 10)
filling_color = "#FF1C1C"
bitesize = 3
+ goal_difficulty = FOOD_GOAL_NORMAL
diff --git a/code/modules/food_and_drinks/food/foods/misc_food.dm b/code/modules/food_and_drinks/food/foods/misc_food.dm
index 26624dbd595..d9189b03aa3 100644
--- a/code/modules/food_and_drinks/food/foods/misc_food.dm
+++ b/code/modules/food_and_drinks/food/foods/misc_food.dm
@@ -11,6 +11,7 @@
filling_color = "#4D2F5E"
list_reagents = list("nutriment" = 6, "vitamin" = 2)
tastes = list("eggplant" = 2, "cheese" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/soylentgreen
name = "soylent green"
@@ -29,6 +30,7 @@
filling_color = "#E6FA61"
list_reagents = list("nutriment" = 10, "vitamin" = 1)
tastes = list("waffles" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/monkeysdelight
name = "monkey's delight"
@@ -39,6 +41,7 @@
bitesize = 6
list_reagents = list("nutriment" = 10, "banana" = 5, "vitamin" = 5)
tastes = list("banana" = 1, "the jungle" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/dionaroast
name = "roast diona"
@@ -48,6 +51,7 @@
filling_color = "#75754B"
list_reagents = list("plantmatter" = 4, "nutriment" = 2, "radium" = 2, "vitamin" = 4)
tastes = list("chewy vegetables" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/tofurkey
name = "tofurkey"
@@ -57,6 +61,7 @@
bitesize = 3
list_reagents = list("nutriment" = 12, "ether" = 3)
tastes = list("tofu" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
//////////////////////
@@ -73,6 +78,7 @@
bitesize = 3
list_reagents = list("nutriment" = 6,"vitamin" = 4)
tastes = list("lettuce" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/salad/aesir
name = "aesir salad"
@@ -80,6 +86,7 @@
icon_state = "aesirsalad"
list_reagents = list("nutriment" = 8, "omnizine" = 8, "vitamin" = 6)
tastes = list("divinity" = 1, "lettuce" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/salad/antipasto
name = "antipasto salad"
@@ -87,6 +94,7 @@
icon_state = "antipasto_salad"
list_reagents = list("nutriment" = 12, "protein" = 6, "vitamin" = 6)
tastes = list("lettuce" = 2, "salami" = 2, "mozzarella cheese" = 2, "tomatoes" = 2, "dressing" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/salad/caesar
name = "Caesar salad"
@@ -94,6 +102,7 @@
icon_state = "caesar_salad"
list_reagents = list("nutriment" = 12, "vitamin" = 6)
tastes = list("healthy greens" = 2, "olive dressing" = 2, "feta cheese" = 2, "pita bread" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/salad/fruit
name = "fruit salad"
@@ -101,6 +110,7 @@
icon_state = "fruitsalad"
list_reagents = list("nutriment" = 9, "vitamin" = 4)
tastes = list("fruit" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/salad/greek
name = "Greek salad"
@@ -108,6 +118,7 @@
icon_state = "greek_salad"
list_reagents = list("nutriment" = 13, "vitamin" = 14)
tastes = list("healthy greens" = 2, "olive dressing" = 1, "feta cheese" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/salad/citrusdelight
name = "citrus delight"
@@ -115,6 +126,7 @@
icon_state = "citrusdelight"
list_reagents = list("nutriment" = 11, "vitamin" = 7)
tastes = list("sourness" = 1, "leaves" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/salad/jungle
name = "jungle salad"
@@ -122,6 +134,7 @@
icon_state = "junglesalad"
list_reagents = list("banana" = 5, "nutriment" = 11, "vitamin" = 7)
tastes = list("fruit" = 1, "the jungle" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/salad/kale
name = "kale salad"
@@ -129,6 +142,7 @@
icon_state = "kale_salad"
list_reagents = list("nutriment" = 12, "vitamin" = 12)
tastes = list("healthy greens" = 2, "olive dressing" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/salad/potato
name = "potato salad"
@@ -136,6 +150,7 @@
icon_state = "potato_salad"
list_reagents = list("nutriment" = 10, "protein" = 4)
tastes = list("potato" = 2, "egg" = 2, "mayonnaise" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/salad/melonfruitbowl
name = "melon fruit bowl"
@@ -144,6 +159,7 @@
trash = null
list_reagents = list("nutriment" = 6, "vitamin" = 4)
tastes = list("melon" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/salad/herb
name = "herb salad"
@@ -152,6 +168,7 @@
filling_color = "#76B87F"
list_reagents = list("nutriment" = 8, "vitamin" = 2)
tastes = list("lettuce" = 1, "apple" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/salad/valid
name = "valid salad"
@@ -160,6 +177,7 @@
filling_color = "#76B87F"
list_reagents = list("nutriment" = 8, "salglu_solution" = 5, "vitamin" = 2)
tastes = list("fried potato" = 1, "lettuce" = 1, "meat" = 1, "valids" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
//////////////////////
@@ -270,6 +288,7 @@
bitesize = 0.1 //this snack is supposed to be eating during looooong time. And this it not dinner food! --rastaf0
list_reagents = list("nutriment" = 2)
tastes = list("popcorn" = 3, "butter" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/popcorn/Initialize(mapload)
. = ..()
diff --git a/code/modules/food_and_drinks/food/foods/pasta.dm b/code/modules/food_and_drinks/food/foods/pasta.dm
index 984fb60c1a8..e8aadb6ce29 100644
--- a/code/modules/food_and_drinks/food/foods/pasta.dm
+++ b/code/modules/food_and_drinks/food/foods/pasta.dm
@@ -35,6 +35,7 @@
filling_color = "#FCEE81"
list_reagents = list("nutriment" = 2, "vitamin" = 1)
tastes = list("pasta" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/pastatomato
name = "spaghetti"
@@ -46,6 +47,7 @@
bitesize = 4
list_reagents = list("nutriment" = 6, "tomatojuice" = 10, "vitamin" = 4)
tastes = list("pasta" = 1, "tomato" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/meatballspaghetti
name = "spaghetti & meatballs"
@@ -56,6 +58,7 @@
filling_color = "#DE4545"
list_reagents = list("nutriment" = 8, "synaptizine" = 5, "vitamin" = 4)
tastes = list("pasta" = 1, "tomato" = 1, "meat" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/spesslaw
name = "spesslaw"
@@ -65,6 +68,7 @@
filling_color = "#DE4545"
list_reagents = list("nutriment" = 8, "synaptizine" = 10, "vitamin" = 6)
tastes = list("pasta" = 1, "tomato" = 1, "meat" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/macncheese
name = "mac 'n' cheese"
@@ -75,6 +79,7 @@
filling_color = "#ffe45d"
list_reagents = list("nutriment" = 5, "vitamin" = 2, "cheese" = 4)
tastes = list("pasta" = 1, "cheese" = 1, "comfort" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/lasagna
name = "lasagna"
@@ -84,3 +89,4 @@
filling_color = "#E18712"
list_reagents = list("nutriment" = 10, "msg" = 3, "vitamin" = 4, "tomatojuice" = 10)
tastes = list("pasta" = 1, "cheese" = 1, "tomato" = 1, "meat" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
diff --git a/code/modules/food_and_drinks/food/foods/pizza.dm b/code/modules/food_and_drinks/food/foods/pizza.dm
index d37e3f05843..8e7a9205045 100644
--- a/code/modules/food_and_drinks/food/foods/pizza.dm
+++ b/code/modules/food_and_drinks/food/foods/pizza.dm
@@ -24,6 +24,7 @@
icon_state = "margheritapizzaslice"
filling_color = "#BAA14C"
tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
// Meat Pizza
/obj/item/food/snacks/sliceable/pizza/meatpizza
@@ -41,6 +42,7 @@
icon_state = "meatpizzaslice"
filling_color = "#BAA14C"
tastes = list("crust" = 1, "cheese" = 1, "meat" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
// Mushroom Pizza
/obj/item/food/snacks/sliceable/pizza/mushroompizza
@@ -58,6 +60,7 @@
icon_state = "mushroompizzaslice"
filling_color = "#BAA14C"
tastes = list("crust" = 1, "cheese" = 1, "mushroom" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
// Vegetable Pizza
/obj/item/food/snacks/sliceable/pizza/vegetablepizza
@@ -75,6 +78,7 @@
icon_state = "vegetablepizzaslice"
filling_color = "#BAA14C"
tastes = list("crust" = 1, "tomato" = 1, "carrot" = 1, "vegetables" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
// Hawaiian Pizza
/obj/item/food/snacks/sliceable/pizza/hawaiianpizza
@@ -92,6 +96,7 @@
icon_state = "hawaiianpizzaslice"
filling_color = "#e5b437"
tastes = list("crust" = 1, "cheese" = 1, "pineapple" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
// Mac 'n' Cheese Pizza
/obj/item/food/snacks/sliceable/pizza/macpizza
@@ -110,6 +115,7 @@
icon_state = "macpizzaslice"
filling_color = "#ffe45d"
tastes = list("crust" = 1, "tomato" = 1, "cheese" = 2, "pasta" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
// Pepperoni Pizza
/obj/item/food/snacks/sliceable/pizza/pepperonipizza
@@ -128,6 +134,7 @@
icon_state = "pepperonipizzaslice"
filling_color = "#ffe45d"
tastes = list("cheese" = 3, "pepperoni" = 3, "grease" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
// Cheese Pizza
/obj/item/food/snacks/sliceable/pizza/cheesepizza
@@ -144,6 +151,7 @@
icon_state = "cheesepizzaslice"
filling_color = "#BAA14C"
tastes = list("crust" = 1, "tomato" = 1, "cheese" = 3)
+ goal_difficulty = FOOD_GOAL_EASY
// Donk-pocket Pizza
/obj/item/food/snacks/sliceable/pizza/donkpocketpizza
@@ -161,6 +169,7 @@
icon_state = "donkpocketpizzaslice"
filling_color = "#BAA14C"
tastes = list("crust" = 1, "meat" = 1, "laziness" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
// Dank Pizza
/obj/item/food/snacks/sliceable/pizza/dankpizza
@@ -178,6 +187,7 @@
icon_state = "dankpizzaslice"
filling_color = "#BAA14C"
tastes = list("crust" = 1, "cheese" = 1, "special herbs" = 2)
+ goal_difficulty = FOOD_GOAL_EASY
// Firecracker Pizza
/obj/item/food/snacks/sliceable/pizza/firecrackerpizza
@@ -195,6 +205,7 @@
icon_state = "firecrackerpizzaslice"
filling_color = "#BAA14C"
tastes = list("crust" = 1, "cheese" = 1, "HOTNESS" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
// "Pesto" Pizza
/obj/item/food/snacks/sliceable/pizza/pestopizza
@@ -212,6 +223,7 @@
icon_state = "pestopizzaslice"
filling_color = "#BAA14C"
tastes = list("tomato" = 1, "cheese" = 1, "wasabi" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
// Garlic Pizza
/obj/item/food/snacks/sliceable/pizza/garlicpizza
@@ -229,6 +241,7 @@
icon_state = "garlicpizzaslice"
filling_color = "#BAA14C"
tastes = list("crust" = 1, "cheese" = 1, "garlic" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
//////////////////////
diff --git a/code/modules/food_and_drinks/food/foods/sandwiches.dm b/code/modules/food_and_drinks/food/foods/sandwiches.dm
index 05d58422984..42a9a4d0b69 100644
--- a/code/modules/food_and_drinks/food/foods/sandwiches.dm
+++ b/code/modules/food_and_drinks/food/foods/sandwiches.dm
@@ -19,6 +19,7 @@
bitesize = 3
list_reagents = list("nutriment" = 6, "vitamin" = 1)
tastes = list("bun" = 4, "meat" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/burger/brain
name = "brainburger"
@@ -59,6 +60,7 @@
bitesize = 3
list_reagents = list("nutriment" = 6, "vitamin" = 1)
tastes = list("bun" = 4, "meat" = 1, "cheese" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/burger/tofu
name = "tofu burger"
@@ -68,6 +70,7 @@
bitesize = 3
list_reagents = list("nutriment" = 6, "vitamin" = 1)
tastes = list("bun" = 4, "tofu" = 4)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/burger/hamborger
name = "hamborger"
@@ -135,6 +138,7 @@
bitesize = 3
list_reagents = list("nutriment" = 10, "vitamin" = 2)
tastes = list("bun" = 4, "meat" = 2, "cheese" = 2, "type two diabetes" = 10)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/burger/superbite
name = "SuperBite burger"
@@ -162,6 +166,7 @@
bitesize = 2
list_reagents = list("nutriment" = 7, "protein" = 1)
tastes = list("bun" = 2, "meat" = 2, "white" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/burger/ppatty/red
name = "red pretty patty"
@@ -171,6 +176,7 @@
bitesize = 2
list_reagents = list("nutriment" = 7, "protein" = 1)
tastes = list("bun" = 2, "meat" = 2, "red" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/burger/ppatty/orange
name = "orange pretty patty"
@@ -180,6 +186,7 @@
bitesize = 2
list_reagents = list("nutriment" = 7, "protein" = 1)
tastes = list("bun" = 2, "meat" = 2, "orange" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/burger/ppatty/yellow
name = "yellow pretty patty"
@@ -189,6 +196,7 @@
bitesize = 2
list_reagents = list("nutriment" = 7, "protein" = 1)
tastes = list("bun" = 2, "meat" = 2, "yellow" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/burger/ppatty/green
name = "green pretty patty"
@@ -198,6 +206,7 @@
bitesize = 2
list_reagents = list("nutriment" = 7, "protein" = 1)
tastes = list("bun" = 2, "meat" = 2, "green" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/burger/ppatty/blue
name = "blue pretty patty"
@@ -207,6 +216,7 @@
bitesize = 2
list_reagents = list("nutriment" = 7, "protein" = 1)
tastes = list("bun" = 2, "meat" = 2, "blue" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/burger/ppatty/purple
name = "purple pretty patty"
@@ -216,6 +226,7 @@
bitesize = 2
list_reagents = list("nutriment" = 7, "protein" = 1)
tastes = list("bun" = 2, "meat" = 2, "purple" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/burger/ppatty/rainbow
name = "rainbow pretty patty"
@@ -225,6 +236,7 @@
bitesize = 4
list_reagents = list("nutriment" = 14, "protein" = 5, "omnizine" = 10)
tastes = list("bun" = 2, "meat" = 2, "rainbow" = 5)
+ goal_difficulty = FOOD_GOAL_HARD
/obj/item/food/snacks/burger/elec
name = "empowered burger"
@@ -234,6 +246,7 @@
bitesize = 2
list_reagents = list("nutriment" = 5, "protein" = 1, "plasma" = 2)
tastes = list("bun" = 2, "pure electricity" = 5)
+ goal_difficulty = FOOD_GOAL_HARD
/obj/item/food/snacks/burger/rat
name = "mouse burger"
@@ -261,6 +274,7 @@
bitesize = 3
list_reagents = list("nutriment" = 3, "vitamin" = 2, "protein" = 6)
tastes = list("bun" = 1, "bacon" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/burger/bearger
@@ -280,6 +294,7 @@
filling_color = "#F2B6EA"
list_reagents = list("nutriment" = 4, "protein" = 6, "condensedcapsaicin" = 5, "capsaicin" = 5)
tastes = list("bun" = 1, "extreme heat" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/burger/mcguffin
name = "mcGuffin"
@@ -289,6 +304,7 @@
filling_color = "#F2B6EA"
list_reagents = list("nutriment" = 2, "protein" = 7, "vitamin" = 1)
tastes = list("muffin" = 1, "bacon" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/burger/mcrib
name = "mcRib"
@@ -298,6 +314,7 @@
filling_color = "#F2B6EA"
list_reagents = list("nutriment" = 2, "protein" = 7, "vitamin" = 4, "bbqsauce" = 1)
tastes = list("bun" = 1, "pork" = 1, "patty" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/burger/jelly
name = "jelly burger"
@@ -308,10 +325,13 @@
tastes = list("bun" = 4, "jelly" = 2)
/obj/item/food/snacks/burger/jelly/slime
+ name = "slime burger"
list_reagents = list("nutriment" = 6, "slimejelly" = 5, "vitamin" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/burger/jelly/cherry
list_reagents = list("nutriment" = 6, "cherryjelly" = 5, "vitamin" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
//////////////////////
@@ -326,6 +346,7 @@
filling_color = "#D9BE29"
list_reagents = list("nutriment" = 6, "vitamin" = 1)
tastes = list("meat" = 2, "cheese" = 1, "bread" = 2, "lettuce" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/toastedsandwich
name = "toasted sandwich"
@@ -335,6 +356,7 @@
filling_color = "#D9BE29"
list_reagents = list("nutriment" = 6, "carbon" = 2)
tastes = list("toast" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/grilledcheese
name = "grilled cheese sandwich"
@@ -344,6 +366,7 @@
filling_color = "#D9BE29"
list_reagents = list("nutriment" = 7, "vitamin" = 1) //why make a regualr sandwhich when you can make grilled cheese, with this nutriment value?
tastes = list("toast" = 1, "grilled cheese" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/jellysandwich
name = "jelly sandwich"
@@ -356,9 +379,12 @@
/obj/item/food/snacks/jellysandwich/slime
list_reagents = list("nutriment" = 2, "slimejelly" = 5, "vitamin" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/jellysandwich/cherry
+ name = "slime sandwich"
list_reagents = list("nutriment" = 2, "cherryjelly" = 5, "vitamin" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/notasandwich
name = "not-a-sandwich"
@@ -375,6 +401,7 @@
icon_state = "wrap"
list_reagents = list("nutriment" = 5)
tastes = list("egg" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/blt
name = "\improper BLT"
@@ -385,6 +412,7 @@
bitesize = 4
list_reagents = list("nutriment" = 5, "protein" = 2)
tastes = list("bacon" = 3, "lettuce" = 2, "tomato" = 2, "bread" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/peanut_butter_jelly
name = "peanut butter and jelly sandwich"
@@ -396,10 +424,14 @@
tastes = list("peanut butter" = 3, "jelly" = 3, "bread" = 2)
/obj/item/food/snacks/peanut_butter_jelly/slime
+ name = "peanut butter and slime sandwich"
+ desc = "A classic PB&J sandwich, just like your mom used to make?"
list_reagents = list("peanutbutter" = 2, "slimejelly" = 5, "nutriment" = 5, "protein" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/peanut_butter_jelly/cherry
list_reagents = list("peanutbutter" = 2, "cherryjelly" = 5, "nutriment" = 5, "protein" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/philly_cheesesteak
name = "Philly cheesesteak"
@@ -410,6 +442,7 @@
bitesize = 4
list_reagents = list("nutriment" = 10, "protein" = 4)
tastes = list("steak" = 3, "melted cheese" = 3, "onions" = 2, "bread" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/peanut_butter_banana
name = "peanut butter and banana sandwich"
@@ -420,3 +453,4 @@
bitesize = 2
list_reagents = list("nutriment" = 5, "protein" = 2)
tastes = list("peanutbutter" = 3, "banana" = 3, "bread" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
diff --git a/code/modules/food_and_drinks/food/foods/seafood.dm b/code/modules/food_and_drinks/food/foods/seafood.dm
index 629886de6b5..69f88b307ec 100644
--- a/code/modules/food_and_drinks/food/foods/seafood.dm
+++ b/code/modules/food_and_drinks/food/foods/seafood.dm
@@ -51,6 +51,7 @@
bitesize = 1
list_reagents = list("nutriment" = 4)
tastes = list("fish" = 1, "bread" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/fishburger
name = "Fillet-O-Carp sandwich"
@@ -61,6 +62,7 @@
bitesize = 3
list_reagents = list("nutriment" = 6, "vitamin" = 1)
tastes = list("bun" = 4, "fish" = 4)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/cubancarp
name = "cuban carp"
@@ -72,6 +74,7 @@
bitesize = 3
list_reagents = list("nutriment" = 6, "capsaicin" = 1)
tastes = list("fish" = 4, "batter" = 1, "hot peppers" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/fishandchips
name = "fish and chips"
@@ -82,6 +85,7 @@
bitesize = 3
list_reagents = list("nutriment" = 6)
tastes = list("fish" = 1, "chips" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/sashimi
name = "carp sashimi"
@@ -91,6 +95,7 @@
bitesize = 3
list_reagents = list("nutriment" = 6, "capsaicin" = 5)
tastes = list("raw carp" = 1, "hot peppers" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/fried_shrimp
name = "fried shrimp"
@@ -100,6 +105,7 @@
bitesize = 3
list_reagents = list("nutriment" = 2)
tastes = list("shrimp" = 1, "bread crumbs" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/boiled_shrimp
name = "boiled shrimp"
@@ -109,6 +115,7 @@
bitesize = 3
list_reagents = list("nutriment" = 2)
tastes = list("shrimp" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/shrimp_skewer
name = "shrimp skewer"
@@ -119,6 +126,7 @@
bitesize = 3
list_reagents = list("nutriment" = 8)
tastes = list("shrimp" = 4)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/fish_skewer
name = "fish skewer"
@@ -129,6 +137,7 @@
bitesize = 3
list_reagents = list("protein" = 6, "vitamin" = 4)
tastes = list("shrimp" = 1, "batter" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/sliceable/Ebi_maki
name = "ebi maki roll"
@@ -149,6 +158,7 @@
bitesize = 3
list_reagents = list("nutriment" = 2)
tastes = list("shrimp" = 1, "rice" = 1, "seaweed" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/Ikura_maki
name = "ikura maki roll"
@@ -169,6 +179,7 @@
bitesize = 3
list_reagents = list("nutriment" = 2, "protein" = 1)
tastes = list("salmon roe" = 1, "rice" = 1, "seaweed" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/Sake_maki
name = "sake maki roll"
@@ -189,6 +200,7 @@
bitesize = 3
list_reagents = list("nutriment" = 2)
tastes = list("raw salmon" = 1, "rice" = 1, "seaweed" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/SmokedSalmon_maki
name = "smoked salmon maki roll"
@@ -209,6 +221,7 @@
bitesize = 3
list_reagents = list("nutriment" = 2)
tastes = list("smoked salmon" = 1, "rice" = 1, "seaweed" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/Tamago_maki
name = "tamago maki roll"
@@ -229,6 +242,7 @@
bitesize = 3
list_reagents = list("nutriment" = 2)
tastes = list("egg" = 1, "rice" = 1, "seaweed" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/Inari_maki
name = "inari maki roll"
@@ -249,6 +263,7 @@
bitesize = 3
list_reagents = list("nutriment" = 2)
tastes = list("fried tofu" = 1, "rice" = 1, "seaweed" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/Masago_maki
name = "masago maki roll"
@@ -269,6 +284,7 @@
bitesize = 3
list_reagents = list("nutriment" = 2, "protein" = 1)
tastes = list("goldfish roe" = 1, "rice" = 1, "seaweed" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/Tobiko_maki
name = "tobiko maki roll"
@@ -289,6 +305,7 @@
bitesize = 3
list_reagents = list("nutriment" = 2, "protein" = 1)
tastes = list("shark roe" = 1, "rice" = 1, "seaweed" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/TobikoEgg_maki
name = "tobiko and egg maki roll"
@@ -309,6 +326,7 @@
bitesize = 3
list_reagents = list("nutriment" = 2, "protein" = 1)
tastes = list("shark roe" = 1, "rice" = 1, "egg" = 1, "seaweed" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sliceable/Tai_maki
name = "tai maki roll"
@@ -329,6 +347,7 @@
bitesize = 3
list_reagents = list("nutriment" = 2)
tastes = list("catfish" = 1, "rice" = 1, "seaweed" = 1)
+ goal_difficulty = FOOD_GOAL_EASY
/obj/item/food/snacks/sushi_Unagi
name = "unagi sushi"
@@ -338,3 +357,4 @@
bitesize = 3
list_reagents = list("nutriment" = 2)
tastes = list("grilled eel" = 1, "seaweed" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
diff --git a/code/modules/food_and_drinks/food/foods/side_dishes.dm b/code/modules/food_and_drinks/food/foods/side_dishes.dm
index 648fd6f1038..31e7aec3670 100644
--- a/code/modules/food_and_drinks/food/foods/side_dishes.dm
+++ b/code/modules/food_and_drinks/food/foods/side_dishes.dm
@@ -24,6 +24,7 @@
filling_color = "#EDDD00"
list_reagents = list("nutriment" = 4)
tastes = list("fries" = 3, "salt" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/cheesyfries
name = "cheesy fries"
@@ -33,6 +34,7 @@
filling_color = "#EDDD00"
list_reagents = list("nutriment" = 6)
tastes = list("fries" = 3, "cheese" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/tatortot
name = "tator tot"
@@ -41,6 +43,7 @@
list_reagents = list("nutriment" = 4)
filling_color = "FFD700"
tastes = list("fried potato" = 3, "valids" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/onionrings
name = "onion rings"
@@ -50,6 +53,7 @@
filling_color = "#C0C9A0"
gender = PLURAL
tastes = list("onion" = 3, "batter" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/carrotfries
name = "carrot fries"
@@ -59,6 +63,7 @@
filling_color = "#FAA005"
list_reagents = list("plantmatter" = 3, "oculine" = 3, "vitamin" = 2)
tastes = list("carrots" = 3, "salt" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
//////////////////////
@@ -71,6 +76,7 @@
icon_state = "beans"
list_reagents = list("nutriment" = 10, "beans" = 10, "vitamin" = 3)
tastes = list("beans" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/// mashed taters
/obj/item/food/snacks/mashed_potatoes
@@ -81,6 +87,7 @@
filling_color = "#D6D9C1"
list_reagents = list("nutriment" = 5, "gravy" = 5, "mashedpotatoes" = 10, "vitamin" = 2)
tastes = list("mashed potato" = 3, "gravy" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/stuffing
name = "stuffing"
@@ -89,6 +96,7 @@
filling_color = "#C9AC83"
list_reagents = list("nutriment" = 3)
tastes = list("bread crumbs" = 1, "herbs" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/loadedbakedpotato
name = "loaded baked potato"
@@ -97,6 +105,7 @@
filling_color = "#9C7A68"
list_reagents = list("nutriment" = 6)
tastes = list("potato" = 1, "cheese" = 1, "herbs" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/boiledrice
name = "boiled rice"
@@ -106,6 +115,7 @@
filling_color = "#FFFBDB"
list_reagents = list("nutriment" = 5, "vitamin" = 1)
tastes = list("rice" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/roastparsnip
@@ -116,3 +126,4 @@
list_reagents = list("nutriment" = 3, "vitamin" = 4)
filling_color = "#FF5500"
tastes = list("parsnip" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
diff --git a/code/modules/food_and_drinks/food/foods/soups.dm b/code/modules/food_and_drinks/food/foods/soups.dm
index d60b10a0d6e..e2c4df37a92 100644
--- a/code/modules/food_and_drinks/food/foods/soups.dm
+++ b/code/modules/food_and_drinks/food/foods/soups.dm
@@ -20,6 +20,7 @@
filling_color = "#785210"
list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4)
tastes = list("meatball" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/soup/slimesoup
name = "slime soup"
@@ -28,6 +29,7 @@
filling_color = "#C4DBA0"
list_reagents = list("nutriment" = 5, "slimejelly" = 5, "water" = 5, "vitamin" = 4)
tastes = list("slime" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/soup/bloodsoup
name = "tomato soup"
@@ -36,6 +38,7 @@
filling_color = "#FF0000"
list_reagents = list("nutriment" = 2, "blood" = 10, "water" = 5, "vitamin" = 4)
tastes = list("iron" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/soup/clownstears
name = "clown's tears"
@@ -52,6 +55,7 @@
filling_color = "#AFC4B5"
list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4)
tastes = list("vegetables" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/soup/nettlesoup
name = "nettle soup"
@@ -60,6 +64,7 @@
filling_color = "#AFC4B5"
list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4)
tastes = list("nettles" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/soup/mysterysoup
name = "mystery soup"
@@ -68,6 +73,7 @@
var/extra_reagent = null
list_reagents = list("nutriment" = 6)
tastes = list("chaos" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/soup/mysterysoup/Initialize(mapload)
. = ..()
@@ -96,6 +102,7 @@
filling_color = "#D92929"
list_reagents = list("nutriment" = 5, "tomatojuice" = 10, "vitamin" = 3)
tastes = list("tomato" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/soup/misosoup
name = "miso soup"
@@ -103,6 +110,7 @@
icon_state = "misosoup"
list_reagents = list("nutriment" = 7, "vitamin" = 2)
tastes = list("miso" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/soup/mushroomsoup
name = "chantrelle soup"
@@ -111,6 +119,7 @@
filling_color = "#E386BF"
list_reagents = list("nutriment" = 8, "vitamin" = 4)
tastes = list("mushroom" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/soup/beetsoup
name = "beet soup"
@@ -119,6 +128,7 @@
filling_color = "#FAC9FF"
list_reagents = list("nutriment" = 7, "vitamin" = 2)
tastes = list("beet" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/soup/beetsoup/Initialize(mapload)
. = ..()
@@ -131,6 +141,7 @@
filling_color = "#E386BF"
list_reagents = list("nutriment" = 7, "protein" = 2)
tastes = list("squirming" = 2, "tomato" = 2)
+ goal_difficulty = FOOD_GOAL_HARD
/obj/item/food/snacks/soup/sweetpotatosoup
name = "sweet potato soup"
@@ -138,6 +149,7 @@
icon_state = "sweetpotatosoup"
list_reagents = list("nutriment" = 5)
tastes = list("sweet potato" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
/obj/item/food/snacks/soup/redbeetsoup
name = "red beet soup"
@@ -145,6 +157,8 @@
icon_state = "redbeetsoup"
list_reagents = list("nutriment" = 5)
tastes = list("red beet" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
+
/obj/item/food/snacks/soup/frenchonionsoup
name = "french onion soup"
@@ -152,6 +166,8 @@
icon_state = "onionsoup"
list_reagents = list("nutriment" = 8)
tastes = list("caramelized onions" = 3, "cheese" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
+
/obj/item/food/snacks/soup/zurek
name = "zurek"
@@ -159,6 +175,8 @@
icon_state = "zurek"
list_reagents = list("nutriment" = 10, "protein" = 4)
tastes = list("creamy vegetables" = 3, "sausage" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
+
/obj/item/food/snacks/soup/cullenskink
name = "cullen skink"
@@ -166,6 +184,8 @@
icon_state = "cullen_skink"
list_reagents = list("nutriment" = 10, "protein" = 4)
tastes = list("creamy broth" = 2, "fish" = 2, "vegetables" = 2)
+ goal_difficulty = FOOD_GOAL_NORMAL
+
/obj/item/food/snacks/soup/chicken_noodle_soup
name = "chicken noodle soup"
@@ -173,6 +193,8 @@
icon_state = "chicken_noodle_soup"
list_reagents = list("nutriment" = 10, "protein" = 4)
tastes = list("broth" = 1, "chicken" = 1, "carrots" = 1, "noodles" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
+
/obj/item/food/snacks/soup/cornchowder
name = "corn chowder"
@@ -180,6 +202,8 @@
icon_state = "corn_chowder"
list_reagents = list("nutriment" = 10, "protein" = 4)
tastes = list("creamy broth" = 1, "bacon" = 1, "mixed vegetables" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
+
/obj/item/food/snacks/soup/meatball_noodles
name = "meatball noodle soup"
@@ -187,6 +211,8 @@
icon_state = "meatball_noodles"
list_reagents = list("nutriment" = 10, "protein" = 4)
tastes = list("bone broth" = 1, "meat" = 1, "gnocchi" = 1, "peanuts" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
+
/obj/item/food/snacks/soup/seedsoup
name = "Misklmæsch" //miskl = seed, mæsch = soup
@@ -195,6 +221,8 @@
icon_state = "moth_seed_soup"
list_reagents = list("nutriment" = 6)
tastes = list("bitterness" = 1, "sourness" = 1, "nature" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
+
//////////////////////
// Stews //
@@ -208,6 +236,8 @@
bitesize = 7
list_reagents = list("nutriment" = 10, "oculine" = 5, "tomatojuice" = 5, "vitamin" = 5)
tastes = list("tomato" = 1, "carrot" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
+
/obj/item/food/snacks/stewedsoymeat
name = "stewed soy meat"
@@ -217,6 +247,8 @@
trash = /obj/item/trash/plate
list_reagents = list("nutriment" = 8)
tastes = list("soy" = 1, "vegetables" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
+
/obj/item/food/snacks/soup/beanstew
name = "Prickeldröndolhaskl" //prickeld = spicy, röndol = bean, haskl = stew
@@ -224,6 +256,8 @@
icon_state = "moth_bean_stew"
list_reagents = list("nutriment" = 10)
tastes = list("beans" = 1, "cabbage" = 1, "spicy sauce" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
+
/obj/item/food/snacks/soup/oatstew
name = "Häfmisklhaskl" //häfmiskl = oat (häf from German hafer meaning oat, miskl meaning seed), haskl = stew
@@ -231,6 +265,8 @@
icon_state = "moth_oat_stew"
list_reagents = list("nutriment" = 10)
tastes = list("oats" = 1, "sweet potato" = 1, "carrot" = 1, "pumpkin" = 1, "parsnip" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
+
/obj/item/food/snacks/soup/hong_kong_borscht
name = "hong kong borscht"
@@ -238,6 +274,8 @@
icon_state = "hong_kong_borscht"
list_reagents = list("nutriment" = 10, "protein" = 2)
tastes = list("tomato" = 1, "cabbage" = 1, "meat" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
+
/obj/item/food/snacks/soup/hong_kong_macaroni
name = "hong kong macaroni"
@@ -245,6 +283,8 @@
icon_state = "hong_kong_macaroni"
list_reagents = list("nutriment" = 8, "protein" = 2)
tastes = list("cream" = 1, "chicken" = 1, "pasta" = 1, "ham" =1)
+ goal_difficulty = FOOD_GOAL_NORMAL
+
//////////////////////
// Chili //
@@ -257,6 +297,8 @@
filling_color = "#FF3C00"
list_reagents = list("nutriment" = 5, "capsaicin" = 1, "tomatojuice" = 2, "vitamin" = 2)
tastes = list("hot peppers" = 1, "tomato" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
+
/obj/item/food/snacks/soup/coldchili
name = "cold chili"
@@ -265,6 +307,8 @@
filling_color = "#2B00FF"
list_reagents = list("nutriment" = 5, "frostoil" = 1, "tomatojuice" = 2, "vitamin" = 2)
tastes = list("tomato" = 1, "mint" = 1)
+ goal_difficulty = FOOD_GOAL_NORMAL
+
/obj/item/food/snacks/soup/clownchili
name = "chili con carnival"
diff --git a/code/modules/food_and_drinks/food_base.dm b/code/modules/food_and_drinks/food_base.dm
index 64facc6b031..d748c00e5bd 100644
--- a/code/modules/food_and_drinks/food_base.dm
+++ b/code/modules/food_and_drinks/food_base.dm
@@ -29,6 +29,10 @@
var/temperature_min = 0 // To limit the temperature of a reagent container can attain when exposed to heat/cold
var/temperature_max = 10000
+ // How difficult is this food for the kitchen to make?
+ // Affects the quantity of food that is requested by CC.
+ var/goal_difficulty = REAGENT_GOAL_SKIP
+
/obj/item/food/Initialize(mapload)
. = ..()
diff --git a/code/modules/hydroponics/grown/kudzu.dm b/code/modules/hydroponics/grown/kudzu.dm
index 6eb13e46ead..1f08ff6b347 100644
--- a/code/modules/hydroponics/grown/kudzu.dm
+++ b/code/modules/hydroponics/grown/kudzu.dm
@@ -44,7 +44,7 @@
var/text = ..()
var/text_string = ""
for(var/datum/spacevine_mutation/SM in mutations)
- text_string += "[(text_string == "") ? "" : ", "][SM.name]"
+ text_string += "[(text_string == "") ? "" : ", "][initial(SM.name)]"
text += "\n- Plant Mutations: [(text_string == "") ? "None" : text_string]"
return text
@@ -53,7 +53,7 @@
if(S.has_reagent("sterilizine", 5))
for(var/datum/spacevine_mutation/SM in mutations)
- if(SM.quality == SPACEVINE_MUTATION_NEGATIVE)
+ if(initial(SM.quality) == SPACEVINE_MUTATION_NEGATIVE)
temp_mut_list += SM
if(prob(20) && temp_mut_list.len)
mutations.Remove(pick(temp_mut_list))
@@ -61,7 +61,7 @@
if(S.has_reagent("fuel", 5))
for(var/datum/spacevine_mutation/SM in mutations)
- if(SM.quality == SPACEVINE_MUTATION_POSITIVE)
+ if(initial(SM.quality) == SPACEVINE_MUTATION_POSITIVE)
temp_mut_list += SM
if(prob(20) && temp_mut_list.len)
mutations.Remove(pick(temp_mut_list))
@@ -69,7 +69,7 @@
if(S.has_reagent("phenol", 5))
for(var/datum/spacevine_mutation/SM in mutations)
- if(SM.quality == SPACEVINE_MUTATION_MINOR_NEGATIVE)
+ if(initial(SM.quality) == SPACEVINE_MUTATION_MINOR_NEGATIVE)
temp_mut_list += SM
if(prob(20) && temp_mut_list.len)
mutations.Remove(pick(temp_mut_list))
diff --git a/code/modules/paperwork/handlabeler.dm b/code/modules/paperwork/handlabeler.dm
index 11726195d05..72fae016821 100644
--- a/code/modules/paperwork/handlabeler.dm
+++ b/code/modules/paperwork/handlabeler.dm
@@ -1,3 +1,7 @@
+#define LABEL_MODE_OFF 0
+#define LABEL_MODE_NORMAL 1
+#define LABEL_MODE_GOAL 2
+
/obj/item/hand_labeler
name = "hand labeler"
desc = "A combined label printer, applicator, and remover, all in a single portable device. Designed to be easy to operate and use."
@@ -6,12 +10,12 @@
item_state = "flight"
var/label = null
var/labels_left = 30
- var/mode = 0
+ var/mode = LABEL_MODE_OFF
/obj/item/hand_labeler/afterattack(atom/A, mob/user, proximity)
if(!proximity)
return
- if(!mode) //if it's off, give up.
+ if(mode == LABEL_MODE_OFF) //if it's off, give up.
return
if(!labels_left)
@@ -20,13 +24,23 @@
if(!label || !length(label))
to_chat(user, "No text set!")
return
- if(length(A.name) + length(label) > 64)
- to_chat(user, "Label too big!")
- return
if(ismob(A))
to_chat(user, "You can't label creatures!") // use a collar
return
+ if(mode == LABEL_MODE_GOAL)
+ if(istype(A, /obj/item))
+ to_chat(user, "Put it in a personal crate instead!")
+ return
+ user.visible_message("[user] labels [A] as part of a secondary goal for [label].", \
+ "You label [A] as part of a secondary goal for [label].")
+ A.AddComponent(/datum/component/label/goal, label)
+ return
+
+ if(length(A.name) + length(label) > 64)
+ to_chat(user, "Label too big!")
+ return
+
user.visible_message("[user] labels [A] as [label].", \
"You label [A] as [label].")
investigate_log("[key_name(user)] ([ADMIN_FLW(user,"FLW")]) labelled \"[A]\" ([ADMIN_VV(A, "VV")]) with \"[label]\" at [COORD(A.loc)] [ADMIN_JMP(A)].", INVESTIGATE_RENAME) // Investigate goes BEFORE rename so the original name is preserved in the log
@@ -35,6 +49,8 @@
labels_left--
/obj/item/hand_labeler/attack_self(mob/user as mob)
+ // off -> normal
+ // normal or goal -> off
mode = !mode
icon_state = "labeler[mode]"
if(mode)
@@ -55,8 +71,16 @@
user.drop_item()
qdel(I)
labels_left = initial(labels_left) //Yes, it's capped at its initial value
- else
- return ..()
+ else if(istype(I, /obj/item/card/id))
+ var/obj/item/card/id/id = I
+ if(istype(id, /obj/item/card/id/guest) || !id.registered_name)
+ to_chat(user, "Invalid ID card.")
+ return
+ label = id.registered_name
+ mode = LABEL_MODE_GOAL
+ to_chat(user, "You configure the hand labeler with [I].")
+ icon_state = "labeler1"
+
/obj/item/hand_labeler_refill
name = "hand labeler paper roll"
@@ -65,3 +89,7 @@
icon_state = "labeler_refill"
item_state = "electropack"
w_class = WEIGHT_CLASS_TINY
+
+#undef LABEL_MODE_OFF
+#undef LABEL_MODE_NORMAL
+#undef LABEL_MODE_GOAL
diff --git a/code/modules/reagents/chemistry/reagents/alcohol.dm b/code/modules/reagents/chemistry/reagents/alcohol.dm
index 9ef0f6fac0a..e72a81a8a68 100644
--- a/code/modules/reagents/chemistry/reagents/alcohol.dm
+++ b/code/modules/reagents/chemistry/reagents/alcohol.dm
@@ -9,6 +9,7 @@
var/dizzy_adj = 6 SECONDS
var/alcohol_perc = 1 //percentage of ethanol in a beverage 0.0 - 1.0
taste_description = "liquid fire"
+ goal_department = "Bar"
/datum/reagent/consumable/ethanol/on_mob_life(mob/living/M)
M.AdjustDrunk(alcohol_perc STATUS_EFFECT_CONSTANT)
@@ -125,6 +126,7 @@
drink_name = "Hooch"
drink_desc = "You've really hit rock bottom now... your liver packed its bags and left last night."
taste_description = "pure resignation"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ethanol/hooch/on_mob_life(mob/living/carbon/M)
if(M.mind && M.mind.assigned_role == "Assistant")
@@ -161,6 +163,7 @@
drink_name = "Glass of Mojito"
drink_desc = "Fresh from Spesscuba."
taste_description = "mojito"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/vodka
name = "Vodka"
@@ -242,6 +245,7 @@
drink_name = "Suicider"
drink_desc = "You've really hit rock bottom now... your liver packed its bags and left last night."
taste_description = "approaching death"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ethanol/ale
name = "Ale"
@@ -291,6 +295,7 @@
drink_name = "Glass of bilk"
drink_desc = "A brew of milk and beer. For those alcoholics who fear osteoporosis."
taste_description = "bilk"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/atomicbomb
name = "Atomic Bomb"
@@ -303,6 +308,7 @@
drink_name = "Atomic Bomb"
drink_desc = "Nanotrasen cannot take legal responsibility for your actions after imbibing."
taste_description = "a long, fiery burn"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/consumable/ethanol/threemileisland
name = "Three Mile Island Iced Tea"
@@ -315,6 +321,7 @@
drink_name = "Three Mile Island Ice Tea"
drink_desc = "A glass of this is sure to prevent a meltdown."
taste_description = "a creeping heat"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/consumable/ethanol/goldschlager
name = "Goldschlager"
@@ -351,6 +358,7 @@
drink_name = "Gin and Tonic"
drink_desc = "A mild but still great cocktail. Drink up, like a true Englishman."
taste_description = "bitter medicine"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/cuba_libre
name = "Cuba Libre"
@@ -363,6 +371,7 @@
drink_name = "Cuba Libre"
drink_desc = "A classic mix of rum and cola."
taste_description = "liberation"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/whiskey_cola
name = "Whiskey Cola"
@@ -375,6 +384,7 @@
drink_name = "Whiskey Cola"
drink_desc = "An innocent-looking mixture of cola and Whiskey. Delicious."
taste_description = "whiskey and coke"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/daiquiri
name = "Daiquiri"
@@ -387,6 +397,7 @@
drink_name = "Daiquiri"
drink_desc = "When Botany gives you limes, make daiquiris."
taste_description = "sweetened lime juice and rum"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/martini
name = "Classic Martini"
@@ -399,6 +410,7 @@
drink_name = "Classic Martini"
drink_desc = "Damn, the bartender even stirred it, not shook it."
taste_description = "class"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/vodkamartini
name = "Vodka Martini"
@@ -411,6 +423,7 @@
drink_name = "Vodka martini"
drink_desc ="A bastardisation of the classic martini. Still great."
taste_description = "class and potatoes"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/white_russian
name = "White Russian"
@@ -423,6 +436,7 @@
drink_name = "White Russian"
drink_desc = "A very nice looking drink. But that's just, like, your opinion, man."
taste_description = "very creamy alcohol"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/screwdrivercocktail
name = "Screwdriver"
@@ -435,6 +449,7 @@
drink_name = "Screwdriver"
drink_desc = "A simple, yet superb mixture of Vodka and orange juice. Just the thing for the tired engineer."
taste_description = "a naughty secret"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/booger
name = "Booger"
@@ -447,6 +462,7 @@
drink_name = "Booger"
drink_desc = "Eww..."
taste_description = "a fruity mess"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/bloody_mary
name = "Bloody Mary"
@@ -459,6 +475,7 @@
drink_name = "Bloody Mary"
drink_desc = "Tomato juice, mixed with Vodka and a lil' bit of lime. Tastes like liquid murder."
taste_description = "tomatoes with booze"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/gargle_blaster
name = "Pan-Galactic Gargle Blaster"
@@ -471,6 +488,7 @@
drink_name = "Pan-Galactic Gargle Blaster"
drink_desc = "Does... does this mean that Arthur and Ford are on the station? Oh joy."
taste_description = "the number fourty two"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/flaming_homer
name = "Flaming Moe"
@@ -483,6 +501,7 @@
drink_name = "Flaming Moe"
drink_desc = "Happiness is just a Flaming Moe away!"
taste_description = "caramelised booze and sweet, salty medicine"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ethanol/brave_bull
name = "Brave Bull"
@@ -507,6 +526,7 @@
drink_name = "Tequila Sunrise"
drink_desc = "Oh great, now you feel nostalgic about sunrises back on Terra..."
taste_description = "fruity alcohol"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/toxins_special
name = "Toxins Special"
@@ -519,6 +539,7 @@
drink_name = "Toxins Special"
drink_desc = "Whoah, this thing is on FIRE"
taste_description = "FIRE"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ethanol/toxins_special/on_mob_life(mob/living/M)
if(M.bodytemperature < 330)
@@ -536,6 +557,7 @@
drink_name = "Beepsky Smash"
drink_desc = "Heavy, hot and strong. Just like the Iron fist of the LAW."
taste_description = "THE LAW"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ethanol/irish_cream
name = "Irish Cream"
@@ -560,6 +582,7 @@
drink_name = "The Manly Dorf"
drink_desc = "A manly concotion made from Ale and Beer. Intended for true men only."
taste_description = "manliness"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/longislandicedtea
name = "Long Island Iced Tea"
@@ -572,6 +595,7 @@
drink_name = "Long Island Iced Tea"
drink_desc = "The liquor cabinet, brought together in a delicious mix. Intended for middle-aged alcoholic women only."
taste_description = "fruity alcohol"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/moonshine
name = "Moonshine"
@@ -584,6 +608,7 @@
drink_name = "Moonshine"
drink_desc = "You've really hit rock bottom now... your liver packed its bags and left last night."
taste_description = "prohibition"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ethanol/b52
name = "B-52"
@@ -596,6 +621,7 @@
drink_name = "B-52"
drink_desc = "Kahlua, Irish Cream, and congac. You will get bombed."
taste_description = "destruction"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/irishcoffee
name = "Irish Coffee"
@@ -608,6 +634,7 @@
drink_name = "Irish Coffee"
drink_desc = "Coffee and alcohol. More fun than a Mimosa to drink in the morning."
taste_description = "coffee and booze"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/margarita
name = "Margarita"
@@ -620,6 +647,7 @@
drink_name = "Margarita"
drink_desc = "On the rocks with salt on the rim. Arriba~!"
taste_description = "daisies"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/black_russian
name = "Black Russian"
@@ -632,6 +660,7 @@
drink_name = "Black Russian"
drink_desc = "For the lactose-intolerant. Still as classy as a White Russian."
taste_description = "sweet alcohol"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/manhattan
name = "Manhattan"
@@ -656,6 +685,7 @@
drink_name = "Manhattan Project"
drink_desc = "A scientist's drink of choice, for thinking how to blow up the station."
taste_description = "the apocalypse"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/consumable/ethanol/whiskeysoda
name = "Whiskey Soda"
@@ -668,6 +698,7 @@
drink_name = "Whiskey Soda"
drink_desc = "Ultimate refreshment."
taste_description = "mediocrity"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/antifreeze
name = "Anti-freeze"
@@ -680,6 +711,7 @@
drink_name = "Anti-freeze"
drink_desc = "The ultimate refreshment."
taste_description = "poor life choices"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/antifreeze/on_mob_life(mob/living/M)
if(M.bodytemperature < 330)
@@ -698,6 +730,7 @@
drink_name = "Admin Freeze"
drink_desc = "The ultimate punishment."
taste_description = "a series of bad decisions"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/consumable/ethanol/adminfreeze/reaction_mob(mob/living/M, method = REAGENT_INGEST, volume)
..()
@@ -716,6 +749,7 @@
drink_name = "Barefoot"
drink_desc = "Barefoot and pregnant"
taste_description = "pregnancy"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/snowwhite
name = "Snow White"
@@ -728,6 +762,7 @@
drink_name = "Snow White"
drink_desc = "A cold refreshment."
taste_description = "a poisoned apple"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/demonsblood
name = "Demons Blood"
@@ -741,6 +776,7 @@
drink_name = "Demons Blood"
drink_desc = "Just looking at this thing makes the hair at the back of your neck stand up."
taste_description = "evil"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/vodkatonic
name = "Vodka and Tonic"
@@ -754,6 +790,7 @@
drink_name = "Vodka and Tonic"
drink_desc = "For when a gin and tonic isn't russian enough."
taste_description = "bitter medicine"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/ginfizz
name = "Gin Fizz"
@@ -767,6 +804,7 @@
drink_name = "Gin Fizz"
drink_desc = "Refreshingly lemony, deliciously dry."
taste_description = "fizzy alcohol"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/bahama_mama
name = "Bahama mama"
@@ -779,6 +817,7 @@
drink_name = "Bahama Mama"
drink_desc = "Tropic cocktail"
taste_description = "HONK"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/singulo
name = "Singulo"
@@ -792,6 +831,7 @@
drink_name = "Singulo"
drink_desc = "A bluespace beverage."
taste_description = "infinity"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ethanol/sbiten
name = "Sbiten"
@@ -804,6 +844,7 @@
drink_name = "Sbiten"
drink_desc = "A spicy mix of Vodka and Spice. Very hot."
taste_description = "comforting warmth"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ethanol/sbiten/on_mob_life(mob/living/M)
if(M.bodytemperature < 360)
@@ -821,6 +862,7 @@
drink_name = "Devils Kiss"
drink_desc = "Creepy time!"
taste_description = "naughtiness"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/red_mead
name = "Red Mead"
@@ -833,6 +875,7 @@
drink_name = "Red Mead"
drink_desc = "A True Vikings Beverage, though its color is strange."
taste_description = "blood"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/consumable/ethanol/mead
name = "Mead"
@@ -875,6 +918,7 @@
drink_name = "Grog"
drink_desc = "A fine and cepa drink for Space."
taste_description = "strongly diluted rum"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/aloe
name = "Aloe"
@@ -887,6 +931,7 @@
drink_name = "Aloe"
drink_desc = "Very, very, very good."
taste_description = "healthy skin"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/andalusia
name = "Andalusia"
@@ -899,6 +944,7 @@
drink_name = "Andalusia"
drink_desc = "A nice, strange named drink."
taste_description = "sweet alcohol"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/alliescocktail
name = "Allies Cocktail"
@@ -911,6 +957,7 @@
drink_name = "Allies cocktail"
drink_desc = "A drink made from your allies."
taste_description = "victory"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/acid_spit
name = "Acid Spit"
@@ -923,6 +970,7 @@
drink_name = "Acid Spit"
drink_desc = "A drink from Nanotrasen. Made from live aliens."
taste_description = "PAIN"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ethanol/amasec
name = "Amasec"
@@ -935,6 +983,7 @@
drink_name = "Amasec"
drink_desc = "Always handy before COMBAT!!!"
taste_description = "a stunbaton"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ethanol/neurotoxin
name = "Neuro-toxin"
@@ -949,6 +998,7 @@
drink_name = "Neurotoxin"
drink_desc = "A drink that is guaranteed to knock you silly."
taste_description = "brain damageeeEEeee"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ethanol/neurotoxin/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -971,6 +1021,7 @@
drink_name = "Hippie's Delight"
drink_desc = "A drink enjoyed by people during the 1960's."
taste_description = "colors"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/consumable/ethanol/hippies_delight/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -1009,6 +1060,7 @@
drink_name = "Changeling Sting"
drink_desc = "A stingy drink."
taste_description = "a tiny prick"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/dublindrop
name = "Dublin Drop"
@@ -1022,6 +1074,7 @@
drink_name = "Dublin Drop"
drink_desc = "A Dublin drop. Pub legends say one of the ingredients can bring back the dead."
taste_description = "a belt in the gob"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/syndicatebomb
name = "Syndicate Bomb"
@@ -1034,6 +1087,7 @@
drink_name = "Syndicate Bomb"
drink_desc = "A syndicate bomb."
taste_description = "a job offer"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/erikasurprise
name = "Erika Surprise"
@@ -1046,6 +1100,7 @@
drink_name = "Erika Surprise"
drink_desc = "The surprise is, it's green!"
taste_description = "disappointment"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/driestmartini
name = "Driest Martini"
@@ -1059,6 +1114,7 @@
drink_name = "Driest Martini"
drink_desc = "Only for the experienced. You think you see sand floating in the glass."
taste_description = "dust and ashes"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/driestmartini/on_mob_life(mob/living/M)
if(current_cycle >= 55 && current_cycle < 115)
@@ -1093,6 +1149,7 @@
drink_name = "Gin and Sonic"
drink_desc = "An extremely high amperage drink. Absolutely not for the true Englishman."
taste_description = "SPEED"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/ginsonic/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -1121,6 +1178,7 @@
drink_name = "Glass of applejack"
drink_desc = "When cider isn't strong enough, you gotta jack it."
taste_description = "strong cider"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ethanol/jackrose
name = "Jack Rose"
@@ -1132,6 +1190,7 @@
drink_name = "Jack Rose"
drink_desc = "Drinking this makes you feel like you belong in a luxury hotel bar during the 1920s."
taste_description = "style"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ethanol/drunkenblumpkin
name = "Drunken Blumpkin"
@@ -1143,6 +1202,7 @@
drink_name = "Drunken Blumpkin"
drink_desc = "A drink for the drunks"
taste_description = "weirdness"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ethanol/eggnog
name = "Eggnog"
@@ -1155,6 +1215,7 @@
drink_name = "Eggnog"
drink_desc = "For enjoying the most wonderful time of the year."
taste_description = "christmas spirit"
+ goal_difficulty = REAGENT_GOAL_HARD
/// inaccessible to players, but here for admin shennanigans
/datum/reagent/consumable/ethanol/dragons_breath
@@ -1256,6 +1317,7 @@
drink_name = "Glass of Trinary"
drink_desc = "Colorful drink made for synthetic crewmembers. It doesn't seem like it would taste well."
taste_description = "modem static"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/synthanol/servo
name = "Servo"
@@ -1268,6 +1330,7 @@
drink_name = "Glass of Servo"
drink_desc = "Chocolate - based drink made for IPCs. Not sure if anyone's actually tried out the recipe."
taste_description = "motor oil and cocoa"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/synthanol/uplink
name = "Uplink"
@@ -1280,6 +1343,7 @@
drink_name = "Glass of Uplink"
drink_desc = "An exquisite mix of the finest liquoirs and synthanol. Meant only for synthetics."
taste_description = "a GUI in visual basic"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/synthanol/synthnsoda
name = "Synth 'n Soda"
@@ -1292,6 +1356,7 @@
drink_name = "Glass of Synth 'n Soda"
drink_desc = "Classic drink altered to fit the tastes of a robot. Bad idea to drink if you're made of carbon."
taste_description = "fizzy motor oil"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/synthanol/synthignon
name = "Synthignon"
@@ -1464,6 +1529,7 @@
drink_desc = "A sawed-off cola bottle filled with Fernet Cola. You can hear cuarteto music coming from the inside."
taste_description = "low class heaven"
remove_nutrition = 1
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/gimlet
name = "Gimlet"
@@ -1475,6 +1541,7 @@
drink_name = "Gimlet"
drink_desc = "There are debates on whether this drink should be half gin and half lime, or three parts gin and one part lime. All you know is, it's alcohol."
taste_description = "sharpness"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/sidecar
name = "Sidecar"
@@ -1486,6 +1553,7 @@
drink_name = "Sidecar"
drink_desc = "You can smell the citrus from here!"
taste_description = "smooth cognac and tart citrus"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/consumable/ethanol/whiskey_sour
name = "Whiskey Sour"
@@ -1497,6 +1565,7 @@
drink_name = "Whiskey Sour"
drink_desc = "Lemon and whiskey, with a cute foamy head!"
taste_description = "warm whiskey and sweetness"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/consumable/ethanol/mint_julep
name = "Mint Julep"
@@ -1508,6 +1577,7 @@
drink_name = "Mint Julep"
drink_desc = "A dainty glass of whiskey and mint on the rocks. Perfect for summer!"
taste_description = "sweet and cooling mint"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/pina_colada
name = "Pina Colada"
@@ -1519,6 +1589,7 @@
drink_name = "Pina Colada"
drink_desc = "After taking a sip, you feel contractually obligated to start singing a certain song of the same name."
taste_description = "tart and tropical pineapple"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/bilkshake
name = "Bilkshake"
@@ -1531,6 +1602,7 @@
drink_name = "Bilkshake"
drink_desc = "Your mind bubbles and oozes as it tries to comprehend what it's seeing. What the HELL is this?"
taste_description = "bilk, cream, and cold tears"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/sontse
name = "Sontse"
@@ -1543,6 +1615,7 @@
drink_desc = "The Sun, The Sun, The Sun, The Sun, The Sun, THE SUN!"
taste_description = "warmth and brightness"
var/light_activated = FALSE
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/consumable/ethanol/sontse/on_mob_life(mob/living/M)
if(current_cycle != 5 || !ismoth(M))
@@ -1571,6 +1644,7 @@
drink_desc = "Blizzard in a glass. Tajaran signature drink!"
taste_description = "ice"
var/min_achievable_temp = 250
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ethanol/ahdomai_eclipse/on_mob_life(mob/living/M)
. = ..()
@@ -1587,6 +1661,7 @@
drink_name = "Feast by the Beach"
drink_desc = "A classic Unathi drink. You can spot sand sediment at the bottom of the glass. The drink is hot as hell and more."
taste_description = "sand"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ethanol/beach_feast/on_mob_life(mob/living/M)
if(!isunathi(M))
@@ -1605,6 +1680,7 @@
drink_name = "Jungle Vox"
drink_desc = "Classy drink in a glass vox head with a bit of liquid nitrogen added on."
taste_description = "bubbles"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ethanol/jungle_vox/on_mob_life(mob/living/M)
if(current_cycle <= 5 || !isvox(M))
@@ -1624,6 +1700,7 @@
drink_name = "Slime Mold"
drink_desc = "You can swear that this jelly looks alive."
taste_description = "jelly"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/consumable/ethanol/slime_mold/on_mob_life(mob/living/M)
if(!isslimeperson(M))
@@ -1644,6 +1721,7 @@
drink_name = "Die Seife"
drink_desc = "There is a piece of soap at the bottom of the glass and it is slowly melting."
taste_description = "soap"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ethanol/die_seife/on_mob_life(mob/living/M)
if(current_cycle % 10 != 0 || !isdrask(M))
@@ -1664,6 +1742,7 @@
drink_name = "Acid Dreams"
drink_desc = "This one looks just weird and reeks of acid."
taste_description = "acid"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ethanol/acid_dreams/on_mob_life(mob/living/M)
if(current_cycle % 10 != 0 || !isgrey(M))
@@ -1689,6 +1768,7 @@
drink_name = "Islay Whiskey"
drink_desc = "Named in honor of one of the most gritty and earth smelling types of Whiskey of Earth, this drink is a treat for any Diona."
taste_description = "soil"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ethanol/islay_whiskey/on_mob_life(mob/living/M)
if(current_cycle <=5 || !isdiona(M))
@@ -1715,6 +1795,7 @@
drink_desc = "In the triangle of fire, this is apex of fuel."
taste_description = "fire"
var/on_fire = FALSE
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/consumable/ethanol/ultramatter/on_mob_life(mob/living/M)
// species agnostic as it is DRINKS on_fire, so only plasmaman can get it
@@ -1747,6 +1828,7 @@
drink_name = "Howler"
drink_desc = "Old classic human drink that was adopted by Vulpkanin."
taste_description = "citrus"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/consumable/ethanol/howler/on_mob_life(mob/living/M)
if(!isvulpkanin(M))
@@ -1769,6 +1851,7 @@
drink_desc = "Fake Diona is floating carelessly in the middle of this drink."
taste_description = "the crunch"
var/mutated = FALSE
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ethanol/diona_smash/on_mob_life(mob/living/M)
if(mutated || !iskidan(M))
diff --git a/code/modules/reagents/chemistry/reagents/drugs.dm b/code/modules/reagents/chemistry/reagents/drugs.dm
index 9854ebec5c2..f2a1442f275 100644
--- a/code/modules/reagents/chemistry/reagents/drugs.dm
+++ b/code/modules/reagents/chemistry/reagents/drugs.dm
@@ -28,6 +28,8 @@
reagent_state = LIQUID
color = "#0000D8"
taste_description = "a magical journey"
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/lsd/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -46,6 +48,8 @@
addiction_threshold = 10
heart_rate_decrease = 1
taste_description = "a synthetic high"
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/space_drugs/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -171,6 +175,8 @@
addiction_threshold = 5
addiction_decay_rate = 0.2 // half the metabolism rate
taste_description = "bitterness"
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/crank/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -249,6 +255,8 @@
overdose_threshold = 20
addiction_chance = 10
addiction_threshold = 5
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/pump_up/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -290,6 +298,8 @@
addiction_threshold = 10
taste_description = "very poor life choices"
allowed_overdose_process = TRUE
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/krokodil/on_mob_life(mob/living/M)
@@ -370,6 +380,8 @@
allowed_overdose_process = TRUE //Requested by balance.
/// modifier to the stun time of the mob taking the drug
var/tenacity = 1.5
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/methamphetamine/on_mob_add(mob/living/L)
ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id)
@@ -440,6 +452,8 @@
addiction_decay_rate = 0.2
taste_description = "WAAAAGH"
var/bonus_damage = 2
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/bath_salts/on_mob_add(mob/living/L)
if(ishuman(L))
@@ -541,6 +555,8 @@
addiction_chance = 5
addiction_threshold = 5
taste_description = "the inside of a toilet... or worse"
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/jenkem/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -563,6 +579,8 @@
addiction_decay_rate = 0.2
/// how much do we edit the stun and stamina mods? lower is more resistance
var/tenacity = 0.5
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/aranesp/on_mob_add(mob/living/L)
if(ishuman(L))
@@ -610,6 +628,8 @@
addiction_chance_additional = 20
addiction_threshold = 20
minor_addiction = TRUE
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/happiness/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -718,6 +738,8 @@
addiction_chance_additional = 20
addiction_threshold = 10
taste_description = "flips"
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/fliptonium/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -784,6 +806,8 @@
color = "#AC88CA" //RGB: 172, 136, 202
metabolization_rate = 0.6 * REAGENTS_METABOLISM
taste_description = "spinning"
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/rotatium/on_mob_life(mob/living/carbon/M)
if(M.hud_used)
@@ -834,6 +858,8 @@
var/constant_dose_time = 0
/// Keeps track of how many chemicals we are delaying the changeling by.
var/changeling_chemical_tracker = 0
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/mephedrone/on_mob_add(mob/living/carbon/L)
@@ -1121,6 +1147,8 @@
addiction_decay_rate = 0.1 //very low to force them to take time off of meth
taste_description = "wiper fluid"
var/tenacity = 1.5 // higher is worse
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/lube/ultra/on_mob_add(mob/living/L)
ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id)
@@ -1184,6 +1212,8 @@
addiction_threshold = 5
addiction_decay_rate = 0.2
taste_description = "silicon"
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/surge/on_mob_life(mob/living/M)
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index 1db066db7dc..28e66a573fd 100644
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -133,6 +133,8 @@
nutriment_factor = 2 * REAGENTS_METABOLISM
color = "#792300" // rgb: 121, 35, 0
taste_description = "soy"
+ goal_department = "Kitchen"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/ketchup
name = "Ketchup"
@@ -150,6 +152,8 @@
reagent_state = LIQUID
color = "#DFDFDF" // rgb: 223, 223, 223
taste_description = "mayonnaise"
+ goal_department = "Kitchen"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/consumable/peanutbutter
name = "Peanut Butter"
@@ -169,6 +173,8 @@
color = "#78280A" // rbg: 120, 40, 10
taste_mult = 2.5
taste_description = "smokey sweetness"
+ goal_department = "Kitchen"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/capsaicin
name = "Capsaicin Oil"
@@ -372,6 +378,8 @@
nutriment_factor = 10 * REAGENTS_METABOLISM
color = "#DBCF5C" //rgb: 219, 207, 92
taste_description = "olive oil"
+ goal_department = "Kitchen"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/cornoil/reaction_turf(turf/simulated/T, volume)
if(!istype(T))
@@ -393,6 +401,8 @@
reagent_state = LIQUID
color = "#282314" // rgb: 54, 94, 48
taste_description = "sweetness"
+ goal_department = "Kitchen"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/consumable/dry_ramen
name = "Dry Ramen"
@@ -778,6 +788,8 @@
reagent_state = LIQUID
color = "#B4641B"
taste_description = "gravy"
+ goal_department = "Kitchen"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/consumable/wasabi
name = "Wasabi"
@@ -1014,3 +1026,5 @@
description = "Useful for pickling, or putting on chips."
taste_description = "vinegar"
color = "#ffffff"
+ goal_department = "Kitchen"
+ goal_difficulty = REAGENT_GOAL_NORMAL
diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm
index 9ba2163d191..5e779a76070 100644
--- a/code/modules/reagents/chemistry/reagents/medicine.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine.dm
@@ -3,6 +3,7 @@
id = "medicine"
taste_description = "bitterness"
harmless = TRUE
+ goal_department = "Medbay"
/datum/reagent/medicine/on_mob_life(mob/living/M)
current_cycle++
@@ -22,6 +23,7 @@
metabolization_rate = 0.3 // Lasts 1.5 minutes for 15 units
shock_reduction = 200
taste_description = "numbness"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/medicine/hydrocodone/on_mob_life(mob/living/M) //Needed so the hud updates when injested / removed from system
var/update_flags = STATUS_UPDATE_HEALTH
@@ -34,6 +36,7 @@
reagent_state = LIQUID
color = "#C8A5DC" // rgb: 200, 165, 220
taste_description = "antiseptic"
+ goal_difficulty = REAGENT_GOAL_EASY
//makes you squeaky clean
/datum/reagent/medicine/sterilizine/reaction_mob(mob/living/M, method=REAGENT_TOUCH, volume)
@@ -97,6 +100,7 @@
reagent_state = LIQUID
color = "#C8A5DC" // rgb: 200, 165, 220
taste_description = "nurturing"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/medicine/mitocholide/on_mob_life(mob/living/M)
if(ishuman(M))
@@ -124,6 +128,7 @@
color = "#0000C8" // rgb: 200, 165, 220
heart_rate_decrease = 1
taste_description = "a safe refuge"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/medicine/cryoxadone/reaction_mob(mob/living/M, method = REAGENT_TOUCH, volume, show_message = TRUE)
if(iscarbon(M))
@@ -161,6 +166,7 @@
overdose_threshold = 30
harmless = FALSE
taste_description = "reformation"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/medicine/rezadone/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -190,6 +196,7 @@
color = "#0AB478"
metabolization_rate = 0.2
taste_description = "antibiotics"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/medicine/spaceacillin/on_mob_life(mob/living/M)
var/list/organs_list = list()
@@ -223,6 +230,7 @@
penetrates_skin = TRUE
metabolization_rate = 0.15
taste_description = "salt"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/medicine/salglu_solution/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -286,6 +294,7 @@
color = "#FFEBEB"
penetrates_skin = TRUE
taste_description = "blood"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/medicine/heal_on_apply/synthflesh/reaction_mob(mob/living/M, method = REAGENT_TOUCH, volume, show_message = 1)
var/mob/living/carbon/human/H = M
@@ -320,6 +329,7 @@
metabolization_rate = 3
harmless = FALSE
taste_description = "wound cream"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/medicine/heal_on_apply/styptic_powder/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -353,6 +363,7 @@
metabolization_rate = 3
harmless = FALSE //toxic if ingested, and I am NOT going to account for the difference
taste_description = "burn cream"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/medicine/heal_on_apply/silver_sulfadiazine/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -383,6 +394,7 @@
reagent_state = LIQUID
color = "#000000"
taste_description = "dust"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/medicine/charcoal/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -464,6 +476,7 @@
metabolization_rate = 0.8
harmless = FALSE
taste_description = "a painful cleansing"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/medicine/calomel/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -483,6 +496,7 @@
reagent_state = LIQUID
color = "#B4DCBE"
taste_description = "cleansing"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/medicine/potass_iodide/on_mob_life(mob/living/M)
M.radiation = max(0, M.radiation - 25)
@@ -496,6 +510,7 @@
color = "#C8A5DC"
harmless = FALSE
taste_description = "a purge"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/medicine/pen_acid/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -521,6 +536,7 @@
overdose_threshold = 25
harmless = FALSE
taste_description = "relief"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/medicine/sal_acid/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -555,6 +571,7 @@
color = "#00FFFF"
metabolization_rate = 0.2
taste_description = "safety"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/medicine/salbutamol/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -576,6 +593,7 @@
addiction_threshold = 10
harmless = FALSE
taste_description = "oxygenation"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/medicine/perfluorodecalin/on_mob_life(mob/living/carbon/human/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -601,6 +619,7 @@
overdose_threshold = 35
harmless = FALSE
taste_description = "stimulation"
+ goal_difficulty = REAGENT_GOAL_HARD
//super weak antistun chem, barely any downside
/datum/reagent/medicine/ephedrine/on_mob_life(mob/living/M)
@@ -656,6 +675,7 @@
overdose_threshold = 35
harmless = FALSE
taste_description = "antihistamine"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/medicine/diphenhydramine/on_mob_life(mob/living/M)
M.AdjustJitter(-40 SECONDS)
@@ -743,6 +763,7 @@
reagent_state = LIQUID
color = "#C8A5DC"
taste_description = "clarity"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/medicine/oculine/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -775,6 +796,7 @@
overdose_threshold = 25
harmless = FALSE
taste_description = "a moment of respite"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/medicine/atropine/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -804,6 +826,7 @@
overdose_threshold = 20
harmless = FALSE
taste_description = "borrowed time"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/medicine/epinephrine/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -856,6 +879,7 @@
taste_description = "life"
harmless = FALSE
var/revive_type = SENTIENCE_ORGANIC //So you can't revive boss monsters or robots with it
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/medicine/lazarus_reagent/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -926,6 +950,7 @@
taste_description = "coppery fuel"
harmless = FALSE
overdose_threshold = 15
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/medicine/sanguine_reagent/on_mob_life(mob/living/M)
if(!ishuman(M))
@@ -981,6 +1006,7 @@
taste_description = "chunky marrow"
harmless = FALSE
overdose_threshold = 30 //so a single shotgun dart can't cause the tumor effect
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/medicine/osseous_reagent/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -1004,6 +1030,7 @@
description = "Mannitol is a sugar alcohol that can help alleviate cranial swelling."
color = "#D1D1F1"
taste_description = "sweetness"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/medicine/mannitol/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -1016,6 +1043,7 @@
description = "Mutadone is an experimental bromide that can cure genetic abnomalities."
color = "#5096C8"
taste_description = "cleanliness"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/medicine/mutadone/on_mob_life(mob/living/carbon/human/M)
if(M.mind && M.mind.assigned_role == "Cluwne") // HUNKE
@@ -1045,6 +1073,7 @@
description = "A medicine which quickly eliminates alcohol in the body."
color = "#009CA8"
taste_description = "sobriety"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/medicine/antihol/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -1160,6 +1189,7 @@
color = "#eee6da"
overdose_threshold = 20
taste_description = "bitterness"
+ goal_difficulty = REAGENT_GOAL_HARD
/datum/reagent/heparin/on_mob_life(mob/living/M)
M.reagents.remove_reagent("cholesterol", 2)
@@ -1200,6 +1230,7 @@
addiction_threshold = 10
overdose_threshold = 50
taste_description = "warmth and stability"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/medicine/teporone/on_mob_life(mob/living/M)
if(M.bodytemperature > 310)
@@ -1217,6 +1248,7 @@
taste_description = "stability"
harmless = FALSE
var/list/drug_list = list("crank", "methamphetamine", "space_drugs", "synaptizine", "psilocybin", "ephedrine", "epinephrine", "stimulants", "stimulative_agent", "bath_salts", "lsd", "thc", "mephedrone")
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/medicine/haloperidol/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -1246,6 +1278,7 @@
metabolization_rate = 0.1
harmless = FALSE
taste_description = "sleepiness"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/medicine/ether/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -1326,6 +1359,7 @@
color = "#CC7A00"
process_flags = SYNTHETIC
taste_description = "overclocking"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/medicine/degreaser/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -1354,6 +1388,7 @@
color = "#D7B395"
process_flags = SYNTHETIC
taste_description = "heavy metals"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/medicine/liquid_solder/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm
index 8e0d0b7f3ff..5b2d9752536 100644
--- a/code/modules/reagents/chemistry/reagents/toxins.dm
+++ b/code/modules/reagents/chemistry/reagents/toxins.dm
@@ -182,6 +182,8 @@
metabolization_rate = 0.3
taste_mult = 0.9
taste_description = "slime"
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/mutagen/reaction_mob(mob/living/M, method=REAGENT_TOUCH, volume)
if(!M || !M.dna || HAS_TRAIT(M, TRAIT_BADDNA) || HAS_TRAIT(M, TRAIT_GENELESS))
@@ -279,6 +281,8 @@
process_flags = ORGANIC | SYNTHETIC
taste_description = "ACID"
var/acidpwr = 10 //the amount of protection removed from the armour
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/acid/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -336,6 +340,8 @@
description = "Fluorosulfuric acid is a an extremely corrosive super-acid."
color = "#5050FF"
acidpwr = 42
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/acid/facid/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -389,6 +395,8 @@
color = "#0080ff"
reagent_state = LIQUID
taste_description = "vinegar"
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/acetic_acid/reaction_mob(mob/living/carbon/human/H, method = REAGENT_TOUCH, volume)
if(method != REAGENT_TOUCH)
@@ -588,6 +596,8 @@
color = "#B44B00"
penetrates_skin = TRUE
taste_description = "bitterness"
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/formaldehyde/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -604,6 +614,8 @@
color = "#B44B00"
penetrates_skin = TRUE
taste_description = "apples"
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/acetaldehyde/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -645,6 +657,8 @@
color = "#60A584"
metabolization_rate = 1
taste_mult = 0
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_EASY
/datum/reagent/neurotoxin2/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -685,6 +699,8 @@
metabolization_rate = 0.1
penetrates_skin = TRUE
taste_description = "almonds"
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/cyanide/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_NONE
@@ -710,6 +726,8 @@
metabolization_rate = 0.3
penetrates_skin = TRUE
taste_description = "prickliness"
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_NORMAL
/datum/reagent/itching_powder/on_mob_life(mob/living/M)
var/update_flags = STATUS_UPDATE_STAT
@@ -1083,6 +1101,8 @@
reagent_state = LIQUID
color = "#773E73" //RGB: 47 24 45
lethality = 2 //Atrazine, however, is definitely toxic
+ goal_department = "Science"
+ goal_difficulty = REAGENT_GOAL_EASY
/// To-Do; make this more realistic.
diff --git a/code/modules/reagents/chemistry/reagents_datum.dm b/code/modules/reagents/chemistry/reagents_datum.dm
index 90cb9a79e57..2b4fbe56263 100644
--- a/code/modules/reagents/chemistry/reagents_datum.dm
+++ b/code/modules/reagents/chemistry/reagents_datum.dm
@@ -38,6 +38,13 @@
/// how quickly the addiction threshold var decays
var/addiction_decay_rate = 0.01
+ // Which department's (if any) reagent goals this is eligible for.
+ // Must match the values used by request consoles.
+ var/goal_department = "Unknown"
+ // How difficult is this chemical for the department to make?
+ // Affects the quantity of the reagent that is requested by CC.
+ var/goal_difficulty = REAGENT_GOAL_SKIP
+
/datum/reagent/Destroy()
. = ..()
holder = null
diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm
index 1299016a5a7..0777506e95e 100644
--- a/code/modules/research/message_server.dm
+++ b/code/modules/research/message_server.dm
@@ -82,23 +82,20 @@ GLOBAL_LIST_EMPTY(message_servers)
/obj/machinery/message_server/proc/send_pda_message(recipient = "", sender = "", message = "")
pda_msgs += new/datum/data_pda_msg(recipient,sender,message)
-/obj/machinery/message_server/proc/send_rc_message(recipient = "", sender = "", message = "", stamp = "", id_auth = "", priority = 1)
+/obj/machinery/message_server/proc/send_rc_message(recipient = "", sender = "", message = list(), stamp = "Not stamped", id_auth = "Not verified", priority = 1)
+ if(!islist(message))
+ message = list(message)
rc_msgs += new/datum/data_rc_msg(recipient,sender,message,stamp,id_auth)
- var/authmsg = "[message]"
- if(id_auth)
- authmsg += " - [id_auth]"
- if(stamp)
- authmsg += " - [stamp]"
for(var/C in GLOB.allRequestConsoles)
var/obj/machinery/requests_console/RC = C
if(ckey(RC.department) == ckey(recipient))
var/title
switch(priority)
if(2)
- title = "PRIORITY Alert in [sender]"
+ title = "PRIORITY Alert from [sender]"
else
title = "Message from [sender]"
- RC.createMessage(sender, title, authmsg, priority)
+ RC.createMessage(sender, title, message, priority, verified = id_auth, stamped = stamp)
/obj/machinery/message_server/attack_hand(user as mob)
to_chat(user, "You toggle PDA message passing from [active ? "On" : "Off"] to [active ? "Off" : "On"]")
diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm
index a11c6174ed4..021265fd716 100644
--- a/code/modules/shuttle/shuttle.dm
+++ b/code/modules/shuttle/shuttle.dm
@@ -284,7 +284,7 @@
//this is a hook for custom behaviour. Maybe at some point we could add checks to see if engines are intact
/obj/docking_port/mobile/proc/canMove()
- return 0 //0 means we can move
+ return TRUE // TRUE means we can move. Why would it ever be otherwise?
//this is to check if this shuttle can physically dock at dock S
/obj/docking_port/mobile/proc/canDock(obj/docking_port/stationary/S)
@@ -450,7 +450,7 @@
if(!check_dock(S1))
return -1
- if(canMove())
+ if(!canMove())
return -1
var/obj/docking_port/stationary/S0 = get_docked()
diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm
index a15863a3866..9fcc73e6fc6 100644
--- a/code/modules/shuttle/supply.dm
+++ b/code/modules/shuttle/supply.dm
@@ -1,5 +1,12 @@
#define MAX_CRATE_DELIVERY 40
+#define CARGO_OK 0
+#define CARGO_PREVENT_SHUTTLE 1
+#define CARGO_SKIP_ATOM 2
+#define CARGO_REQUIRE_PRIORITY 3
+#define CARGO_HAS_PRIORITY 4
+
+
/obj/docking_port/mobile/supply
name = "supply shuttle"
id = "supply"
@@ -10,45 +17,57 @@
dwidth = 5
height = 7
+ // The list of things that can't be sent to CC.
+ var/list/blacklist = list(
+ "living creatures" = list(
+ /mob/living,
+ /obj/structure/blob,
+ /obj/structure/spider/spiderling,
+ /obj/machinery/clonepod,
+ /obj/item/paicard),
+ "classified nuclear weaponry" = list(
+ /obj/item/disk/nuclear,
+ /obj/machinery/nuclearbomb),
+ "homing beacons" = list(
+ /obj/item/radio/beacon,
+ /obj/machinery/quantumpad,
+ /obj/machinery/teleport/station,
+ /obj/machinery/teleport/hub,
+ /obj/machinery/telepad,
+ /obj/machinery/telepad_cargo,
+ /obj/structure/extraction_point),
+ "high-energy objects" = list(
+ /obj/singularity,
+ /obj/machinery/the_singularitygen,
+ /obj/effect/hierophant,
+ /obj/item/warp_cube),
+ "undelivered mail" = list(/obj/item/envelope))
+
+ // The current manifest of what's on the shuttle.
+ var/datum/economy/cargo_shuttle_manifest/manifest = new
+
+ // The auto-registered simple_seller instances.
+ var/list/simple_sellers = list()
+
+ // The item preventing this shuttle from going to CC.
+ var/blocking_item = "ERR_UNKNOWN"
+
+/obj/docking_port/mobile/supply/Initialize()
+ ..()
+ for(var/T in subtypesof(/datum/economy/simple_seller))
+ var/datum/economy/simple_seller/seller = new T
+ simple_sellers += seller
+ seller.register(src)
+
/obj/docking_port/mobile/supply/register()
if(!..())
return FALSE
SSshuttle.supply = src
return TRUE
-/obj/docking_port/mobile/supply/proc/forbidden_atoms_check(atom/A)
- var/list/blacklist = list(
- /mob/living,
- /obj/structure/blob,
- /obj/structure/spider/spiderling,
- /obj/item/disk/nuclear,
- /obj/machinery/nuclearbomb,
- /obj/item/radio/beacon,
- /obj/machinery/the_singularitygen,
- /obj/singularity,
- /obj/machinery/teleport/station,
- /obj/machinery/teleport/hub,
- /obj/machinery/telepad,
- /obj/machinery/telepad_cargo,
- /obj/machinery/clonepod,
- /obj/effect/hierophant,
- /obj/item/warp_cube,
- /obj/machinery/quantumpad,
- /obj/structure/extraction_point,
- /obj/item/envelope,
- /obj/item/paicard)
- if(A)
- if(is_type_in_list(A, blacklist))
- return TRUE
- for(var/thing in A)
- if(.(thing))
- return TRUE
-
- return FALSE
-
/obj/docking_port/mobile/supply/canMove()
if(is_station_level(z))
- return forbidden_atoms_check(areaInstance)
+ return scan_cargo()
return ..()
/obj/docking_port/mobile/supply/request(obj/docking_port/stationary/S)
@@ -56,27 +75,30 @@
return 2
return ..()
-/obj/docking_port/mobile/supply/dock()
+/obj/docking_port/mobile/supply/dock(port)
. = ..()
if(.)
return
- buy()
- sell()
+ if(istype(port, /obj/docking_port/stationary/transit))
+ // Ignore transit ports.
+ return
+
+ if(is_station_level(z))
+ // Buy when arriving at the station.
+ buy()
+
+ if(z == level_name_to_num(CENTCOMM))
+ // Sell when arriving at CentComm.
+ sell()
/obj/docking_port/mobile/supply/proc/buy()
- if(!is_station_level(z)) //we only buy when we are -at- the station
- return 1
-
for(var/datum/supply_order/order as anything in SSeconomy.shopping_list)
if(length(SSeconomy.delivery_list) >= MAX_CRATE_DELIVERY)
break
SSeconomy.delivery_list += order
SSeconomy.shopping_list -= order
- if(!length(SSeconomy.delivery_list))
- return 2
-
var/list/emptyTurfs = list()
for(var/turf/simulated/T in areaInstance)
if(T.density)
@@ -108,151 +130,673 @@
SSeconomy.delivery_list.Cut()
-/obj/docking_port/mobile/supply/proc/sell()
- if(z != level_name_to_num(CENTCOMM)) //we only sell when we are -at- centcomm
- return 1
+ for(var/datum/station_goal/secondary/SG in SSticker.mode.secondary_goals)
+ if(!SG.should_send_crate)
+ continue
- var/plasma_count = 0
- var/intel_count = 0
- var/crate_count = 0
- var/total_crate_value = 0
+ var/turf/T = pick_n_take(emptyTurfs) //turf we will place it in
+ if(!T)
+ break
+
+ var/obj/structure/closet/crate/secure/personal/PC = new(T)
+ if(SG.requester_name)
+ PC.name = "goal crate ([SG.requester_name] in [SG.department])"
+ PC.desc = "This personal crate has been configured by CC for [SG.requester_name]'s use in completing the secondary goal [SG.name]."
+ PC.registered_name = SG.requester_name
+ else
+ PC.name = "goal crate (Unknown in [SG.department])"
+ PC.locked = FALSE
+ PC.update_icon()
+
+ SG.should_send_crate = FALSE
+
+/obj/docking_port/mobile/supply/proc/scan_cargo()
+ manifest = new
+ SEND_SIGNAL(src, COMSIG_CARGO_BEGIN_SCAN)
+ for(var/atom/movable/AM in areaInstance)
+ if(deep_scan(AM, TRUE) == CARGO_PREVENT_SHUTTLE)
+ return FALSE
+ return TRUE
+
+/obj/docking_port/mobile/supply/proc/deep_scan(atom/movable/AM, top_level = FALSE)
+ var/handling = prefilter_atom(AM)
+ if(handling == CARGO_PREVENT_SHUTTLE)
+ return CARGO_PREVENT_SHUTTLE
+
+ var/found_priority = FALSE
+ for(var/atom/movable/child in AM)
+ var/child_handling = deep_scan(child)
+ if(child_handling == CARGO_PREVENT_SHUTTLE)
+ return CARGO_PREVENT_SHUTTLE
+ if(child_handling == CARGO_HAS_PRIORITY)
+ found_priority = TRUE
+
+ if(handling != CARGO_SKIP_ATOM)
+ if(handling == CARGO_REQUIRE_PRIORITY && !found_priority)
+ blocking_item = "locked containers that don't contain goal items ([AM])"
+ return CARGO_PREVENT_SHUTTLE
+ var/sellable = SEND_SIGNAL(src, COMSIG_CARGO_CHECK_SELL, AM)
+ manifest.items_to_sell[AM] = sellable
+ if(top_level && !(sellable & COMSIG_CARGO_IS_SECURED))
+ manifest.loose_cargo = TRUE
+ if(sellable & COMSIG_CARGO_SELL_PRIORITY)
+ if(top_level)
+ return CARGO_OK
+ return CARGO_HAS_PRIORITY
+
+ return CARGO_OK
+
+/obj/docking_port/mobile/supply/proc/prefilter_atom(atom/movable/AM)
+ for(var/reason in blacklist)
+ if(is_type_in_list(AM, blacklist[reason]))
+ blocking_item = "[reason] ([AM])"
+ return CARGO_PREVENT_SHUTTLE
+
+ if(istype(AM, /obj/structure/largecrate))
+ blocking_item = "unopened large crates ([AM])"
+ return CARGO_PREVENT_SHUTTLE
+
+ if(istype(AM, /obj/structure/closet/crate))
+ var/obj/structure/closet/crate/C = AM
+ if(C.manifest)
+ blocking_item = "crates with their manifest still attached ([AM])"
+ return CARGO_PREVENT_SHUTTLE
+
+ if(istype(AM, /obj/structure/closet/crate/secure))
+ var/obj/structure/closet/crate/secure/SC = AM
+ if(SC.locked)
+ return CARGO_REQUIRE_PRIORITY
+ else if(istype(SC, /obj/structure/closet/crate/secure/personal))
+ blocking_item = "unlocked personal crates ([AM])"
+ return CARGO_PREVENT_SHUTTLE
+
+ if(istype(AM, /obj/item/storage/lockbox))
+ var/obj/item/storage/lockbox/LB = AM
+ if(LB.locked)
+ return CARGO_REQUIRE_PRIORITY
+
+ if(istype(AM, /obj/effect))
+ var/obj/effect/E = AM
+ if(E.is_cleanable())
+ return CARGO_OK
+
+ if(AM.anchored && !istype(AM, /obj/mecha/working))
+ return CARGO_SKIP_ATOM
+
+ return CARGO_OK
+
+
+/obj/docking_port/mobile/supply/proc/sell()
+ SEND_SIGNAL(src, COMSIG_CARGO_BEGIN_SELL)
+ SSeconomy.sold_atoms = list()
+ var/list/qdel_atoms = list()
+ var/list/rescue_atoms = list()
+ for(var/atom/movable/AM in manifest.items_to_sell)
+ var/sellable = manifest.items_to_sell[AM]
+ if(sellable & COMSIG_CARGO_SELL_PRIORITY)
+ SEND_SIGNAL(src, COMSIG_CARGO_DO_PRIORITY_SELL, AM, manifest)
+ SSeconomy.sold_atoms += "[AM.name](priority)"
+ qdel_atoms += AM
+ continue
+ else if(sellable & COMSIG_CARGO_SELL_NORMAL)
+ SEND_SIGNAL(src, COMSIG_CARGO_DO_SELL, AM, manifest)
+ SSeconomy.sold_atoms += "[AM.name](normal)"
+ qdel_atoms += AM
+ continue
+ else if(sellable & COMSIG_CARGO_SELL_WRONG)
+ SEND_SIGNAL(src, COMSIG_CARGO_SEND_ERROR, AM, manifest)
+ SSeconomy.sold_atoms += "[AM.name](error)"
+ qdel_atoms += AM
+ continue
+ else if(sellable & COMSIG_CARGO_MESS)
+ manifest.messy_shuttle = TRUE
+ SSeconomy.sold_atoms += "[AM.name](mess)"
+ qdel_atoms += AM
+ continue
+ else if(!(sellable & COMSIG_CARGO_SELL_SKIP))
+ manifest.sent_trash = TRUE
+
+ rescue_atoms += AM
+
+ for(var/atom/movable/AM in rescue_atoms)
+ if(AM.loc in qdel_atoms)
+ AM.forceMove(get_turf(AM))
+
+ for(var/AM in qdel_atoms)
+ qdel(AM)
+
+ SEND_SIGNAL(src, COMSIG_CARGO_END_SELL, manifest)
+
+ SSblackbox.record_feedback("amount", "cargo shipments", 1)
+
+ if(manifest.loose_cargo)
+ var/datum/economy/line_item/item = new
+ item.account = SSeconomy.cargo_account
+ item.credits = SSeconomy.fine_for_loose_cargo
+ item.reason = "Please remember to secure all items in crates."
+ manifest.line_items += item
+ SSblackbox.record_feedback("nested tally", "cargo fines", 1, list("loose cargo", "amount"))
+ SSblackbox.record_feedback("nested tally", "cargo fines", SSeconomy.fine_for_loose_cargo, list("loose cargo", "credits"))
+ if(manifest.messy_shuttle)
+ var/datum/economy/line_item/item = new
+ item.account = SSeconomy.cargo_account
+ item.credits = SSeconomy.fine_for_messy_shuttle
+ item.reason = "Shuttle cleaning fee."
+ manifest.line_items += item
+ SSblackbox.record_feedback("nested tally", "cargo fines", 1, list("messy shuttle", "amount"))
+ SSblackbox.record_feedback("nested tally", "cargo fines", SSeconomy.fine_for_messy_shuttle, list("messy shuttle", "credits"))
+ if(manifest.sent_trash)
+ var/datum/economy/line_item/item = new
+ item.account = SSeconomy.cargo_account
+ item.credits = SSeconomy.fine_for_selling_trash
+ item.reason = "Don't send us random junk."
+ manifest.line_items += item
+ SSblackbox.record_feedback("nested tally", "cargo fines", 1, list("sent trash", "amount"))
+ SSblackbox.record_feedback("nested tally", "cargo fines", SSeconomy.fine_for_selling_trash, list("sent trash", "credits"))
var/msg = "
---[station_time_timestamp()]---
"
- var/credits_to_deposit = 0
- var/research_credits = 0
- var/service_credits = 0
- var/medical_credits = 0
- for(var/atom/movable/MA in areaInstance)
- if(MA.anchored)
- continue
- if(istype(MA, /mob/dead))
- continue
- if(istype(MA, /obj/structure/closet/crate/mail))
- continue
- SSeconomy.sold_atoms += " [MA.name]"
+ var/list/credit_changes = list()
+ for(var/datum/economy/line_item/item in manifest.line_items)
+ if(!credit_changes[item.account])
+ credit_changes[item.account] = 0
+ credit_changes[item.account] += item.credits
- // Must be in a crate (or a critter crate)!
- if(istype(MA, /obj/structure/closet/crate) || istype(MA, /obj/structure/closet/critter))
- SSeconomy.sold_atoms += ":"
- if(!length(MA.contents))
- SSeconomy.sold_atoms += " (empty)"
- if(istype(MA, /obj/structure/closet/crate))
- var/obj/structure/closet/crate/exported_crate = MA
- total_crate_value += exported_crate.crate_value
- else
- total_crate_value += DEFAULT_CRATE_VALUE
- crate_count++
+ if(item.credits > 0)
+ msg += "[item.account.account_name] +[item.credits]: [item.reason]
"
+ else if(item.credits == 0)
+ msg += "[item.account.account_name] Notice: [item.reason]
"
+ else
+ msg += "[item.account.account_name] [item.credits]: [item.reason]
"
- var/find_slip = TRUE
- for(var/thing in MA)
- // Sell manifests
- SSeconomy.sold_atoms += " [thing:name]"
- if(find_slip && istype(thing,/obj/item/paper/manifest))
- var/obj/item/paper/manifest/slip = thing
- credits_to_deposit += SSeconomy.credits_per_manifest
- msg += "+[SSeconomy.credits_per_manifest]: Package [slip.ordernumber] accorded.
"
+ for(var/datum/money_account/account in credit_changes)
+ if(account.account_type == ACCOUNT_TYPE_DEPARTMENT)
+ SSblackbox.record_feedback("tally", "cargo profits", credit_changes[account], "[account.account_name]")
+ else
+ SSblackbox.record_feedback("tally", "cargo profits", credit_changes[account], "All personal accounts")
- // Sell plasma
- if(istype(thing, /obj/item/stack/sheet/mineral/plasma))
- var/obj/item/stack/sheet/mineral/plasma/P = thing
- plasma_count += P.amount
-
- // Sell syndicate intel
- if(istype(thing, /obj/item/documents/syndicate))
- ++intel_count
-
- // Sell tech levels
- if(istype(thing, /obj/item/disk/tech_disk))
- var/obj/item/disk/tech_disk/disk = thing
- if(!disk.stored)
- continue
- var/datum/tech/tech = disk.stored
-
- var/cost = tech.getCost(SSeconomy.tech_levels[tech.id])
- if(cost)
- SSeconomy.tech_levels[tech.id] = tech.level
- research_credits += cost / 2
- credits_to_deposit += cost / 2
- msg += "+[cost]: [tech.name] - new data.
"
-
- // Sell designs
- if(istype(thing, /obj/item/disk/design_disk))
- var/obj/item/disk/design_disk/disk = thing
- if(!disk.blueprint)
- continue
- var/datum/design/design = disk.blueprint
- if(design.id in SSeconomy.research_designs)
- continue
- credits_to_deposit += SSeconomy.credits_per_design
- SSeconomy.research_designs += design.id
- msg += "+[SSeconomy.credits_per_design]: [design.name] design.
"
-
- // Sell viral sample virology goals, those in vial lockboxes included
- if(istype(thing, /obj/item/reagent_containers) || istype(thing, /obj/item/storage/lockbox/vials))
- var/list/sold_containers = list()
- if(istype(thing, /obj/item/reagent_containers))
- sold_containers += thing
- if(istype(thing, /obj/item/storage/lockbox/vials))
- for(var/obj/item/reagent_containers/C in thing)
- sold_containers += C
- for(var/obj/item/reagent_containers/C in sold_containers)
- if(C.reagents?.reagent_list)
- for(var/datum/virology_goal/G in GLOB.virology_goals)
- if(G.completed)
- continue
- if(G.check_completion(C.reagents.reagent_list))
- medical_credits += SSeconomy.credits_per_virology_goal
- msg += "+[SSeconomy.credits_per_virology_goal]: [G.name] completion.
"
-
- // Sell exotic plants
- if(istype(thing, /obj/item/seeds))
- var/obj/item/seeds/S = thing
- if(S.rarity == 0) // Mundane species
- msg += "+0: We don't need samples of mundane species \"[capitalize(S.species)]\".
"
- else if(SSeconomy.discovered_plants[S.type]) // This species has already been sent to CentComm
- var/potDiff = S.potency - SSeconomy.discovered_plants[S.type] // Compare it to the previous best
- if(potDiff > 0) // This sample is better
- SSeconomy.discovered_plants[S.type] = S.potency
- msg += "+[potDiff]: New sample of \"[capitalize(S.species)]\" is superior. Good work.
"
- service_credits += potDiff / 2
- credits_to_deposit += potDiff / 2
- else // This sample is worthless
- msg += "+0: New sample of \"[capitalize(S.species)]\" is not more potent than existing sample ([SSeconomy.discovered_plants[S.type]] potency).
"
- else // This is a new discovery!
- SSeconomy.discovered_plants[S.type] = S.potency
- msg += "[S.rarity]: New species discovered: \"[capitalize(S.species)]\". Excellent work.
"
- service_credits += S.rarity / 2 // That's right, no bonus for potency. Send a crappy sample first to "show improvement" later
- credits_to_deposit += S.rarity / 2
-
- if(istype(thing, /obj/item/organ/internal/alien))
- var/obj/item/organ/internal/alien/organ = thing
- credits_to_deposit += organ.cargo_profit
- qdel(MA)
- SSeconomy.sold_atoms += "."
-
- if(plasma_count > 0)
- var/credits_from_plasma = plasma_count * SSeconomy.credits_per_plasma
- msg += "+[credits_from_plasma]: Received [plasma_count] unit(s) of exotic material.
"
- credits_to_deposit += credits_from_plasma
-
- if(intel_count > 0)
- var/credits_from_intel = intel_count * SSeconomy.credits_per_intel
- msg += "+[credits_from_intel]: Received [intel_count] article(s) of enemy intelligence.
"
- credits_to_deposit += credits_from_intel
-
- if(crate_count > 0)
- msg += "+[total_crate_value]: Received [crate_count] crate(s).
"
- credits_to_deposit += total_crate_value
+ if(credit_changes[account] > 0)
+ GLOB.station_money_database.credit_account(account, credit_changes[account], "Supply Shuttle Exports Payment", "Central Command Supply Master", supress_log = FALSE)
+ else
+ GLOB.station_money_database.charge_account(account, -credit_changes[account], "Supply Shuttle Fine", "Central Command Supply Master", allow_overdraft = TRUE, supress_log = FALSE)
SSeconomy.centcom_message += "[msg]
"
- if(credits_to_deposit > 0)
- GLOB.station_money_database.credit_account(SSeconomy.cargo_account, credits_to_deposit, "Supply Shuttle Exports Payment", "Central Command Supply Master", supress_log = FALSE)
- if(research_credits)
- GLOB.station_money_database.credit_account(GLOB.station_money_database.get_account_by_department(DEPARTMENT_SCIENCE), research_credits, "Supply Shuttle Exports Payment", "Central Command Supply Master", supress_log = FALSE)
- if(service_credits)
- GLOB.station_money_database.credit_account(GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE), service_credits, "Supply Shuttle Exports Payment", "Central Command Supply Master", supress_log = FALSE)
- if(medical_credits)
- GLOB.station_money_database.credit_account(GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL), medical_credits, "Supply Shuttle Exports Payment", "Central Command Supply Master", supress_log = FALSE)
+ manifest = new
+
+
+// Convenience object that registers itself with the supply shuttle and provides
+// methods for you to override.
+/datum/economy/simple_seller
+
+/datum/economy/simple_seller/proc/register(obj/docking_port/mobile/supply/S)
+ RegisterSignal(S, COMSIG_CARGO_BEGIN_SCAN, PROC_REF(begin_scan))
+ RegisterSignal(S, COMSIG_CARGO_CHECK_SELL, PROC_REF(check_sell))
+ RegisterSignal(S, COMSIG_CARGO_BEGIN_SELL, PROC_REF(begin_sell))
+ RegisterSignal(S, COMSIG_CARGO_DO_PRIORITY_SELL, PROC_REF(sell_priority))
+ RegisterSignal(S, COMSIG_CARGO_DO_SELL, PROC_REF(sell_normal))
+ RegisterSignal(S, COMSIG_CARGO_SEND_ERROR, PROC_REF(sell_wrong))
+ RegisterSignal(S, COMSIG_CARGO_END_SELL, PROC_REF(end_sell))
+
+/datum/economy/simple_seller/proc/begin_scan(obj/docking_port/mobile/supply/S)
+ SIGNAL_HANDLER // COMSIG_CARGO_BEGIN_SCAN
+ return
+
+/datum/economy/simple_seller/proc/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM)
+ SIGNAL_HANDLER // COMSIG_CARGO_CHECK_SELL
+ return NONE
+
+/datum/economy/simple_seller/proc/begin_sell(obj/docking_port/mobile/supply/S)
+ SIGNAL_HANDLER // COMSIG_CARGO_BEGIN_SELL
+ return
+
+/datum/economy/simple_seller/proc/sell_priority(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest)
+ SIGNAL_HANDLER // COMSIG_CARGO_DO_PRIORITY_SELL
+ return check_sell(S, AM) & COMSIG_CARGO_SELL_PRIORITY
+
+/datum/economy/simple_seller/proc/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest)
+ SIGNAL_HANDLER // COMSIG_CARGO_DO_SELL
+ return check_sell(S, AM) & COMSIG_CARGO_SELL_NORMAL
+
+/datum/economy/simple_seller/proc/sell_wrong(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest)
+ SIGNAL_HANDLER // COMSIG_CARGO_SEND_ERROR
+ return check_sell(S, AM) & COMSIG_CARGO_SELL_WRONG
+
+/datum/economy/simple_seller/proc/end_sell(obj/docking_port/mobile/supply/S, datum/economy/cargo_shuttle_manifest/manifest)
+ SIGNAL_HANDLER // COMSIG_CARGO_END_SELL
+ return
+
+
+/datum/economy/simple_seller/crates
+ var/crates = 0
+ var/credits = 0
+
+/datum/economy/simple_seller/crates/begin_sell(obj/docking_port/mobile/supply/S)
+ crates = 0
+ credits = 0
+
+/datum/economy/simple_seller/crates/check_sell(obj/docking_port/mobile/supply/S, AM)
+ if(istype(AM, /obj/structure/closet/crate) || istype(AM, /obj/structure/closet/critter) || istype(AM, /obj/structure/closet/crate/mail))
+ return COMSIG_CARGO_SELL_NORMAL | COMSIG_CARGO_IS_SECURED
+
+/datum/economy/simple_seller/crates/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest)
+ if(!..())
+ return
+
+ crates += 1
+ if(istype(AM, /obj/structure/closet/crate))
+ var/obj/structure/closet/crate/exported_crate = AM
+ credits += exported_crate.crate_value
+ else
+ credits += DEFAULT_CRATE_VALUE
+
+/datum/economy/simple_seller/crates/end_sell(obj/docking_port/mobile/supply/S, datum/economy/cargo_shuttle_manifest/manifest)
+ if(!credits)
+ return
+ var/datum/economy/line_item/item = new
+ item.account = SSeconomy.cargo_account
+ item.credits = credits
+ item.reason = "Returned [crates] crate(s)."
+ manifest.line_items += item
+ SSblackbox.record_feedback("tally", "cargo crates sold", crates, "amount")
+ SSblackbox.record_feedback("tally", "cargo crates sold", item.credits, "credits")
+
+
+/datum/economy/simple_seller/plasma
+ var/plasma = 0
+
+/datum/economy/simple_seller/plasma/begin_sell(obj/docking_port/mobile/supply/S)
+ plasma = 0
+
+/datum/economy/simple_seller/plasma/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM)
+ if(istype(AM, /obj/item/stack/sheet/mineral/plasma))
+ return COMSIG_CARGO_SELL_NORMAL
+
+/datum/economy/simple_seller/plasma/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest)
+ if(!..())
+ return
+
+ var/obj/item/stack/sheet/mineral/plasma/P = AM
+ plasma += P.amount
+
+/datum/economy/simple_seller/plasma/end_sell(obj/docking_port/mobile/supply/S, datum/economy/cargo_shuttle_manifest/manifest)
+ if(!plasma)
+ return
+ var/datum/economy/line_item/item = new
+ item.account = SSeconomy.cargo_account
+ item.credits = plasma * SSeconomy.credits_per_plasma
+ item.reason = "Received [plasma] unit(s) of exotic material."
+ manifest.line_items += item
+ SSblackbox.record_feedback("tally", "cargo plasma sold", plasma, "amount")
+ SSblackbox.record_feedback("tally", "cargo plasma sold", item.credits, "credits")
+
+
+/datum/economy/simple_seller/intel
+ var/intel = 0
+
+/datum/economy/simple_seller/intel/begin_sell(obj/docking_port/mobile/supply/S)
+ intel = 0
+
+/datum/economy/simple_seller/intel/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM)
+ if(istype(AM, /obj/item/documents/syndicate))
+ return COMSIG_CARGO_SELL_NORMAL
+
+/datum/economy/simple_seller/intel/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest)
+ if(!..())
+ return
+
+ intel++
+
+/datum/economy/simple_seller/intel/end_sell(obj/docking_port/mobile/supply/S, datum/economy/cargo_shuttle_manifest/manifest)
+ if(!intel)
+ return
+ var/datum/economy/line_item/item = new
+ item.account = SSeconomy.cargo_account
+ item.credits = intel * SSeconomy.credits_per_intel
+ item.reason = "Received [intel] article(s) of enemy intelligence."
+ manifest.line_items += item
+ SSblackbox.record_feedback("tally", "cargo intel sold", intel, "amount")
+ SSblackbox.record_feedback("tally", "cargo intel sold", item.credits, "credits")
+
+
+/datum/economy/simple_seller/alien_organs
+
+/datum/economy/simple_seller/alien_organs/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM)
+ if(istype(AM, /obj/item/organ/internal/alien))
+ return COMSIG_CARGO_SELL_NORMAL
+
+/datum/economy/simple_seller/alien_organs/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest)
+ if(!..())
+ return
+
+ var/obj/item/organ/internal/alien/organ = AM
+ var/datum/economy/line_item/item = new
+ item.account = SSeconomy.cargo_account
+ item.credits = organ.cargo_profit
+ item.reason = "Received a sample of exotic biological tissue."
+ manifest.line_items += item
+ SSblackbox.record_feedback("tally", "cargo alien organs sold", 1, "amount")
+ SSblackbox.record_feedback("tally", "cargo alien organs sold", item.credits, "credits")
+
+
+/datum/economy/simple_seller/shipping_manifests
+
+/datum/economy/simple_seller/shipping_manifests/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM)
+ if(istype(AM,/obj/item/paper/manifest))
+ return COMSIG_CARGO_SELL_NORMAL
+
+/datum/economy/simple_seller/shipping_manifests/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest)
+ if(!..())
+ return
+
+ var/obj/item/paper/manifest/slip = AM
+
+ var/datum/economy/line_item/item = new
+ item.account = SSeconomy.cargo_account
+ item.credits = SSeconomy.credits_per_manifest
+ item.reason = "Package [slip.ordernumber] accorded."
+ manifest.line_items += item
+ SSblackbox.record_feedback("tally", "cargo manifests sold", 1, "amount")
+ SSblackbox.record_feedback("tally", "cargo manifests sold", item.credits, "credits")
+
+
+/datum/economy/simple_seller/tech_levels
+ var/list/temp_tech_levels
+
+/datum/economy/simple_seller/tech_levels/begin_scan(obj/docking_port/mobile/supply/S)
+ temp_tech_levels = SSeconomy.tech_levels.Copy()
+
+/datum/economy/simple_seller/tech_levels/begin_sell(obj/docking_port/mobile/supply/S)
+ temp_tech_levels = SSeconomy.tech_levels.Copy()
+
+/datum/economy/simple_seller/tech_levels/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM)
+ if(istype(AM, /obj/item/disk/tech_disk))
+ var/obj/item/disk/tech_disk/disk = AM
+ if(!disk.stored)
+ return COMSIG_CARGO_SELL_WRONG
+ var/datum/tech/tech = disk.stored
+
+ var/cost = tech.getCost(temp_tech_levels[tech.id])
+ if(cost)
+ temp_tech_levels[tech.id] = tech.level
+ return COMSIG_CARGO_SELL_NORMAL
+ return COMSIG_CARGO_SELL_WRONG
+
+/datum/economy/simple_seller/tech_levels/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest)
+ if(!..())
+ return
+
+ var/obj/item/disk/tech_disk/disk = AM
+ if(!disk.stored)
+ return
+ var/datum/tech/tech = disk.stored
+
+ var/cost = tech.getCost(SSeconomy.tech_levels[tech.id])
+ if(!cost)
+ return
+
+ SSeconomy.tech_levels[tech.id] = tech.level
+ SSblackbox.record_feedback("tally", "cargo tech disks sold", 1, "amount")
+ SSblackbox.record_feedback("tally", "cargo tech disks sold", cost, "credits")
+
+ var/datum/economy/line_item/cargo_item = new
+ cargo_item.account = SSeconomy.cargo_account
+ cargo_item.credits = cost / 2
+ cargo_item.reason = "[tech.name] - new data."
+ manifest.line_items += cargo_item
+
+ var/datum/economy/line_item/science_item = new
+ science_item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SCIENCE)
+ science_item.credits = cost / 2
+ science_item.reason = "[tech.name] - new data."
+ manifest.line_items += science_item
+
+/datum/economy/simple_seller/tech_levels/sell_wrong(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest)
+ if(!..())
+ return
+
+ var/datum/economy/line_item/item = new
+ item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SCIENCE)
+ item.credits = 0
+
+ var/obj/item/disk/tech_disk/disk = AM
+ if(!disk.stored)
+ item.reason = "Blank tech disk."
+ manifest.line_items += item
+ SSblackbox.record_feedback("tally", "cargo tech disks sold", 1, "blank")
+ return
+
+ var/datum/tech/tech = disk.stored
+ var/cost = tech.getCost(SSeconomy.tech_levels[tech.id])
+ if(!cost)
+ item.reason = "[tech.name] - no new data."
+ manifest.line_items += item
+ SSblackbox.record_feedback("tally", "cargo tech disks sold", 1, "repeat")
+
+
+/datum/economy/simple_seller/designs
+ var/list/temp_designs
+
+/datum/economy/simple_seller/designs/begin_scan(obj/docking_port/mobile/supply/S)
+ temp_designs = SSeconomy.research_designs.Copy()
+
+/datum/economy/simple_seller/designs/begin_sell(obj/docking_port/mobile/supply/S)
+ temp_designs = SSeconomy.research_designs.Copy()
+
+/datum/economy/simple_seller/designs/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM)
+ if(istype(AM, /obj/item/disk/design_disk))
+ var/obj/item/disk/design_disk/disk = AM
+ if(!disk.blueprint)
+ return COMSIG_CARGO_SELL_WRONG
+ var/datum/design/design = disk.blueprint
+ if(design.id in temp_designs)
+ return COMSIG_CARGO_SELL_WRONG
+ temp_designs += design.id
+ return COMSIG_CARGO_SELL_NORMAL
+
+/datum/economy/simple_seller/designs/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest)
+ if(!..())
+ return
+
+ var/obj/item/disk/design_disk/disk = AM
+ if(!disk.blueprint)
+ return
+ var/datum/design/design = disk.blueprint
+ if(design.id in SSeconomy.research_designs)
+ return
+ SSeconomy.research_designs += design.id
+ SSblackbox.record_feedback("tally", "cargo design disks sold", 1, "amount")
+ SSblackbox.record_feedback("tally", "cargo design disks sold", SSeconomy.credits_per_design, "credits")
+
+ var/datum/economy/line_item/cargo_item = new
+ cargo_item.account = SSeconomy.cargo_account
+ cargo_item.credits = SSeconomy.credits_per_design / 2
+ cargo_item.reason = "[design.name] design."
+ manifest.line_items += cargo_item
+
+ var/datum/economy/line_item/science_item = new
+ science_item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SCIENCE)
+ science_item.credits = SSeconomy.credits_per_design / 2
+ science_item.reason = "[design.name] design."
+ manifest.line_items += science_item
+
+/datum/economy/simple_seller/designs/sell_wrong(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest)
+ if(!..())
+ return
+
+ var/datum/economy/line_item/item = new
+ item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SCIENCE)
+ item.credits = 0
+
+ var/obj/item/disk/design_disk/disk = AM
+ if(!disk.blueprint)
+ item.reason = "Blank design disk."
+ manifest.line_items += item
+ SSblackbox.record_feedback("tally", "cargo design disks sold", 1, "blank")
+ return
+ var/datum/design/design = disk.blueprint
+ if(design.id in SSeconomy.research_designs)
+ item.reason = "Duplicate design for [design.name]."
+ manifest.line_items += item
+ SSblackbox.record_feedback("tally", "cargo design disks sold", 1, "repeat")
+ return
+
+
+/datum/economy/simple_seller/seeds
+ var/list/temp_discovered
+
+/datum/economy/simple_seller/seeds/begin_scan(obj/docking_port/mobile/supply/S)
+ temp_discovered = SSeconomy.discovered_plants.Copy()
+
+/datum/economy/simple_seller/seeds/begin_sell(obj/docking_port/mobile/supply/S)
+ temp_discovered = SSeconomy.discovered_plants.Copy()
+
+/datum/economy/simple_seller/seeds/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM)
+ if(istype(AM, /obj/item/seeds))
+ var/obj/item/seeds/seed = AM
+ if(seed.rarity == 0) // Mundane species
+ return COMSIG_CARGO_SELL_WRONG
+ if(!temp_discovered[seed.type] || temp_discovered[seed.type] < seed.potency)
+ temp_discovered[seed.type] = seed.potency
+ return COMSIG_CARGO_SELL_NORMAL
+ return COMSIG_CARGO_SELL_WRONG
+
+/datum/economy/simple_seller/seeds/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest)
+ if(!..())
+ return
+
+ var/msg = ""
+ var/credits = 0
+ var/obj/item/seeds/seed = AM
+ if(seed.rarity == 0) // Mundane species
+ return
+ else if(SSeconomy.discovered_plants[seed.type])
+ // This species has already been sent to CentComm
+ // Compare it to the previous best
+ var/potDiff = seed.potency - SSeconomy.discovered_plants[seed.type]
+ if(potDiff > 0)
+ SSeconomy.discovered_plants[seed.type] = seed.potency
+ credits = potDiff
+ msg = "New sample of \"[capitalize(seed.species)]\" is superior. Good work."
+ SSblackbox.record_feedback("tally", "cargo seeds sold", 1, "improved")
+ else
+ // This is a new discovery!
+ SSeconomy.discovered_plants[seed.type] = seed.potency
+ credits = seed.rarity + seed.potency
+ msg = "New species discovered: \"[capitalize(seed.species)]\". Excellent work."
+ SSblackbox.record_feedback("tally", "cargo seeds sold", 1, "new")
+
+ if(credits == 0)
+ return
+
+ SSblackbox.record_feedback("tally", "cargo seeds sold", 1, "amount")
+ SSblackbox.record_feedback("tally", "cargo seeds sold", credits, "credits")
+
+ var/datum/economy/line_item/cargo_item = new
+ cargo_item.account = SSeconomy.cargo_account
+ cargo_item.credits = credits / 2
+ cargo_item.reason = msg
+ manifest.line_items += cargo_item
+
+ var/datum/economy/line_item/service_item = new
+ service_item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE)
+ service_item.credits = credits / 2
+ service_item.reason = msg
+ manifest.line_items += service_item
+
+/datum/economy/simple_seller/seeds/sell_wrong(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest)
+ if(!..())
+ return
+
+ var/datum/economy/line_item/item = new
+ item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE)
+ item.credits = 0
+
+ var/obj/item/seeds/seed = AM
+ if(seed.rarity == 0)
+ item.reason = "We don't need samples of mundane species \"[capitalize(seed.species)]\"."
+ manifest.line_items += item
+ SSblackbox.record_feedback("tally", "cargo seeds sold", 1, "boring")
+ else if(SSeconomy.discovered_plants[seed.type] && SSeconomy.discovered_plants[seed.type] < seed.potency)
+ item.reason = "New sample of \"[capitalize(seed.species)]\" is not more potent than existing sample ([SSeconomy.discovered_plants[seed.type]] potency)."
+ manifest.line_items += item
+ SSblackbox.record_feedback("tally", "cargo seeds sold", 1, "repeat")
+ // If neither succeeds, this seed was declared wrong by a different
+ // seller, so we should be quiet.
+
+
+/datum/economy/simple_seller/messes
+
+/datum/economy/simple_seller/messes/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM)
+ if(istype(AM, /obj/effect))
+ var/obj/effect/E = AM
+ if(E.is_cleanable())
+ return COMSIG_CARGO_MESS | COMSIG_CARGO_IS_SECURED
+
+
+/datum/economy/simple_seller/containers
+
+/datum/economy/simple_seller/containers/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM)
+ if(istype(AM, /obj/item/storage))
+ return COMSIG_CARGO_SELL_NORMAL
+
+/datum/economy/simple_seller/containers/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest)
+ if(!..())
+ return
+ SSblackbox.record_feedback("amount", "cargo containers sold", 1)
+
+
+/datum/economy/simple_seller/mechs
+
+/datum/economy/simple_seller/mechs/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest)
+ if(!..())
+ return
+ SSblackbox.record_feedback("tally", "cargo basic mechs sold", 1, "amount")
+ SSblackbox.record_feedback("tally", "cargo basic mechs sold", SSeconomy.credits_per_mech, "credits")
+
+ var/datum/economy/line_item/cargo_item = new
+ cargo_item.account = SSeconomy.cargo_account
+ cargo_item.credits = SSeconomy.credits_per_mech / 2
+ cargo_item.reason = "Received a working [AM.name], great job!"
+ manifest.line_items += cargo_item
+
+ var/datum/economy/line_item/science_item = new
+ science_item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SCIENCE)
+ science_item.credits = SSeconomy.credits_per_mech / 2
+ science_item.reason = "Received a working [AM.name], great job!"
+ manifest.line_items += science_item
+
+
+/datum/economy/simple_seller/mechs/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM)
+ if(istype(AM, /obj/mecha/working))
+ return COMSIG_CARGO_SELL_NORMAL | COMSIG_CARGO_IS_SECURED
+
+
+// Skip mech parts to avoid complaining about them.
+/datum/economy/simple_seller/mech_parts
+
+/datum/economy/simple_seller/mech_parts/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM)
+ if(istype(AM.loc, /obj/mecha/working))
+ return COMSIG_CARGO_SELL_SKIP
+
+
+/datum/economy/cargo_shuttle_manifest
+ var/list/items_to_sell = list()
+ var/list/line_items = list()
+ var/loose_cargo = FALSE
+ var/messy_shuttle = FALSE
+ var/sent_trash = FALSE
+
+
+/datum/economy/line_item
+ var/datum/money_account/account
+ var/credits
+ var/reason
+ var/zero_is_good = FALSE
#undef MAX_CRATE_DELIVERY
+
+#undef CARGO_OK
+#undef CARGO_PREVENT_SHUTTLE
+#undef CARGO_SKIP_ATOM
+#undef CARGO_REQUIRE_PRIORITY
+#undef CARGO_HAS_PRIORITY
diff --git a/code/modules/station_goals/secondary/bar/random_bulk_drink.dm b/code/modules/station_goals/secondary/bar/random_bulk_drink.dm
new file mode 100644
index 00000000000..016e9e74b3b
--- /dev/null
+++ b/code/modules/station_goals/secondary/bar/random_bulk_drink.dm
@@ -0,0 +1,9 @@
+/datum/station_goal/secondary/random_bulk_reagent/bar
+ name = "Random Bulk Drink"
+ department = "Bar"
+ abstract = FALSE
+
+/datum/station_goal/secondary/random_bulk_reagent/bar/randomize_params()
+ ..()
+ department_account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE)
+ report_message = "A visiting dignitary loves [initial(reagent_type.name)]. Please send us at least [amount] units of it."
diff --git a/code/modules/station_goals/secondary/bar/variety_drinks.dm b/code/modules/station_goals/secondary/bar/variety_drinks.dm
new file mode 100644
index 00000000000..fe11f919de3
--- /dev/null
+++ b/code/modules/station_goals/secondary/bar/variety_drinks.dm
@@ -0,0 +1,11 @@
+/datum/station_goal/secondary/variety_reagent/bar
+ name = "Variety of Drinks"
+ progress_type = /datum/secondary_goal_progress/variety_reagent
+ department = "Bar"
+ generic_name_plural = "alcoholic drinks"
+ abstract = FALSE
+
+/datum/station_goal/secondary/variety_reagent/bar/randomize_params()
+ ..()
+ department_account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE)
+ report_message = "We're hosting a party, and need a variety of alcoholic drinks. Send us at least [amount_per] units each of [different_types] different ones. Keep them separate, and don't include anything too simple; we have our own booze dispenser."
diff --git a/code/modules/station_goals/secondary/botany/kudzu_goal.dm b/code/modules/station_goals/secondary/botany/kudzu_goal.dm
new file mode 100644
index 00000000000..68387c00754
--- /dev/null
+++ b/code/modules/station_goals/secondary/botany/kudzu_goal.dm
@@ -0,0 +1,105 @@
+/datum/station_goal/secondary/random_kudzu
+ name = "Random Kudzu"
+ department = "Hydroponics"
+ progress_type = /datum/secondary_goal_progress/random_kudzu
+ abstract = FALSE
+ var/list/traits = list()
+ var/amount = 5
+
+/datum/station_goal/secondary/random_kudzu/randomize_params()
+ var/list/valid_traits = subtypesof(/datum/spacevine_mutation)
+
+ traits += pick(valid_traits)
+
+ var/list/trait_names = list()
+ for(var/dumb_trait in traits)
+ var/datum/spacevine_mutation/trait = dumb_trait
+ trait_names += initial(trait.name)
+
+ report_message = "The NSV Watney is studying kudzu, and needs some samples with [english_list(trait_names)], but no other mutations. [amount] packs of seeds should do."
+ admin_desc = "Kudzu with [trait_names.Join(",")]"
+
+/datum/secondary_goal_progress/random_kudzu
+ var/list/traits
+ var/needed
+ var/sent = 0
+ var/sent_this_shipment = 0
+
+/datum/secondary_goal_progress/random_kudzu/configure(datum/station_goal/secondary/random_kudzu/goal)
+ ..()
+ traits = goal.traits
+ needed = goal.amount
+
+/datum/secondary_goal_progress/random_kudzu/Copy()
+ var/datum/secondary_goal_progress/random_kudzu/copy = ..()
+ copy.traits = traits
+ copy.needed = needed
+ copy.sent = sent
+ return copy
+
+/datum/secondary_goal_progress/random_kudzu/start_shipment()
+ sent_this_shipment = 0
+
+/datum/secondary_goal_progress/random_kudzu/proc/check_mutations(obj/item/seeds/kudzu/seed)
+ if(length(seed.mutations) != length(traits))
+ // Wrong number of traits.
+ return FALSE
+ if(length(seed.mutations - traits))
+ // Different traits.
+ return FALSE
+ return TRUE
+
+
+/datum/secondary_goal_progress/random_kudzu/update(atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest = null)
+ // Not in a matching personal crate? Ignore.
+ if(!check_personal_crate(AM))
+ return
+
+ if(!istype(AM, /obj/item/seeds/kudzu))
+ return
+
+ if(!check_mutations(AM))
+ if(!manifest)
+ return COMSIG_CARGO_SELL_WRONG
+ var/datum/economy/line_item/item = new
+ item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE)
+ item.credits = 0
+ item.reason = "[AM] does not have the right traits."
+ manifest.line_items += item
+ return COMSIG_CARGO_SELL_WRONG
+
+ sent++
+ sent_this_shipment++
+ return COMSIG_CARGO_SELL_PRIORITY
+
+/datum/secondary_goal_progress/random_kudzu/check_complete(datum/economy/cargo_shuttle_manifest/manifest)
+ if(sent_this_shipment > 0)
+ var/datum/economy/line_item/update_item = new
+ update_item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE)
+ update_item.credits = 0
+ update_item.zero_is_good = TRUE
+ update_item.reason = "Received [sent_this_shipment] useful samples of kudzu seeds."
+ manifest.line_items += update_item
+
+ if(sent < needed)
+ return
+
+ var/datum/economy/line_item/supply_item = new
+ supply_item.account = SSeconomy.cargo_account
+ supply_item.credits = SSeconomy.credits_per_kudzu_goal / 3
+ supply_item.reason = "Secondary goal complete: [needed] samples of kudzu seeds."
+ manifest.line_items += supply_item
+
+ var/datum/economy/line_item/department_item = new
+ department_item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE)
+ department_item.credits = SSeconomy.credits_per_kudzu_goal / 3
+ department_item.reason = "Secondary goal complete: [needed] samples of kudzu seeds."
+ manifest.line_items += department_item
+
+ var/datum/economy/line_item/personal_item = new
+ personal_item.account = personal_account || department_item.account
+ personal_item.credits = SSeconomy.credits_per_kudzu_goal / 3
+ personal_item.reason = "Secondary goal complete: [needed] samples of kudzu seeds."
+ manifest.line_items += personal_item
+
+ return TRUE
diff --git a/code/modules/station_goals/secondary/kitchen/random_bulk_condiment.dm b/code/modules/station_goals/secondary/kitchen/random_bulk_condiment.dm
new file mode 100644
index 00000000000..a92d3fae94b
--- /dev/null
+++ b/code/modules/station_goals/secondary/kitchen/random_bulk_condiment.dm
@@ -0,0 +1,9 @@
+/datum/station_goal/secondary/random_bulk_reagent/kitchen
+ name = "Random Bulk Condiment"
+ department = "Kitchen"
+ abstract = FALSE
+
+/datum/station_goal/secondary/random_bulk_reagent/kitchen/randomize_params()
+ ..()
+ department_account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE)
+ report_message = "Steve drank all of our [initial(reagent_type.name)]. Please send us another [amount] units of it."
diff --git a/code/modules/station_goals/secondary/kitchen/random_bulk_food.dm b/code/modules/station_goals/secondary/kitchen/random_bulk_food.dm
new file mode 100644
index 00000000000..7580945d711
--- /dev/null
+++ b/code/modules/station_goals/secondary/kitchen/random_bulk_food.dm
@@ -0,0 +1,92 @@
+/datum/station_goal/secondary/random_bulk_food
+ name = "Random Bulk Food"
+ department = "Kitchen"
+ progress_type = /datum/secondary_goal_progress/random_bulk_food
+ abstract = FALSE
+ var/obj/item/food/snacks/food_type
+ var/amount
+ var/reward
+
+/datum/station_goal/secondary/random_bulk_food/randomize_params()
+ var/list/valid_food = list()
+ for(var/S in subtypesof(/obj/item/food/snacks))
+ var/obj/item/food/snacks/candidate = S
+ if(initial(candidate.goal_difficulty) == FOOD_GOAL_SKIP)
+ continue
+ valid_food += candidate
+
+ if(!valid_food)
+ food_type = /obj/item/food/snacks/cheesewedge
+ amount = 50
+ return
+
+ food_type = pick(valid_food)
+ switch(initial(food_type.goal_difficulty))
+ if(FOOD_GOAL_EASY)
+ amount = 35
+ reward = SSeconomy.credits_per_easy_food_goal
+ if(FOOD_GOAL_NORMAL)
+ amount = 15
+ reward = SSeconomy.credits_per_normal_food_goal
+ else // FOOD_GOAL_HARD
+ amount = 5
+ reward = SSeconomy.credits_per_hard_food_goal
+
+ report_message = "Someone spiked the water cooler at CC with Space Drugs again, and we all have a craving for [initial(food_type.name)]. Please send us [amount] servings of it."
+ admin_desc = "[amount] servings of [initial(food_type.name)]"
+
+
+/datum/secondary_goal_progress/random_bulk_food
+ var/obj/item/food/snacks/food_type
+ var/needed
+ var/sent = 0
+ var/sent_this_shipment = 0
+ var/reward
+
+/datum/secondary_goal_progress/random_bulk_food/configure(datum/station_goal/secondary/random_bulk_food/goal)
+ ..()
+ food_type = goal.food_type
+ needed = goal.amount
+ reward = goal.reward
+
+/datum/secondary_goal_progress/random_bulk_food/Copy()
+ var/datum/secondary_goal_progress/random_bulk_food/copy = ..()
+ copy.food_type = food_type
+ copy.needed = needed
+ copy.sent = sent
+ // These ones aren't really needed in the intended use case, they're
+ // just here in case someone uses this method somewhere else.
+ copy.reward = reward
+ return copy
+
+/datum/secondary_goal_progress/random_bulk_food/start_shipment()
+ sent_this_shipment = 0
+
+/datum/secondary_goal_progress/random_bulk_food/update(atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest = null)
+ // Not in a matching personal crate? Ignore.
+ if(!check_personal_crate(AM))
+ return
+
+ if(!istype(AM, food_type))
+ return
+
+ sent++
+ sent_this_shipment++
+ return COMSIG_CARGO_SELL_PRIORITY
+
+/datum/secondary_goal_progress/random_bulk_food/check_complete(datum/economy/cargo_shuttle_manifest/manifest)
+ if(sent_this_shipment > 0)
+ SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "food shipments", initial(food_type.name)))
+ SSblackbox.record_feedback("nested tally", "secondary goals", sent_this_shipment, list(goal_name, "food servings", initial(food_type.name)))
+ var/datum/economy/line_item/update_item = new
+ update_item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE)
+ update_item.credits = 0
+ update_item.zero_is_good = TRUE
+ update_item.reason = "Received [sent_this_shipment] servings of [initial(food_type.name)]."
+ manifest.line_items += update_item
+
+ if(sent < needed)
+ return
+
+ three_way_reward(manifest, "Kitchen", GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE), reward, "Secondary goal complete: [needed] units of [initial(food_type.name)].")
+ return TRUE
diff --git a/code/modules/station_goals/secondary/medical/random_bulk_medicine.dm b/code/modules/station_goals/secondary/medical/random_bulk_medicine.dm
new file mode 100644
index 00000000000..67f4ecba402
--- /dev/null
+++ b/code/modules/station_goals/secondary/medical/random_bulk_medicine.dm
@@ -0,0 +1,9 @@
+/datum/station_goal/secondary/random_bulk_reagent/medchem
+ name = "Random Bulk Medicine"
+ department = "Medbay"
+ abstract = FALSE
+
+/datum/station_goal/secondary/random_bulk_reagent/medchem/randomize_params()
+ ..()
+ department_account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL)
+ report_message = "Doctor, I've got a fever, and the only prescription, is more [initial(reagent_type.name)]. No, really, send us [amount] units of it, please."
diff --git a/code/modules/station_goals/secondary/medical/variety_medicine.dm b/code/modules/station_goals/secondary/medical/variety_medicine.dm
new file mode 100644
index 00000000000..4344004fa35
--- /dev/null
+++ b/code/modules/station_goals/secondary/medical/variety_medicine.dm
@@ -0,0 +1,11 @@
+/datum/station_goal/secondary/variety_reagent/medchem
+ name = "Variety of Medicine"
+ progress_type = /datum/secondary_goal_progress/variety_reagent
+ department = "Medbay"
+ generic_name_plural = "medicines"
+ abstract = FALSE
+
+/datum/station_goal/secondary/variety_reagent/medchem/randomize_params()
+ ..()
+ department_account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL)
+ report_message = "A refrigiration failure on a smaller station has left them critically low on supplies. Please send us at least [amount_per] units each of [different_types] different medicines. Pills, patches, bottles, however you can send them, just keep the medicines from mixing."
diff --git a/code/modules/station_goals/secondary/random_bulk_reagent.dm b/code/modules/station_goals/secondary/random_bulk_reagent.dm
new file mode 100644
index 00000000000..62585e95e4c
--- /dev/null
+++ b/code/modules/station_goals/secondary/random_bulk_reagent.dm
@@ -0,0 +1,102 @@
+/datum/station_goal/secondary/random_bulk_reagent
+ name = "Random Bulk Reagent"
+ progress_type = /datum/secondary_goal_progress/random_bulk_reagent
+ var/datum/reagent/reagent_type
+ var/amount
+ var/department_account
+ var/reward
+
+/datum/station_goal/secondary/random_bulk_reagent/Initialize(requester_account)
+ ..()
+ admin_desc = "[amount] units of [initial(reagent_type.name)]"
+
+/datum/station_goal/secondary/random_bulk_reagent/randomize_params()
+ var/list/valid_reagents = list()
+ for(var/R in subtypesof(/datum/reagent))
+ var/datum/reagent/candidate = R
+ if(initial(candidate.goal_department) != department)
+ continue
+ if(initial(candidate.goal_difficulty) == REAGENT_GOAL_SKIP)
+ continue
+ valid_reagents += candidate
+
+ if(!valid_reagents)
+ reagent_type = /datum/reagent/water
+ amount = 100
+ return
+
+ reagent_type = pick(valid_reagents)
+ switch(initial(reagent_type.goal_difficulty))
+ if(REAGENT_GOAL_EASY)
+ amount = 600
+ reward = SSeconomy.credits_per_easy_reagent_goal
+ if(REAGENT_GOAL_NORMAL)
+ amount = 300
+ reward = SSeconomy.credits_per_normal_reagent_goal
+ else // REAGENT_GOAL_HARD
+ amount = 50
+ reward = SSeconomy.credits_per_hard_reagent_goal
+
+
+/datum/secondary_goal_progress/random_bulk_reagent
+ var/datum/reagent/reagent_type
+ var/needed
+ var/sent = 0
+ var/department
+ var/department_account
+ var/reward
+
+/datum/secondary_goal_progress/random_bulk_reagent/configure(datum/station_goal/secondary/random_bulk_reagent/goal)
+ ..(goal)
+ reagent_type = goal.reagent_type
+ needed = goal.amount
+ department = goal.department
+ department_account = goal.department_account
+ reward = goal.reward
+
+/datum/secondary_goal_progress/random_bulk_reagent/Copy()
+ var/datum/secondary_goal_progress/random_bulk_reagent/copy = ..()
+ copy.reagent_type = reagent_type
+ copy.needed = needed
+ copy.sent = sent
+ // These ones aren't really needed in the intended use case, they're
+ // just here in case someone uses this method somewhere else.
+ copy.department = department
+ copy.department_account = department_account
+ copy.reward = reward
+ return copy
+
+/datum/secondary_goal_progress/random_bulk_reagent/update(atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest = null)
+ // Not a reagent container? Ignore.
+ if(!istype(AM, /obj/item/reagent_containers))
+ return
+
+ // Not in a matching personal crate? Ignore.
+ if(!check_personal_crate(AM))
+ return
+
+ var/obj/item/reagent_containers/container = AM
+ var/amount = container.reagents?.get_reagent_amount(initial(reagent_type.id))
+ if(!amount)
+ return
+ sent += amount
+ if(!manifest)
+ return COMSIG_CARGO_SELL_PRIORITY
+
+ SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "reagents", initial(reagent_type.id), "containers"))
+ SSblackbox.record_feedback("nested tally", "secondary goals", amount, list(goal_name, "reagents", initial(reagent_type.id), "units"))
+ var/datum/economy/line_item/item = new
+ item.account = department_account
+ item.credits = 0
+ item.reason = "Received [amount] units of [initial(reagent_type.name)]."
+ item.zero_is_good = TRUE
+ manifest.line_items += item
+
+ return COMSIG_CARGO_SELL_PRIORITY
+
+/datum/secondary_goal_progress/random_bulk_reagent/check_complete(datum/economy/cargo_shuttle_manifest/manifest)
+ if(sent < needed - REAGENT_GOAL_FORGIVENESS)
+ return
+
+ three_way_reward(manifest, department, department_account, reward, "Secondary goal complete: [needed] units of [initial(reagent_type.name)].")
+ return TRUE
diff --git a/code/modules/station_goals/secondary/science/random_bulk_chemical.dm b/code/modules/station_goals/secondary/science/random_bulk_chemical.dm
new file mode 100644
index 00000000000..ce20898ed20
--- /dev/null
+++ b/code/modules/station_goals/secondary/science/random_bulk_chemical.dm
@@ -0,0 +1,9 @@
+/datum/station_goal/secondary/random_bulk_reagent/scichem
+ name = "Random Bulk Chemical"
+ department = "Science"
+ abstract = FALSE
+
+/datum/station_goal/secondary/random_bulk_reagent/scichem/randomize_params()
+ ..()
+ department_account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SCIENCE)
+ report_message = "We're running an experiment with [initial(reagent_type.name)] and need more. Please send us [amount] units of it."
diff --git a/code/modules/station_goals/secondary/science/random_ripley.dm b/code/modules/station_goals/secondary/science/random_ripley.dm
new file mode 100644
index 00000000000..8398a523fbf
--- /dev/null
+++ b/code/modules/station_goals/secondary/science/random_ripley.dm
@@ -0,0 +1,105 @@
+/datum/station_goal/secondary/random_ripley
+ name = "Random Ripley"
+ department = "Robotics"
+ progress_type = /datum/secondary_goal_progress/random_ripley
+ should_send_crate = FALSE
+ abstract = FALSE
+ var/list/modules = list()
+ var/static/list/general_modules = list(
+ /obj/item/mecha_parts/mecha_equipment/repair_droid,
+ /obj/item/mecha_parts/mecha_equipment/generator/nuclear,
+ /obj/item/mecha_parts/mecha_equipment/generator,
+ /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay,
+ /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster,
+ /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster,
+ /obj/item/mecha_parts/mecha_equipment/thrusters,
+ /obj/item/mecha_parts/mecha_equipment/gravcatapult
+ )
+ var/static/list/engineering_modules = list(
+ /obj/item/mecha_parts/mecha_equipment/cable_layer,
+ /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp,
+ /obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma,
+ /obj/item/mecha_parts/mecha_equipment/drill,
+ /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill,
+ /obj/item/mecha_parts/mecha_equipment/rcd,
+ /obj/item/mecha_parts/mecha_equipment/mining_scanner,
+ /obj/item/mecha_parts/mecha_equipment/extinguisher
+ )
+
+/datum/station_goal/secondary/random_ripley/randomize_params()
+ var/obj/item/mecha_parts/general_module = pick(general_modules)
+ modules += general_module
+ var/obj/item/mecha_parts/engineering_module = pick(engineering_modules)
+ modules += engineering_module
+
+ report_message = list("One of our rapid-response teams lost a mech, and needs a replacement Ripley with \a [initial(general_module.name)] and \a [initial(engineering_module.name)].",
+ "You must label the mech properly. Use your ID card on a hand labeller to configure it.")
+ admin_desc = "Ripley with [initial(general_module.name)] and [initial(engineering_module.name)]"
+
+
+/datum/secondary_goal_progress/random_ripley
+ var/obj/item/food/snacks/food_type
+ var/list/modules
+ var/sent = FALSE
+
+/datum/secondary_goal_progress/random_ripley/configure(datum/station_goal/secondary/random_ripley/goal)
+ ..()
+ modules = goal.modules
+
+/datum/secondary_goal_progress/random_ripley/Copy()
+ var/datum/secondary_goal_progress/random_ripley/copy = ..()
+ copy.modules = modules
+ copy.sent = sent
+ // These ones aren't really needed in the intended use case, they're
+ // just here in case someone uses this method somewhere else.
+ copy.personal_account = personal_account
+ return copy
+
+/datum/secondary_goal_progress/random_ripley/update(atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest = null)
+ var/datum/component/label/goal/label = AM.GetComponent(/datum/component/label/goal)
+ // Not labelled for this goal? Ignore.
+ if(!istype(label) || label.label_name != goal_requester)
+ return
+ if(!istype(AM, /obj/mecha/working/ripley))
+ return
+ if(!manifest)
+ return COMSIG_CARGO_SELL_PRIORITY | COMSIG_CARGO_IS_SECURED
+ if(sent)
+ SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "extra mech"))
+ SSblackbox.record_feedback("nested tally", "secondary goals", SSeconomy.credits_per_mech, list(goal_name, "extra mech credits"))
+ var/datum/economy/line_item/extra_item = new
+ extra_item.account = SSeconomy.cargo_account
+ extra_item.credits = SSeconomy.credits_per_mech
+ extra_item.reason = "We already got the mech we needed, but we'll take this one at the usual price."
+ manifest.line_items += extra_item
+ send_requests_console_message(extra_item.reason, "Central Command", "Robotics", "Stamped with the Central Command rubber stamp.", null, RQ_NORMALPRIORITY)
+ return COMSIG_CARGO_SELL_PRIORITY | COMSIG_CARGO_IS_SECURED
+
+ var/remaining_needs = modules.Copy()
+ for(var/component in AM)
+ for(var/need in remaining_needs)
+ if(istype(component, need))
+ remaining_needs -= need
+ break
+ // We sell or skip all of these, so we can delete it.
+ qdel(component)
+ if(length(remaining_needs))
+ if(manifest)
+ SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "incorrect mech"))
+ SSblackbox.record_feedback("nested tally", "secondary goals", SSeconomy.credits_per_mech, list(goal_name, "incorrect mech credits"))
+ var/datum/economy/line_item/wrong_item = new
+ wrong_item.account = SSeconomy.cargo_account
+ wrong_item.credits = SSeconomy.credits_per_mech
+ wrong_item.reason = "That's not the equipment we needed, but it's still a mech"
+ manifest.line_items += wrong_item
+ send_requests_console_message(wrong_item.reason + ", so we sent the usual amount to your supply account.", "Central Command", "Robotics", "Stamped with the Central Command rubber stamp.", null, RQ_NORMALPRIORITY)
+ return COMSIG_CARGO_SELL_PRIORITY | COMSIG_CARGO_IS_SECURED
+
+ sent = TRUE
+ return COMSIG_CARGO_SELL_PRIORITY | COMSIG_CARGO_IS_SECURED
+
+/datum/secondary_goal_progress/random_ripley/check_complete(datum/economy/cargo_shuttle_manifest/manifest)
+ if(sent)
+ SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "correct mech"))
+ three_way_reward(manifest, "Robotics", GLOB.station_money_database.get_account_by_department(DEPARTMENT_SCIENCE), SSeconomy.credits_per_ripley_goal, "Secondary goal complete: Customized Ripley.")
+ return sent
diff --git a/code/modules/station_goals/secondary/science/variety_chemicals.dm b/code/modules/station_goals/secondary/science/variety_chemicals.dm
new file mode 100644
index 00000000000..68080f0641e
--- /dev/null
+++ b/code/modules/station_goals/secondary/science/variety_chemicals.dm
@@ -0,0 +1,12 @@
+/datum/station_goal/secondary/variety_reagent/scichem
+ name = "Variety of Chemicals"
+ progress_type = /datum/secondary_goal_progress/variety_reagent
+ different_types = 5
+ department = "Science"
+ generic_name_plural = "chemicals"
+ abstract = FALSE
+
+/datum/station_goal/secondary/variety_reagent/scichem/randomize_params()
+ ..()
+ department_account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SCIENCE)
+ report_message = "We're training a drug moose, and need some samples of drugs. Send us at least [amount_per] units each of [different_types] different ones. --Not Steve"
diff --git a/code/modules/station_goals/secondary/secondary_goal.dm b/code/modules/station_goals/secondary/secondary_goal.dm
new file mode 100644
index 00000000000..ae5df8807c9
--- /dev/null
+++ b/code/modules/station_goals/secondary/secondary_goal.dm
@@ -0,0 +1,104 @@
+/datum/station_goal/secondary
+ name = "Generic Secondary Goal"
+ required_crew = 1
+ /// Admin-only shor description of the goal.
+ var/admin_desc = "No description"
+ /// Assigned department. Should match the values used for requests consoles.
+ var/department = "Unknown"
+ /// The person who requested the goal.
+ var/requester_name
+ /// The money account of the person who requested the goal.
+ var/personal_account
+ /// Should we (still) send a personal crate on the next shipment?
+ var/should_send_crate = TRUE
+ /// Type path of the progress tracker used.
+ var/progress_type = /datum/secondary_goal_progress
+ /// Progress type of this goal.
+ var/datum/secondary_goal_progress/progress
+ /// Tracker that manages the goal progress, permanent and temporary.
+ var/datum/secondary_goal_tracker/tracker
+ /// Abstract goals can't be used directly.
+ var/abstract = TRUE
+
+/datum/station_goal/secondary/proc/Initialize(requester_name_in, requester_account)
+ SHOULD_CALL_PARENT(TRUE)
+ requester_name = requester_name_in
+ personal_account = requester_account
+ randomize_params()
+ progress = new progress_type
+ progress.configure(src)
+ tracker = new(src, progress)
+ tracker.register(SSshuttle.supply)
+
+// Override this to randomly configure the goal before generating a progress
+// tracker.
+/datum/station_goal/secondary/proc/randomize_params()
+ return
+
+/datum/station_goal/secondary/send_report(requester, intro_override = FALSE)
+ var/list/message_parts = list()
+ if(intro_override)
+ message_parts += intro_override
+ else
+ message_parts += "Received secondary goal request from [requester] for [department]."
+ message_parts += "Querying master task list...."
+ message_parts += "Suitable task found. Task details:"
+ message_parts += ""
+ message_parts += report_message
+ if(should_send_crate)
+ message_parts += "You must submit this in a locked personal crate. One will be sent to your Cargo department. More can be ordered if needed."
+ send_requests_console_message(message_parts, "Central Command", department, "Stamped with the Central Command rubber stamp.", "Verified by A.L.I.C.E (CentCom AI)", RQ_HIGHPRIORITY)
+ if(department != "Captain's Desk")
+ send_requests_console_message(message_parts, "Central Command", "Captain's Desk", "Stamped with the Central Command rubber stamp.", "Verified by A.L.I.C.E (CentCom AI)", RQ_NORMALPRIORITY)
+ if(department != "Bridge")
+ send_requests_console_message(message_parts, "Central Command", "Bridge", "Stamped with the Central Command rubber stamp.", "Verified by A.L.I.C.E (CentCom AI)", RQ_NORMALPRIORITY)
+
+/proc/generate_secondary_goal(department, requester = null, mob/user = null)
+ var/list/possible = list()
+ var/list/departments = list()
+ for(var/T in subtypesof(/datum/station_goal/secondary))
+ var/datum/station_goal/secondary/G = T
+ if(!initial(G.abstract) && !departments[initial(G.department)])
+ departments[initial(G.department)] = TRUE
+ if(initial(G.department) != department || initial(G.abstract))
+ continue
+ possible += G
+
+ if(!length(possible))
+ if(user)
+ to_chat(user, "No goals available for [department]. Goals are currently available for [english_list(departments)].")
+ return
+
+ var/datum/station_goal/secondary/picked = pick(possible)
+ var/datum/station_goal/secondary/built = new picked
+
+ var/requester_name = null
+ var/requester_account = null
+ var/obj/item/card/id/ID = requester
+ if(ID)
+ requester_name = ID.registered_name
+ requester_account = GLOB.station_money_database.find_user_account(ID.associated_account_number)
+ built.Initialize(requester_name, requester_account)
+ if(!ID)
+ built.send_report("CentCom")
+ else
+ built.send_report(ID.assignment ? "[ID.assignment] [ID.registered_name]" : ID.registered_name)
+ SSticker.mode.secondary_goals += built
+
+/datum/station_goal/secondary/Topic(href, href_list)
+ if(!check_rights(R_EVENT))
+ return
+
+ if(href_list["announce"])
+ send_report("CentCom", "A task for [department] has been issued by Central Command:")
+ else if(href_list["remove"])
+ SSticker.mode.secondary_goals -= src
+ qdel(src)
+ usr.client.modify_goals()
+ else if(href_list["mark_complete"])
+ completed = 1
+ usr.client.modify_goals()
+ else if(href_list["reset_progress"])
+ completed = 0
+ tracker.reset()
+ usr.client.modify_goals()
diff --git a/code/modules/station_goals/secondary/secondary_goal_tracker.dm b/code/modules/station_goals/secondary/secondary_goal_tracker.dm
new file mode 100644
index 00000000000..db31ce322bf
--- /dev/null
+++ b/code/modules/station_goals/secondary/secondary_goal_tracker.dm
@@ -0,0 +1,125 @@
+/datum/secondary_goal_tracker
+ var/datum/secondary_goal_progress/real_progress
+ var/datum/secondary_goal_progress/temporary_progress
+ var/datum/station_goal/secondary/goal
+
+/datum/secondary_goal_tracker/New(datum/station_goal/secondary/goal_in, datum/secondary_goal_progress/progress)
+ goal = goal_in
+ real_progress = progress
+ temporary_progress = progress.Copy()
+
+/datum/secondary_goal_tracker/proc/reset()
+ real_progress = new real_progress.type(goal)
+ temporary_progress = real_progress.Copy()
+
+/datum/secondary_goal_tracker/proc/register(shuttle)
+ RegisterSignal(shuttle, COMSIG_CARGO_BEGIN_SCAN, PROC_REF(reset_tempporary_progress))
+ RegisterSignal(shuttle, COMSIG_CARGO_BEGIN_SELL, PROC_REF(reset_tempporary_progress))
+ RegisterSignal(shuttle, COMSIG_CARGO_CHECK_SELL, PROC_REF(check_for_progress))
+ RegisterSignal(shuttle, COMSIG_CARGO_DO_PRIORITY_SELL, PROC_REF(update_progress))
+ RegisterSignal(shuttle, COMSIG_CARGO_SEND_ERROR, PROC_REF(update_progress))
+ RegisterSignal(shuttle, COMSIG_CARGO_END_SELL, PROC_REF(check_for_completion))
+
+/datum/secondary_goal_tracker/proc/unregister(shuttle)
+ UnregisterSignal(shuttle, COMSIG_CARGO_BEGIN_SCAN)
+ UnregisterSignal(shuttle, COMSIG_CARGO_BEGIN_SELL)
+ UnregisterSignal(shuttle, COMSIG_CARGO_CHECK_SELL)
+ UnregisterSignal(shuttle, COMSIG_CARGO_DO_PRIORITY_SELL)
+ UnregisterSignal(shuttle, COMSIG_CARGO_SEND_ERROR)
+ UnregisterSignal(shuttle, COMSIG_CARGO_END_SELL)
+
+// Resets the temporary porgress to match the real progress.
+/datum/secondary_goal_tracker/proc/reset_tempporary_progress(obj/docking_port/mobile/supply/shuttle)
+ SIGNAL_HANDLER // COMSIG_CARGO_BEGIN_SCAN, COMSIG_CARGO_BEGIN_SELL
+ temporary_progress = real_progress.Copy()
+ real_progress.start_shipment()
+
+// Checks for temporary goal progress when selling a cargo item.
+/datum/secondary_goal_tracker/proc/check_for_progress(obj/docking_port/mobile/supply/shuttle, atom/movable/thing)
+ SIGNAL_HANDLER // COMSIG_CARGO_CHECK_SELL
+ return temporary_progress.update(thing)
+
+// Update real goal progress when selling a cargo item.
+/datum/secondary_goal_tracker/proc/update_progress(obj/docking_port/mobile/supply/shuttle, atom/movable/thing, datum/economy/cargo_shuttle_manifest/manifest)
+ SIGNAL_HANDLER // COMSIG_CARGO_DO_PRIORITY_SELL, COMSIG_CARGO_DO_SELL, COMSIG_CARGO_SEND_ERROR
+ . = real_progress.update(thing, manifest)
+ if(. & COMSIG_CARGO_SELL_PRIORITY)
+ SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal.name, "items sold"))
+
+/datum/secondary_goal_tracker/proc/check_for_completion(obj/docking_port/mobile/supply/shuttle, datum/economy/cargo_shuttle_manifest/manifest)
+ SIGNAL_HANDLER // COMSIG_CARGO_END_SELL
+ if(real_progress.check_complete(manifest))
+ goal.completed = TRUE
+ SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal.name, "times completed"))
+ unregister(SSshuttle.supply)
+
+
+/datum/secondary_goal_progress
+ var/personal_account
+ var/goal_requester
+ var/goal_name
+
+/datum/secondary_goal_progress/proc/configure(datum/station_goal/secondary/goal)
+ SHOULD_CALL_PARENT(TRUE)
+ goal_requester = goal.requester_name
+ personal_account = goal.personal_account
+ goal_name = goal.name
+
+/datum/secondary_goal_progress/proc/Copy()
+ SHOULD_CALL_PARENT(TRUE)
+ var/datum/secondary_goal_progress/copy = new type
+ copy.personal_account = personal_account
+ copy.goal_requester = goal_requester
+ copy.goal_name = goal_name
+ return copy
+
+// Override for custom shipment start behavior
+// (e.g. ampount-per-shipment tracking)
+// Only called on the real progress tracker.
+/datum/secondary_goal_progress/proc/start_shipment()
+ return
+
+// Check the item to see if it belongs to this goal.
+// Update the manifest accodingly, if provided.
+// Return values from code/__DEFINES/supply_defines.dm.
+// Use COMSIG_CARGO_SELL_PRIORITY, not COMSIG_CARGO_SELL_NORMAL.
+/datum/secondary_goal_progress/proc/update(atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest = null)
+ return
+
+// Check to see if this goal has been completed.
+// Update the manifest accordingly.
+// Returns whether the goal was completed.
+/datum/secondary_goal_progress/proc/check_complete(datum/economy/cargo_shuttle_manifest/manifest)
+ return FALSE
+
+/datum/secondary_goal_progress/proc/check_personal_crate(atom/movable/AM)
+ var/obj/structure/closet/crate/secure/personal/PC = get_atom_on_turf(AM, /obj/structure/closet/crate/secure/personal)
+ if(!istype(PC))
+ return FALSE
+ if(goal_requester && PC.registered_name != goal_requester)
+ return FALSE
+ return TRUE
+
+/datum/secondary_goal_progress/proc/three_way_reward(datum/economy/cargo_shuttle_manifest/manifest, department, department_account, reward, message)
+ SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "payments made"))
+ SSblackbox.record_feedback("nested tally", "secondary goals", reward, list(goal_name, "credits"))
+
+ var/datum/economy/line_item/supply_item = new
+ supply_item.account = SSeconomy.cargo_account
+ supply_item.credits = reward / 3
+ supply_item.reason = message
+ manifest.line_items += supply_item
+
+ var/datum/economy/line_item/department_item = new
+ department_item.account = department_account
+ department_item.credits = reward / 3
+ department_item.reason = message
+ manifest.line_items += department_item
+
+ var/datum/economy/line_item/personal_item = new
+ personal_item.account = personal_account || department_account
+ personal_item.credits = reward / 3
+ personal_item.reason = message
+ manifest.line_items += personal_item
+
+ send_requests_console_message(message, "Central Command", department, "Stamped with the Central Command rubber stamp.", null, RQ_NORMALPRIORITY)
diff --git a/code/modules/station_goals/secondary/variety_reagent.dm b/code/modules/station_goals/secondary/variety_reagent.dm
new file mode 100644
index 00000000000..ffccf8c8912
--- /dev/null
+++ b/code/modules/station_goals/secondary/variety_reagent.dm
@@ -0,0 +1,138 @@
+/datum/station_goal/secondary/variety_reagent
+ name = "Variety of Reagent"
+ progress_type = /datum/secondary_goal_progress/variety_reagent
+ var/different_types = 10
+ var/amount_per = 50
+ var/department_account
+ var/generic_name_plural = "reagents"
+ var/reward
+
+/datum/station_goal/secondary/variety_reagent/Initialize(requester_account)
+ reward = SSeconomy.credits_per_variety_reagent_goal
+ ..()
+ admin_desc = "[amount_per] units of [different_types] [generic_name_plural]"
+
+
+/datum/secondary_goal_progress/variety_reagent
+ var/list/reagents_sent = list()
+ var/department
+ var/needed
+ var/amount_per
+ var/department_account
+ var/reward
+ var/generic_name_plural
+
+/datum/secondary_goal_progress/variety_reagent/configure(datum/station_goal/secondary/variety_reagent/goal)
+ ..()
+ department = goal.department
+ needed = goal.different_types
+ amount_per = goal.amount_per
+ department_account = goal.department_account
+ reward = goal.reward
+ generic_name_plural = goal.generic_name_plural
+
+/datum/secondary_goal_progress/variety_reagent/Copy()
+ var/datum/secondary_goal_progress/variety_reagent/copy = ..()
+ copy.reagents_sent = reagents_sent.Copy()
+ copy.department = department
+ copy.needed = needed
+ copy.amount_per = amount_per
+ // These ones aren't really needed in the intended use case, they're
+ // just here in case someone uses this method somewhere else.
+ copy.department_account = department_account
+ copy.reward = reward
+ copy.generic_name_plural = generic_name_plural
+ return copy
+
+/datum/secondary_goal_progress/variety_reagent/update(atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest = null)
+ // Not a reagent container? Ignore.
+ if(!istype(AM, /obj/item/reagent_containers))
+ return
+
+ // Not in a matching personal crate? Ignore.
+ if(!check_personal_crate(AM))
+ return
+
+ var/obj/item/reagent_containers/container = AM
+ // No reagents? Ignore.
+ if(!container.reagents.reagent_list)
+ return
+
+ var/datum/reagent/reagent = container.reagents?.get_master_reagent()
+
+ // Make sure it's for our department.
+ if(!reagent || reagent.goal_department != department)
+ return
+
+ // Isolated reagents only, please.
+ if(length(container.reagents.reagent_list) != 1)
+ if(!manifest)
+ return COMSIG_CARGO_SELL_WRONG
+ SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "mixed reagents"))
+ var/datum/economy/line_item/item = new
+ item.account = department_account
+ item.credits = 0
+ item.reason = "That [reagent.name] seems to be mixed with something else. Send it by itself, please."
+ manifest.line_items += item
+ send_requests_console_message(item.reason, "Central Command", department, "Stamped with the Central Command rubber stamp.", null, RQ_NORMALPRIORITY)
+ return COMSIG_CARGO_SELL_WRONG
+
+ // No easy reagents allowed.
+ if(reagent.goal_difficulty == REAGENT_GOAL_SKIP)
+ if(!manifest)
+ return COMSIG_CARGO_SELL_WRONG
+ SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "boring reagents"))
+ var/datum/economy/line_item/item = new
+ item.account = department_account
+ item.credits = 0
+ item.reason = "We don't need [reagent.name]. Send something better."
+ manifest.line_items += item
+ send_requests_console_message(item.reason, "Central Command", department, "Stamped with the Central Command rubber stamp.", null, RQ_NORMALPRIORITY)
+ return COMSIG_CARGO_SELL_WRONG
+
+ // Make sure there's enough.
+ if(reagent.volume < amount_per - REAGENT_GOAL_FORGIVENESS)
+ if(!manifest)
+ return COMSIG_CARGO_SELL_WRONG
+ SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "insufficient quantity of reagents"))
+ var/datum/economy/line_item/item = new
+ item.account = department_account
+ item.credits = 0
+ item.reason = "That batch of [reagent.name] was too small; send at least [amount_per] units."
+ manifest.line_items += item
+ send_requests_console_message(item.reason, "Central Command", department, "Stamped with the Central Command rubber stamp.", null, RQ_NORMALPRIORITY)
+ return COMSIG_CARGO_SELL_WRONG
+
+ if(reagents_sent[reagent.id])
+ if(!manifest)
+ return COMSIG_CARGO_SELL_WRONG
+ SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "repeat reagents"))
+ var/datum/economy/line_item/item = new
+ item.account = department_account
+ item.credits = 0
+ item.reason = "You already sent us [reagent.name]."
+ manifest.line_items += item
+ send_requests_console_message(item.reason, "Central Command", department, "Stamped with the Central Command rubber stamp.", null, RQ_NORMALPRIORITY)
+ return COMSIG_CARGO_SELL_WRONG
+
+ reagents_sent[reagent.id] = TRUE
+
+ if(!manifest)
+ return COMSIG_CARGO_SELL_PRIORITY
+ SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "valid reagents"))
+ SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "reagents", reagent.id))
+ var/datum/economy/line_item/item = new
+ item.account = department_account
+ item.credits = 0
+ item.reason = "Received [initial(reagent.name)]."
+ item.zero_is_good = TRUE
+ manifest.line_items += item
+ send_requests_console_message(item.reason, "Central Command", department, "Stamped with the Central Command rubber stamp.", null, RQ_NORMALPRIORITY)
+ return COMSIG_CARGO_SELL_PRIORITY
+
+/datum/secondary_goal_progress/variety_reagent/check_complete(datum/economy/cargo_shuttle_manifest/manifest)
+ if(length(reagents_sent) < needed)
+ return
+
+ three_way_reward(manifest, department, department_account, reward, "Secondary goal complete: [needed] different [generic_name_plural].")
+ return TRUE
diff --git a/code/modules/station_goals/station_goal.dm b/code/modules/station_goals/station_goal.dm
index 683c1bdc35d..5cf4c0b67d6 100644
--- a/code/modules/station_goals/station_goal.dm
+++ b/code/modules/station_goals/station_goal.dm
@@ -46,4 +46,6 @@
on_report()
send_report()
else if(href_list["remove"])
+ SSticker.mode.station_goals -= src
qdel(src)
+ usr.client.modify_goals()
diff --git a/code/modules/station_goals/task_backlog.dm b/code/modules/station_goals/task_backlog.dm
new file mode 100644
index 00000000000..3850adbe84f
--- /dev/null
+++ b/code/modules/station_goals/task_backlog.dm
@@ -0,0 +1,23 @@
+/datum/station_goal/clear_task_backlog
+ name = "Clear Task Backlog"
+ var/goal = 10
+
+/datum/station_goal/clear_task_backlog/get_report()
+ return {"Clear Task Backlog
+ The last few weeks have been extremely profitable for Nanotrasen, but
+ we've got so many things to do that we're getting a bit overwhelmed.
+
+ We need you to pick up the slack. Use the Request Consoles on your
+ station to get Secondary Goals, and complete at least [goal] of them.
+
+
+ -Nanotrasen Accounting"}
+
+/datum/station_goal/clear_task_backlog/check_completion()
+ if(..())
+ return TRUE
+ var/count = 0
+ for(var/datum/station_goal/secondary/S in SSticker.mode.secondary_goals)
+ if(S.completed)
+ count++
+ return count >= goal
diff --git a/code/modules/supply/supply_console.dm b/code/modules/supply/supply_console.dm
index f24d0693b14..a70e43223b1 100644
--- a/code/modules/supply/supply_console.dm
+++ b/code/modules/supply/supply_console.dm
@@ -441,8 +441,8 @@
/obj/machinery/computer/supplycomp/proc/move_shuttle(mob/user)
if(is_public) // Public consoles cant move the shuttle. Dont allow exploiters.
return
- if(SSshuttle.supply.canMove())
- to_chat(user, "For safety reasons the automated supply shuttle cannot transport live organisms, undelivered mail, classified nuclear weaponry or homing beacons.")
+ if(!SSshuttle.supply.canMove())
+ to_chat(user, "For safety reasons, the automated supply shuttle cannot transport [SSshuttle.supply.blocking_item].")
else if(SSshuttle.supply.getDockedId() == "supply_home")
SSshuttle.toggleShuttle("supply", "supply_home", "supply_away", 1)
investigate_log("| [key_name(user)] has sent the supply shuttle away. Shuttle contents: [SSeconomy.sold_atoms]", "cargo")
diff --git a/code/modules/supply/supply_packs/pack_miscellaneous.dm b/code/modules/supply/supply_packs/pack_miscellaneous.dm
index 80dfa802b46..66b1ef894d6 100644
--- a/code/modules/supply/supply_packs/pack_miscellaneous.dm
+++ b/code/modules/supply/supply_packs/pack_miscellaneous.dm
@@ -82,6 +82,18 @@
contains = list(/obj/item/stack/tile/carpet/twenty)
containername = "carpet crate"
+/datum/supply_packs/misc/personal_crates
+ name = "Personal Crates Pack"
+ cost = 100
+ containertype = /obj/structure/largecrate
+ contains = list(/obj/structure/closet/crate/secure/personal,
+ /obj/structure/closet/crate/secure/personal,
+ /obj/structure/closet/crate/secure/personal,
+ /obj/structure/closet/crate/secure/personal,
+ /obj/structure/closet/crate/secure/personal,
+ /obj/structure/closet/crate/secure/personal)
+ containername = "personal crates pack"
+
///////////// Paper Work
diff --git a/code/modules/virology/virology_goals.dm b/code/modules/virology/virology_goals.dm
index 4306ec9093f..805e1c23296 100644
--- a/code/modules/virology/virology_goals.dm
+++ b/code/modules/virology/virology_goals.dm
@@ -1,4 +1,4 @@
-GLOBAL_LIST_INIT(virology_goals, list(new /datum/virology_goal/property_symptom, new /datum/virology_goal/virus, new /datum/virology_goal/virus/stealth))
+GLOBAL_LIST_EMPTY(virology_goals)
GLOBAL_LIST_EMPTY(archived_virology_goals)
#define MAX_LOOPS 30
@@ -10,10 +10,62 @@ GLOBAL_LIST_EMPTY(archived_virology_goals)
var/delivery_goal = 15
var/completed = FALSE
+/datum/virology_goal/proc/register()
+ RegisterSignal(SSshuttle.supply, COMSIG_CARGO_CHECK_SELL, PROC_REF(check_for_virus))
+ RegisterSignal(SSshuttle.supply, COMSIG_CARGO_DO_PRIORITY_SELL, PROC_REF(sell_virus))
+ RegisterSignal(SSshuttle.supply, COMSIG_CARGO_SEND_ERROR, PROC_REF(complain_about_virus))
+
+/datum/virology_goal/proc/unregister()
+ UnregisterSignal(SSshuttle.supply, COMSIG_CARGO_CHECK_SELL)
+ UnregisterSignal(SSshuttle.supply, COMSIG_CARGO_DO_PRIORITY_SELL)
+ UnregisterSignal(SSshuttle.supply, COMSIG_CARGO_SEND_ERROR)
+
+/datum/virology_goal/proc/check_for_virus(shuttle, atom/movable/thing)
+ SIGNAL_HANDLER // COMSIG_CARGO_CHECK_SELL
+ if(istype(thing, /obj/item/reagent_containers))
+ var/obj/item/reagent_containers/C = thing
+ if(check_viruses(C.reagents.reagent_list))
+ return COMSIG_CARGO_SELL_PRIORITY
+ return COMSIG_CARGO_SELL_WRONG
+
+/datum/virology_goal/proc/sell_virus(shuttle, atom/movable/thing, datum/economy/cargo_shuttle_manifest/manifest, complain = FALSE)
+ SIGNAL_HANDLER // COMSIG_CARGO_DO_PRIORITY_SELL
+ // Ignore everything after we're done.
+ if(completed)
+ return
+
+ // Look for reagent containers, those in vial lockboxes included
+ if(!istype(thing, /obj/item/reagent_containers))
+ return
+
+ var/obj/item/reagent_containers/C = thing
+ if(!length(C.reagents?.reagent_list))
+ // Nothing to look at.
+ return
+
+ check_viruses(C.reagents.reagent_list, manifest, complain, complain)
+
+ if(!completed)
+ // Didn't finish yet.
+ return
+
+ // Report and give credits for the goal.
+ var/datum/economy/line_item/item = new
+ item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL)
+ item.credits = SSeconomy.credits_per_virology_goal
+ item.reason = "[name] completed."
+ manifest.line_items += item
+
+ // Stop listening.
+ unregister()
+
+/datum/virology_goal/proc/complain_about_virus(shuttle, atom/movable/thing, datum/economy/cargo_shuttle_manifest/manifest)
+ sell_virus(shuttle, thing, manifest, TRUE)
+
/datum/virology_goal/proc/get_report()
return "Complete this goal."
-/datum/virology_goal/proc/check_completion(list/reagent_list)
+/datum/virology_goal/proc/check_viruses(list/reagent_list)
check_total_virology_goals_completion()
return TRUE
@@ -45,12 +97,13 @@ GLOBAL_LIST_EMPTY(archived_virology_goals)
/datum/virology_goal/property_symptom
name = "Symptom With Properties Viral Sample Request"
- var/goal_symptom //Type path of the symptom
+ var/datum/symptom/goal_symptom //Type path of the symptom
var/goal_symptom_name
var/goal_property
var/goal_property_value
/datum/virology_goal/property_symptom/New()
+ register()
var/times_looped = 0 //The chance for this to make a infinite loop that lags the server is astronomically small but its still a chance
do
var/type = pick(subtypesof(/datum/symptom))
@@ -87,7 +140,7 @@ GLOBAL_LIST_EMPTY(archived_virology_goals)
return_text += "Viral samples with a specific symptom and properties are required to study the effects of this symptom in various conditions. We need you to deliver [delivery_goal]u of viral samples containing the [goal_symptom_name] symptom and with the [goal_property] property at level [goal_property_value] along with 3 other symptoms to us through the cargo shuttle."
return return_text
-/datum/virology_goal/property_symptom/check_completion(list/datum/reagent/reagent_list)
+/datum/virology_goal/property_symptom/check_viruses(list/datum/reagent/reagent_list, datum/economy/cargo_shuttle_manifest/manifest, simulate = TRUE, complain = FALSE)
. = FALSE
var/datum/reagent/blood/BL = locate() in reagent_list
if(!BL)
@@ -95,27 +148,54 @@ GLOBAL_LIST_EMPTY(archived_virology_goals)
if(!BL.data || !BL.data["viruses"])
return
for(var/datum/disease/advance/D in BL.data["viruses"])
- if(length(D.symptoms) < 4) //We want 3 other symptoms alongside the requested one
+ //We want 3 other symptoms alongside the requested one
+ var/required_symptoms = 4
+ if(length(D.symptoms) < required_symptoms)
+ if(simulate || !manifest || !complain)
+ continue
+ var/datum/economy/line_item/item = new
+ item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL)
+ item.credits = 0
+ item.reason = "Virus [D.name] has too few symptoms for [name] ([length(D.symptoms)] is less than [required_symptoms])."
+ manifest.line_items += item
continue
var/properties = D.GenerateProperties()
var/property = properties[goal_property]
if(property != goal_property_value)
+ if(simulate || !manifest || !complain)
+ continue
+ var/datum/economy/line_item/item = new
+ item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL)
+ item.credits = 0
+ item.reason = "Virus [D.name] has the wrong [goal_property] for [name] ([property] is not [goal_property_value])."
+ manifest.line_items += item
continue
- var/found_goal_symptom = FALSE
for(var/datum/symptom/S in D.symptoms)
if(!goal_symptom)
return
if(S.type != goal_symptom)
continue
- found_goal_symptom = TRUE
- break
- if(!found_goal_symptom)
- return
- delivered_amount += BL.volume
- if(delivered_amount >= delivery_goal)
- completed = TRUE
- check_total_virology_goals_completion()
- return TRUE
+ if(simulate)
+ return TRUE
+ if(manifest)
+ var/datum/economy/line_item/item = new
+ item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL)
+ item.credits = 0
+ item.zero_is_good = TRUE
+ item.reason = "Received [BL.volume] units of usable virus [D.name] for [name]."
+ manifest.line_items += item
+ delivered_amount += BL.volume
+ if(delivered_amount >= delivery_goal)
+ completed = TRUE
+ check_total_virology_goals_completion()
+ return TRUE
+ if(simulate || !manifest || !complain)
+ continue
+ var/datum/economy/line_item/item = new
+ item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL)
+ item.credits = 0
+ item.reason = "Virus [D.name] is missing the required symptom [initial(goal_symptom.name)] for [name]."
+ manifest.line_items += item
/datum/virology_goal/virus
name = "Specific Viral Sample Request (Non-Stealth)"
@@ -123,6 +203,7 @@ GLOBAL_LIST_EMPTY(archived_virology_goals)
var/symptoms_amount = 5
/datum/virology_goal/virus/New()
+ register()
var/times_looped = 0 //The chance for this to make a infinite loop that lags the server is astronomically small but its still a chance
do
goal_symptoms = list()
@@ -165,7 +246,7 @@ GLOBAL_LIST_EMPTY(archived_virology_goals)
msg += initial(S.name)
return english_list(msg, ", ")
-/datum/virology_goal/virus/check_completion(list/datum/reagent/reagent_list)
+/datum/virology_goal/virus/check_viruses(list/datum/reagent/reagent_list, datum/economy/cargo_shuttle_manifest/manifest, simulate = TRUE, complain = FALSE)
. = FALSE
var/datum/reagent/blood/BL = locate() in reagent_list
if(!BL)
@@ -173,12 +254,35 @@ GLOBAL_LIST_EMPTY(archived_virology_goals)
if(!BL.data || !BL.data["viruses"])
return
for(var/datum/disease/advance/D in BL.data["viruses"])
- if(length(D.symptoms) != length(goal_symptoms)) //This is here so viruses with extra symptoms dont get approved
- return
+ if(length(D.symptoms) != length(goal_symptoms))
+ if(simulate || !manifest || !complain)
+ continue
+ var/datum/economy/line_item/item = new
+ item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL)
+ item.credits = 0
+ item.reason = "Virus [D.name] has the wrong number of symptoms for [name] ([length(D.symptoms)] is not [length(goal_symptoms)])."
+ manifest.line_items += item
+ continue
for(var/S in goal_symptoms)
var/datum/symptom/SY = locate(S) in D.symptoms
if(!SY)
+ if(simulate || !manifest || !complain)
+ continue
+ var/datum/economy/line_item/item = new
+ item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL)
+ item.credits = 0
+ item.reason = "Virus [D.name] is missing symptom [initial(SY.name)] for [name]."
+ manifest.line_items += item
return
+ if(simulate)
+ return TRUE
+ if(manifest)
+ var/datum/economy/line_item/item = new
+ item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL)
+ item.credits = 0
+ item.zero_is_good = TRUE
+ item.reason = "Received [BL.volume] units of usable virus [D.name] for [name]."
+ manifest.line_items += item
delivered_amount += BL.volume
if(delivered_amount >= delivery_goal)
completed = TRUE
diff --git a/paradise.dme b/paradise.dme
index 99ff381c75c..c7abc177879 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -59,6 +59,7 @@
#include "code\__DEFINES\emotes_defines.dm"
#include "code\__DEFINES\error_handler_defines.dm"
#include "code\__DEFINES\flags.dm"
+#include "code\__DEFINES\food_defines.dm"
#include "code\__DEFINES\footstep_defines.dm"
#include "code\__DEFINES\game_defines.dm"
#include "code\__DEFINES\gamemode.dm"
@@ -115,6 +116,7 @@
#include "code\__DEFINES\status_effects.dm"
#include "code\__DEFINES\subsystems.dm"
#include "code\__DEFINES\supermatter_defines.dm"
+#include "code\__DEFINES\supply_defines.dm"
#include "code\__DEFINES\surgery_defines.dm"
#include "code\__DEFINES\text_defines.dm"
#include "code\__DEFINES\tg_cooldowns.dm"
@@ -2712,6 +2714,21 @@
#include "code\modules\station_goals\dna_vault.dm"
#include "code\modules\station_goals\shield.dm"
#include "code\modules\station_goals\station_goal.dm"
+#include "code\modules\station_goals\task_backlog.dm"
+#include "code\modules\station_goals\secondary\random_bulk_reagent.dm"
+#include "code\modules\station_goals\secondary\secondary_goal.dm"
+#include "code\modules\station_goals\secondary\secondary_goal_tracker.dm"
+#include "code\modules\station_goals\secondary\variety_reagent.dm"
+#include "code\modules\station_goals\secondary\bar\random_bulk_drink.dm"
+#include "code\modules\station_goals\secondary\bar\variety_drinks.dm"
+#include "code\modules\station_goals\secondary\botany\kudzu_goal.dm"
+#include "code\modules\station_goals\secondary\kitchen\random_bulk_condiment.dm"
+#include "code\modules\station_goals\secondary\kitchen\random_bulk_food.dm"
+#include "code\modules\station_goals\secondary\medical\random_bulk_medicine.dm"
+#include "code\modules\station_goals\secondary\medical\variety_medicine.dm"
+#include "code\modules\station_goals\secondary\science\random_bulk_chemical.dm"
+#include "code\modules\station_goals\secondary\science\random_ripley.dm"
+#include "code\modules\station_goals\secondary\science\variety_chemicals.dm"
#include "code\modules\supply\supply_console.dm"
#include "code\modules\supply\supply_order.dm"
#include "code\modules\supply\supply_pack.dm"
diff --git a/tgui/packages/tgui/interfaces/RequestConsole.js b/tgui/packages/tgui/interfaces/RequestConsole.js
index 2001a7014b7..b1cd113399c 100644
--- a/tgui/packages/tgui/interfaces/RequestConsole.js
+++ b/tgui/packages/tgui/interfaces/RequestConsole.js
@@ -30,13 +30,15 @@ export const RequestConsole = (props, context) => {
return ;
case 10:
return ;
+ case 11:
+ return ;
default:
return "WE SHOULDN'T BE HERE!";
}
};
return (
-
+
{pickPage(screen)}
@@ -116,6 +118,14 @@ const MainMenu = (props, context) => {
icon="box"
onClick={() => act('setScreen', { setScreen: 2 })}
/>
+