diff --git a/code/controllers/subsystem/SSshuttles.dm b/code/controllers/subsystem/SSshuttles.dm index df6ce8e3943..39085c985f4 100644 --- a/code/controllers/subsystem/SSshuttles.dm +++ b/code/controllers/subsystem/SSshuttles.dm @@ -37,6 +37,8 @@ SUBSYSTEM_DEF(shuttle) var/obj/docking_port/mobile/supply/supply /// Supply shuttle turfs to make mail be put down faster var/static/list/supply_shuttle_turfs = list() + /// The current shuttle loan event, if any. + var/shuttle_loan_UID var/list/hidden_shuttle_turfs = list() //all turfs hidden from navigation computers associated with a list containing the image hiding them and the type of the turf they are pretending to be var/list/hidden_shuttle_turf_images = list() //only the images from the above list diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index a32cb09a5b4..787239990c2 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -308,6 +308,24 @@ . = ..() wires.cut_all() +/obj/machinery/syndicatebomb/shuttle_loan + +/obj/machinery/syndicatebomb/shuttle_loan/Initialize(mapload) + . = ..() + anchored = TRUE + timer_set = rand(180, 300) // once the supply shuttle docks (after 5 minutes travel time), players have between 3-5 minutes to defuse the bomb. Units are in seconds. + activate() + update_appearance() + +/obj/machinery/syndicatebomb/badmin/clown/shuttle_loan + payload = /obj/item/bombcore/badmin/summon/clown/lesser + +/obj/machinery/syndicatebomb/badmin/clown/shuttle_loan/Initialize(mapload) + . = ..() + anchored = TRUE + timer_set = rand(180, 300) // once the supply shuttle docks (after 5 minutes travel time), players have between 3-5 minutes to defuse the bomb. Units are in seconds. + activate() + update_appearance() ///Bomb Cores/// @@ -422,6 +440,9 @@ playsound(src.loc, 'sound/misc/sadtrombone.ogg', 50) ..() +/obj/item/bombcore/badmin/summon/clown/lesser + amt_summon = 10 + /obj/item/bombcore/explosive_wall admin_log = FALSE diff --git a/code/modules/awaymissions/mob_spawn.dm b/code/modules/awaymissions/mob_spawn.dm index 037ea75d3be..8e4602e6bae 100644 --- a/code/modules/awaymissions/mob_spawn.dm +++ b/code/modules/awaymissions/mob_spawn.dm @@ -620,6 +620,13 @@ id_job = "Medical Doctor" outfit = /datum/outfit/job/doctor +// Cargo tech corpse +/obj/effect/mob_spawn/human/corpse/random_species/cargo_tech + name = "Cargo Technician" + mob_name = "Cargo Technician" + id_job = "Cargo Technician" + outfit = /datum/outfit/job/cargo_tech + //Engineer corpse. /obj/effect/mob_spawn/human/corpse/engineer name = "Engineer" diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index 77f3d917dd8..b4cd5163c11 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -8,6 +8,7 @@ #define ASSIGNMENT_SCIENTIST "Scientist" #define ASSIGNMENT_SECURITY "Security" #define ASSIGNMENT_CHEMIST "Chemist" +#define ASSIGNMENT_CARGO "Cargo Bay" GLOBAL_LIST_INIT(severity_to_string, list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT_LEVEL_MODERATE = "Moderate", EVENT_LEVEL_MAJOR = "Major")) GLOBAL_LIST_EMPTY(event_last_fired) @@ -190,7 +191,8 @@ GLOBAL_LIST_EMPTY(event_last_fired) new /datum/event_meta(EVENT_LEVEL_MODERATE, "Morph Spawn", /datum/event/spawn_morph, 40, list(ASSIGNMENT_SECURITY = 10), is_one_shot = TRUE), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Disease Outbreak", /datum/event/disease_outbreak, 50, list(ASSIGNMENT_MEDICAL = 30), TRUE), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Door Runtime", /datum/event/door_runtime, 50, list(ASSIGNMENT_ENGINEER = 25, ASSIGNMENT_AI = 150), TRUE), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Tourist Arrivals", /datum/event/tourist_arrivals, 100, list(ASSIGNMENT_SECURITY = 15), TRUE) + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Tourist Arrivals", /datum/event/tourist_arrivals, 100, list(ASSIGNMENT_SECURITY = 15), TRUE), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Shuttle Loan", /datum/event/shuttle_loan, 100, list(ASSIGNMENT_CARGO = 15, ASSIGNMENT_SECURITY = 10), is_one_shot = TRUE) ) /datum/event_container/major @@ -226,3 +228,4 @@ GLOBAL_LIST_EMPTY(event_last_fired) #undef ASSIGNMENT_SCIENTIST #undef ASSIGNMENT_SECURITY #undef ASSIGNMENT_CHEMIST +#undef ASSIGNMENT_CARGO diff --git a/code/modules/events/shuttle_loan/shuttle_loan_datum.dm b/code/modules/events/shuttle_loan/shuttle_loan_datum.dm new file mode 100644 index 00000000000..d14f107bc69 --- /dev/null +++ b/code/modules/events/shuttle_loan/shuttle_loan_datum.dm @@ -0,0 +1,202 @@ +/// One of the potential shuttle loans you might receive. +/datum/shuttle_loan_situation + /// Who sent the shuttle + var/sender = "Central Command" + /// What they said about it. + var/announcement_text = "Unset announcement text" + /// Supply points earned for taking the deal. + var/bonus_points = 1000 + /// Small description of the loan for easier log reading. + var/logging_desc + +/datum/shuttle_loan_situation/New() + . = ..() + if(!logging_desc) + stack_trace("No logging blurb set for [src.type]!") + +/// Spawns paths added to `spawn_list`, and passes empty shuttle turfs so you can spawn more complicated things like dead bodies. +/datum/shuttle_loan_situation/proc/spawn_items(list/spawn_list, list/empty_shuttle_turfs) + SHOULD_CALL_PARENT(FALSE) + CRASH("Unimplemented get_spawned_items() on [src.type].") + +/datum/shuttle_loan_situation/department_resupply + sender = "Central Command Supply Department" + announcement_text = "Seems we've ordered doubles of our department resupply packages this month. We'll be sending them to you." + bonus_points = 0 + logging_desc = "Resupply packages" + +/datum/shuttle_loan_situation/department_resupply/spawn_items(list/spawn_list, list/empty_shuttle_turfs) + var/static/list/crate_types = list( + /datum/supply_packs/emergency/evac, + /datum/supply_packs/security/supplies, + /datum/supply_packs/organic/food, + /datum/supply_packs/emergency/weedcontrol, + /datum/supply_packs/engineering/tools, + /datum/supply_packs/engineering/engiequipment, + /datum/supply_packs/science/robotics, + /datum/supply_packs/science/plasma, + /datum/supply_packs/medical/supplies + ) + for(var/datum/supply_packs/crate in crate_types) + var/datum/supply_packs/new_crate = new crate() + new_crate.create_package(pick_n_take(empty_shuttle_turfs)) + + for(var/i in 1 to 5) + var/decal = pick(/obj/effect/decal/cleanable/flour, /obj/effect/decal/cleanable/blood/gibs/robot, /obj/effect/decal/cleanable/blood/oil) + new decal(pick_n_take(empty_shuttle_turfs)) + +/datum/shuttle_loan_situation/syndiehijacking + sender = "Central Command Counter-Intelligence" + announcement_text = "The syndicate are trying to infiltrate your station. We let them hijack your cargo shuttle; you're saving us a headache." + logging_desc = "Syndicate boarding party" + +/datum/shuttle_loan_situation/syndiehijacking/spawn_items(list/spawn_list, list/empty_shuttle_turfs) + spawn_list.Add(/mob/living/simple_animal/hostile/syndicate) + spawn_list.Add(/mob/living/simple_animal/hostile/syndicate/ranged) + if(prob(75)) + spawn_list.Add(/mob/living/simple_animal/hostile/syndicate/modsuit) + if(prob(50)) + spawn_list.Add(/mob/living/simple_animal/hostile/syndicate/modsuit/ranged) + +/datum/shuttle_loan_situation/lots_of_bees + sender = "Central Command Janitorial Division" + announcement_text = "One of our freighters carrying a bee shipment has been attacked by eco-terrorists. Clean up this mess." + bonus_points = 800 // Toxin bees can be unbeelievably lethal + logging_desc = "Shuttle full of bees" + +/datum/shuttle_loan_situation/lots_of_bees/spawn_items(list/spawn_list, list/empty_shuttle_turfs) + spawn_list.Add(/obj/effect/mob_spawn/human/corpse/syndicate) + spawn_list.Add(/obj/effect/mob_spawn/human/corpse/random_species/cargo_tech) + spawn_list.Add(/obj/effect/mob_spawn/human/corpse/random_species/cargo_tech) + spawn_list.Add(/obj/effect/mob_spawn/human/corpse/random_species/security_officer) + spawn_list.Add(/obj/item/honey_frame) + spawn_list.Add(/obj/item/honey_frame) + spawn_list.Add(/obj/item/honey_frame) + spawn_list.Add(/obj/structure/beebox/unwrenched) + spawn_list.Add(/obj/item/queen_bee/bought) + spawn_list.Add(/obj/structure/closet/crate/hydroponics) + var/datum/supply_packs/organic/hydroponics/beekeeping_fullkit/new_crate = new() + new_crate.create_package(pick_n_take(empty_shuttle_turfs)) + + for(var/i in 1 to 8) + // A large influx of bees, directly into the cargo workplace + spawn_list.Add(/mob/living/simple_animal/hostile/poison/bees) + + for(var/i in 1 to 5) + var/decal = pick(/obj/effect/decal/cleanable/blood, /obj/effect/decal/cleanable/insectguts) + new decal(pick_n_take(empty_shuttle_turfs)) + + for(var/i in 1 to 10) + var/casing = /obj/item/trash/spentcasing/bullet + new casing(pick_n_take(empty_shuttle_turfs)) + +/datum/shuttle_loan_situation/jc_a_bomb + sender = "Central Command Security Division" + announcement_text = "We have discovered an active Syndicate bomb near our VIP shuttle's fuel lines. We're paying you to defuse it." + bonus_points = 3000 // If you mess up, people die and the shuttle gets turned into swiss cheese + logging_desc = "Shuttle with a ticking bomb" + +/datum/shuttle_loan_situation/jc_a_bomb/spawn_items(list/spawn_list, list/empty_shuttle_turfs) + spawn_list.Add(/obj/machinery/syndicatebomb/shuttle_loan) + spawn_list.Add(/obj/item/paper/fluff/cargo/bomb) + +/obj/item/paper/fluff/cargo/bomb + name = "hastly scribbled note" + info = "GOOD LUCK!" + +/datum/shuttle_loan_situation/pizza_delivery + sender = "Central Command Spacepizza Division" + announcement_text = "It looks like a neighboring station accidentally delivered their pizza to you instead." + bonus_points = 0 + logging_desc = "Pizza delivery" + +/datum/shuttle_loan_situation/pizza_delivery/spawn_items(list/spawn_list, list/empty_shuttle_turfs) + var/static/list/naughtypizza = list(/obj/item/pizzabox/pizza_bomb/autoarm) + var/static/list/nicepizza = list(/obj/item/pizzabox/margherita, /obj/item/pizzabox/meat, /obj/item/pizzabox/vegetable, /obj/item/pizzabox/mushroom) + for(var/i in 1 to 6) + spawn_list.Add(pick(prob(5) ? naughtypizza : nicepizza)) + +/datum/shuttle_loan_situation/russian_party + sender = "Central Command Soviet Outreach Program" + announcement_text = "A group of angry Soviets want to have a party. We rented them your cargo shuttle as a venue." + logging_desc = "Russian party squad" + +/datum/shuttle_loan_situation/russian_party/spawn_items(list/spawn_list, list/empty_shuttle_turfs) + var/datum/supply_packs/organic/party/party_crate = new() + party_crate.create_package(pick_n_take(empty_shuttle_turfs)) + spawn_list.Add(/datum/supply_packs/organic/party) + spawn_list.Add(/mob/living/basic/soviet) + spawn_list.Add(/mob/living/basic/soviet/ranged/mosin) + spawn_list.Add(/mob/living/basic/bear) + if(prob(75)) + spawn_list.Add(/mob/living/basic/soviet) + if(prob(50)) + spawn_list.Add(/mob/living/basic/bear) + +/datum/shuttle_loan_situation/spider_gift + sender = "Central Command Diplomatic Corps" + announcement_text = "The Spider Clan has sent us a mysterious gift. We shipped it to you to see what's inside." + logging_desc = "Shuttle full of spiders" + +/datum/shuttle_loan_situation/spider_gift/spawn_items(list/spawn_list, list/empty_shuttle_turfs) + spawn_list.Add(/mob/living/basic/giant_spider) + spawn_list.Add(/mob/living/basic/giant_spider) + spawn_list.Add(/mob/living/basic/giant_spider/nurse) + if(prob(50)) + spawn_list.Add(/mob/living/basic/giant_spider/hunter) + + var/turf/victim_turf = pick_n_take(empty_shuttle_turfs) + + new /obj/effect/decal/remains/human(victim_turf) + new /obj/item/clothing/shoes/jackboots/noisy(victim_turf) + new /obj/item/clothing/mask/balaclava(victim_turf) + + for(var/i in 1 to 5) + var/turf/web_turf = pick_n_take(empty_shuttle_turfs) + new /obj/structure/spider/stickyweb(web_turf) + +/datum/shuttle_loan_situation/mineral_haul + sender = "Central Command Supply Department" + announcement_text = "Another station's mining division has struck a mineral motherlode. We'll be sending your station some of the haul." + bonus_points = 0 + logging_desc = "Mineral haul" + +/datum/shuttle_loan_situation/mineral_haul/spawn_items(list/spawn_list, list/empty_shuttle_turfs) + var/static/list/crate_types = list( + /datum/supply_packs/materials/metal50, + /datum/supply_packs/materials/glass50, + /datum/supply_packs/materials/sandstone30, + ) + for(var/datum/supply_packs/crate in crate_types) + var/datum/supply_packs/new_crate = new crate() + new_crate.create_package(pick_n_take(empty_shuttle_turfs)) + + var/static/list/mineral_types = list( + /obj/item/stack/sheet/mineral/diamond, + /obj/item/stack/sheet/mineral/uranium, + /obj/item/stack/sheet/mineral/plasma, + /obj/item/stack/sheet/mineral/gold, + /obj/item/stack/sheet/mineral/bananium, + /obj/item/stack/sheet/mineral/tranquillite, + /obj/item/stack/sheet/mineral/platinum, + /obj/item/stack/sheet/mineral/palladium, + /obj/item/stack/sheet/mineral/iridium, + /obj/item/stack/sheet/mineral/silver + ) + for(var/i in 1 to 5) + var/mineral_type = pick(mineral_types) + var/obj/item/stack/sheet/mineral/new_mineral = new mineral_type() + new_mineral.amount = 10 + new new_mineral(pick_n_take(empty_shuttle_turfs)) + +/datum/shuttle_loan_situation/honk + sender = "Central Command Entertainment Division" + announcement_text = "A surplus of clowns were sent to us from the Clown College. You should be able to find some use of them." + bonus_points = 500 // If you mess up, people die and the shuttle gets turned into swiss cheese + logging_desc = "Shuttle with clowns" + +/datum/shuttle_loan_situation/honk/spawn_items(list/spawn_list, list/empty_shuttle_turfs) + spawn_list.Add(/obj/machinery/syndicatebomb/badmin/clown/shuttle_loan) + spawn_list.Add(/obj/item/paper/fluff/cargo/bomb) + for(var/i in 1 to 4) + spawn_list.Add(/mob/living/basic/clown) diff --git a/code/modules/events/shuttle_loan/shuttle_loan_event.dm b/code/modules/events/shuttle_loan/shuttle_loan_event.dm new file mode 100644 index 00000000000..74a36821984 --- /dev/null +++ b/code/modules/events/shuttle_loan/shuttle_loan_event.dm @@ -0,0 +1,60 @@ +/datum/event/shuttle_loan + name = "Shuttle Loan" + announceWhen = 1 + endWhen = 500 + /// what type of shuttle loan situation the station faces. + var/datum/shuttle_loan_situation/situation + /// Whether the station has let Centcom commandeer the shuttle yet. + var/dispatched = FALSE + /// How many times can it try to take the shuttle before it gives up and rerolls? + var/dispatch_attempts = 3 + +/datum/event/shuttle_loan/setup() + var/situation_type = pick(subtypesof(/datum/shuttle_loan_situation)) + situation = new situation_type + if(!SSshuttle.supply.canMove()) + log_debug("Shuttle loan event fired while shuttle cannot move. Reattempting in 30s.") + if(dispatch_attempts) + dispatch_attempts-- + addtimer(CALLBACK(src, PROC_REF(setup)), 30 SECONDS) + return + // Failed to run, reroll a new moderate in 60 seconds + var/datum/event_container/EC = SSevents.event_containers[EVENT_LEVEL_MODERATE] + EC.next_event_time = world.time + (60 SECONDS) + endWhen = activeFor + return + if(SSshuttle.supply.getDockedId() == "supply_home") + SSshuttle.supply.dock(SSshuttle.getDock("supply_away")) + addtimer(CALLBACK(src, PROC_REF(loan_shuttle)), 5 SECONDS) // Needed to prevent a runtime in SSshuttle + +/datum/event/shuttle_loan/fake_announce() + . = TRUE + situation = pick(subtypesof(/datum/shuttle_loan_situation)) + GLOB.minor_announcement.Announce("Cargo: [situation.announcement_text]", situation.sender) + +/datum/event/shuttle_loan/proc/loan_shuttle() + SSshuttle.shuttle_loan_UID = UID() + SSblackbox.record_feedback("tally", "Shuttle Loan Event Type", 1, situation.type) + GLOB.minor_announcement.Announce("Cargo: [situation.announcement_text]", situation.sender) + log_debug("Shuttle loan event firing with type '[situation.logging_desc]'.") + + dispatched = TRUE + GLOB.station_money_database.credit_account(SSeconomy.cargo_account, situation.bonus_points, "Central Command Cargo Shuttle Reimbursement", "Central Command Supply Master", supress_log = FALSE) + SSshuttle.supply.request(SSshuttle.getDock("supply_home")) + SSshuttle.supply.setTimer(5 MINUTES) + SSshuttle.supply.mode = SHUTTLE_CALL + endWhen = activeFor + 1 + +/datum/event/shuttle_loan/tick() + if(dispatched) + if(SSshuttle.supply.mode != SHUTTLE_IDLE) + endWhen = activeFor + else + endWhen = activeFor + 1 + +/datum/event/shuttle_loan/end() + if(!SSshuttle.shuttle_loan_UID) + return + var/datum/event/shuttle_loan/shuttle_loan = locateUID(SSshuttle.shuttle_loan_UID) + if(!shuttle_loan.dispatched) + return diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index 680aaec4acd..51b6b225183 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -41,7 +41,9 @@ /obj/machinery/the_singularitygen, /obj/effect/hierophant, /obj/item/warp_cube), - "undelivered mail" = list(/obj/item/envelope)) + "undelivered mail" = list(/obj/item/envelope), + "live ordnance" = list(/obj/machinery/syndicatebomb) + ) // The current manifest of what's on the shuttle. var/datum/economy/cargo_shuttle_manifest/manifest = new @@ -146,6 +148,23 @@ PC.update_icon() SG.should_send_crate = FALSE + if(SSshuttle.shuttle_loan_UID) + var/datum/event/shuttle_loan/shuttle_loan = locateUID(SSshuttle.shuttle_loan_UID) + if(!shuttle_loan.dispatched) + return + // let the situation spawn its items + var/list/spawn_list = list() + shuttle_loan.situation.spawn_items(spawn_list, emptyTurfs) + var/false_positive = 0 + while(spawn_list.len && emptyTurfs.len) + var/turf/spawn_turf = pick_n_take(emptyTurfs) + if(spawn_turf.contents.len && false_positive < 5) + false_positive++ + continue + var/spawn_type = pick_n_take(spawn_list) + new spawn_type(spawn_turf) + // Clear the event so it doesn't cause a problem again + SSshuttle.shuttle_loan_UID = null /obj/docking_port/mobile/supply/proc/scan_cargo() manifest = new diff --git a/paradise.dme b/paradise.dme index 58945e4edb3..7588e5f8317 100644 --- a/paradise.dme +++ b/paradise.dme @@ -2132,6 +2132,8 @@ #include "code\modules\events\blob\blob_structures\resource.dm" #include "code\modules\events\blob\blob_structures\storage_blob.dm" #include "code\modules\events\blob\blob_structures\strong_blob.dm" +#include "code\modules\events\shuttle_loan\shuttle_loan_datum.dm" +#include "code\modules\events\shuttle_loan\shuttle_loan_event.dm" #include "code\modules\events\wizard\ghost_wizard_spells.dm" #include "code\modules\fish\fish_eggs.dm" #include "code\modules\fish\fish_items.dm"