diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm index 83c27f2eb01..611ca03ecc6 100644 --- a/code/__HELPERS/lists.dm +++ b/code/__HELPERS/lists.dm @@ -63,6 +63,7 @@ //Checks for specific types in specifically structured (Assoc "type" = TRUE) lists ('typecaches') /proc/is_type_in_typecache(atom/A, list/L) if(!L || !L.len || !A) + return 0 return L[A.type] diff --git a/code/modules/cargo/export_scanner.dm b/code/modules/cargo/export_scanner.dm index e17e7b5f635..ffbfa05fe1c 100644 --- a/code/modules/cargo/export_scanner.dm +++ b/code/modules/cargo/export_scanner.dm @@ -33,15 +33,10 @@ user << "Scanned [O]." // Before you fix it: yes, checking manifests is a part of intended functionality. - var/exported = FALSE - for(var/a in supply.exports) - var/datum/export/E = a - if(E.applies_to(O, cargo_console.contraband, cargo_console.emagged)) - var/cost = E.get_cost(O, cargo_console.contraband, cargo_console.emagged) - user << "Export cost: [cost] credits." - if(is_type_in_list(O, supply.storage_objects) && O.contents.len) - user << "(contents not included)" - exported = TRUE - break - if(!exported) - user << "The object is unexportable." + var/price = export_item_and_contents(O, supply.exports, cargo_console.contraband, cargo_console.emagged, dry_run=TRUE) + + if(price) + user << "Export value: [price] \ + credits." + if(O.contents.len) + user << "(contents included)" diff --git a/code/modules/cargo/exports.dm b/code/modules/cargo/exports.dm index 59f8362a98a..98f4e14099e 100644 --- a/code/modules/cargo/exports.dm +++ b/code/modules/cargo/exports.dm @@ -26,7 +26,32 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they then the player gets the profit from selling his own wasted time. */ +/proc/export_item_and_contents(atom/movable/AM, exports, contraband, emagged, dry_run=FALSE) + var/sold_str = "" + var/cost = 0 + var/list/contents = AM.GetAllContents() + + // We go backwards, so it'll be innermost objects sold first + for(var/i in reverseRange(contents)) + var/atom/movable/thing + for(var/datum/export/E in exports) + if(!E) + continue + if(E.applies_to(thing, contraband, emagged)) + if(dry_run) + cost += E.get_cost(thing, contraband, emagged) + else + E.sell_object(thing, contraband, emagged) + sold_str += " [thing.name]" + break + if(!dry_run) + qdel(thing) + + if(dry_run) + return cost + else + return sold_str /datum/export var/unit_name = "" // Unit name. Only used in "Received [total_amount] [name]s [message]." message @@ -37,7 +62,6 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they var/list/export_types = list() // Type of the exported object. If none, the export datum is considered base type. var/include_subtypes = TRUE // Set to FALSE to make the datum apply only to a strict type. var/list/exclude_types = list() // Types excluded from export - var/shuttle_floor = FALSE // TRUE if the item can be sold on the floor, not only in crates. // Used by print-out var/total_cost = 0 @@ -104,3 +128,11 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they /datum/export/proc/export_end() total_cost = 0 total_amount = 0 + +var/list/exports_list = list() + +/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 + exports += E diff --git a/code/modules/cargo/exports/large_objects.dm b/code/modules/cargo/exports/large_objects.dm index b5567796985..158710eccdc 100644 --- a/code/modules/cargo/exports/large_objects.dm +++ b/code/modules/cargo/exports/large_objects.dm @@ -1,9 +1,5 @@ // Large objects that don't fit in crates, but must be sellable anyway. -/datum/export/large - shuttle_floor = TRUE - - // Crates, boxes, lockers. /datum/export/large/crate cost = 500 @@ -111,4 +107,4 @@ /datum/export/large/barrier cost = 325 unit_name = "security barrier" - export_types = list(/obj/item/weapon/grenade/barrier, /obj/structure/barricade/security) \ No newline at end of file + export_types = list(/obj/item/weapon/grenade/barrier, /obj/structure/barricade/security) diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index 0493e2138be..f4c2511d63c 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -1,3 +1,19 @@ +var/list/blacklisted_cargo_types = typecacheof(list( + /mob/living, + /obj/effect/blob, + /obj/effect/rune, + /obj/effect/spider/spiderling, + /obj/item/weapon/disk/nuclear, + /obj/machinery/nuclearbomb, + /obj/item/device/radio/beacon, + /obj/singularity, + /obj/machinery/teleport/station, + /obj/machinery/teleport/hub, + /obj/machinery/telepad, + /obj/machinery/clonepod, + /obj/effect/mob_spawn + )) + /obj/docking_port/mobile/supply name = "supply shuttle" id = "supply" @@ -10,30 +26,7 @@ height = 7 roundstart_move = "supply_away" - var/list/blacklist = list( - /mob/living, - /obj/effect/blob, - /obj/effect/rune, - /obj/effect/spider/spiderling, - /obj/item/weapon/disk/nuclear, - /obj/machinery/nuclearbomb, - /obj/item/device/radio/beacon, - /obj/singularity, - /obj/machinery/teleport/station, - /obj/machinery/teleport/hub, - /obj/machinery/telepad, - /obj/machinery/clonepod - ) - var/list/storage_objects = list( - /obj/structure/closet, - /obj/item/weapon/storage, - /obj/item/weapon/storage/bag/money, - /obj/item/weapon/folder, // Selling a folder of stamped manifests? Sure, why not! - /obj/structure/filingcabinet, - /obj/structure/ore_box, - ) var/list/exports = list() - var/list/exports_floor = list() // When TRUE, these vars allow exporting emagged/contraband items, and add some special interactions to existing exports. var/contraband = FALSE @@ -49,11 +42,10 @@ return ..() /obj/docking_port/mobile/supply/proc/check_blacklist(atom/A) - if(is_type_in_list(A, blacklist)) - return 1 - for(var/thing in A) - if(.(thing)) - return 1 + for(var/thing in list(A) | A.GetAllContents()) + if(is_type_in_typecache(thing, blacklisted_cargo_types)) + return TRUE + return FALSE /obj/docking_port/mobile/supply/request() if(mode != SHUTTLE_IDLE) @@ -105,14 +97,6 @@ var/presale_points = SSshuttle.points if(!exports.len) // No exports list? Generate it! - exports_floor.Cut() - var/datum/export/E - for(var/subtype in subtypesof(/datum/export)) - E = new subtype - if(E.export_types && E.export_types.len) // Exports without a type are invalid/base types - exports += E - if(E.shuttle_floor) - exports_floor += E var/msg = "" var/sold_atoms = "" @@ -120,7 +104,7 @@ for(var/atom/movable/AM in areaInstance) if(AM.anchored) continue - sold_atoms += recursive_sell(AM) + sold_atoms += export_item_and_contents(AM, exports, contraband, emagged, dry_run = FALSE) if(sold_atoms) sold_atoms += "." @@ -137,22 +121,3 @@ SSshuttle.centcom_message = msg investigate_log("Shuttle contents sold for [SSshuttle.points - presale_points] credits. Contents: [sold_atoms || "none."] Message: [SSshuttle.centcom_message || "none."]", "cargo") - -/obj/docking_port/mobile/supply/proc/recursive_sell(var/obj/O, var/level=0) - var/sold_atoms = " [O.name]" - var/list/xports = exports - if(level == 0) - xports = exports_floor // If on the floor level, sell floor exports only - level++ - - for(var/a in xports) - var/datum/export/E = a - if(E.applies_to(O, contraband, emagged)) - E.sell_object(O, contraband, emagged) - break - - if(level < 10 && is_type_in_list(O, storage_objects)) - for(var/obj/thing in O) - sold_atoms += recursive_sell(thing, level) - qdel(O) - return sold_atoms