diff --git a/code/__DEFINES/exports.dm b/code/__DEFINES/exports.dm deleted file mode 100644 index 6c8b00de528..00000000000 --- a/code/__DEFINES/exports.dm +++ /dev/null @@ -1,4 +0,0 @@ -#define EXPORT_CARGO 1 -#define EXPORT_EMAG 2 -#define EXPORT_CONTRABAND 4 -#define EXPORT_PIRATE 8 diff --git a/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm b/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm index b48b8e2df9f..82b1c3a611f 100644 --- a/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm +++ b/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm @@ -6,8 +6,11 @@ icon = 'icons/obj/machines/dominator.dmi' icon_state = "dominator" density = TRUE + /// Is the machine siphoning right now var/active = FALSE + /// The amount of money stored in the machine var/credits_stored = 0 + /// The amount of money removed per tick var/siphon_per_tick = 5 /obj/machinery/shuttle_scrambler/Initialize(mapload) @@ -17,10 +20,10 @@ /obj/machinery/shuttle_scrambler/process() if(active) if(is_station_level(z)) - var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) - if(D) - var/siphoned = min(D.account_balance,siphon_per_tick) - D.adjust_money(-siphoned) + var/datum/bank_account/account = SSeconomy.get_dep_account(ACCOUNT_CAR) + if(account) + var/siphoned = min(account.account_balance,siphon_per_tick) + account.adjust_money(-siphoned) credits_stored += siphoned interrupt_research() else @@ -28,6 +31,7 @@ else STOP_PROCESSING(SSobj,src) +///Turns on the siphoning, and its various side effects /obj/machinery/shuttle_scrambler/proc/toggle_on(mob/user) SSshuttle.registerTradeBlockade(src) AddComponent(/datum/component/gps, "Nautical Signal") @@ -49,14 +53,15 @@ update_appearance() send_notification() -//interrupt_research +/// Handles interrupting research /obj/machinery/shuttle_scrambler/proc/interrupt_research() - for(var/obj/machinery/rnd/server/S as anything in SSresearch.science_tech.techweb_servers) - if(S.machine_stat & (NOPOWER|BROKEN|EMPED)) + for(var/obj/machinery/rnd/server/research_server as anything in SSresearch.science_tech.techweb_servers) + if(research_server.machine_stat & (NOPOWER|BROKEN|EMPED)) continue - S.emp_act(EMP_LIGHT) - new /obj/effect/temp_visual/emp(get_turf(S)) + research_server.emp_act(EMP_LIGHT) + new /obj/effect/temp_visual/emp(get_turf(research_server)) +/// Handles expelling all the siphoned credits as holochips /obj/machinery/shuttle_scrambler/proc/dump_loot(mob/user) if(credits_stored) // Prevents spamming empty holochips new /obj/item/holochip(drop_location(), credits_stored) @@ -65,9 +70,11 @@ else to_chat(user,span_notice("There's nothing to withdraw.")) +/// Alerts the crew about the siphon /obj/machinery/shuttle_scrambler/proc/send_notification() priority_announce("Data theft signal detected; source registered on local GPS units.") +/// Switches off the siphon /obj/machinery/shuttle_scrambler/proc/toggle_off(mob/user) SSshuttle.clearTradeBlockade(src) active = FALSE @@ -124,24 +131,25 @@ to_chat(user,span_warning("[src] is recharging.")) return next_use = world.time + cooldown - var/atom/movable/AM = find_random_loot() - if(!AM) + var/atom/movable/found_loot = find_random_loot() + if(!found_loot) say("No valuables located. Try again later.") else - say("Located: [AM.name] at [get_area_name(AM)]") + say("Located: [found_loot.name] at [get_area_name(found_loot)]") +/// Looks across the station for items that are pirate specific exports /obj/machinery/loot_locator/proc/find_random_loot() if(!GLOB.exports_list.len) setupExports() var/list/possible_loot = list() - for(var/datum/export/pirate/E in GLOB.exports_list) - possible_loot += E - var/datum/export/pirate/P - var/atom/movable/AM - while(!AM && possible_loot.len) - P = pick_n_take(possible_loot) - AM = P.find_loot() - return AM + for(var/datum/export/pirate/possible_export in GLOB.exports_list) + possible_loot += possible_export + var/datum/export/pirate/selected_export + var/atom/movable/found_loot + while(!found_loot && possible_loot.len) + selected_export = pick_n_take(possible_loot) + found_loot = selected_export.find_loot() + return found_loot //Pad & Pad Terminal /obj/machinery/piratepad @@ -250,57 +258,59 @@ stop_sending() . = TRUE +/// Calculates the predicted value of the items on the pirate pad /obj/machinery/computer/piratepad_control/proc/recalc() if(sending) return status_report = "Predicted value: " var/value = 0 - var/datum/export_report/ex = new + var/datum/export_report/report = new var/obj/machinery/piratepad/pad = pad_ref?.resolve() for(var/atom/movable/AM in get_turf(pad)) if(AM == pad) continue - export_item_and_contents(AM, apply_elastic = FALSE, dry_run = TRUE, external_report = ex) + export_item_and_contents(AM, apply_elastic = FALSE, dry_run = TRUE, external_report = report) - for(var/datum/export/E in ex.total_amount) - status_report += E.total_printout(ex,notes = FALSE) + for(var/datum/export/exported_datum in report.total_amount) + status_report += exported_datum.total_printout(report,notes = FALSE) status_report += " " - value += ex.total_value[E] + value += report.total_value[exported_datum] if(!value) status_report += "0" +/// Deletes and sells the item /obj/machinery/computer/piratepad_control/proc/send() if(!sending) return - var/datum/export_report/ex = new + var/datum/export_report/report = new var/obj/machinery/piratepad/pad = pad_ref?.resolve() - for(var/atom/movable/AM in get_turf(pad)) - if(AM == pad) + for(var/atom/movable/item_on_pad in get_turf(pad)) + if(item_on_pad == pad) continue - export_item_and_contents(AM, EXPORT_PIRATE | EXPORT_CARGO | EXPORT_CONTRABAND | EXPORT_EMAG, apply_elastic = FALSE, delete_unsold = FALSE, external_report = ex) + export_item_and_contents(item_on_pad, apply_elastic = FALSE, delete_unsold = FALSE, external_report = report) status_report = "Sold: " var/value = 0 - for(var/datum/export/E in ex.total_amount) - var/export_text = E.total_printout(ex,notes = FALSE) //Don't want nanotrasen messages, makes no sense here. + for(var/datum/export/exported_datum in report.total_amount) + var/export_text = exported_datum.total_printout(report,notes = FALSE) //Don't want nanotrasen messages, makes no sense here. if(!export_text) continue status_report += export_text status_report += " " - value += ex.total_value[E] + value += report.total_value[exported_datum] if(!total_report) - total_report = ex + total_report = report else - total_report.exported_atoms += ex.exported_atoms - for(var/datum/export/E in ex.total_amount) - total_report.total_amount[E] += ex.total_amount[E] - total_report.total_value[E] += ex.total_value[E] + total_report.exported_atoms += report.exported_atoms + for(var/datum/export/exported_datum in report.total_amount) + total_report.total_amount[exported_datum] += report.total_amount[exported_datum] + total_report.total_value[exported_datum] += report.total_value[exported_datum] playsound(loc, 'sound/machines/wewewew.ogg', 70, TRUE) points += value @@ -313,6 +323,7 @@ pad.icon_state = pad.idle_state sending = FALSE +/// Prepares to sell the items on the pad /obj/machinery/computer/piratepad_control/proc/start_sending() var/obj/machinery/piratepad/pad = pad_ref?.resolve() if(!pad) @@ -331,6 +342,7 @@ pad.icon_state = pad.warmup_state sending_timer = addtimer(CALLBACK(src, PROC_REF(send)),warmup_time, TIMER_STOPPABLE) +/// Finishes the sending state of the pad /obj/machinery/computer/piratepad_control/proc/stop_sending(custom_report) if(!sending) return @@ -342,7 +354,7 @@ pad.icon_state = pad.idle_state deltimer(sending_timer) -//Attempts to find the thing on station +/// Attempts to find the thing on station /datum/export/pirate/proc/find_loot() return @@ -359,13 +371,13 @@ if(head_mobs.len) return pick(head_mobs) -/datum/export/pirate/ransom/get_cost(atom/movable/AM) - var/mob/living/carbon/human/H = AM - if(H.stat != CONSCIOUS || !H.mind) //mint condition only +/datum/export/pirate/ransom/get_cost(atom/movable/exported_item) + var/mob/living/carbon/human/ransomee = exported_item + if(ransomee.stat != CONSCIOUS || !ransomee.mind) //mint condition only return 0 - else if(FACTION_PIRATE in H.faction) //can't ransom your fellow pirates to CentCom! + else if(FACTION_PIRATE in ransomee.faction) //can't ransom your fellow pirates to CentCom! return 0 - else if(H.mind.assigned_role.departments_bitflags & DEPARTMENT_BITFLAG_COMMAND) + else if(ransomee.mind.assigned_role.departments_bitflags & DEPARTMENT_BITFLAG_COMMAND) return 3000 else return 1000 @@ -376,25 +388,25 @@ export_types = list(/mob/living/simple_animal/parrot) /datum/export/pirate/parrot/find_loot() - for(var/mob/living/simple_animal/parrot/P in GLOB.alive_mob_list) - var/turf/T = get_turf(P) - if(T && is_station_level(T.z)) - return P + for(var/mob/living/simple_animal/parrot/current_parrot in GLOB.alive_mob_list) + var/turf/parrot_turf = get_turf(current_parrot) + if(parrot_turf && is_station_level(parrot_turf.z)) + return current_parrot /datum/export/pirate/cash cost = 1 unit_name = "bills" export_types = list(/obj/item/stack/spacecash) -/datum/export/pirate/cash/get_amount(obj/O) - var/obj/item/stack/spacecash/C = O - return ..() * C.amount * C.value +/datum/export/pirate/cash/get_amount(obj/exported_item) + var/obj/item/stack/spacecash/cash = exported_item + return ..() * cash.amount * cash.value /datum/export/pirate/holochip cost = 1 unit_name = "holochip" export_types = list(/obj/item/holochip) -/datum/export/pirate/holochip/get_cost(atom/movable/AM) - var/obj/item/holochip/H = AM - return H.credits +/datum/export/pirate/holochip/get_cost(atom/movable/exported_item) + var/obj/item/holochip/chip = exported_item + return chip.credits diff --git a/code/modules/cargo/exports.dm b/code/modules/cargo/exports.dm index 31cb255cbbb..a9d408c8699 100644 --- a/code/modules/cargo/exports.dm +++ b/code/modules/cargo/exports.dm @@ -21,16 +21,26 @@ Then the player gets the profit from selling his own wasted time. // Simple holder datum to pass export results around /datum/export_report - var/list/exported_atoms = list() //names of atoms sold/deleted by export - var/list/total_amount = list() //export instance => total count of sold objects of its type, only exists if any were sold - var/list/total_value = list() //export instance => total value of sold objects + ///names of atoms sold/deleted by export + var/list/exported_atoms = list() + ///export instance => total count of sold objects of its type, only exists if any were sold + var/list/total_amount = list() + ///export instance => total value of sold objects + var/list/total_value = list() -// external_report works as "transaction" object, pass same one in if you're doing more than one export in single go -/proc/export_item_and_contents(atom/movable/AM, apply_elastic = TRUE, delete_unsold = TRUE, dry_run = FALSE, datum/export_report/external_report) +/* + * Handles exporting a movable atom and its contents + * Arguments: + ** apply_elastic: if the price will change based on amount sold, where applicable + ** delete_unsold: if the items that were not sold should be deleted + ** dry_run: if the item should be actually sold, or if its just a pirce test + ** external_report: works as "transaction" object, pass same one in if you're doing more than one export in single go +*/ +/proc/export_item_and_contents(atom/movable/exported_atom, apply_elastic = TRUE, delete_unsold = TRUE, dry_run = FALSE, datum/export_report/external_report) if(!GLOB.exports_list.len) setupExports() - var/list/contents = AM.get_all_contents() + var/list/contents = exported_atom.get_all_contents() var/datum/export_report/report = external_report @@ -60,8 +70,9 @@ Then the player gets the profit from selling his own wasted time. return report /datum/export - /// Unit name. Only used in "Received [total_amount] [name]s [message]." message + /// Unit name. Only used in "Received [total_amount] [name]s [message]." var/unit_name = "" + /// Message appended to the sale report var/message = "" /// Cost of item, in cargo credits. Must not allow for infinite price dupes, see above. var/cost = 1 @@ -100,9 +111,9 @@ Then the player gets the profit from selling his own wasted time. if(cost > init_cost) cost = init_cost -// Checks the cost. 0 cost items are skipped in export. -/datum/export/proc/get_cost(obj/O, apply_elastic = TRUE) - var/amount = get_amount(O) +/// Checks the cost. 0 cost items are skipped in export. +/datum/export/proc/get_cost(obj/exported_item, apply_elastic = TRUE) + var/amount = get_amount(exported_item) if(apply_elastic) if(k_elasticity != 0) return round((cost/k_elasticity) * (1 - NUM_E**(-1 * k_elasticity * amount))) //anti-derivative of the marginal cost function @@ -111,20 +122,22 @@ Then the player gets the profit from selling his own wasted time. else return round(init_cost * amount) -// Checks the amount of exportable in object. Credits in the bill, sheets in the stack, etc. -// Usually acts as a multiplier for a cost, so item that has 0 amount will be skipped in export. -/datum/export/proc/get_amount(obj/O) +/* +* Checks the amount of exportable in object. Credits in the bill, sheets in the stack, etc. +* Usually acts as a multiplier for a cost, so item that has 0 amount will be skipped in export. +*/ +/datum/export/proc/get_amount(obj/exported_item) return 1 -// Checks if the item is fit for export datum. -/datum/export/proc/applies_to(obj/O, apply_elastic = TRUE) - if(!is_type_in_typecache(O, export_types)) +/// Checks if the item is fit for export datum. +/datum/export/proc/applies_to(obj/exported_item, apply_elastic = TRUE) + if(!is_type_in_typecache(exported_item, export_types)) return FALSE - if(include_subtypes && is_type_in_typecache(O, exclude_types)) + if(include_subtypes && is_type_in_typecache(exported_item, exclude_types)) return FALSE - if(!get_cost(O, apply_elastic)) + if(!get_cost(exported_item, apply_elastic)) return FALSE - if(O.flags_1 & HOLOGRAM_1) + if(exported_item.flags_1 & HOLOGRAM_1) return FALSE return TRUE @@ -161,9 +174,11 @@ Then the player gets the profit from selling his own wasted time. SSblackbox.record_feedback("nested tally", "export_sold_cost", 1, list("[sold_item.type]", "[export_value]")) return TRUE -// Total printout for the cargo console. -// Called before the end of current export cycle. -// It must always return something if the datum adds or removes any credts. +/* +* Total printout for the cargo console. +* Called before the end of current export cycle. +* It must always return something if the datum adds or removes any credtis. +*/ /datum/export/proc/total_printout(datum/export_report/ex, notes = TRUE) if(!ex.total_amount[src] || !ex.total_value[src]) return "" @@ -190,8 +205,9 @@ Then the player gets the profit from selling his own wasted time. GLOBAL_LIST_EMPTY(exports_list) +/// Called when the global exports_list is empty, and sets it up. /proc/setupExports() for(var/subtype in subtypesof(/datum/export)) - var/datum/export/E = new subtype - if(E.export_types && E.export_types.len) // Exports without a type are invalid/base types - GLOB.exports_list += E + var/datum/export/export_datum = new subtype + if(export_datum.export_types && export_datum.export_types.len) // Exports without a type are invalid/base types + GLOB.exports_list += export_datum diff --git a/code/modules/cargo/orderconsole.dm b/code/modules/cargo/orderconsole.dm index e090c67f8b2..ca5b5597746 100644 --- a/code/modules/cargo/orderconsole.dm +++ b/code/modules/cargo/orderconsole.dm @@ -62,13 +62,6 @@ else return ..() -/obj/machinery/computer/cargo/proc/get_export_categories() - . = EXPORT_CARGO - if(contraband) - . |= EXPORT_CONTRABAND - if(obj_flags & EMAGGED) - . |= EXPORT_EMAG - /obj/machinery/computer/cargo/emag_act(mob/user) if(obj_flags & EMAGGED) return @@ -327,7 +320,6 @@ requisition_paper.update_appearance() if(SSshuttle.supply.getDockedId() == docking_home) - SSshuttle.supply.export_categories = get_export_categories() SSshuttle.moveShuttle(cargo_shuttle, docking_away, TRUE) say("The supply shuttle is departing.") usr.investigate_log("sent the supply shuttle away.", INVESTIGATE_CARGO) diff --git a/code/modules/cargo/universal_scanner.dm b/code/modules/cargo/universal_scanner.dm index 7e352aca98f..300b805df4a 100644 --- a/code/modules/cargo/universal_scanner.dm +++ b/code/modules/cargo/universal_scanner.dm @@ -169,10 +169,10 @@ /obj/item/universal_scanner/proc/export_scan(obj/target, mob/user) // Before you fix it: // yes, checking manifests is a part of intended functionality. - var/datum/export_report/ex = export_item_and_contents(target, dry_run = TRUE) + var/datum/export_report/report = export_item_and_contents(target, dry_run = TRUE) var/price = 0 - for(var/x in ex.total_amount) - price += ex.total_value[x] + for(var/exported_datum in report.total_amount) + price += report.total_value[exported_datum] if(price) to_chat(user, span_notice("Scanned [target], value: [price] credits[target.contents.len ? " (contents included)" : ""].")) else diff --git a/code/modules/modular_computers/file_system/programs/budgetordering.dm b/code/modules/modular_computers/file_system/programs/budgetordering.dm index e42cf66e004..1c7aae6f62a 100644 --- a/code/modules/modular_computers/file_system/programs/budgetordering.dm +++ b/code/modules/modular_computers/file_system/programs/budgetordering.dm @@ -33,9 +33,6 @@ ///The account this console processes and displays. Independent from the account the shuttle processes. var/cargo_account = ACCOUNT_CAR -/datum/computer_file/program/budgetorders/proc/get_export_categories() - . = EXPORT_CARGO - /datum/computer_file/program/budgetorders/proc/is_visible_pack(mob/user, paccess_to_check, list/access, contraband) if(issilicon(user)) //Borgs can't buy things. return FALSE @@ -169,7 +166,6 @@ computer.say(blockade_warning) return if(SSshuttle.supply.getDockedId() == docking_home) - SSshuttle.supply.export_categories = get_export_categories() SSshuttle.moveShuttle(cargo_shuttle, docking_away, TRUE) computer.say("The supply shuttle is departing.") usr.investigate_log("sent the supply shuttle away.", INVESTIGATE_CARGO) diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index df5ec005f86..15577f348d4 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -48,9 +48,6 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list( port_direction = EAST movement_force = list("KNOCKDOWN" = 0, "THROW" = 0) - //Export categories for this run, this is set by console sending the shuttle. - var/export_categories = EXPORT_CARGO - /obj/docking_port/mobile/supply/register() . = ..() SSshuttle.supply = src @@ -93,10 +90,10 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list( var/list/empty_turfs = list() for(var/area/shuttle/shuttle_area as anything in shuttle_areas) - for(var/turf/open/floor/T in shuttle_area) - if(T.is_blocked_turf()) + for(var/turf/open/floor/shuttle_turf in shuttle_area) + if(shuttle_turf.is_blocked_turf()) continue - empty_turfs += T + empty_turfs += shuttle_turf //quickly and greedily handle chef's grocery runs first, there are a few reasons why this isn't attached to the rest of cargo... //but the biggest reason is that the chef requires produce to cook and do their job, and if they are using this system they @@ -176,9 +173,9 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list( // we handle packing all the goodies last, since the type of crate we use depends on how many goodies they ordered. If it's more than GOODY_FREE_SHIPPING_MAX // then we send it in a crate (including the CRATE_TAX cost), otherwise send it in a free shipping case - for(var/D in goodies_by_buyer) - var/list/buying_account_orders = goodies_by_buyer[D] - var/datum/bank_account/buying_account = D + for(var/buyer_key in goodies_by_buyer) + var/list/buying_account_orders = goodies_by_buyer[buyer_key] + var/datum/bank_account/buying_account = buyer_key var/buyer = buying_account.account_holder if(buying_account_orders.len > GOODY_FREE_SHIPPING_MAX) // no free shipping, send a crate @@ -199,49 +196,50 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list( misc_costs[buyer] += our_order.pack.cost misc_order_num[buyer] = "[misc_order_num[buyer]]#[our_order.id] " - for(var/I in miscboxes) - var/datum/supply_order/SO = new/datum/supply_order() - SO.id = misc_order_num[I] - SO.generateCombo(miscboxes[I], I, misc_contents[I], misc_costs[I]) - qdel(SO) + for(var/miscbox in miscboxes) + var/datum/supply_order/order = new/datum/supply_order() + order.id = misc_order_num[miscbox] + order.generateCombo(miscboxes[miscbox], miscbox, misc_contents[miscbox], misc_costs[miscbox]) + qdel(order) SSeconomy.import_total += value var/datum/bank_account/cargo_budget = SSeconomy.get_dep_account(ACCOUNT_CAR) investigate_log("[purchases] orders in this shipment, worth [value] credits. [cargo_budget.account_balance] credits left.", INVESTIGATE_CARGO) +/// Deletes and sells the items on the shuttle /obj/docking_port/mobile/supply/proc/sell() - var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) - var/presale_points = D.account_balance + var/datum/bank_account/cargo_budget = SSeconomy.get_dep_account(ACCOUNT_CAR) + var/presale_points = cargo_budget.account_balance if(!GLOB.exports_list.len) // No exports list? Generate it! setupExports() var/msg = "" - var/datum/export_report/ex = new + var/datum/export_report/report = new for(var/area/shuttle/shuttle_area as anything in shuttle_areas) - for(var/atom/movable/AM in shuttle_area) - if(iscameramob(AM)) + for(var/atom/movable/exporting_atom in shuttle_area) + if(iscameramob(exporting_atom)) continue - if(AM.anchored) + if(exporting_atom.anchored) continue - export_item_and_contents(AM, export_categories, dry_run = FALSE, external_report = ex) + export_item_and_contents(exporting_atom, apply_elastic = TRUE, dry_run = FALSE, external_report = report) - if(ex.exported_atoms) - ex.exported_atoms += "." //ugh + if(report.exported_atoms) + report.exported_atoms += "." //ugh - for(var/datum/export/E in ex.total_amount) - var/export_text = E.total_printout(ex) + for(var/datum/export/exported_datum in report.total_amount) + var/export_text = exported_datum.total_printout(report) if(!export_text) continue msg += export_text + "\n" - D.adjust_money(ex.total_value[E]) + cargo_budget.adjust_money(report.total_value[exported_datum]) - SSeconomy.export_total += (D.account_balance - presale_points) + SSeconomy.export_total += (cargo_budget.account_balance - presale_points) SSshuttle.centcom_message = msg - investigate_log("contents sold for [D.account_balance - presale_points] credits. Contents: [ex.exported_atoms ? ex.exported_atoms.Join(",") + "." : "none."] Message: [SSshuttle.centcom_message || "none."]", INVESTIGATE_CARGO) + investigate_log("contents sold for [cargo_budget.account_balance - presale_points] credits. Contents: [report.exported_atoms ? report.exported_atoms.Join(",") + "." : "none."] Message: [SSshuttle.centcom_message || "none."]", INVESTIGATE_CARGO) /* Generates a box of mail depending on our exports and imports. diff --git a/tgstation.dme b/tgstation.dme index 3342c8e4e2e..03c83aab21c 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -92,7 +92,6 @@ #include "code\__DEFINES\exosuit_fab.dm" #include "code\__DEFINES\experisci.dm" #include "code\__DEFINES\explosions.dm" -#include "code\__DEFINES\exports.dm" #include "code\__DEFINES\external_organs.dm" #include "code\__DEFINES\fantasy_affixes.dm" #include "code\__DEFINES\firealarm.dm"