mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-20 19:49:39 +01:00
# Conflicts: # .github/CODEOWNERS # .github/workflows/compile_changelogs.yml # .github/workflows/stale.yml # SQL/database_changelog.md # _maps/map_files/CatwalkStation/CatwalkStation_2023.dmm # code/__DEFINES/atom_hud.dm # code/__DEFINES/inventory.dm # code/__DEFINES/mobs.dm # code/__DEFINES/species_clothing_paths.dm # code/__DEFINES/subsystems.dm # code/__DEFINES/surgery.dm # code/__HELPERS/global_lists.dm # code/_globalvars/lists/maintenance_loot.dm # code/_globalvars/traits/_traits.dm # code/controllers/subsystem/minor_mapping.dm # code/controllers/subsystem/processing/quirks.dm # code/controllers/subsystem/shuttle.dm # code/datums/components/palette.dm # code/datums/components/surgery_initiator.dm # code/datums/diseases/advance/advance.dm # code/datums/hud.dm # code/datums/mood.dm # code/datums/mutations/chameleon.dm # code/datums/quirks/negative_quirks/nyctophobia.dm # code/datums/status_effects/debuffs/debuffs.dm # code/datums/status_effects/debuffs/drunk.dm # code/datums/status_effects/debuffs/slime/slime_leech.dm # code/datums/weather/weather.dm # code/game/data_huds.dm # code/game/objects/items.dm # code/game/objects/items/devices/scanners/health_analyzer.dm # code/game/objects/items/frog_statue.dm # code/game/objects/items/rcd/RLD.dm # code/game/objects/items/robot/items/hypo.dm # code/game/objects/items/stacks/medical.dm # code/game/objects/items/stacks/wrap.dm # code/game/objects/items/storage/garment.dm # code/game/objects/items/tools/medical/defib.dm # code/game/objects/items/weaponry.dm # code/game/objects/items/weaponry/melee/misc.dm # code/game/objects/structures/crates_lockers/closets/secure/security.dm # code/game/objects/structures/curtains.dm # code/game/objects/structures/dresser.dm # code/game/objects/structures/girders.dm # code/game/objects/structures/maintenance.dm # code/game/objects/structures/mirror.dm # code/modules/admin/greyscale_modify_menu.dm # code/modules/admin/verbs/light_debug.dm # code/modules/antagonists/ashwalker/ashwalker.dm # code/modules/antagonists/heretic/knowledge/starting_lore.dm # code/modules/antagonists/ninja/ninjaDrainAct.dm # code/modules/art/paintings.dm # code/modules/client/preferences.dm # code/modules/client/verbs/ooc.dm # code/modules/clothing/head/wig.dm # code/modules/events/disease_outbreak.dm # code/modules/holodeck/holo_effect.dm # code/modules/jobs/job_types/head_of_security.dm # code/modules/jobs/job_types/security_officer.dm # code/modules/library/skill_learning/generic_skillchips/point.dm # code/modules/mining/lavaland/ash_flora.dm # code/modules/mining/lavaland/mining_loot/megafauna/ash_drake.dm # code/modules/mob/dead/new_player/new_player.dm # code/modules/mob/living/basic/guardian/guardian.dm # code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm # code/modules/mob/living/carbon/carbon.dm # code/modules/mob/living/carbon/human/human.dm # code/modules/mob/living/carbon/human/human_defines.dm # code/modules/mob/living/carbon/life.dm # code/modules/mob/living/living.dm # code/modules/mob/living/living_defines.dm # code/modules/mob/mob.dm # code/modules/mob_spawn/ghost_roles/mining_roles.dm # code/modules/mod/mod_control.dm # code/modules/mod/modules/modules_general.dm # code/modules/modular_computers/computers/item/computer_ui.dm # code/modules/paperwork/paper.dm # code/modules/paperwork/paperbin.dm # code/modules/power/lighting/light.dm # code/modules/projectiles/guns/energy/kinetic_accelerator.dm # code/modules/projectiles/projectile.dm # code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm # code/modules/reagents/chemistry/reagents/food_reagents.dm # code/modules/reagents/chemistry/reagents/other_reagents.dm # code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm # code/modules/research/xenobiology/crossbreeding/_clothing.dm # code/modules/research/xenobiology/crossbreeding/prismatic.dm # code/modules/surgery/advanced/brainwashing.dm # code/modules/surgery/advanced/lobotomy.dm # code/modules/surgery/amputation.dm # code/modules/surgery/blood_filter.dm # code/modules/surgery/bodyparts/_bodyparts.dm # code/modules/surgery/brain_surgery.dm # code/modules/surgery/cavity_implant.dm # code/modules/surgery/coronary_bypass.dm # code/modules/surgery/gastrectomy.dm # code/modules/surgery/healing.dm # code/modules/surgery/limb_augmentation.dm # code/modules/surgery/organ_manipulation.dm # code/modules/surgery/revival.dm # code/modules/surgery/sleeper_protocol.dm # code/modules/surgery/surgery_helpers.dm # code/modules/surgery/surgery_step.dm # code/modules/unit_tests/_unit_tests.dm # code/modules/unit_tests/designs.dm # code/modules/unit_tests/icon_state_worn.dm # code/modules/unit_tests/screenshots/screenshot_antag_icons_cultist.png # code/modules/unit_tests/screenshots/screenshot_antag_icons_headrevolutionary.png # code/modules/unit_tests/screenshots/screenshot_antag_icons_provocateur.png # code/modules/unit_tests/screenshots/screenshot_husk_body.png # code/modules/unit_tests/screenshots/screenshot_husk_body_missing_limbs.png # icons/map_icons/clothing/head/_head.dmi # icons/map_icons/clothing/shoes.dmi # icons/map_icons/items/_item.dmi # icons/mob/huds/hud.dmi # icons/mob/inhands/64x64_lefthand.dmi # icons/mob/inhands/64x64_righthand.dmi # icons/obj/machines/computer.dmi # tgui/packages/tgui/interfaces/OperatingComputer.jsx # tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferences/MainPage.tsx # tgui/packages/tgui/interfaces/PreferencesMenu/types.ts # tgui/packages/tgui/interfaces/SurgeryInitiator.tsx # tools/icon_cutter/check.py
229 lines
8.7 KiB
Plaintext
229 lines
8.7 KiB
Plaintext
/// The chance for a manifest or crate to be created with errors
|
|
#define MANIFEST_ERROR_CHANCE 5
|
|
|
|
// MANIFEST BITFLAGS
|
|
/// Determines if the station name will be incorrect on the manifest
|
|
#define MANIFEST_ERROR_NAME (1 << 0)
|
|
/// Determines if contents will be deleted from the manifest but still be present in the crate
|
|
#define MANIFEST_ERROR_CONTENTS (1 << 1)
|
|
/// Determines if contents will be deleted from the crate but still be present in the manifest
|
|
#define MANIFEST_ERROR_ITEM (1 << 2)
|
|
|
|
/obj/item/paper/fluff/jobs/cargo/manifest
|
|
can_become_message_in_bottle = FALSE //A lot of these are spawned each round, they'd only dilute the pool and make it boring.
|
|
var/order_cost = 0
|
|
var/order_id = 0
|
|
var/errors = 0
|
|
|
|
/obj/item/paper/requisition
|
|
can_become_message_in_bottle = FALSE //A lot of these are spawned each round, they'd only dilute the pool and make it boring.
|
|
|
|
|
|
/obj/item/paper/fluff/jobs/cargo/manifest/Initialize(mapload, id, cost, manifest_can_fail = TRUE)
|
|
. = ..()
|
|
order_id = id
|
|
order_cost = cost
|
|
if(!manifest_can_fail)
|
|
return
|
|
|
|
if(prob(MANIFEST_ERROR_CHANCE) && (world.time-SSticker.round_start_time > STATION_RENAME_TIME_LIMIT)) //Too confusing if station name gets changed
|
|
errors |= MANIFEST_ERROR_NAME
|
|
investigate_log("Supply order #[order_id] generated a manifest with an incorrect station name.", INVESTIGATE_CARGO)
|
|
if(prob(MANIFEST_ERROR_CHANCE))
|
|
errors |= MANIFEST_ERROR_CONTENTS
|
|
investigate_log("Supply order #[order_id] generated a manifest missing listed contents.", INVESTIGATE_CARGO)
|
|
else if(prob(MANIFEST_ERROR_CHANCE)) //Content and item errors could remove the same items, so only one at a time
|
|
errors |= MANIFEST_ERROR_ITEM
|
|
investigate_log("Supply order #[order_id] generated with incorrect contents shipped.", INVESTIGATE_CARGO)
|
|
|
|
/obj/item/paper/fluff/jobs/cargo/manifest/proc/is_approved()
|
|
return LAZYLEN(stamp_cache) && !is_denied()
|
|
|
|
/obj/item/paper/fluff/jobs/cargo/manifest/proc/is_denied()
|
|
return LAZYLEN(stamp_cache) && ("stamp-deny" in stamp_cache)
|
|
|
|
/datum/supply_order
|
|
var/id
|
|
var/cost_type
|
|
var/orderer
|
|
var/orderer_rank
|
|
var/orderer_ckey
|
|
var/reason
|
|
var/discounted_pct
|
|
///If set to FALSE, we won't charge when the cargo shuttle arrives with this.
|
|
var/charge_on_purchase = TRUE
|
|
///area this order wants to reach, if not null then it will come with the deliver_first component set to this area
|
|
var/department_destination
|
|
var/datum/supply_pack/pack
|
|
var/datum/bank_account/paying_account
|
|
var/obj/item/coupon/applied_coupon
|
|
///Boolean on whether the manifest can fail or not.
|
|
var/manifest_can_fail = TRUE
|
|
///Boolean on whether the manifest can be cancelled through cargo consoles.
|
|
var/can_be_cancelled = TRUE
|
|
|
|
/datum/supply_order/New(
|
|
datum/supply_pack/pack,
|
|
orderer,
|
|
orderer_rank,
|
|
orderer_ckey,
|
|
reason,
|
|
paying_account,
|
|
department_destination,
|
|
coupon,
|
|
charge_on_purchase = TRUE,
|
|
manifest_can_fail = TRUE,
|
|
cost_type = MONEY_SYMBOL,
|
|
can_be_cancelled = TRUE,
|
|
)
|
|
id = SSshuttle.order_number++
|
|
src.cost_type = cost_type
|
|
src.pack = pack
|
|
src.orderer = orderer
|
|
src.orderer_rank = orderer_rank
|
|
src.orderer_ckey = orderer_ckey
|
|
src.reason = reason
|
|
src.paying_account = paying_account
|
|
src.department_destination = department_destination
|
|
src.applied_coupon = coupon
|
|
src.charge_on_purchase = charge_on_purchase
|
|
src.manifest_can_fail = manifest_can_fail
|
|
src.can_be_cancelled = can_be_cancelled
|
|
|
|
/datum/supply_order/Destroy(force)
|
|
QDEL_NULL(applied_coupon)
|
|
return ..()
|
|
|
|
//returns the total cost of this order. Its not the total price paid by cargo but the total value of this order
|
|
/datum/supply_order/proc/get_final_cost()
|
|
var/cost = pack.get_cost()
|
|
if(applied_coupon) //apply discount price
|
|
cost *= (1 - applied_coupon.discount_pct_off)
|
|
if(paying_account?.add_to_accounts && !(pack.order_flags & ORDER_GOODY)) //privately purchased and not a goody means 1.1x the cost
|
|
cost *= 1.1
|
|
return round(cost)
|
|
|
|
/datum/supply_order/proc/generateRequisition(turf/T)
|
|
var/obj/item/paper/requisition/requisition_paper = new(T)
|
|
|
|
requisition_paper.name = "requisition form - #[id] ([pack.name])"
|
|
var/requisition_text = "<h2>[station_name()] Supply Requisition</h2>"
|
|
requisition_text += "<hr/>"
|
|
requisition_text += "Order #[id]<br/>"
|
|
requisition_text+= "Time of Order: [station_time_timestamp()]<br/>"
|
|
requisition_text += "Item: [pack.name]<br/>"
|
|
requisition_text += "Access Restrictions: [SSid_access.get_access_desc(pack.access)]<br/>"
|
|
requisition_text += "Requested by: [orderer]<br/>"
|
|
if(paying_account)
|
|
requisition_text += "Paid by: [paying_account.account_holder]<br/>"
|
|
requisition_text += "Rank: [orderer_rank]<br/>"
|
|
requisition_text += "Comment: [reason]<br/>"
|
|
|
|
requisition_paper.add_raw_text(requisition_text)
|
|
requisition_paper.update_appearance()
|
|
return requisition_paper
|
|
|
|
/datum/supply_order/proc/generateManifest(obj/container, owner, packname, cost) //generates-the-manifests.
|
|
var/obj/item/paper/fluff/jobs/cargo/manifest/manifest_paper = new(null, id, cost, manifest_can_fail)
|
|
|
|
var/station_name = (manifest_paper.errors & MANIFEST_ERROR_NAME) ? new_station_name() : station_name()
|
|
|
|
manifest_paper.name = "shipping manifest - [packname?"#[id] ([pack.name])":"(Grouped Item Crate)"]"
|
|
|
|
var/manifest_text = "<h2>[command_name()] Shipping Manifest</h2>"
|
|
manifest_text += "<hr/>"
|
|
if(owner && !(owner == "Cargo"))
|
|
manifest_text += "Direct purchase from [owner]<br/>"
|
|
manifest_paper.name += " - Purchased by [owner]"
|
|
manifest_text += "Order[packname?"":"s"]: [id]<br/>"
|
|
manifest_text += "Destination: [station_name]<br/>"
|
|
if(packname)
|
|
manifest_text += "Item: [packname]<br/>"
|
|
manifest_text += "Contents: <br/>"
|
|
manifest_text += "<ul>"
|
|
var/container_contents = list() // Associative list with the format (item_name = nº of occurrences, ...)
|
|
for(var/atom/movable/stuff as anything in container.contents - manifest_paper)
|
|
if(isstack(stuff))
|
|
var/obj/item/stack/thing = stuff
|
|
container_contents[thing.singular_name] += thing.amount
|
|
continue
|
|
container_contents[stuff.name]++
|
|
if((manifest_paper.errors & MANIFEST_ERROR_CONTENTS) && container_contents)
|
|
if(HAS_TRAIT(container, TRAIT_NO_MANIFEST_CONTENTS_ERROR))
|
|
manifest_paper.errors &= ~MANIFEST_ERROR_CONTENTS
|
|
else
|
|
for(var/iteration in 1 to rand(1, round(container.contents.len * 0.5))) // Remove anywhere from one to half of the items
|
|
var/missing_item = pick(container_contents)
|
|
container_contents[missing_item]--
|
|
if(!container_contents[missing_item]) // To avoid 0s and negative values on the manifest
|
|
container_contents -= missing_item
|
|
|
|
for(var/item in container_contents)
|
|
manifest_text += "<li> [container_contents[item]] [item][container_contents[item] == 1 ? "" : plural_s(item)]</li>"
|
|
manifest_text += "</ul>"
|
|
manifest_text += "<h4>Stamp below to confirm receipt of goods:</h4>"
|
|
|
|
manifest_paper.add_raw_text(manifest_text)
|
|
|
|
if(manifest_paper.errors & MANIFEST_ERROR_ITEM)
|
|
if(HAS_TRAIT(container, TRAIT_NO_MISSING_ITEM_ERROR))
|
|
manifest_paper.errors &= ~MANIFEST_ERROR_ITEM
|
|
else
|
|
var/lost = max(round(container.contents.len / 10), 1)
|
|
while(--lost >= 0)
|
|
qdel(pick(container.contents))
|
|
|
|
manifest_paper.update_appearance()
|
|
manifest_paper.forceMove(container)
|
|
|
|
if(istype(container, /obj/structure/closet/crate))
|
|
var/obj/structure/closet/crate/crate = container
|
|
crate.manifest = WEAKREF(manifest_paper)
|
|
crate.update_appearance()
|
|
|
|
return manifest_paper
|
|
|
|
/datum/supply_order/proc/generate(atom/A)
|
|
var/account_holder
|
|
if(paying_account)
|
|
account_holder = paying_account.account_holder
|
|
else
|
|
account_holder = "Cargo"
|
|
var/obj/structure/closet/crate/crate = pack.generate(A, paying_account)
|
|
if(pack.order_flags & ORDER_CONTRABAND)
|
|
for(var/atom/movable/item_within as anything in crate.get_all_contents())
|
|
ADD_TRAIT(item_within, TRAIT_CONTRABAND, INNATE_TRAIT)
|
|
if(department_destination)
|
|
crate.AddElement(/datum/element/deliver_first, department_destination, pack.cost)
|
|
generateManifest(crate, account_holder, pack, pack.cost)
|
|
return crate
|
|
|
|
/datum/supply_order/proc/generateCombo(miscbox, misc_own, misc_contents, misc_cost)
|
|
for (var/I in misc_contents)
|
|
new I(miscbox)
|
|
generateManifest(miscbox, misc_own, "", misc_cost)
|
|
return
|
|
|
|
/datum/supply_order/proc/append_order(list/new_contents, cost_increase)
|
|
for(var/i in new_contents)
|
|
if(pack.contains[i])
|
|
pack.contains[i] += new_contents[i]
|
|
else
|
|
pack.contains += i
|
|
pack.contains[i] = new_contents[i]
|
|
pack.cost += cost_increase
|
|
|
|
/// Custom type of order who's supply pack can be safely deleted
|
|
/datum/supply_order/disposable/Destroy(force)
|
|
QDEL_NULL(pack)
|
|
return ..()
|
|
|
|
/// Custom material order to append cargo crate value to the final order cost
|
|
/datum/supply_order/disposable/materials/get_final_cost()
|
|
return (..() + CARGO_CRATE_VALUE)
|
|
|
|
#undef MANIFEST_ERROR_CHANCE
|
|
#undef MANIFEST_ERROR_NAME
|
|
#undef MANIFEST_ERROR_CONTENTS
|
|
#undef MANIFEST_ERROR_ITEM
|