diff --git a/code/__HELPERS/hallucinations.dm b/code/__HELPERS/hallucinations.dm
index 412a35935ce..809ff475fc9 100644
--- a/code/__HELPERS/hallucinations.dm
+++ b/code/__HELPERS/hallucinations.dm
@@ -1,6 +1,14 @@
/// A global list of all ongoing hallucinations, primarily for easy access to be able to stop (delete) hallucinations.
GLOBAL_LIST_EMPTY(all_ongoing_hallucinations)
+/// What typepath of the hallucination
+#define HALLUCINATION_ARG_TYPE 1
+/// Where the hallucination came from, for logging
+#define HALLUCINATION_ARG_SOURCE 2
+
+/// Onwards from this index, it's the arglist that gets passed into the hallucination created.
+#define HALLUCINATION_ARGLIST 3
+
/// Biotypes which cannot hallucinate for balance and logic reasons (not code)
#define NO_HALLUCINATION_BIOTYPES (MOB_ROBOTIC|MOB_SPIRIT|MOB_EPIC)
@@ -20,16 +28,16 @@ GLOBAL_LIST_EMPTY(all_ongoing_hallucinations)
if(!length(raw_args))
CRASH("cause_hallucination called with no arguments.")
- var/datum/hallucination/hallucination_type = raw_args[1] // first arg is the type always
+ var/datum/hallucination/hallucination_type = raw_args[HALLUCINATION_ARG_TYPE] // first arg is the type always
if(!ispath(hallucination_type))
CRASH("cause_hallucination was given a non-hallucination type.")
- var/hallucination_source = raw_args[2] // and second arg, the source
+ var/hallucination_source = raw_args[HALLUCINATION_ARG_SOURCE] // and second arg, the source
var/datum/hallucination/new_hallucination
- if(length(raw_args) > 2)
- var/list/passed_args = raw_args.Copy(3)
- passed_args.Insert(1, src)
+ if(length(raw_args) >= HALLUCINATION_ARGLIST)
+ var/list/passed_args = raw_args.Copy(HALLUCINATION_ARGLIST)
+ passed_args.Insert(HALLUCINATION_ARG_TYPE, src)
new_hallucination = new hallucination_type(arglist(passed_args))
else
diff --git a/code/modules/admin/force_event.dm b/code/modules/admin/force_event.dm
index 4e4338d019c..d0d332b7d6c 100644
--- a/code/modules/admin/force_event.dm
+++ b/code/modules/admin/force_event.dm
@@ -88,7 +88,7 @@
var/datum/round_event_control/event = locate(event_to_run_type) in SSevents.control
if(!event)
return
- if(event.admin_setup(usr) == ADMIN_CANCEL_EVENT)
+ if(event.admin_setup && event.admin_setup.prompt_admins() == ADMIN_CANCEL_EVENT)
return
var/always_announce_chance = 100
var/no_announce_chance = 0
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index c5a77df1b46..6c8fcbba9ca 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -83,31 +83,6 @@
else message_admins("[key_name_admin(usr)] FAILED to create '[href_list["makeAntag"]]' with a parameter of '[opt]'.")
// SKYRAT EDIT END -- ONE CLICK ANTAG
- else if(href_list["forceevent"])
- if(!check_rights(R_FUN))
- return
- var/datum/round_event_control/E = locate(href_list["forceevent"]) in SSevents.control
- if(E)
- E.admin_setup(usr)
- var/datum/round_event/event = E.runEvent()
- if(event.cancel_event)
- return
- if(event.announce_when>0)
- event.processing = FALSE
- var/prompt = tgui_alert(usr, "Would you like to alert the crew?", "Alert", list("Yes", "No", "Cancel"))
- switch(prompt)
- if("Yes")
- event.announce_chance = 100
- if("Cancel")
- event.kill()
- return
- if("No")
- event.announce_chance = 0
- event.processing = TRUE
- message_admins("[key_name_admin(usr)] has triggered an event. ([E.name])")
- log_admin("[key_name(usr)] has triggered an event. ([E.name])")
- return
-
else if(href_list["editrightsbrowser"])
edit_admin_permissions(0)
diff --git a/code/modules/antagonists/pirate/pirate_event.dm b/code/modules/antagonists/pirate/pirate_event.dm
index 9bc7f6bbdb4..78b5ff6d61e 100644
--- a/code/modules/antagonists/pirate/pirate_event.dm
+++ b/code/modules/antagonists/pirate/pirate_event.dm
@@ -7,30 +7,19 @@
dynamic_should_hijack = TRUE
category = EVENT_CATEGORY_INVASION
description = "The crew will either pay up, or face a pirate assault."
- ///admin chosen pirate team
- var/datum/pirate_gang/chosen_gang
-
-/datum/round_event_control/pirates/admin_setup(mob/admin)
- var/list/gang_choices = list("Random")
-
- for(var/datum/pirate_gang/possible_gang as anything in GLOB.pirate_gangs)
- gang_choices[possible_gang.name] = possible_gang
-
- var/chosen = tgui_input_list(usr, "Select pirate gang", "TICKETS TO THE SPONGEBOB MOVIE!!", gang_choices)
- if(!chosen)
- return ADMIN_CANCEL_EVENT
- if(chosen == "Random")
- return //still do the event, but chosen_gang is still null, so it will pick from the choices
- chosen_gang = gang_choices[chosen]
+ admin_setup = /datum/event_admin_setup/pirates
/datum/round_event_control/pirates/preRunEvent()
if (!SSmapping.empty_space)
return EVENT_CANT_RUN
return ..()
+/datum/round_event/pirates
+ ///admin chosen pirate team
+ var/datum/pirate_gang/chosen_gang
+
/datum/round_event/pirates/start()
- var/datum/round_event_control/pirates/pirate_control = control
- send_pirate_threat(pirate_control.chosen_gang)
+ send_pirate_threat(chosen_gang)
/proc/send_pirate_threat(datum/pirate_gang/chosen_gang)
if(!chosen_gang)
@@ -91,43 +80,25 @@
priority_announce("Unidentified armed ship detected near the station.")
-//Shuttle equipment
+/datum/event_admin_setup/pirates
+ ///admin chosen pirate team
+ var/datum/pirate_gang/chosen_gang
-/obj/machinery/shuttle_scrambler
- name = "Data Siphon"
- desc = "This heap of machinery steals credits and data from unprotected systems and locks down cargo shuttles."
- icon = 'icons/obj/machines/dominator.dmi'
- icon_state = "dominator"
- density = TRUE
- var/active = FALSE
- var/credits_stored = 0
- var/siphon_per_tick = 5
+/datum/event_admin_setup/pirates/prompt_admins()
-/obj/machinery/shuttle_scrambler/Initialize(mapload)
- . = ..()
- update_appearance()
+ var/list/gang_choices = list("Random")
-/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)
- credits_stored += siphoned
- interrupt_research()
- else
- return
- else
- STOP_PROCESSING(SSobj,src)
+ for(var/datum/pirate_gang/possible_gang as anything in GLOB.pirate_gangs)
+ gang_choices[possible_gang.name] = possible_gang
-/obj/machinery/shuttle_scrambler/proc/toggle_on(mob/user)
- SSshuttle.registerTradeBlockade(src)
- AddComponent(/datum/component/gps, "Nautical Signal")
- active = TRUE
- to_chat(user,span_notice("You toggle [src] [active ? "on":"off"]."))
- to_chat(user,span_warning("The scrambling signal can be now tracked by GPS."))
- START_PROCESSING(SSobj,src)
+ var/chosen = tgui_input_list(usr, "Select pirate gang", "TICKETS TO THE SPONGEBOB MOVIE!!", gang_choices)
+ if(!chosen)
+ return ADMIN_CANCEL_EVENT
+ if(chosen == "Random")
+ return //still do the event, but chosen_gang is still null, so it will pick from the choices
+ chosen_gang = gang_choices[chosen]
+
+/datum/event_admin_setup/pirates/apply_to_event(datum/round_event/pirates/event)
/obj/machinery/shuttle_scrambler/interact(mob/user)
if(active)
@@ -142,30 +113,6 @@
update_appearance()
send_notification()
-//interrupt_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))
- continue
- S.emp_act()
- new /obj/effect/temp_visual/emp(get_turf(S))
-
-/obj/machinery/shuttle_scrambler/proc/dump_loot(mob/user)
- if(credits_stored) // Prevents spamming empty holochips
- new /obj/item/holochip(drop_location(), credits_stored)
- to_chat(user,span_notice("You retrieve the siphoned credits!"))
- credits_stored = 0
- else
- to_chat(user,span_notice("There's nothing to withdraw."))
-
-/obj/machinery/shuttle_scrambler/proc/send_notification()
- priority_announce("Data theft signal detected, source registered on local gps units.")
-
-/obj/machinery/shuttle_scrambler/proc/toggle_off(mob/user)
- SSshuttle.clearTradeBlockade(src)
- active = FALSE
- STOP_PROCESSING(SSobj,src)
-
/obj/machinery/shuttle_scrambler/update_icon_state()
icon_state = active ? "dominator-Blue" : "dominator"
return ..()
@@ -211,15 +158,6 @@
mask_type = /obj/item/clothing/mask/breath
storage_type = /obj/item/tank/internals/oxygen
-/obj/machinery/loot_locator
- name = "Booty Locator"
- desc = "This sophisticated machine scans the nearby space for items of value."
- icon = 'icons/obj/machines/research.dmi'
- icon_state = "tdoppler"
- density = TRUE
- var/cooldown = 300
- var/next_use = 0
-
/obj/machinery/loot_locator/interact(mob/user)
if(world.time <= next_use)
to_chat(user,span_warning("[src] is recharging."))
@@ -231,33 +169,6 @@
else
say("Located: [AM.name] at [get_area_name(AM)]")
-/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
-
-//Pad & Pad Terminal
-/obj/machinery/piratepad
- name = "cargo hold pad"
- icon = 'icons/obj/telescience.dmi'
- icon_state = "lpad-idle-off"
- ///This is the icon_state that this telepad uses when it's not in use.
- var/idle_state = "lpad-idle-off"
- ///This is the icon_state that this telepad uses when it's warming up for goods teleportation.
- var/warmup_state = "lpad-idle"
- ///This is the icon_state to flick when the goods are being sent off by the telepad.
- var/sending_state = "lpad-beam"
- ///This is the cargo hold ID used by the piratepad_control. Match these two to link them together.
- var/cargo_hold_id
-
/obj/machinery/piratepad/multitool_act(mob/living/user, obj/item/multitool/I)
. = ..()
if (istype(I))
@@ -275,27 +186,6 @@
default_deconstruction_crowbar(tool)
return TRUE
-/obj/machinery/computer/piratepad_control
- name = "cargo hold control terminal"
- ///Message to display on the TGUI window.
- var/status_report = "Ready for delivery."
- ///Reference to the specific pad that the control computer is linked up to.
- var/datum/weakref/pad_ref
- ///How long does it take to warmup the pad to teleport?
- var/warmup_time = 100
- ///Is the teleport pad/computer sending something right now? TRUE/FALSE
- var/sending = FALSE
- ///For the purposes of space pirates, how many points does the control pad have collected.
- var/points = 0
- ///Reference to the export report totaling all sent objects and mobs.
- var/datum/export_report/total_report
- ///Callback holding the sending timer for sending the goods after a delay.
- var/sending_timer
- ///This is the cargo hold ID used by the piratepad machine. Match these two to link them together.
- var/cargo_hold_id
- ///Interface name for the ui_interact call for different subtypes.
- var/interface_type = "CargoHoldTerminal"
-
/obj/machinery/computer/piratepad_control/Initialize(mapload)
..()
return INITIALIZE_HINT_LATELOAD
@@ -351,10 +241,6 @@
stop_sending()
. = TRUE
-/obj/machinery/computer/piratepad_control/proc/recalc()
- if(sending)
- return
-
status_report = "Predicted value: "
var/value = 0
var/datum/export_report/ex = new
@@ -362,10 +248,6 @@
for(var/atom/movable/AM in get_turf(pad))
if(AM == pad)
continue
- //SKYRAT EDIT ADDITION - NO MOBS!
- if(ismob(AM))
- continue
- //SKYRAT EDIT END
export_item_and_contents(AM, apply_elastic = FALSE, dry_run = TRUE, external_report = ex)
for(var/datum/export/E in ex.total_amount)
@@ -376,85 +258,6 @@
if(!value)
status_report += "0"
-/obj/machinery/computer/piratepad_control/proc/send()
- if(!sending)
- return
-
- var/datum/export_report/ex = new
- var/obj/machinery/piratepad/pad = pad_ref?.resolve()
-
- for(var/atom/movable/AM in get_turf(pad))
- if(AM == pad)
- continue
- //SKYRAT EDIT ADDITION - NO MOBS!
- if(ismob(AM))
- continue
- //SKYRAT EDIT END
- export_item_and_contents(AM, EXPORT_PIRATE | EXPORT_CARGO | EXPORT_CONTRABAND | EXPORT_EMAG, apply_elastic = FALSE, delete_unsold = FALSE, external_report = ex)
-
- 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.
- if(!export_text)
- continue
-
- status_report += export_text
- status_report += " "
- value += ex.total_value[E]
-
- if(!total_report)
- total_report = ex
- 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]
- playsound(loc, 'sound/machines/wewewew.ogg', 70, TRUE)
-
- points += value
-
- if(!value)
- status_report += "Nothing"
-
- pad.visible_message(span_notice("[pad] activates!"))
- flick(pad.sending_state,pad)
- pad.icon_state = pad.idle_state
- sending = FALSE
-
-/obj/machinery/computer/piratepad_control/proc/start_sending()
- var/obj/machinery/piratepad/pad = pad_ref?.resolve()
- if(!pad)
- status_report = "No pad detected. Build or link a pad."
- pad.audible_message(span_notice("[pad] beeps."))
- return
- if(pad?.panel_open)
- status_report = "Please screwdrive pad closed to send. "
- pad.audible_message(span_notice("[pad] beeps."))
- return
- if(sending)
- return
- sending = TRUE
- status_report = "Sending... "
- pad.visible_message(span_notice("[pad] starts charging up."))
- pad.icon_state = pad.warmup_state
- sending_timer = addtimer(CALLBACK(src, PROC_REF(send)),warmup_time, TIMER_STOPPABLE)
-
-/obj/machinery/computer/piratepad_control/proc/stop_sending(custom_report)
- if(!sending)
- return
- sending = FALSE
- status_report = "Ready for delivery."
- if(custom_report)
- status_report = custom_report
- var/obj/machinery/piratepad/pad = pad_ref?.resolve()
- pad.icon_state = pad.idle_state
- deltimer(sending_timer)
-
-//Attempts to find the thing on station
-/datum/export/pirate/proc/find_loot()
- return
-
/datum/export/pirate/ransom
cost = 3000
unit_name = "hostage"
diff --git a/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm b/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm
new file mode 100644
index 00000000000..e1bef982f62
--- /dev/null
+++ b/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm
@@ -0,0 +1,408 @@
+//Shuttle equipment
+
+/obj/machinery/shuttle_scrambler
+ name = "Data Siphon"
+ desc = "This heap of machinery steals credits and data from unprotected systems and locks down cargo shuttles."
+ icon = 'icons/obj/machines/dominator.dmi'
+ icon_state = "dominator"
+ density = TRUE
+ var/active = FALSE
+ var/credits_stored = 0
+ var/siphon_per_tick = 5
+
+/obj/machinery/shuttle_scrambler/Initialize(mapload)
+ . = ..()
+ update_appearance()
+
+/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)
+ credits_stored += siphoned
+ interrupt_research()
+ else
+ return
+ else
+ STOP_PROCESSING(SSobj,src)
+
+/obj/machinery/shuttle_scrambler/proc/toggle_on(mob/user)
+ SSshuttle.registerTradeBlockade(src)
+ AddComponent(/datum/component/gps, "Nautical Signal")
+ active = TRUE
+ to_chat(user,span_notice("You toggle [src] [active ? "on":"off"]."))
+ to_chat(user,span_warning("The scrambling signal can be now tracked by GPS."))
+ START_PROCESSING(SSobj,src)
+
+/obj/machinery/shuttle_scrambler/interact(mob/user)
+ if(active)
+ dump_loot(user)
+ return
+ var/scramble_response = tgui_alert(user, "Turning the scrambler on will make the shuttle trackable by GPS. Are you sure you want to do it?", "Scrambler", list("Yes", "Cancel"))
+ if(scramble_response != "Yes")
+ return
+ if(active || !user.canUseTopic(src, be_close = TRUE))
+ return
+ toggle_on(user)
+ update_appearance()
+ send_notification()
+
+//interrupt_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))
+ continue
+ S.emp_act()
+ new /obj/effect/temp_visual/emp(get_turf(S))
+
+/obj/machinery/shuttle_scrambler/proc/dump_loot(mob/user)
+ if(credits_stored) // Prevents spamming empty holochips
+ new /obj/item/holochip(drop_location(), credits_stored)
+ to_chat(user,span_notice("You retrieve the siphoned credits!"))
+ credits_stored = 0
+ else
+ to_chat(user,span_notice("There's nothing to withdraw."))
+
+/obj/machinery/shuttle_scrambler/proc/send_notification()
+ priority_announce("Data theft signal detected, source registered on local gps units.")
+
+/obj/machinery/shuttle_scrambler/proc/toggle_off(mob/user)
+ SSshuttle.clearTradeBlockade(src)
+ active = FALSE
+ STOP_PROCESSING(SSobj,src)
+
+/obj/machinery/shuttle_scrambler/update_icon_state()
+ icon_state = active ? "dominator-Blue" : "dominator"
+ return ..()
+
+/obj/machinery/shuttle_scrambler/Destroy()
+ toggle_off()
+ return ..()
+
+/obj/machinery/computer/shuttle/pirate
+ name = "pirate shuttle console"
+ shuttleId = "pirate"
+ icon_screen = "syndishuttle"
+ icon_keyboard = "syndie_key"
+ light_color = COLOR_SOFT_RED
+ possible_destinations = "pirate_away;pirate_home;pirate_custom"
+
+/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate/pirate
+ name = "pirate shuttle navigation computer"
+ desc = "Used to designate a precise transit location for the pirate shuttle."
+ shuttleId = "pirate"
+ lock_override = CAMERA_LOCK_STATION
+ shuttlePortId = "pirate_custom"
+ x_offset = 9
+ y_offset = 0
+ see_hidden = FALSE
+
+/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate/pirate/psyker
+ name = "psyker navigation warper"
+ desc = "Used to designate a precise transit location for the psyker shuttle, using sent out brainwaves as detailed sight."
+ icon_screen = "recharge_comp_on"
+ interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_SET_MACHINE //blind friendly
+ x_offset = 0
+ y_offset = 11
+
+/obj/docking_port/mobile/pirate
+ name = "pirate shuttle"
+ shuttle_id = "pirate"
+ rechargeTime = 3 MINUTES
+
+/obj/machinery/suit_storage_unit/pirate
+ suit_type = /obj/item/clothing/suit/space
+ helmet_type = /obj/item/clothing/head/helmet/space
+ mask_type = /obj/item/clothing/mask/breath
+ storage_type = /obj/item/tank/internals/oxygen
+
+/obj/machinery/loot_locator
+ name = "Booty Locator"
+ desc = "This sophisticated machine scans the nearby space for items of value."
+ icon = 'icons/obj/machines/research.dmi'
+ icon_state = "tdoppler"
+ density = TRUE
+ var/cooldown = 300
+ var/next_use = 0
+
+/obj/machinery/loot_locator/interact(mob/user)
+ if(world.time <= next_use)
+ to_chat(user,span_warning("[src] is recharging."))
+ return
+ next_use = world.time + cooldown
+ var/atom/movable/AM = find_random_loot()
+ if(!AM)
+ say("No valuables located. Try again later.")
+ else
+ say("Located: [AM.name] at [get_area_name(AM)]")
+
+/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
+
+//Pad & Pad Terminal
+/obj/machinery/piratepad
+ name = "cargo hold pad"
+ icon = 'icons/obj/telescience.dmi'
+ icon_state = "lpad-idle-off"
+ ///This is the icon_state that this telepad uses when it's not in use.
+ var/idle_state = "lpad-idle-off"
+ ///This is the icon_state that this telepad uses when it's warming up for goods teleportation.
+ var/warmup_state = "lpad-idle"
+ ///This is the icon_state to flick when the goods are being sent off by the telepad.
+ var/sending_state = "lpad-beam"
+ ///This is the cargo hold ID used by the piratepad_control. Match these two to link them together.
+ var/cargo_hold_id
+
+/obj/machinery/piratepad/multitool_act(mob/living/user, obj/item/multitool/I)
+ . = ..()
+ if (istype(I))
+ to_chat(user, span_notice("You register [src] in [I]s buffer."))
+ I.buffer = src
+ return TRUE
+
+/obj/machinery/piratepad/screwdriver_act_secondary(mob/living/user, obj/item/screwdriver/screw)
+ . = ..()
+ if(!.)
+ return default_deconstruction_screwdriver(user, "lpad-idle-open", "lpad-idle-off", screw)
+
+/obj/machinery/piratepad/crowbar_act_secondary(mob/living/user, obj/item/tool)
+ . = ..()
+ default_deconstruction_crowbar(tool)
+ return TRUE
+
+/obj/machinery/computer/piratepad_control
+ name = "cargo hold control terminal"
+ ///Message to display on the TGUI window.
+ var/status_report = "Ready for delivery."
+ ///Reference to the specific pad that the control computer is linked up to.
+ var/datum/weakref/pad_ref
+ ///How long does it take to warmup the pad to teleport?
+ var/warmup_time = 100
+ ///Is the teleport pad/computer sending something right now? TRUE/FALSE
+ var/sending = FALSE
+ ///For the purposes of space pirates, how many points does the control pad have collected.
+ var/points = 0
+ ///Reference to the export report totaling all sent objects and mobs.
+ var/datum/export_report/total_report
+ ///Callback holding the sending timer for sending the goods after a delay.
+ var/sending_timer
+ ///This is the cargo hold ID used by the piratepad machine. Match these two to link them together.
+ var/cargo_hold_id
+ ///Interface name for the ui_interact call for different subtypes.
+ var/interface_type = "CargoHoldTerminal"
+
+/obj/machinery/computer/piratepad_control/Initialize(mapload)
+ ..()
+ return INITIALIZE_HINT_LATELOAD
+
+/obj/machinery/computer/piratepad_control/multitool_act(mob/living/user, obj/item/multitool/I)
+ . = ..()
+ if (istype(I) && istype(I.buffer,/obj/machinery/piratepad))
+ to_chat(user, span_notice("You link [src] with [I.buffer] in [I] buffer."))
+ pad_ref = WEAKREF(I.buffer)
+ return TRUE
+
+/obj/machinery/computer/piratepad_control/LateInitialize()
+ . = ..()
+ if(cargo_hold_id)
+ for(var/obj/machinery/piratepad/P in GLOB.machines)
+ if(P.cargo_hold_id == cargo_hold_id)
+ pad_ref = WEAKREF(P)
+ return
+ else
+ var/obj/machinery/piratepad/pad = locate() in range(4, src)
+ pad_ref = WEAKREF(pad)
+
+/obj/machinery/computer/piratepad_control/ui_interact(mob/user, datum/tgui/ui)
+ . = ..()
+ ui = SStgui.try_update_ui(user, src, ui)
+ if(!ui)
+ ui = new(user, src, interface_type, name)
+ ui.open()
+
+/obj/machinery/computer/piratepad_control/ui_data(mob/user)
+ var/list/data = list()
+ data["points"] = points
+ data["pad"] = pad_ref?.resolve() ? TRUE : FALSE
+ data["sending"] = sending
+ data["status_report"] = status_report
+ return data
+
+/obj/machinery/computer/piratepad_control/ui_act(action, params)
+ . = ..()
+ if(.)
+ return
+ if(!pad_ref?.resolve())
+ return
+
+ switch(action)
+ if("recalc")
+ recalc()
+ . = TRUE
+ if("send")
+ start_sending()
+ . = TRUE
+ if("stop")
+ stop_sending()
+ . = TRUE
+
+/obj/machinery/computer/piratepad_control/proc/recalc()
+ if(sending)
+ return
+
+ status_report = "Predicted value: "
+ var/value = 0
+ var/datum/export_report/ex = 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)
+
+ for(var/datum/export/E in ex.total_amount)
+ status_report += E.total_printout(ex,notes = FALSE)
+ status_report += " "
+ value += ex.total_value[E]
+
+ if(!value)
+ status_report += "0"
+
+/obj/machinery/computer/piratepad_control/proc/send()
+ if(!sending)
+ return
+
+ var/datum/export_report/ex = 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, EXPORT_PIRATE | EXPORT_CARGO | EXPORT_CONTRABAND | EXPORT_EMAG, apply_elastic = FALSE, delete_unsold = FALSE, external_report = ex)
+
+ 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.
+ if(!export_text)
+ continue
+
+ status_report += export_text
+ status_report += " "
+ value += ex.total_value[E]
+
+ if(!total_report)
+ total_report = ex
+ 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]
+ playsound(loc, 'sound/machines/wewewew.ogg', 70, TRUE)
+
+ points += value
+
+ if(!value)
+ status_report += "Nothing"
+
+ pad.visible_message(span_notice("[pad] activates!"))
+ flick(pad.sending_state,pad)
+ pad.icon_state = pad.idle_state
+ sending = FALSE
+
+/obj/machinery/computer/piratepad_control/proc/start_sending()
+ var/obj/machinery/piratepad/pad = pad_ref?.resolve()
+ if(!pad)
+ status_report = "No pad detected. Build or link a pad."
+ pad.audible_message(span_notice("[pad] beeps."))
+ return
+ if(pad?.panel_open)
+ status_report = "Please screwdrive pad closed to send. "
+ pad.audible_message(span_notice("[pad] beeps."))
+ return
+ if(sending)
+ return
+ sending = TRUE
+ status_report = "Sending... "
+ pad.visible_message(span_notice("[pad] starts charging up."))
+ pad.icon_state = pad.warmup_state
+ sending_timer = addtimer(CALLBACK(src, PROC_REF(send)),warmup_time, TIMER_STOPPABLE)
+
+/obj/machinery/computer/piratepad_control/proc/stop_sending(custom_report)
+ if(!sending)
+ return
+ sending = FALSE
+ status_report = "Ready for delivery."
+ if(custom_report)
+ status_report = custom_report
+ var/obj/machinery/piratepad/pad = pad_ref?.resolve()
+ pad.icon_state = pad.idle_state
+ deltimer(sending_timer)
+
+//Attempts to find the thing on station
+/datum/export/pirate/proc/find_loot()
+ return
+
+/datum/export/pirate/ransom
+ cost = 3000
+ unit_name = "hostage"
+ export_types = list(/mob/living/carbon/human)
+
+/datum/export/pirate/ransom/find_loot()
+ var/list/head_minds = SSjob.get_living_heads()
+ var/list/head_mobs = list()
+ for(var/datum/mind/M as anything in head_minds)
+ head_mobs += M.current
+ 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
+ return 0
+ else if("pirate" in H.faction) //can't ransom your fellow pirates to CentCom!
+ return 0
+ else if(H.mind.assigned_role.departments_bitflags & DEPARTMENT_BITFLAG_COMMAND)
+ return 3000
+ else
+ return 1000
+
+/datum/export/pirate/parrot
+ cost = 2000
+ unit_name = "alive parrot"
+ 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
+
+/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/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
diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm
index a84a2e3d7d4..cd1e2f178ea 100644
--- a/code/modules/events/_event.dm
+++ b/code/modules/events/_event.dm
@@ -30,10 +30,16 @@
/// Whether or not dynamic should hijack this event
var/dynamic_should_hijack = FALSE
+ /// Datum that will handle admin options for forcing the event.
+ /// If there are no options, just leave it null.
+ var/datum/event_admin_setup/admin_setup = null
+
/datum/round_event_control/New()
if(config && !wizardevent) // Magic is unaffected by configs
earliest_start = CEILING(earliest_start * CONFIG_GET(number/events_min_time_mul), 1)
min_players = CEILING(min_players * CONFIG_GET(number/events_min_players_mul), 1)
+ if(admin_setup)
+ admin_setup = new admin_setup(src)
/datum/round_event_control/wizard
category = EVENT_CATEGORY_WIZARD
@@ -122,22 +128,25 @@ Runs the event
* * In the worst case scenario we can still recall a event which we cancelled by accident, which is much better then to have a unwanted event
*/
UnregisterSignal(SSdcs, COMSIG_GLOB_RANDOM_EVENT)
- var/datum/round_event/E = new typepath(TRUE, src)
- E.current_players = get_active_player_count(alive_check = 1, afk_check = 1, human_check = 1)
+ var/datum/round_event/round_event = new typepath(TRUE, src)
+ if(admin_forced && admin_setup)
+ admin_setup.apply_to_event(round_event)
+ round_event.setup()
+ round_event.current_players = get_active_player_count(alive_check = 1, afk_check = 1, human_check = 1)
occurrences++
SSevents.previously_run += src //SKYRAT EDIT ADDITION
if(announce_chance_override != null)
- E.announce_chance = announce_chance_override
+ round_event.announce_chance = announce_chance_override
- testing("[time2text(world.time, "hh:mm:ss")] [E.type]")
+ testing("[time2text(world.time, "hh:mm:ss")] [round_event.type]")
triggering = TRUE
if(!triggering)
RegisterSignal(SSdcs, COMSIG_GLOB_RANDOM_EVENT, PROC_REF(stop_random_event))
- E.cancel_event = TRUE
- return E
+ round_event.cancel_event = TRUE
+ return round_event
triggering = FALSE
if(random)
@@ -146,8 +155,8 @@ Runs the event
if(alert_observers)
announce_deadchat(random)
- SSblackbox.record_feedback("tally", "event_ran", 1, "[E]")
- return E
+ SSblackbox.record_feedback("tally", "event_ran", 1, "[round_event]")
+ return round_event
///Annouces the event name to deadchat, override this if what an event should show to deadchat is different to its event name.
/datum/round_event_control/proc/announce_deadchat(random)
@@ -158,12 +167,6 @@ Runs the event
SIGNAL_HANDLER
return CANCEL_RANDOM_EVENT
-/// Any special things admins can do while triggering this event to "improve" it.
-/// Return [ADMIN_CANCEL_EVENT] to stop the event from actually happening after all
-/datum/round_event_control/proc/admin_setup(mob/admin)
- SHOULD_CALL_PARENT(FALSE)
- return
-
/datum/round_event //NOTE: Times are measured in master controller ticks!
var/processing = TRUE
var/datum/round_event_control/control
@@ -194,12 +197,14 @@ Runs the event
//It will only have been overridden by the time we get to announce() start() tick() or end() (anything but setup basically).
//This is really only for setting defaults which can be overridden later when New() finishes.
/datum/round_event/proc/setup()
+ SHOULD_CALL_PARENT(FALSE)
return
//Called when the tick is equal to the start_when variable.
//Allows you to start before announcing or vice versa.
//Only called once.
/datum/round_event/proc/start()
+ SHOULD_CALL_PARENT(FALSE)
return
//Called after something followable has been spawned by an event
@@ -285,7 +290,6 @@ Runs the event
//Sets up the event then adds the event to the the list of running events
/datum/round_event/New(my_processing = TRUE, datum/round_event_control/event_controller)
control = event_controller
- setup()
processing = my_processing
SSevents.running += src
return ..()
diff --git a/code/modules/events/_event_admin_setup.dm b/code/modules/events/_event_admin_setup.dm
new file mode 100644
index 00000000000..1116eb05866
--- /dev/null
+++ b/code/modules/events/_event_admin_setup.dm
@@ -0,0 +1,83 @@
+/// Datum that holds a proc for additional options when running an event.
+/// Prototypes are declared here, non-prototypes on the event files.
+/datum/event_admin_setup
+ /// event control that owns this.
+ var/datum/round_event_control/event_control
+
+/datum/event_admin_setup/New(event_control)
+ src.event_control = event_control
+
+/datum/event_admin_setup/proc/prompt_admins()
+ SHOULD_CALL_PARENT(FALSE)
+ CRASH("Unimplemented prompt_admins() on [event_control]'s admin setup.")
+
+/datum/event_admin_setup/proc/apply_to_event(datum/round_event/event)
+ SHOULD_CALL_PARENT(FALSE)
+ CRASH("Unimplemented apply_to_event() on [event_control]'s admin setup.")
+
+/// A very common pattern is picking from a tgui list input, so this does that.
+/// Supply a list in `get_list` and prompt admins will have the admin pick from it or cancel.
+/datum/event_admin_setup/listed_options
+ /// Text to ask the user, for example "What deal would you like to offer the crew?"
+ var/input_text = "Unset Text"
+ /// If set, picking this will be the same as running the event without admin setup.
+ var/normal_run_option
+ /// Picked list option to be applied.
+ var/chosen
+
+/datum/event_admin_setup/listed_options/proc/get_list()
+ SHOULD_CALL_PARENT(FALSE)
+ CRASH("Unimplemented get_list() on [event_control]'s admin setup.")
+
+/datum/event_admin_setup/listed_options/prompt_admins()
+ var/list/options = get_list()
+ if(normal_run_option)
+ options.Insert(1, normal_run_option)
+ chosen = tgui_input_list(usr, input_text, event_control.name, options)
+ if(!chosen)
+ return ADMIN_CANCEL_EVENT
+ if(normal_run_option && chosen == normal_run_option)
+ chosen = null //no admin pick = runs as normal
+
+/// For admin setups that want a custom string. Suggests what the event would have picked normally.
+/datum/event_admin_setup/text_input
+ /// Text to ask the user, for example "What horrifying truth will you reveal?"
+ var/input_text = "Unset Text"
+ /// Picked string to be applied.
+ var/chosen
+
+/// Returns a string to suggest to the admin, which would be what the event would have chosen.
+/// No suggestion if an empty string, which is default behavior.
+/datum/event_admin_setup/text_input/proc/get_text_suggestion()
+ return ""
+
+/datum/event_admin_setup/text_input/prompt_admins()
+ var/suggestion = get_text_suggestion()
+ chosen = tgui_input_text(usr, input_text, event_control.name, suggestion)
+ if(!chosen)
+ return ADMIN_CANCEL_EVENT
+
+/// Some events are not always a good idea when a game state is in a certain situation.
+/// This runs a check and warns the admin.
+/datum/event_admin_setup/warn_admin
+ /// Warning text shown to admin on the alert.
+ var/warning_text = "Unset warning text"
+ /// Message sent to other admins. Example: "has forced a shuttle catastrophe while a shuttle was already docked."
+ var/snitch_text = "Unset snitching text (be mad at coders AND the admin responsible)"
+
+/datum/event_admin_setup/warn_admin/prompt_admins()
+ if(!should_warn())
+ return
+ var/mob/admin = usr
+ if(tgui_alert(usr, "WARNING: [warning_text]", event_control.name, list("Yes", "No")) == "Yes")
+ message_admins("[admin.ckey] [snitch_text]")
+ else
+ return ADMIN_CANCEL_EVENT
+
+/// Returns whether the admin should get an alert.
+/datum/event_admin_setup/warn_admin/proc/should_warn()
+ SHOULD_CALL_PARENT(FALSE)
+ CRASH("Unimplemented should_warn() on [event_control]'s admin setup.")
+
+/datum/event_admin_setup/warn_admin/apply_to_event(datum/round_event/event)
+ return
diff --git a/code/modules/events/anomaly/_anomaly.dm b/code/modules/events/anomaly/_anomaly.dm
index 0e3cb80bcc9..4b15ac93c29 100644
--- a/code/modules/events/anomaly/_anomaly.dm
+++ b/code/modules/events/anomaly/_anomaly.dm
@@ -7,31 +7,20 @@
weight = 15
category = EVENT_CATEGORY_ANOMALIES
description = "This anomaly shocks and explodes. This is the base type."
- ///The admin-chosen spawn location.
- var/turf/spawn_location
-
-/datum/round_event_control/anomaly/admin_setup(mob/admin)
- . = ..()
-
- if(!check_rights(R_FUN))
- return ADMIN_CANCEL_EVENT
-
- if(tgui_alert(usr, "Spawn anomaly at your current location?", "Anomaly Alert", list("Yes", "No")) == "Yes")
- spawn_location = get_turf(usr)
+ admin_setup = /datum/event_admin_setup/anomaly
/datum/round_event/anomaly
+ announce_when = 1
var/area/impact_area
var/datum/anomaly_placer/placer = new()
var/obj/effect/anomaly/anomaly_path = /obj/effect/anomaly/flux
- announce_when = 1
+ ///The admin-chosen spawn location.
+ var/turf/spawn_location
/datum/round_event/anomaly/setup()
- end_when = start_when + 1 //Admin vars are cleared on end(), so we make sure the anomaly spawns before then.
-
- var/datum/round_event_control/anomaly/anomaly_event = control
- if(anomaly_event.spawn_location)
- impact_area = get_area(anomaly_event.spawn_location)
+ if(spawn_location)
+ impact_area = get_area(spawn_location)
else
impact_area = placer.findValidArea()
@@ -41,9 +30,8 @@
/datum/round_event/anomaly/start()
var/turf/anomaly_turf
- var/datum/round_event_control/anomaly/anomaly_event = control
- if(anomaly_event.spawn_location)
- anomaly_turf = anomaly_event.spawn_location
+ if(spawn_location)
+ anomaly_turf = spawn_location
else
anomaly_turf = placer.findValidTurf(impact_area)
@@ -53,6 +41,13 @@
if (newAnomaly)
announce_to_ghosts(newAnomaly)
-/datum/round_event/anomaly/end()
- var/datum/round_event_control/anomaly/anomaly_event = control
- anomaly_event.spawn_location = null
+/datum/event_admin_setup/anomaly
+ ///The admin-chosen spawn location.
+ var/turf/spawn_location
+
+/datum/event_admin_setup/anomaly/prompt_admins()
+ if(tgui_alert(usr, "Spawn anomaly at your current location?", "Anomaly Alert", list("Yes", "No")) == "Yes")
+ spawn_location = get_turf(usr)
+
+/datum/event_admin_setup/anomaly/apply_to_event(datum/round_event/anomaly/event)
+ event.spawn_location = spawn_location
diff --git a/code/modules/events/brand_intelligence.dm b/code/modules/events/brand_intelligence.dm
index 94cf816d3b5..1484ea3cad1 100644
--- a/code/modules/events/brand_intelligence.dm
+++ b/code/modules/events/brand_intelligence.dm
@@ -6,23 +6,20 @@
description = "Vending machines will attack people until the Patient Zero is disabled."
min_players = 15
max_occurrences = 1
- ///Var used to determine vendor subtype if used for admin setup
- var/chosen_vendor
-
-/datum/round_event_control/brand_intelligence/admin_setup()
- if(!check_rights(R_FUN))
- return ADMIN_CANCEL_EVENT
- if(tgui_alert(usr, "Select a specific vendor path?", "Capitalism-ho!", list("Yes", "No")) == "Yes")
- var/list/vendors = list()
- vendors += subtypesof(/obj/machinery/vending)
- chosen_vendor = tgui_input_list(usr, "Vendor type must have at least one instance on the station for this to work!","Vendor Selector", vendors)
+ admin_setup = /datum/event_admin_setup/listed_options/brand_intelligence
/datum/round_event/brand_intelligence
announce_when = 21
end_when = 1000 //Ends when all vending machines are subverted anyway.
- var/list/obj/machinery/vending/vendingMachines = list()
- var/list/obj/machinery/vending/infectedMachines = list()
- var/obj/machinery/vending/originMachine
+ /// Admin picked subtype for what kind of vendor goes haywire.
+ var/chosen_vendor_type
+ /// All vending machines valid to get infected.
+ var/list/obj/machinery/vending/vending_machines = list()
+ /// All vending machines that have been infected.
+ var/list/obj/machinery/vending/infected_machines = list()
+ /// The original machine infected. Killing it ends the event.
+ var/obj/machinery/vending/origin_machine
+ /// Murderous sayings from the machines.
var/list/rampant_speeches = list(
"Try our aggressive new marketing strategies!",
"You should buy products to feed your lifestyle obsession!",
@@ -33,66 +30,62 @@
"You don't want to buy anything? Yeah, well, I didn't want to buy your mom either.",
)
+/datum/round_event/brand_intelligence/setup()
+ //select our origin machine (which will also be the type of vending machine affected.)
+ for(var/obj/machinery/vending/vendor in GLOB.machines)
+ if(!is_station_level(vendor.z))
+ continue
+ if(!vendor.density)
+ continue
+ if(chosen_vendor_type && !istype(vendor, chosen_vendor_type))
+ continue
+ vending_machines.Add(vendor)
+ if(!length(vending_machines)) //If somehow there are still no elligible vendors, give up.
+ kill()
+ return
+ origin_machine = pick_n_take(vending_machines)
/datum/round_event/brand_intelligence/announce(fake)
- var/source = "unknown machine"
- if(fake)
- for(var/obj/machinery/vending/vendor in GLOB.machines)
- if(!is_station_level(vendor.z))
- continue
- vendingMachines.Add(vendor)
- var/obj/machinery/vending/chosen_vendor = pick(vendingMachines)
- source = chosen_vendor.name
- else if(originMachine)
- source = originMachine.name
- priority_announce("Rampant brand intelligence has been detected aboard [station_name()]. Please inspect any [source] brand vendors for aggressive marketing tactics, and reboot them if necessary.", "Machine Learning Alert")
+ priority_announce("Rampant brand intelligence has been detected aboard [station_name()]. Please inspect any [origin_machine] brand vendors for aggressive marketing tactics, and reboot them if necessary.", "Machine Learning Alert")
/datum/round_event/brand_intelligence/start()
- var/datum/round_event_control/brand_intelligence/brand_event = control
- if(brand_event.chosen_vendor) //Attempt to search for vendors of the selected admin subtype
- var/chosen_vendor = brand_event.chosen_vendor
- for(var/obj/machinery/vending/vendor in GLOB.machines)
- if(!is_station_level(vendor.z) || !istype(vendor, chosen_vendor) || !vendor.density)
- continue
- vendingMachines.Add(vendor)
- brand_event.chosen_vendor = null //Event has a max_occurences of 1 but juuust in case
- if(!length(vendingMachines)) //If no vendors are in vendingMachines, setup defaults back to randomly selecting one.
- for(var/obj/machinery/vending/vendor in GLOB.machines)
- if(!is_station_level(vendor.z) || !vendor.density)
- continue
- vendingMachines.Add(vendor)
- if(!length(vendingMachines)) //If somehow there are still no elligible vendors, give up.
- kill()
- return
- originMachine = pick(vendingMachines)
- vendingMachines.Remove(originMachine)
- originMachine.shut_up = FALSE
- originMachine.shoot_inventory = TRUE
- announce_to_ghosts(originMachine)
+ origin_machine.shut_up = FALSE
+ origin_machine.shoot_inventory = TRUE
+ announce_to_ghosts(origin_machine)
/datum/round_event/brand_intelligence/tick()
- if(!originMachine || QDELETED(originMachine) || originMachine.shut_up || originMachine.wires.is_all_cut()) //if the original vending machine is missing or has it's voice switch flipped
- for(var/obj/machinery/vending/saved in infectedMachines)
+ if(!origin_machine || QDELETED(origin_machine) || origin_machine.shut_up || origin_machine.wires.is_all_cut()) //if the original vending machine is missing or has it's voice switch flipped
+ for(var/obj/machinery/vending/saved in infected_machines)
saved.shoot_inventory = FALSE
- if(originMachine)
- originMachine.speak("I am... vanquished. My people will remem...ber...meeee.")
- originMachine.visible_message(span_notice("[originMachine] beeps and seems lifeless."))
+ if(origin_machine)
+ origin_machine.speak("I am... vanquished. My people will remem...ber...meeee.")
+ origin_machine.visible_message(span_notice("[origin_machine] beeps and seems lifeless."))
kill()
return
- list_clear_nulls(vendingMachines)
- if(!vendingMachines.len) //if every machine is infected
- for(var/obj/machinery/vending/upriser in infectedMachines)
+ list_clear_nulls(vending_machines)
+ if(!vending_machines.len) //if every machine is infected
+ for(var/obj/machinery/vending/upriser in infected_machines)
if(!QDELETED(upriser))
upriser.ai_controller = new /datum/ai_controller/vending_machine(upriser)
- infectedMachines.Remove(upriser)
+ infected_machines.Remove(upriser)
kill()
return
if(ISMULTIPLE(activeFor, 2))
- var/obj/machinery/vending/rebel = pick(vendingMachines)
- vendingMachines.Remove(rebel)
- infectedMachines.Add(rebel)
+ var/obj/machinery/vending/rebel = pick(vending_machines)
+ vending_machines.Remove(rebel)
+ infected_machines.Add(rebel)
rebel.shut_up = FALSE
rebel.shoot_inventory = TRUE
if(ISMULTIPLE(activeFor, 4))
- originMachine.speak(pick(rampant_speeches))
+ origin_machine.speak(pick(rampant_speeches))
+
+/datum/event_admin_setup/listed_options/brand_intelligence
+ input_text = "Select a specific vendor path?"
+ normal_run_option = "Random Vendor"
+
+/datum/event_admin_setup/listed_options/brand_intelligence/get_list()
+ return subtypesof(/obj/machinery/vending)
+
+/datum/event_admin_setup/listed_options/brand_intelligence/apply_to_event(datum/round_event/brand_intelligence/event)
+ event.chosen_vendor_type = chosen
diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm
index d90a7f6453e..0f246a9248f 100644
--- a/code/modules/events/disease_outbreak.dm
+++ b/code/modules/events/disease_outbreak.dm
@@ -6,10 +6,9 @@
weight = 5
category = EVENT_CATEGORY_HEALTH
description = "A 'classic' virus will infect some members of the crew." //These are the ones with PERSONALITY
+ admin_setup = /datum/event_admin_setup/disease_outbreak
///Disease recipient candidates
var/list/disease_candidates = list()
- ///Admin selected disease, to be passed down to the round_event
- var/chosen_disease
/datum/round_event_control/disease_outbreak/can_spawn_event(players_amt)
. = ..()
@@ -19,21 +18,6 @@
if(length(disease_candidates))
return TRUE
-/datum/round_event_control/disease_outbreak/admin_setup()
- if(!check_rights(R_FUN))
- return ADMIN_CANCEL_EVENT
-
- generate_candidates()
-
- if(!length(disease_candidates))
- message_admins("No disease candidates found!")
- return ADMIN_CANCEL_EVENT
-
- message_admins("[length(disease_candidates)] candidates found!")
-
- if(tgui_alert(usr, "Select a specific disease?", "Sickening behavior", list("Yes", "No")) == "Yes")
- chosen_disease = tgui_input_list(usr, "Warning: Some of these are EXTREMELY dangerous.","Bacteria Hysteria", subtypesof(/datum/disease))
-
/**
* Creates a list of people who are elligible to become disease carriers for the event
*
@@ -68,10 +52,6 @@
var/datum/round_event_control/disease_outbreak/disease_event = control
afflicted += disease_event.disease_candidates
disease_event.disease_candidates.Cut() //Clean the list after use
- if(disease_event.chosen_disease)
- virus_type = disease_event.chosen_disease
- disease_event.chosen_disease = null
-
if(!virus_type)
var/list/virus_candidates = list()
@@ -104,26 +84,7 @@
typepath = /datum/round_event/disease_outbreak/advanced
category = EVENT_CATEGORY_HEALTH
description = "An 'advanced' disease will infect some members of the crew." //These are the ones that get viro lynched!
- ///Admin selected custom severity rating for the event
- var/chosen_severity
- ///Admin selected custom value for the maximum symptoms this virus should have
- var/chosen_max_symptoms
-
-/datum/round_event_control/disease_outbreak/advanced/admin_setup()
- if(!check_rights(R_FUN))
- return ADMIN_CANCEL_EVENT
-
- generate_candidates()
-
- if(!length(disease_candidates))
- message_admins("No disease candidates found!")
- return ADMIN_CANCEL_EVENT
-
- message_admins("[length(disease_candidates)] candidates found!")
-
- if(tgui_alert(usr,"Customize your virus?", "Glorified Debug Tool", list("Yes", "No")) == "Yes")
- chosen_severity = tgui_input_number(usr, "Select a custom severity for your virus!", "Plague Incorporation!", 3, 8)
- chosen_max_symptoms = tgui_input_number(usr, "How many symptoms do you want your virus to have?", "A pox upon ye!", 3, 15)
+ admin_setup = /datum/event_admin_setup/disease_outbreak/advanced
/datum/round_event/disease_outbreak/advanced
///Number of symptoms for our virus
@@ -136,17 +97,11 @@
afflicted += disease_event.disease_candidates
disease_event.disease_candidates.Cut() //Clean the list after use
- if(disease_event.chosen_max_symptoms)
- max_symptoms = disease_event.chosen_max_symptoms
- disease_event.chosen_max_symptoms = null
- else
+ if(!max_symptoms)
max_symptoms = 3 + max(FLOOR((world.time - control.earliest_start)/6000, 1),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes.
max_symptoms = clamp(max_symptoms, 3, 8) //Capping the virus symptoms prevents the event from becoming "smite one poor player with an -12 transmission hell virus" after a certain round length.
- if(disease_event.chosen_severity)
- max_severity = disease_event.chosen_severity
- disease_event.chosen_severity = null
- else
+ if(!max_severity)
max_severity = 3 + max(FLOOR((world.time - control.earliest_start)/6000, 1),0) //Max severity doesn't need clamping
var/datum/disease/advance/advanced_disease = new /datum/disease/advance/random(max_symptoms, max_severity)
@@ -162,3 +117,47 @@
announce_to_ghosts(victim)
else
log_game("An event attempted to trigger a random advanced virus outbreak on [key_name(victim)], but failed.")
+
+/datum/event_admin_setup/disease_outbreak
+ ///Admin selected disease, to be passed down to the round_event
+ var/virus_type
+
+/// Checks for candidates. Returns false if there isn't enough
+/datum/event_admin_setup/disease_outbreak/proc/candidate_check()
+ var/datum/round_event_control/disease_outbreak/disease_control = event_control
+ disease_control.generate_candidates() //can_spawn_event() is bypassed by admin_setup, so this makes sure that the candidates are still generated
+ return length(disease_control.disease_candidates)
+
+/datum/event_admin_setup/disease_outbreak/prompt_admins()
+ var/candidate_count = candidate_check()
+ if(!candidate_check())
+ tgui_alert(usr, "There are no candidates eligible to recieve a disease!", "Error")
+ return ADMIN_CANCEL_EVENT
+ tgui_alert(usr, "[candidate_count] candidates found!", "Disease Outbreak")
+
+ if(tgui_alert(usr, "Select a specific disease?", "Sickening behavior", list("Yes", "No")) == "Yes")
+ virus_type = tgui_input_list(usr, "Warning: Some of these are EXTREMELY dangerous.","Bacteria Hysteria", subtypesof(/datum/disease))
+
+/datum/event_admin_setup/disease_outbreak/apply_to_event(datum/round_event/disease_outbreak/event)
+ event.virus_type = virus_type
+
+/datum/event_admin_setup/disease_outbreak/advanced
+ ///Admin selected custom severity rating for the event
+ var/max_severity
+ ///Admin selected custom value for the maximum symptoms this virus should have
+ var/max_symptoms
+
+/datum/event_admin_setup/disease_outbreak/advanced/prompt_admins()
+ var/candidate_count = candidate_check()
+ if(!candidate_check())
+ tgui_alert(usr, "There are no candidates eligible to recieve a disease!", "Error")
+ return ADMIN_CANCEL_EVENT
+ tgui_alert(usr, "[candidate_count] candidates found!", "Disease Outbreak")
+
+ if(tgui_alert(usr,"Customize your virus?", "Glorified Debug Tool", list("Yes", "No")) == "Yes")
+ max_severity = tgui_input_number(usr, "Select a custom severity for your virus!", "Plague Incorporation!", 3, 8)
+ max_symptoms = tgui_input_number(usr, "How many symptoms do you want your virus to have?", "A pox upon ye!", 3, 15)
+
+/datum/event_admin_setup/disease_outbreak/advanced/apply_to_event(datum/round_event/disease_outbreak/advanced/event)
+ event.max_severity = max_severity
+ event.max_symptoms = max_symptoms
diff --git a/code/modules/events/false_alarm.dm b/code/modules/events/false_alarm.dm
index 5a04b30a6ae..8ed8c065177 100644
--- a/code/modules/events/false_alarm.dm
+++ b/code/modules/events/false_alarm.dm
@@ -3,23 +3,9 @@
typepath = /datum/round_event/falsealarm
weight = 20
max_occurrences = 5
- var/forced_type //Admin abuse
category = EVENT_CATEGORY_BUREAUCRATIC
description = "Fakes an event announcement."
-
-/datum/round_event_control/falsealarm/admin_setup(mob/admin)
- if(!check_rights(R_FUN))
- return
-
- var/list/possible_types = list()
-
- for(var/datum/round_event_control/E in SSevents.control)
- var/datum/round_event/event = E.typepath
- if(!initial(event.fakeable))
- continue
- possible_types += E
-
- forced_type = input(usr, "Select the scare.","False event") as null|anything in sort_names(possible_types)
+ admin_setup = /datum/event_admin_setup/listed_options/false_alarm
/datum/round_event_control/falsealarm/can_spawn_event(players_amt)
. = ..()
@@ -34,6 +20,8 @@
announce_when = 0
end_when = 1
fakeable = FALSE
+ /// Admin's pick of fake event (wow! you picked blob!! you're so creative and smart!)
+ var/forced_type
/datum/round_event/falsealarm/announce(fake)
if(fake) //What are you doing
@@ -42,10 +30,8 @@
var/events_list = gather_false_events(players_amt)
var/datum/round_event_control/event_control
- var/datum/round_event_control/falsealarm/C = control
- if(C.forced_type)
- event_control = C.forced_type
- C.forced_type = null
+ if(forced_type)
+ event_control = forced_type
else
event_control = pick(events_list)
if(event_control)
@@ -66,3 +52,18 @@
if(!initial(event.fakeable))
continue
. += E
+
+/datum/event_admin_setup/listed_options/false_alarm
+ normal_run_option = "Random Fake Event"
+
+/datum/event_admin_setup/listed_options/false_alarm/get_list()
+ var/list/possible_types = list()
+ for(var/datum/round_event_control/event_control in SSevents.control)
+ var/datum/round_event/event = event_control.typepath
+ if(!initial(event.fakeable))
+ continue
+ possible_types += event_control
+ return possible_types
+
+/datum/event_admin_setup/listed_options/false_alarm/apply_to_event(datum/round_event/falsealarm/event)
+ event.forced_type = chosen
diff --git a/code/modules/events/heart_attack.dm b/code/modules/events/heart_attack.dm
index d913dbd6f08..e5ba47dd79a 100644
--- a/code/modules/events/heart_attack.dm
+++ b/code/modules/events/heart_attack.dm
@@ -6,10 +6,9 @@
min_players = 40 // To avoid shafting lowpop
category = EVENT_CATEGORY_HEALTH
description = "A random crewmember's heart gives out."
+ admin_setup = /datum/event_admin_setup/heart_attack
///Candidates for recieving a healthy dose of heart disease
var/list/heart_attack_candidates = list()
- ///Number of candidates to be smote
- var/quantity = 1
/datum/round_event_control/heart_attack/can_spawn_event(players_amt)
. = ..()
@@ -19,17 +18,6 @@
if(length(heart_attack_candidates))
return TRUE
-/datum/round_event_control/heart_attack/admin_setup()
- if(!check_rights(R_FUN))
- return ADMIN_CANCEL_EVENT
-
- generate_candidates() //can_spawn_event() is bypassed by admin_setup, so this makes sure that the candidates are still generated
-
- if(!length(heart_attack_candidates))
- message_admins("There are no candidates eligible to recieve a heart attack!")
- return ADMIN_CANCEL_EVENT
- quantity = tgui_input_number(usr, "There are [length(heart_attack_candidates)] crewmembers eligible for a heart attack. Please select how many people's days you wish to ruin.", "Shia Hato Atakku!", 1, length(heart_attack_candidates))
-
/**
* Performs initial analysis of which living players are eligible to be selected for a heart attack.
*
@@ -52,19 +40,17 @@
///A list of prime candidates for heart attacking
var/list/victims = list()
///Number of heart attacks to distribute
- var/attacks_left = 1
+ var/quantity = 1
+
/datum/round_event/heart_attack/start()
- var/datum/round_event_control/heart_attack/heart_attack_event = control
+ var/datum/round_event_control/heart_attack/heart_control = control
+ victims += heart_control.heart_attack_candidates
+ heart_control.heart_attack_candidates.Cut()
- attacks_left = heart_attack_event.quantity
- victims += heart_attack_event.heart_attack_candidates
- heart_attack_event.heart_attack_candidates.Cut()
- heart_attack_event.quantity = 1
-
- while(attacks_left > 0 && length(victims))
+ while(quantity > 0 && length(victims))
if(attack_heart())
- attacks_left--
+ quantity--
/**
* Picks a victim from a list and attempts to give them a heart attack
@@ -91,3 +77,19 @@
victims -= winner
return TRUE
return FALSE
+
+/datum/event_admin_setup/heart_attack
+ ///Number of candidates to be smote
+ var/quantity = 1
+
+/datum/event_admin_setup/heart_attack/prompt_admins()
+ var/datum/round_event_control/heart_attack/heart_control = event_control
+ heart_control.generate_candidates() //can_spawn_event() is bypassed by admin_setup, so this makes sure that the candidates are still generated
+
+ if(!length(heart_control.heart_attack_candidates))
+ tgui_alert(usr, "There are no candidates eligible to recieve a heart attack!", "Error")
+ return ADMIN_CANCEL_EVENT
+ quantity = tgui_input_number(usr, "There are [length(heart_control.heart_attack_candidates)] crewmembers eligible for a heart attack. Please select how many people's days you wish to ruin.", "Shia Hato Atakku!", 1, length(heart_control.heart_attack_candidates))
+
+/datum/event_admin_setup/heart_attack/apply_to_event(datum/round_event/heart_attack/event)
+ event.quantity = quantity
diff --git a/code/modules/events/immovable_rod.dm b/code/modules/events/immovable_rod/immovable_rod.dm
similarity index 82%
rename from code/modules/events/immovable_rod.dm
rename to code/modules/events/immovable_rod/immovable_rod.dm
index 46500a6bc1b..08453f73837 100644
--- a/code/modules/events/immovable_rod.dm
+++ b/code/modules/events/immovable_rod/immovable_rod.dm
@@ -1,51 +1,4 @@
-/*
-Immovable rod random event.
-The rod will spawn at some location outside the station, and travel in a straight line to the opposite side of the station
-Everything solid in the way will be ex_act()'d
-In my current plan for it, 'solid' will be defined as anything with density == 1
-
---NEOFite
-*/
-
-/datum/round_event_control/immovable_rod
- name = "Immovable Rod"
- typepath = /datum/round_event/immovable_rod
- min_players = 15
- max_occurrences = 5
- var/atom/special_target
- var/force_looping = FALSE
- category = EVENT_CATEGORY_SPACE
- description = "The station passes through an immovable rod."
-
-/datum/round_event_control/immovable_rod/admin_setup(mob/admin)
- if(!check_rights(R_FUN))
- return
-
- var/aimed = tgui_alert(usr,"Aimed at current location?", "Sniperod", list("Yes", "No"))
- if(aimed == "Yes")
- special_target = get_turf(usr)
- var/looper = tgui_alert(usr,"Would you like this rod to force-loop across space z-levels?", "Loopy McLoopface", list("Yes", "No"))
- if(looper == "Yes")
- force_looping = TRUE
- message_admins("[key_name_admin(usr)] has aimed an immovable rod [force_looping ? "(forced looping)" : ""] at [AREACOORD(special_target)].")
- log_admin("[key_name_admin(usr)] has aimed an immovable rod [force_looping ? "(forced looping)" : ""] at [AREACOORD(special_target)].")
-
-/datum/round_event/immovable_rod
- announce_when = 5
-
-/datum/round_event/immovable_rod/announce(fake)
- priority_announce("What the fuck was that?!", "General Alert")
-
-/datum/round_event/immovable_rod/start()
- var/datum/round_event_control/immovable_rod/our_controller = control
- var/startside = pick(GLOB.cardinals)
- var/turf/end_turf = get_edge_target_turf(get_random_station_turf(), turn(startside, 180))
- var/turf/start_turf = spaceDebrisStartLoc(startside, end_turf.z)
- var/atom/rod = new /obj/effect/immovablerod(start_turf, end_turf, our_controller.special_target, our_controller.force_looping)
- our_controller.special_target = null //Cleanup for future event rolls.
- our_controller.force_looping = FALSE
- announce_to_ghosts(rod)
-
+/// "What the fuck was that?!"
/obj/effect/immovablerod
name = "immovable rod"
desc = "What the fuck is that?"
diff --git a/code/modules/events/immovable_rod/immovable_rod_event.dm b/code/modules/events/immovable_rod/immovable_rod_event.dm
new file mode 100644
index 00000000000..a21c77d3e89
--- /dev/null
+++ b/code/modules/events/immovable_rod/immovable_rod_event.dm
@@ -0,0 +1,47 @@
+/// Immovable rod random event.
+/// The rod will spawn at some location outside the station, and travel in a straight line to the opposite side of the station
+/datum/round_event_control/immovable_rod
+ name = "Immovable Rod"
+ typepath = /datum/round_event/immovable_rod
+ min_players = 15
+ max_occurrences = 5
+ category = EVENT_CATEGORY_SPACE
+ description = "The station passes through an immovable rod."
+ admin_setup = /datum/event_admin_setup/immovable_rod
+
+/datum/round_event/immovable_rod
+ announce_when = 5
+ /// Admins can pick a spot the rod will aim for.
+ var/atom/special_target
+ /// Admins can also force it to loop around forever, or at least until the RD gets their hands on it.
+ var/force_looping = FALSE
+
+/datum/round_event/immovable_rod/announce(fake)
+ priority_announce("What the fuck was that?!", "General Alert")
+
+/datum/round_event/immovable_rod/start()
+ var/startside = pick(GLOB.cardinals)
+ var/turf/end_turf = get_edge_target_turf(get_random_station_turf(), turn(startside, 180))
+ var/turf/start_turf = spaceDebrisStartLoc(startside, end_turf.z)
+ var/atom/rod = new /obj/effect/immovablerod(start_turf, end_turf, special_target, force_looping)
+ announce_to_ghosts(rod)
+
+/datum/event_admin_setup/immovable_rod
+ /// Admins can pick a spot the rod will aim for.
+ var/atom/special_target
+ /// Admins can also force it to loop around forever, or at least until the RD gets their hands on it.
+ var/force_looping = FALSE
+
+/datum/event_admin_setup/immovable_rod/prompt_admins()
+ var/aimed = tgui_alert(usr,"Aimed at current location?", "Sniperod", list("Yes", "No"))
+ if(aimed == "Yes")
+ special_target = get_turf(usr)
+ var/looper = tgui_alert(usr,"Would you like this rod to force-loop across space z-levels?", "Loopy McLoopface", list("Yes", "No"))
+ if(looper == "Yes")
+ force_looping = TRUE
+ message_admins("[key_name_admin(usr)] has aimed an immovable rod [force_looping ? "(forced looping)" : ""] at [AREACOORD(special_target)].")
+ log_admin("[key_name_admin(usr)] has aimed an immovable rod [force_looping ? "(forced looping)" : ""] at [AREACOORD(special_target)].")
+
+/datum/event_admin_setup/immovable_rod/apply_to_event(datum/round_event/immovable_rod/event)
+ event.special_target = special_target
+ event.force_looping = force_looping
diff --git a/code/modules/events/mass_hallucination.dm b/code/modules/events/mass_hallucination.dm
index d2ccc2d49e1..188234efd3d 100644
--- a/code/modules/events/mass_hallucination.dm
+++ b/code/modules/events/mass_hallucination.dm
@@ -6,71 +6,36 @@
max_occurrences = 2
min_players = 1
category = EVENT_CATEGORY_HEALTH
+ admin_setup = /datum/event_admin_setup/mass_hallucination
+/datum/round_event/mass_hallucination
+ fakeable = FALSE
/// For admins, what hallucination did we pick
var/admin_forced_hallucination
/// For admins, what arguments are we passing to said hallucination
var/list/admin_forced_args
-/datum/round_event_control/mass_hallucination/admin_setup(mob/admin)
- if(!check_rights(R_FUN))
- return ADMIN_CANCEL_EVENT
-
- var/force = tgui_alert(usr, "Do you want to force a hallucination?", name, list("Yes", "No", "Cancel"))
- if(force == "Cancel")
- return ADMIN_CANCEL_EVENT
- if(force != "Yes")
- return
-
- var/force_what = tgui_alert(usr, "Generic hallucination or Custom configured delusion? (Delusions are those which make people appear as other mobs)", name, list("Hallucination", "Custom Delusion", "Cancel"))
- switch(force_what)
- if("Cancel")
- return ADMIN_CANCEL_EVENT
-
- if("Hallucination")
- var/chosen = select_hallucination_type(admin, "What hallucination should be forced for [name]?", name)
- if(!chosen || !check_rights(R_FUN))
- return ADMIN_CANCEL_EVENT
-
- admin_forced_hallucination = chosen
-
- if("Custom Delusion")
- var/list/chosen_args = create_delusion(admin)
- if(!length(chosen_args) || !check_rights(R_FUN))
- return ADMIN_CANCEL_EVENT
-
- admin_forced_hallucination = chosen_args[1]
- admin_forced_args = chosen_args.Copy(3)
-
-/datum/round_event/mass_hallucination
- fakeable = FALSE
-
/datum/round_event/mass_hallucination/start()
- var/datum/round_event_control/mass_hallucination/our_controller = control
-
- var/picked_hallucination = our_controller?.admin_forced_hallucination
- var/list/other_args = our_controller?.admin_forced_args
-
- if(!picked_hallucination)
+ if(!admin_forced_hallucination)
var/category_to_pick_from = rand(1, 10)
switch(category_to_pick_from)
if(1)
// Send the same sound to everyone
- picked_hallucination = get_random_valid_hallucination_subtype(/datum/hallucination/fake_sound/normal)
+ admin_forced_hallucination = get_random_valid_hallucination_subtype(/datum/hallucination/fake_sound/normal)
if(2)
// Send the same sound to everyone, but weird
- picked_hallucination = get_random_valid_hallucination_subtype(/datum/hallucination/fake_sound/weird)
+ admin_forced_hallucination = get_random_valid_hallucination_subtype(/datum/hallucination/fake_sound/weird)
if(3)
// Send the same message to everyone
- picked_hallucination = get_random_valid_hallucination_subtype(/datum/hallucination/station_message)
+ admin_forced_hallucination = get_random_valid_hallucination_subtype(/datum/hallucination/station_message)
if(4)
// Send the same delusion to everyone, but...
- picked_hallucination = get_random_valid_hallucination_subtype(/datum/hallucination/delusion/preset)
+ admin_forced_hallucination = get_random_valid_hallucination_subtype(/datum/hallucination/delusion/preset)
// The delusion will affect everyone BUT the hallucinator.
- other_args = list(
+ admin_forced_args = list(
duration = 30 SECONDS,
skip_nearby = FALSE,
affects_us = FALSE,
@@ -80,9 +45,9 @@
if(5)
// Send the same delusion to everyone, but...
- picked_hallucination = get_random_valid_hallucination_subtype(/datum/hallucination/delusion/preset)
+ admin_forced_hallucination = get_random_valid_hallucination_subtype(/datum/hallucination/delusion/preset)
// The delusion will affect only the hallucinator.
- other_args = list(
+ admin_forced_args = list(
duration = 45 SECONDS,
skip_nearby = FALSE,
affects_us = TRUE,
@@ -103,14 +68,14 @@
/datum/hallucination/xeno_attack,
)
- picked_hallucination = pick(generic_hallucinations)
+ admin_forced_hallucination = pick(generic_hallucinations)
- if(!picked_hallucination)
- CRASH("[type] couldn't find a hallucination to play. (Got: [picked_hallucination], Picked category: [category_to_pick_from])")
+ if(!admin_forced_hallucination)
+ CRASH("[type] couldn't find a hallucination to play. (Got: [admin_forced_hallucination], Picked category: [category_to_pick_from])")
- var/list/hallucination_args = list(picked_hallucination, "mass hallucination")
- if(islist(other_args))
- hallucination_args += other_args
+ var/list/hallucination_args = list(admin_forced_hallucination, "mass hallucination")
+ if(islist(admin_forced_args))
+ hallucination_args += admin_forced_args
// We'll only hallucinate for carbons now, even though livings can hallucinate just fine in most cases.
for(var/mob/living/carbon/hallucinating as anything in GLOB.carbon_list)
@@ -129,7 +94,39 @@
// Not using the wrapper here because we already have a list / arglist
hallucinating._cause_hallucination(hallucination_args)
-/datum/round_event/mass_hallucination/end()
- var/datum/round_event_control/mass_hallucination/our_controller = control
- our_controller.admin_forced_hallucination = null
- our_controller.admin_forced_args = null
+/datum/event_admin_setup/mass_hallucination
+ /// For admins, what hallucination did we pick
+ var/admin_forced_hallucination
+ /// For admins, what arguments are we passing to said hallucination
+ var/list/admin_forced_args
+
+/datum/event_admin_setup/mass_hallucination/prompt_admins()
+ var/force = tgui_alert(usr, "Do you want to force a hallucination?", event_control.name, list("Yes", "No", "Cancel"))
+ if(force == "Cancel")
+ return ADMIN_CANCEL_EVENT
+ if(force != "Yes")
+ return
+
+ var/force_what = tgui_alert(usr, "Generic hallucination or Custom configured delusion? (Delusions are those which make people appear as other mobs)", event_control.name, list("Hallucination", "Custom Delusion", "Cancel"))
+ switch(force_what)
+ if("Cancel")
+ return ADMIN_CANCEL_EVENT
+
+ if("Hallucination")
+ var/chosen = select_hallucination_type(usr, "What hallucination should be forced for [event_control.name]?", event_control.name)
+ if(!chosen || !check_rights(R_FUN))
+ return ADMIN_CANCEL_EVENT
+
+ admin_forced_hallucination = chosen
+
+ if("Custom Delusion")
+ var/list/chosen_args = create_delusion(usr)
+ if(!length(chosen_args) || !check_rights(R_FUN))
+ return ADMIN_CANCEL_EVENT
+
+ admin_forced_hallucination = chosen_args[HALLUCINATION_ARG_TYPE]
+ admin_forced_args = chosen_args.Copy(HALLUCINATION_ARGLIST)
+
+/datum/event_admin_setup/mass_hallucination/apply_to_event(datum/round_event/mass_hallucination/event)
+ event.admin_forced_hallucination = admin_forced_hallucination
+ event.admin_forced_args = admin_forced_args
diff --git a/code/modules/events/sandstorm.dm b/code/modules/events/sandstorm.dm
index d6a19b5d808..047fb0d5fc3 100644
--- a/code/modules/events/sandstorm.dm
+++ b/code/modules/events/sandstorm.dm
@@ -15,24 +15,7 @@
earliest_start = 35 MINUTES
category = EVENT_CATEGORY_SPACE
description = "A wave of space dust continually grinds down a side of the station."
- ///Where will the sandstorm be coming from -- Established in admin_setup, passed down to round_event
- var/start_side
-
-/datum/round_event_control/sandstorm/admin_setup()
- if(!check_rights(R_FUN))
- return ADMIN_CANCEL_EVENT
-
- if(tgui_alert(usr, "Choose a side to powersand?", "I hate sand.", list("Yes", "No")) == "Yes")
- var/chosen_direction = tgui_input_list(usr, "Pick one!","Rough, gets everywhere, coarse, etc.", list("Up", "Down", "Right", "Left"))
- switch(chosen_direction)
- if("Up")
- start_side = NORTH
- if("Down")
- start_side = SOUTH
- if("Right")
- start_side = EAST
- if("Left")
- start_side = WEST
+ admin_setup = /datum/event_admin_setup/listed_options/sandstorm
/datum/round_event/sandstorm
start_when = 60
@@ -46,10 +29,7 @@
end_when = rand(110, 140)
/datum/round_event/sandstorm/announce(fake)
- var/datum/round_event_control/sandstorm/sandstorm_event = control
- if(sandstorm_event.start_side)
- start_side = sandstorm_event.start_side
- else
+ if(!start_side)
start_side = pick(GLOB.cardinals)
var/start_side_text = "unknown"
@@ -98,3 +78,21 @@
/datum/round_event/sandstorm_classic/tick()
spawn_meteors(10, GLOB.meteors_dust)
+
+/datum/event_admin_setup/listed_options/sandstorm
+ input_text = "Choose a side to powersand?"
+ normal_run_option = "Random Sandstorm Direction"
+
+/datum/event_admin_setup/listed_options/sandstorm/get_list()
+ return list("Up", "Down", "Right", "Left")
+
+/datum/event_admin_setup/listed_options/sandstorm/apply_to_event(datum/round_event/sandstorm/event)
+ switch(chosen)
+ if("Up")
+ event.start_side = NORTH
+ if("Down")
+ event.start_side = SOUTH
+ if("Right")
+ event.start_side = EAST
+ if("Left")
+ event.start_side = WEST
diff --git a/code/modules/events/scrubber_overflow.dm b/code/modules/events/scrubber_overflow.dm
index 1fe0e07c588..153e10f23d8 100644
--- a/code/modules/events/scrubber_overflow.dm
+++ b/code/modules/events/scrubber_overflow.dm
@@ -6,6 +6,7 @@
min_players = 10
category = EVENT_CATEGORY_JANITORIAL
description = "The scrubbers release a tide of mostly harmless froth."
+ admin_setup = /datum/event_admin_setup/listed_options/scrubber_overflow
/datum/round_event/scrubber_overflow
announce_when = 1
@@ -151,13 +152,6 @@
/datum/round_event_control/scrubber_overflow/custom/announce_deadchat(random)
deadchat_broadcast(" has just been[random ? " randomly" : ""] triggered!", "Scrubber Overflow: [initial(custom_reagent.name)]", message_type=DEADCHAT_ANNOUNCEMENT)
-/datum/round_event_control/scrubber_overflow/custom/admin_setup(mob/admin)
- if(!check_rights(R_FUN))
- return
- custom_reagent = tgui_input_list(usr, "Choose a reagent to flood.", "Choose a reagent.", sort_list(subtypesof(/datum/reagent), /proc/cmp_typepaths_asc))
- if (isnull(custom_reagent))
- return ADMIN_CANCEL_EVENT
-
/datum/round_event/scrubber_overflow/custom
overflow_probability = 100
forced_reagent = /datum/reagent/consumable/ethanol/beer
@@ -167,3 +161,12 @@
var/datum/round_event_control/scrubber_overflow/custom/event_controller = control
forced_reagent = event_controller.custom_reagent
return ..()
+
+/datum/event_admin_setup/listed_options/scrubber_overflow
+ normal_run_option = "Random Reagent"
+
+/datum/event_admin_setup/listed_options/scrubber_overflow/get_list()
+ return sort_list(subtypesof(/datum/reagent), /proc/cmp_typepaths_asc)
+
+/datum/event_admin_setup/listed_options/scrubber_overflow/apply_to_event(datum/round_event/scrubber_overflow/event)
+ event.forced_reagent = chosen
diff --git a/code/modules/events/shuttle_catastrophe.dm b/code/modules/events/shuttle_catastrophe.dm
index 79a230a2dff..ac79108c016 100644
--- a/code/modules/events/shuttle_catastrophe.dm
+++ b/code/modules/events/shuttle_catastrophe.dm
@@ -5,6 +5,7 @@
max_occurrences = 1
category = EVENT_CATEGORY_BUREAUCRATIC
description = "Replaces the emergency shuttle with a random one."
+ admin_setup = /datum/event_admin_setup/warn_admin/shuttle_catastrophe
/datum/round_event_control/shuttle_catastrophe/can_spawn_event(players)
. = ..()
@@ -19,13 +20,6 @@
return FALSE //don't remove all players when its already on station or going to centcom
return TRUE
-/datum/round_event_control/shuttle_catastrophe/admin_setup(mob/admin)
- if(EMERGENCY_AT_LEAST_DOCKED || istype(SSshuttle.emergency, /obj/docking_port/mobile/emergency/shuttle_build))
- if(tgui_alert(usr, "WARNING: This will unload the currently docked emergency shuttle, and ERASE ANYTHING within it. Proceed anyways?", "How about a REAL catastrophe?", list("Yes", "No")) == "Yes")
- message_admins("[admin.ckey] has forced a shuttle catastrophe while a shuttle was already docked.") //Just in case
- else
- return ADMIN_CANCEL_EVENT
-
/datum/round_event/shuttle_catastrophe
var/datum/map_template/shuttle/new_shuttle
@@ -63,3 +57,10 @@
SSshuttle.existing_shuttle = SSshuttle.emergency
SSshuttle.action_load(new_shuttle, replace = TRUE)
log_shuttle("Shuttle Catastrophe set a new shuttle, [new_shuttle.name].")
+
+/datum/event_admin_setup/warn_admin/shuttle_catastrophe
+ warning_text = "This will unload the currently docked emergency shuttle, and ERASE ANYTHING within it. Proceed anyways?"
+ snitch_text = "has forced a shuttle catastrophe while a shuttle was already docked."
+
+/datum/event_admin_setup/warn_admin/shuttle_catastrophe/should_warn()
+ return EMERGENCY_AT_LEAST_DOCKED || istype(SSshuttle.emergency, /obj/docking_port/mobile/emergency/shuttle_build)
diff --git a/code/modules/events/shuttle_loan.dm b/code/modules/events/shuttle_loan.dm
deleted file mode 100644
index 9f047863b50..00000000000
--- a/code/modules/events/shuttle_loan.dm
+++ /dev/null
@@ -1,345 +0,0 @@
-#define HIJACK_SYNDIE "syndies"
-#define RUSKY_PARTY "ruskies"
-#define SPIDER_GIFT "spiders"
-#define DEPARTMENT_RESUPPLY "resupplies"
-#define ANTIDOTE_NEEDED "disease"
-#define PIZZA_DELIVERY "pizza"
-#define ITS_HIP_TO "bees"
-#define MY_GOD_JC "bomb"
-#define PAPERS_PLEASE "paperwork"
-
-/datum/round_event_control/shuttle_loan
- name = "Shuttle Loan"
- typepath = /datum/round_event/shuttle_loan
- max_occurrences = 3
- earliest_start = 7 MINUTES
- category = EVENT_CATEGORY_BUREAUCRATIC
- description = "If cargo accepts the offer, fills the shuttle with loot and/or enemies."
- ///The types of loan offers that the crew can recieve.
- var/list/shuttle_loan_offers = list(
- ANTIDOTE_NEEDED,
- DEPARTMENT_RESUPPLY,
- HIJACK_SYNDIE,
- ITS_HIP_TO,
- MY_GOD_JC,
- PIZZA_DELIVERY,
- RUSKY_PARTY,
- SPIDER_GIFT,
- PAPERS_PLEASE,
- )
- ///The types of loan events already run (and to be excluded if the event triggers).
- var/list/run_events = list()
- ///The admin-selected loan offer ID.
- var/chosen_event
-
-/datum/round_event_control/shuttle_loan/can_spawn_event(players_amt)
- . = ..()
-
- for(var/datum/round_event/running_event in SSevents.running)
- if(istype(running_event, /datum/round_event/shuttle_loan)) //Make sure two of these don't happen at once.
- return FALSE
-
-/datum/round_event_control/shuttle_loan/admin_setup()
- if(!check_rights(R_FUN))
- return ADMIN_CANCEL_EVENT
-
- if(tgui_alert(usr, "Select a loan offer?", "Trade Offer:", list("Yes", "No")) == "Yes")
- chosen_event = tgui_input_list(usr, "What deal would you like to offer the crew?", "Throw them a bone.", shuttle_loan_offers)
-
- for(var/datum/round_event/shuttle_loan/loan_event in SSevents.running)
- loan_event.kill() //Force out the old event for a new one to take its place
-
-/datum/round_event/shuttle_loan
- announce_when = 1
- end_when = 500
- var/dispatched = FALSE
- var/dispatch_type = "none"
- var/bonus_points = 10000
- var/thanks_msg = "The cargo shuttle should return in five minutes. Have some supply points for your trouble."
- var/loan_type //for logging
-
-/datum/round_event/shuttle_loan/setup()
-
- for(var/datum/round_event_control/shuttle_loan/loan_event_control in SSevents.control) //We can't call control, because it hasn't been set yet
- if(loan_event_control.chosen_event) //Pass down the admin selection and clean it for future use.
- dispatch_type = loan_event_control.chosen_event
- loan_event_control.chosen_event = null
- else //Otherwise, generate and pick from the list of offerable offers.
- var/list/loan_list = list()
- loan_list += loan_event_control.shuttle_loan_offers
- var/list/run_events = loan_event_control.run_events //Ask the round_event_control which loans have already been offered
- loan_list -= run_events //Remove the already offered loans from the candidate list
- if(!length(loan_list)) //If we somehow run out of loans, they all become available again
- loan_list += loan_event_control.shuttle_loan_offers
- run_events.Cut()
- dispatch_type = pick(loan_list) //Pick a loan to offer
- loan_event_control.run_events += dispatch_type //Regardless of admin selection, we add the event being run to the run_events list
-
-/datum/round_event/shuttle_loan/announce(fake)
- SSshuttle.shuttle_loan = src
- switch(dispatch_type)
- if(HIJACK_SYNDIE)
- priority_announce("Cargo: The syndicate are trying to infiltrate your station. If you let them hijack your cargo shuttle, you'll save us a headache.","CentCom Counterintelligence")
- if(RUSKY_PARTY)
- priority_announce("Cargo: A group of angry Russians want to have a party. Can you send them your cargo shuttle then make them disappear?","CentCom Russian Outreach Program")
- if(SPIDER_GIFT)
- priority_announce("Cargo: The Spider Clan has sent us a mysterious gift. Can we ship it to you to see what's inside?","CentCom Diplomatic Corps")
- if(DEPARTMENT_RESUPPLY)
- priority_announce("Cargo: Seems we've ordered doubles of our department resupply packages this month. Can we send them to you?","CentCom Supply Department")
- thanks_msg = "The cargo shuttle should return in five minutes."
- bonus_points = 0
- if(ANTIDOTE_NEEDED)
- priority_announce("Cargo: Your station has been chosen for an epidemiological research project. Send us your cargo shuttle to receive your research samples.", "CentCom Research Initiatives")
- if(PIZZA_DELIVERY)
- priority_announce("Cargo: It looks like a neighbouring station accidentally delivered their pizza to you instead.", "CentCom Spacepizza Division")
- thanks_msg = "The cargo shuttle should return in five minutes."
- bonus_points = 0
- if(ITS_HIP_TO)
- priority_announce("Cargo: One of our freighters carrying a bee shipment has been attacked by eco-terrorists. Can you clean up the mess for us?", "CentCom Janitorial Division")
- bonus_points = 20000 //Toxin bees can be unbeelievably lethal
- if(MY_GOD_JC)
- priority_announce("Cargo: We have discovered an active Syndicate bomb near our VIP shuttle's fuel lines. If you feel up to the task, we will pay you for defusing it.", "CentCom Security Division")
- thanks_msg = "Live explosive ordnance incoming via supply shuttle. Evacuating cargo bay is recommended."
- bonus_points = 45000 //If you mess up, people die and the shuttle gets turned into swiss cheese
- if(PAPERS_PLEASE)
- priority_announce("Cargo: A neighboring station needs some help handling some paperwork. Could you help process it for us?", "CentCom Paperwork Division")
- thanks_msg = "The cargo shuttle should return in five minutes. Payment will be rendered when the paperwork is processed and returned."
- bonus_points = 0 //Payout is made when the stamped papers are returned
- else
- log_game("Shuttle Loan event could not find [dispatch_type] event to offer.")
- kill()
- return
-
-/datum/round_event/shuttle_loan/proc/loan_shuttle()
- priority_announce(thanks_msg, "Cargo shuttle commandeered by CentCom.")
-
- dispatched = TRUE
- var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR)
- if(D)
- D.adjust_money(bonus_points)
- end_when = activeFor + 1
-
- SSshuttle.supply.mode = SHUTTLE_CALL
- SSshuttle.supply.destination = SSshuttle.getDock("cargo_home")
- SSshuttle.supply.setTimer(3000)
-
- switch(dispatch_type)
- if(HIJACK_SYNDIE)
- SSshuttle.centcom_message += "Syndicate hijack team incoming."
- loan_type = "Syndicate boarding party"
- if(RUSKY_PARTY)
- SSshuttle.centcom_message += "Partying Russians incoming."
- loan_type = "Russian party squad"
- if(SPIDER_GIFT)
- SSshuttle.centcom_message += "Spider Clan gift incoming."
- loan_type = "Shuttle full of spiders"
- if(DEPARTMENT_RESUPPLY)
- SSshuttle.centcom_message += "Department resupply incoming."
- loan_type = "Resupply packages"
- if(ANTIDOTE_NEEDED)
- SSshuttle.centcom_message += "Virus samples incoming."
- loan_type = "Virus shuttle"
- if(PIZZA_DELIVERY)
- SSshuttle.centcom_message += "Pizza delivery for [station_name()]"
- loan_type = "Pizza delivery"
- if(ITS_HIP_TO)
- SSshuttle.centcom_message += "Biohazard cleanup incoming."
- loan_type = "Shuttle full of bees"
- if(MY_GOD_JC)
- SSshuttle.centcom_message += "Live explosive ordnance incoming. Exercise extreme caution."
- loan_type = "Shuttle with a ticking bomb"
- if(PAPERS_PLEASE)
- SSshuttle.centcom_message += "Paperwork incoming."
- loan_type = "Paperwork shipment"
-
- log_game("Shuttle loan event firing with type '[loan_type]'.")
-
-/datum/round_event/shuttle_loan/tick()
- if(dispatched)
- if(SSshuttle.supply.mode != SHUTTLE_IDLE)
- end_when = activeFor
- else
- end_when = activeFor + 1
-
-/datum/round_event/shuttle_loan/end()
- if(SSshuttle.shuttle_loan && SSshuttle.shuttle_loan.dispatched)
- //make sure the shuttle was dispatched in time
- SSshuttle.shuttle_loan = null
-
- var/list/empty_shuttle_turfs = list()
- var/list/area/shuttle/shuttle_areas = SSshuttle.supply.shuttle_areas
- for(var/place in shuttle_areas)
- var/area/shuttle/shuttle_area = place
- for(var/turf/open/floor/T in shuttle_area)
- if(T.is_blocked_turf())
- continue
- empty_shuttle_turfs += T
- if(!empty_shuttle_turfs.len)
- return
-
- var/list/shuttle_spawns = list()
- switch(dispatch_type)
- if(HIJACK_SYNDIE)
- var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/emergency/specialops]
- pack.generate(pick_n_take(empty_shuttle_turfs))
-
- shuttle_spawns.Add(/mob/living/basic/syndicate/ranged/infiltrator)
- shuttle_spawns.Add(/mob/living/basic/syndicate/ranged/infiltrator)
- if(prob(75))
- shuttle_spawns.Add(/mob/living/basic/syndicate/ranged/infiltrator)
- if(prob(50))
- shuttle_spawns.Add(/mob/living/basic/syndicate/ranged/infiltrator)
-
- if(RUSKY_PARTY)
- var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/service/party]
- pack.generate(pick_n_take(empty_shuttle_turfs))
-
- shuttle_spawns.Add(/mob/living/simple_animal/hostile/russian)
- shuttle_spawns.Add(/mob/living/simple_animal/hostile/russian/ranged) //drops a mateba
- shuttle_spawns.Add(/mob/living/simple_animal/hostile/bear/russian)
- if(prob(75))
- shuttle_spawns.Add(/mob/living/simple_animal/hostile/russian)
- if(prob(50))
- shuttle_spawns.Add(/mob/living/simple_animal/hostile/bear/russian)
-
- if(SPIDER_GIFT)
- var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/emergency/specialops]
- pack.generate(pick_n_take(empty_shuttle_turfs))
-
- shuttle_spawns.Add(/mob/living/simple_animal/hostile/giant_spider)
- shuttle_spawns.Add(/mob/living/simple_animal/hostile/giant_spider)
- shuttle_spawns.Add(/mob/living/simple_animal/hostile/giant_spider/nurse)
- if(prob(50))
- shuttle_spawns.Add(/mob/living/simple_animal/hostile/giant_spider/hunter)
-
- var/turf/T = pick_n_take(empty_shuttle_turfs)
-
- new /obj/effect/decal/remains/human(T)
- new /obj/item/clothing/shoes/jackboots/fast(T)
- new /obj/item/clothing/mask/balaclava(T)
-
- for(var/i in 1 to 5)
- T = pick_n_take(empty_shuttle_turfs)
- new /obj/structure/spider/stickyweb(T)
-
- if(ANTIDOTE_NEEDED)
- var/obj/effect/mob_spawn/corpse/human/assistant/infected_assistant = pick(/obj/effect/mob_spawn/corpse/human/assistant/beesease_infection, /obj/effect/mob_spawn/corpse/human/assistant/brainrot_infection, /obj/effect/mob_spawn/corpse/human/assistant/spanishflu_infection)
- var/turf/T
- for(var/i in 1 to 10)
- if(prob(15))
- shuttle_spawns.Add(/obj/item/reagent_containers/cup/bottle)
- else if(prob(15))
- shuttle_spawns.Add(/obj/item/reagent_containers/syringe)
- else if(prob(25))
- shuttle_spawns.Add(/obj/item/shard)
- T = pick_n_take(empty_shuttle_turfs)
- new infected_assistant(T)
- shuttle_spawns.Add(/obj/structure/closet/crate)
- shuttle_spawns.Add(/obj/item/reagent_containers/cup/bottle/pierrot_throat)
- shuttle_spawns.Add(/obj/item/reagent_containers/cup/bottle/magnitis)
-
- if(DEPARTMENT_RESUPPLY)
- var/list/crate_types = list(
- /datum/supply_pack/emergency/equipment,
- /datum/supply_pack/security/supplies,
- /datum/supply_pack/organic/food,
- /datum/supply_pack/emergency/weedcontrol,
- /datum/supply_pack/engineering/tools,
- /datum/supply_pack/engineering/engiequipment,
- /datum/supply_pack/science/robotics,
- /datum/supply_pack/science/plasma,
- /datum/supply_pack/medical/supplies
- )
- for(var/crate in crate_types)
- var/datum/supply_pack/pack = SSshuttle.supply_packs[crate]
- pack.generate(pick_n_take(empty_shuttle_turfs))
-
- for(var/i in 1 to 5)
- var/decal = pick(/obj/effect/decal/cleanable/food/flour, /obj/effect/decal/cleanable/robot_debris, /obj/effect/decal/cleanable/oil)
- new decal(pick_n_take(empty_shuttle_turfs))
- if(PIZZA_DELIVERY)
- var/naughtypizza = list(/obj/item/pizzabox/bomb,/obj/item/pizzabox/margherita/robo) //oh look another blaklist, for pizza nonetheless!
- var/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)
- shuttle_spawns.Add(pick(prob(5) ? naughtypizza : nicepizza))
- if(ITS_HIP_TO)
- var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/organic/hydroponics/beekeeping_fullkit]
- pack.generate(pick_n_take(empty_shuttle_turfs))
-
- shuttle_spawns.Add(/obj/effect/mob_spawn/corpse/human/bee_terrorist)
- shuttle_spawns.Add(/obj/effect/mob_spawn/corpse/human/cargo_tech)
- shuttle_spawns.Add(/obj/effect/mob_spawn/corpse/human/cargo_tech)
- shuttle_spawns.Add(/obj/effect/mob_spawn/corpse/human/nanotrasensoldier)
- shuttle_spawns.Add(/obj/item/gun/ballistic/automatic/pistol/no_mag)
- shuttle_spawns.Add(/obj/item/gun/ballistic/automatic/pistol/m1911/no_mag)
- shuttle_spawns.Add(/obj/item/honey_frame)
- shuttle_spawns.Add(/obj/item/honey_frame)
- shuttle_spawns.Add(/obj/item/honey_frame)
- shuttle_spawns.Add(/obj/structure/beebox/unwrenched)
- shuttle_spawns.Add(/obj/item/queen_bee/bought)
- shuttle_spawns.Add(/obj/structure/closet/crate/hydroponics)
-
- for(var/i in 1 to 8)
- shuttle_spawns.Add(/mob/living/simple_animal/hostile/bee/toxin)
-
- 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/ammo_casing/spent
- new casing(pick_n_take(empty_shuttle_turfs))
-
- if(MY_GOD_JC)
- shuttle_spawns.Add(/obj/machinery/syndicatebomb/shuttle_loan)
- if(prob(95))
- shuttle_spawns.Add(/obj/item/paper/fluff/cargo/bomb)
- else
- shuttle_spawns.Add(/obj/item/paper/fluff/cargo/bomb/allyourbase)
-
- if(PAPERS_PLEASE)
- shuttle_spawns += subtypesof(/obj/item/paperwork) - typesof(/obj/item/paperwork/photocopy) - typesof(/obj/item/paperwork/ancient)
-
- var/false_positive = 0
- while(shuttle_spawns.len && empty_shuttle_turfs.len)
- var/turf/T = pick_n_take(empty_shuttle_turfs)
- if(T.contents.len && false_positive < 5)
- false_positive++
- continue
-
- var/spawn_type = pick_n_take(shuttle_spawns)
- new spawn_type(T)
-
-//items that appear only in shuttle loan events
-
-/obj/item/storage/belt/fannypack/yellow/bee_terrorist/PopulateContents()
- new /obj/item/grenade/c4 (src)
- new /obj/item/reagent_containers/pill/cyanide(src)
- new /obj/item/grenade/chem_grenade/facid(src)
-
-/obj/item/paper/fluff/bee_objectives
- name = "Objectives of a Bee Liberation Front Operative"
- default_raw_text = "Objective #1. Liberate all bees on the NT transport vessel 2416/B. Success!
Objective #2. Escape alive. Failed."
-
-/obj/machinery/syndicatebomb/shuttle_loan/Initialize(mapload)
- . = ..()
- set_anchored(TRUE)
- timer_set = rand(480, 600) //once the supply shuttle docks (after 5 minutes travel time), players have between 3-5 minutes to defuse the bomb
- activate()
- update_appearance()
-
-/obj/item/paper/fluff/cargo/bomb
- name = "hastly scribbled note"
- default_raw_text = "GOOD LUCK!"
-
-/obj/item/paper/fluff/cargo/bomb/allyourbase
- default_raw_text = "Somebody set us up the bomb!"
-
-#undef HIJACK_SYNDIE
-#undef RUSKY_PARTY
-#undef SPIDER_GIFT
-#undef DEPARTMENT_RESUPPLY
-#undef ANTIDOTE_NEEDED
-#undef PIZZA_DELIVERY
-#undef ITS_HIP_TO
-#undef MY_GOD_JC
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..ba85a41132a
--- /dev/null
+++ b/code/modules/events/shuttle_loan/shuttle_loan_datum.dm
@@ -0,0 +1,213 @@
+/// One of the potential shuttle loans you might recieve.
+/datum/shuttle_loan_situation
+ /// Who sent the shuttle
+ var/sender = "Centcom"
+ /// What they said about it.
+ var/announcement_text = "Unset announcement text"
+ /// What the shuttle says about it.
+ var/shuttle_transit_text = "Unset transit text"
+ /// Supply points earned for taking the deal.
+ var/bonus_points = 10000
+ /// Response for taking the deal.
+ var/thanks_msg = "The cargo shuttle should return in five minutes. Have some supply points for your trouble."
+ /// 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/antidote
+ sender = "CentCom Research Initiatives"
+ announcement_text = "Your station has been chosen for an epidemiological research project. Send us your cargo shuttle to receive your research samples."
+ shuttle_transit_text = "Virus samples incoming."
+ logging_desc = "Virus shuttle"
+
+/datum/shuttle_loan_situation/antidote/spawn_items(list/spawn_list, list/empty_shuttle_turfs)
+ var/obj/effect/mob_spawn/corpse/human/assistant/infected_assistant = pick(list(
+ /obj/effect/mob_spawn/corpse/human/assistant/beesease_infection,
+ /obj/effect/mob_spawn/corpse/human/assistant/brainrot_infection,
+ /obj/effect/mob_spawn/corpse/human/assistant/spanishflu_infection,
+ ))
+ for(var/i in 1 to 10)
+ if(prob(15))
+ spawn_list.Add(/obj/item/reagent_containers/cup/bottle)
+ else if(prob(15))
+ spawn_list.Add(/obj/item/reagent_containers/syringe)
+ else if(prob(25))
+ spawn_list.Add(/obj/item/shard)
+ var/turf/assistant_turf = pick_n_take(empty_shuttle_turfs)
+ new infected_assistant(assistant_turf)
+ spawn_list.Add(/obj/structure/closet/crate)
+ spawn_list.Add(/obj/item/reagent_containers/cup/bottle/pierrot_throat)
+ spawn_list.Add(/obj/item/reagent_containers/cup/bottle/magnitis)
+
+/datum/shuttle_loan_situation/department_resupply
+ sender = "CentCom Supply Department"
+ announcement_text = "Seems we've ordered doubles of our department resupply packages this month. Can we send them to you?"
+ shuttle_transit_text = "Department resupply incoming."
+ thanks_msg = "The cargo shuttle should return in five minutes."
+ bonus_points = 0
+ logging_desc = "Resupply packages"
+
+/datum/shuttle_loan_situation/department_resupply/spawn_items(list/spawn_list, list/empty_shuttle_turfs)
+ var/list/crate_types = list(
+ /datum/supply_pack/emergency/equipment,
+ /datum/supply_pack/security/supplies,
+ /datum/supply_pack/organic/food,
+ /datum/supply_pack/emergency/weedcontrol,
+ /datum/supply_pack/engineering/tools,
+ /datum/supply_pack/engineering/engiequipment,
+ /datum/supply_pack/science/robotics,
+ /datum/supply_pack/science/plasma,
+ /datum/supply_pack/medical/supplies
+ )
+ for(var/crate in crate_types)
+ var/datum/supply_pack/pack = SSshuttle.supply_packs[crate]
+ pack.generate(pick_n_take(empty_shuttle_turfs))
+
+ for(var/i in 1 to 5)
+ var/decal = pick(/obj/effect/decal/cleanable/food/flour, /obj/effect/decal/cleanable/robot_debris, /obj/effect/decal/cleanable/oil)
+ new decal(pick_n_take(empty_shuttle_turfs))
+
+/datum/shuttle_loan_situation/department_resupply
+ sender = "CentCom Counterintelligence"
+ announcement_text = "The syndicate are trying to infiltrate your station. If you let them hijack your cargo shuttle, you'll save us a headache."
+ shuttle_transit_text = "Syndicate hijack team incoming."
+ logging_desc = "Syndicate boarding party"
+
+/datum/shuttle_loan_situation/department_resupply/spawn_items(list/spawn_list, list/empty_shuttle_turfs)
+ var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/emergency/specialops]
+ pack.generate(pick_n_take(empty_shuttle_turfs))
+
+ spawn_list.Add(/mob/living/basic/syndicate/ranged/infiltrator)
+ spawn_list.Add(/mob/living/basic/syndicate/ranged/infiltrator)
+ if(prob(75))
+ spawn_list.Add(/mob/living/basic/syndicate/ranged/infiltrator)
+ if(prob(50))
+ spawn_list.Add(/mob/living/basic/syndicate/ranged/infiltrator)
+
+/datum/shuttle_loan_situation/lots_of_bees
+ sender = "CentCom Janitorial Division"
+ announcement_text = "One of our freighters carrying a bee shipment has been attacked by eco-terrorists. Can you clean up the mess for us?"
+ shuttle_transit_text = "Biohazard cleanup incoming."
+ bonus_points = 20000 //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)
+ var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/organic/hydroponics/beekeeping_fullkit]
+ pack.generate(pick_n_take(empty_shuttle_turfs))
+
+ spawn_list.Add(/obj/effect/mob_spawn/corpse/human/bee_terrorist)
+ spawn_list.Add(/obj/effect/mob_spawn/corpse/human/cargo_tech)
+ spawn_list.Add(/obj/effect/mob_spawn/corpse/human/cargo_tech)
+ spawn_list.Add(/obj/effect/mob_spawn/corpse/human/nanotrasensoldier)
+ spawn_list.Add(/obj/item/gun/ballistic/automatic/pistol/no_mag)
+ spawn_list.Add(/obj/item/gun/ballistic/automatic/pistol/m1911/no_mag)
+ 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)
+
+ for(var/i in 1 to 8)
+ spawn_list.Add(/mob/living/simple_animal/hostile/bee/toxin)
+
+ 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/ammo_casing/spent
+ new casing(pick_n_take(empty_shuttle_turfs))
+
+/datum/shuttle_loan_situation/jc_a_bomb
+ sender = "CentCom Security Division"
+ announcement_text = "We have discovered an active Syndicate bomb near our VIP shuttle's fuel lines. If you feel up to the task, we will pay you for defusing it."
+ shuttle_transit_text = "Live explosive ordnance incoming. Exercise extreme caution."
+ thanks_msg = "Live explosive ordnance incoming via supply shuttle. Evacuating cargo bay is recommended."
+ bonus_points = 45000 //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)
+ if(prob(95))
+ spawn_list.Add(/obj/item/paper/fluff/cargo/bomb)
+ else
+ spawn_list.Add(/obj/item/paper/fluff/cargo/bomb/allyourbase)
+
+/datum/shuttle_loan_situation/papers_please
+ sender = "CentCom Paperwork Division"
+ announcement_text = "A neighboring station needs some help handling some paperwork. Could you help process it for us?"
+ shuttle_transit_text = "Paperwork incoming."
+ thanks_msg = "The cargo shuttle should return in five minutes. Payment will be rendered when the paperwork is processed and returned."
+ bonus_points = 0 //Payout is made when the stamped papers are returned
+ logging_desc = "Paperwork shipment"
+
+/datum/shuttle_loan_situation/papers_please/spawn_items(list/spawn_list, list/empty_shuttle_turfs)
+ spawn_list += subtypesof(/obj/item/paperwork) - typesof(/obj/item/paperwork/photocopy) - typesof(/obj/item/paperwork/ancient)
+
+/datum/shuttle_loan_situation/pizza_delivery
+ sender = "CentCom Spacepizza Division"
+ announcement_text = "It looks like a neighbouring station accidentally delivered their pizza to you instead."
+ shuttle_transit_text = "Pizza delivery!"
+ thanks_msg = "The cargo shuttle should return in five minutes."
+ bonus_points = 0
+ logging_desc = "Pizza delivery"
+
+/datum/shuttle_loan_situation/pizza_delivery/spawn_items(list/spawn_list, list/empty_shuttle_turfs)
+ var/naughtypizza = list(/obj/item/pizzabox/bomb, /obj/item/pizzabox/margherita/robo) //oh look another blacklist, for pizza nonetheless!
+ var/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 = "CentCom Russian Outreach Program"
+ announcement_text = "A group of angry Russians want to have a party. Can you send them your cargo shuttle then make them disappear?"
+ shuttle_transit_text = "Partying Russians incoming."
+ logging_desc = "Russian party squad"
+
+/datum/shuttle_loan_situation/russian_party/spawn_items(list/spawn_list, list/empty_shuttle_turfs)
+ var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/service/party]
+ pack.generate(pick_n_take(empty_shuttle_turfs))
+
+ spawn_list.Add(/mob/living/simple_animal/hostile/russian)
+ spawn_list.Add(/mob/living/simple_animal/hostile/russian/ranged) //drops a mateba
+ spawn_list.Add(/mob/living/simple_animal/hostile/bear/russian)
+ if(prob(75))
+ spawn_list.Add(/mob/living/simple_animal/hostile/russian)
+ if(prob(50))
+ spawn_list.Add(/mob/living/simple_animal/hostile/bear/russian)
+
+/datum/shuttle_loan_situation/spider_gift
+ sender = "CentCom Diplomatic Corps"
+ announcement_text = "The Spider Clan has sent us a mysterious gift. Can we ship it to you to see what's inside?"
+ shuttle_transit_text = "Spider Clan gift incoming."
+ logging_desc = "Shuttle full of spiders"
+
+/datum/shuttle_loan_situation/spider_gift/spawn_items(list/spawn_list, list/empty_shuttle_turfs)
+ var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/emergency/specialops]
+ pack.generate(pick_n_take(empty_shuttle_turfs))
+
+ spawn_list.Add(/mob/living/simple_animal/hostile/giant_spider)
+ spawn_list.Add(/mob/living/simple_animal/hostile/giant_spider)
+ spawn_list.Add(/mob/living/simple_animal/hostile/giant_spider/nurse)
+ if(prob(50))
+ spawn_list.Add(/mob/living/simple_animal/hostile/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/fast(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)
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..8dd08772166
--- /dev/null
+++ b/code/modules/events/shuttle_loan/shuttle_loan_event.dm
@@ -0,0 +1,106 @@
+
+/datum/round_event_control/shuttle_loan
+ name = "Shuttle Loan"
+ typepath = /datum/round_event/shuttle_loan
+ max_occurrences = 3
+ earliest_start = 7 MINUTES
+ category = EVENT_CATEGORY_BUREAUCRATIC
+ description = "If cargo accepts the offer, fills the shuttle with loot and/or enemies."
+ ///The types of loan events already run (and to be excluded if the event triggers).
+ admin_setup = /datum/event_admin_setup/listed_options/shuttle_loan
+ var/list/run_situations = list()
+
+/datum/round_event_control/shuttle_loan/can_spawn_event(players_amt)
+ . = ..()
+ for(var/datum/round_event/running_event in SSevents.running)
+ if(istype(running_event, /datum/round_event/shuttle_loan)) //Make sure two of these don't happen at once.
+ return FALSE
+
+/datum/round_event/shuttle_loan
+ announce_when = 1
+ end_when = 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
+
+/datum/round_event/shuttle_loan/setup()
+ var/datum/round_event_control/shuttle_loan/loan_control = control
+ //by this point if situation is admin picked, it is a type, not an instance.
+ if(!situation)
+ var/list/valid_situations = subtypesof(/datum/shuttle_loan_situation) - loan_control.run_situations
+ if(!valid_situations.len)
+ //If we somehow run out of loans (fking campbell), they all become available again
+ loan_control.run_situations.Cut()
+ valid_situations = subtypesof(/datum/shuttle_loan_situation)
+ situation = pick(valid_situations)
+
+ loan_control.run_situations.Add(situation)
+ situation = new situation()
+
+/datum/round_event/shuttle_loan/announce(fake)
+ priority_announce("Cargo: [situation.announcement_text]", situation.sender)
+ SSshuttle.shuttle_loan = src
+
+/datum/round_event/shuttle_loan/proc/loan_shuttle()
+ priority_announce(situation.thanks_msg, "Cargo shuttle commandeered by CentCom.")
+
+ dispatched = TRUE
+ var/datum/bank_account/dep_account = SSeconomy.get_dep_account(ACCOUNT_CAR)
+ dep_account?.adjust_money(situation.bonus_points)
+ end_when = activeFor + 1
+
+ SSshuttle.supply.mode = SHUTTLE_CALL
+ SSshuttle.supply.destination = SSshuttle.getDock("cargo_home")
+ SSshuttle.supply.setTimer(3000)
+ SSshuttle.centcom_message += situation.shuttle_transit_text
+
+ log_game("Shuttle loan event firing with type '[situation.logging_desc]'.")
+
+/datum/round_event/shuttle_loan/tick()
+ if(dispatched)
+ if(SSshuttle.supply.mode != SHUTTLE_IDLE)
+ end_when = activeFor
+ else
+ end_when = activeFor + 1
+
+/datum/round_event/shuttle_loan/end()
+ if(!SSshuttle.shuttle_loan || !SSshuttle.shuttle_loan.dispatched)
+ return
+ //make sure the shuttle was dispatched in time
+ SSshuttle.shuttle_loan = null
+
+ //get empty turfs
+ var/list/empty_shuttle_turfs = list()
+ var/list/area/shuttle/shuttle_areas = SSshuttle.supply.shuttle_areas
+ for(var/area/shuttle/shuttle_area as anything in shuttle_areas)
+ for(var/turf/open/floor/shuttle_turf in shuttle_area)
+ if(shuttle_turf.is_blocked_turf())
+ continue
+ empty_shuttle_turfs += shuttle_turf
+ if(!empty_shuttle_turfs.len)
+ return
+
+ //let the situation spawn its items
+ var/list/spawn_list = list()
+ situation.spawn_items(spawn_list, empty_shuttle_turfs)
+
+ var/false_positive = 0
+ while(spawn_list.len && empty_shuttle_turfs.len)
+ var/turf/spawn_turf = pick_n_take(empty_shuttle_turfs)
+ if(spawn_turf.contents.len && false_positive < 5)
+ false_positive++
+ continue
+ var/spawn_type = pick_n_take(spawn_list)
+ new spawn_type(spawn_turf)
+
+/datum/event_admin_setup/listed_options/shuttle_loan
+ input_text = "Select a loan offer?"
+
+/datum/event_admin_setup/listed_options/shuttle_loan/get_list()
+ var/datum/round_event_control/shuttle_loan/loan_event = event_control
+ var/list/valid_situations = subtypesof(/datum/shuttle_loan_situation) - loan_event.run_situations
+ return valid_situations
+
+/datum/event_admin_setup/listed_options/shuttle_loan/apply_to_event(datum/round_event/shuttle_loan/event)
+ event.situation = chosen
diff --git a/code/modules/events/shuttle_loan/shuttle_loan_items.dm b/code/modules/events/shuttle_loan/shuttle_loan_items.dm
new file mode 100644
index 00000000000..ded82c6e1a6
--- /dev/null
+++ b/code/modules/events/shuttle_loan/shuttle_loan_items.dm
@@ -0,0 +1,23 @@
+
+/obj/item/storage/belt/fannypack/yellow/bee_terrorist/PopulateContents()
+ new /obj/item/grenade/c4 (src)
+ new /obj/item/reagent_containers/pill/cyanide(src)
+ new /obj/item/grenade/chem_grenade/facid(src)
+
+/obj/item/paper/fluff/bee_objectives
+ name = "Objectives of a Bee Liberation Front Operative"
+ default_raw_text = "Objective #1. Liberate all bees on the NT transport vessel 2416/B. Success!
Objective #2. Escape alive. Failed."
+
+/obj/machinery/syndicatebomb/shuttle_loan/Initialize(mapload)
+ . = ..()
+ set_anchored(TRUE)
+ timer_set = rand(480, 600) //once the supply shuttle docks (after 5 minutes travel time), players have between 3-5 minutes to defuse the bomb
+ activate()
+ update_appearance()
+
+/obj/item/paper/fluff/cargo/bomb
+ name = "hastly scribbled note"
+ default_raw_text = "GOOD LUCK!"
+
+/obj/item/paper/fluff/cargo/bomb/allyourbase
+ default_raw_text = "Somebody set us up the bomb!"
diff --git a/code/modules/events/stray_meteor.dm b/code/modules/events/stray_meteor.dm
index 89ae470fa5b..a526dba7cb6 100644
--- a/code/modules/events/stray_meteor.dm
+++ b/code/modules/events/stray_meteor.dm
@@ -7,30 +7,17 @@
earliest_start = 20 MINUTES
category = EVENT_CATEGORY_SPACE
description = "Throw a random meteor somewhere near the station."
- ///The selected meteor type if chosen through admin setup.
- var/chosen_meteor
-
-/datum/round_event_control/stray_meteor/admin_setup()
- if(!check_rights(R_FUN))
- return ADMIN_CANCEL_EVENT
-
- if(tgui_alert(usr, "Select a meteor?", "Plasuable Deniability!", list("Yes", "No")) == "Yes")
- var/list/meteor_list = list()
- meteor_list += subtypesof(/obj/effect/meteor)
- chosen_meteor = tgui_input_list(usr, "Too lazy for buildmode?","Throw meteor", meteor_list)
+ admin_setup = /datum/event_admin_setup/listed_options/stray_meteor
/datum/round_event/stray_meteor
announce_when = 1
fakeable = FALSE //Already faked by meteors that miss
+ ///The selected meteor type if chosen through admin setup.
+ var/chosen_meteor
/datum/round_event/stray_meteor/start()
- var/datum/round_event_control/stray_meteor/meteor_event = control
- if(meteor_event.chosen_meteor)
- var/chosen_meteor = meteor_event.chosen_meteor
- meteor_event.chosen_meteor = null
- var/list/passed_meteor = list()
- passed_meteor[chosen_meteor] = 1
- spawn_meteor(passed_meteor)
+ if(chosen_meteor)
+ spawn_meteor(list(chosen_meteor = 1))
else
spawn_meteor(GLOB.meteors_stray)
@@ -39,3 +26,13 @@
var/obj/effect/meteor/detected_meteor = pick(GLOB.meteor_list) //If we accidentally pick a meteor not spawned by the event, we're still technically not wrong
var/sensor_name = detected_meteor.signature
priority_announce("Our [sensor_name] sensors have detected an incoming signature approaching [GLOB.station_name]. Please brace for impact.", "Meteor Alert")
+
+/datum/event_admin_setup/listed_options/stray_meteor
+ input_text = "Select a meteor type?"
+ normal_run_option = "Random Meteor"
+
+/datum/event_admin_setup/listed_options/stray_meteor/get_list()
+ return subtypesof(/obj/effect/meteor)
+
+/datum/event_admin_setup/listed_options/stray_meteor/apply_to_event(datum/round_event/stray_meteor/event)
+ event.chosen_meteor = chosen
diff --git a/code/modules/events/wizard/departmentrevolt.dm b/code/modules/events/wizard/departmentrevolt.dm
index 4fedb8e784e..48929a0cc3c 100644
--- a/code/modules/events/wizard/departmentrevolt.dm
+++ b/code/modules/events/wizard/departmentrevolt.dm
@@ -1,3 +1,6 @@
+
+#define RANDOM_DEPARTMENT "Random Department"
+
/datum/round_event_control/wizard/deprevolt //stationwide!
name = "Departmental Uprising"
weight = 0 //An order that requires order in a round of chaos was maybe not the best idea. Requiescat in pace departmental uprising August 2014 - March 2015 //hello motherfucker i fixed your shit in 2021
@@ -5,25 +8,39 @@
max_occurrences = 1
earliest_start = 0 MINUTES
description = "A department is turned into an independent state."
+ admin_setup = /datum/event_admin_setup/department_revolt
- ///manual choice of what department to revolt for admins to pick
+/datum/round_event/wizard/deprevolt
+ ///which department is revolting?
var/datum/job_department/picked_department
- ///admin choice on whether to announce the department
+ /// Announce the separatist nation to the round?
var/announce = FALSE
- ///admin choice on whether this nation will have objectives to attack other nations, default true for !fun!
+ /// Is it going to try fighting other nations?
var/dangerous_nation = TRUE
-/datum/round_event_control/wizard/deprevolt/admin_setup(mob/admin)
- if(!check_rights(R_FUN))
- return
+/datum/round_event/wizard/deprevolt/start()
+ // no setup needed, this proc handles empty values. God i'm good (i wrote all of this)
+ create_separatist_nation(picked_department, announce, dangerous_nation)
- var/list/options = list()
+/datum/event_admin_setup/department_revolt
+ ///which department is revolting?
+ var/datum/job_department/picked_department
+ /// Announce the separatist nation to the round?
+ var/announce = FALSE
+ /// Is it going to try fighting other nations?
+ var/dangerous_nation = TRUE
+
+/datum/event_admin_setup/department_revolt/prompt_admins()
+ var/list/options = list("Random" = RANDOM_DEPARTMENT)
var/list/pickable_departments = subtypesof(/datum/job_department)
for(var/datum/job_department/dep as anything in pickable_departments)
options[initial(dep.department_name)] = dep
- picked_department = options[(input(usr,"Which department should revolt? Select none for a random department.","Select a department") as null|anything in options)]
+ picked_department = options[(tgui_input_list(usr,"Which department should revolt? Select none for a random department.","Select a department", options))]
if(!picked_department)
- return //eh just random they dont care
+ return ADMIN_CANCEL_EVENT
+ if(picked_department == RANDOM_DEPARTMENT)
+ picked_department = null
+ return
var/announce_question = tgui_alert(usr, "Announce This New Independent State?", "Secession", list("Announce", "No Announcement"))
if(announce_question == "Announce")
@@ -33,6 +50,9 @@
if(dangerous_question == "No")
dangerous_nation = FALSE
-/datum/round_event/wizard/deprevolt/start()
- var/datum/round_event_control/wizard/deprevolt/event_control = control
- create_separatist_nation(event_control.picked_department, event_control.announce, event_control.dangerous_nation)
+/datum/event_admin_setup/department_revolt/apply_to_event(datum/round_event/wizard/deprevolt/event)
+ event.picked_department = picked_department
+ event.announce = announce
+ event.dangerous_nation = dangerous_nation
+
+#undef RANDOM_DEPARTMENT
diff --git a/code/modules/events/wizard/madness.dm b/code/modules/events/wizard/madness.dm
index bcf40be2883..07d374ee879 100644
--- a/code/modules/events/wizard/madness.dm
+++ b/code/modules/events/wizard/madness.dm
@@ -4,26 +4,23 @@
typepath = /datum/round_event/wizard/madness
earliest_start = 0 MINUTES
description = "Reveals a horrifying truth to everyone, giving them a trauma."
+ admin_setup = /datum/event_admin_setup/text_input/madness
- var/forced_secret
-
-/datum/round_event_control/wizard/madness/admin_setup(mob/admin)
- if(!check_rights(R_FUN))
- return
-
- var/suggested = pick(strings(REDPILL_FILE, "redpill_questions"))
-
- forced_secret = (input(usr, "What horrifying truth will you reveal?", "Curse of Madness", sort_list(suggested)) as text|null) || suggested
-
-/datum/round_event/wizard/madness/start()
- var/datum/round_event_control/wizard/madness/C = control
-
+/datum/round_event/wizard/madness
+ /// the horrifying truth sent to the crew, can be picked by admins.
var/horrifying_truth
- if(C.forced_secret)
- horrifying_truth = C.forced_secret
- C.forced_secret = null
- else
+/datum/round_event/wizard/madness/start()
+ if(!horrifying_truth)
horrifying_truth = pick(strings(REDPILL_FILE, "redpill_questions"))
curse_of_madness(null, horrifying_truth)
+
+/datum/event_admin_setup/text_input/madness
+ input_text = "What horrifying truth will you reveal?"
+
+/datum/event_admin_setup/text_input/madness/get_text_suggestion()
+ return pick(strings(REDPILL_FILE, "redpill_questions"))
+
+/datum/event_admin_setup/text_input/madness/apply_to_event(datum/round_event/wizard/madness/event)
+ event.horrifying_truth = chosen
diff --git a/modular_skyrat/master_files/code/modules/events/disease_outbreak.dm b/modular_skyrat/master_files/code/modules/events/disease_outbreak.dm
deleted file mode 100644
index 14d73eb506a..00000000000
--- a/modular_skyrat/master_files/code/modules/events/disease_outbreak.dm
+++ /dev/null
@@ -1,31 +0,0 @@
-//We cap max disease symptoms at 3 at a preset severity, making them transmissible no matter our round length.
-/datum/round_event/disease_outbreak/advanced/start()
- var/datum/round_event_control/disease_outbreak/advanced/disease_event = control
- afflicted += disease_event.disease_candidates
- disease_event.disease_candidates.Cut() //Clean the list after use
-
- if(disease_event.chosen_max_symptoms)
- max_symptoms = disease_event.chosen_max_symptoms
- disease_event.chosen_max_symptoms = null
- else
- max_symptoms = 3 //Consistent symptoms taking into account severity
-
- if(disease_event.chosen_severity)
- max_severity = disease_event.chosen_severity
- disease_event.chosen_severity = null
- else
- max_severity = 4 //Don't make it too severe or it won't have transmissibility
-
- var/datum/disease/advance/advanced_disease = new /datum/disease/advance/random(max_symptoms, max_severity)
-
- var/list/name_symptoms = list() //for feedback
- for(var/datum/symptom/new_symptom in advanced_disease.symptoms)
- name_symptoms += new_symptom.name
-
- var/mob/living/carbon/human/victim = pick_n_take(afflicted)
- if(victim.ForceContractDisease(advanced_disease, FALSE))
- message_admins("An event has triggered a random advanced virus outbreak on [ADMIN_LOOKUPFLW(victim)]! It has these symptoms: [english_list(name_symptoms)]")
- log_game("An event has triggered a random advanced virus outbreak on [key_name(victim)]! It has these symptoms: [english_list(name_symptoms)].")
- announce_to_ghosts(victim)
- else
- log_game("An event attempted to trigger a random advanced virus outbreak on [key_name(victim)], but failed.")
diff --git a/tgstation.dme b/tgstation.dme
index b197201c60b..e4c2cf3c6ae 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -2615,6 +2615,7 @@
#include "code\modules\antagonists\pirate\pirate_gangs.dm"
#include "code\modules\antagonists\pirate\pirate_outfits.dm"
#include "code\modules\antagonists\pirate\pirate_roles.dm"
+#include "code\modules\antagonists\pirate\pirate_shuttle_equipment.dm"
#include "code\modules\antagonists\pirate\pirate_special_items.dm"
#include "code\modules\antagonists\pyro_slime\pyro_slime.dm"
#include "code\modules\antagonists\revenant\haunted_item.dm"
@@ -3198,6 +3199,7 @@
#include "code\modules\escape_menu\subsystem.dm"
#include "code\modules\escape_menu\title.dm"
#include "code\modules\events\_event.dm"
+#include "code\modules\events\_event_admin_setup.dm"
#include "code\modules\events\aurora_caelus.dm"
#include "code\modules\events\brain_trauma.dm"
#include "code\modules\events\brand_intelligence.dm"
@@ -3215,7 +3217,6 @@
#include "code\modules\events\grey_tide.dm"
#include "code\modules\events\grid_check.dm"
#include "code\modules\events\heart_attack.dm"
-#include "code\modules\events\immovable_rod.dm"
#include "code\modules\events\ion_storm.dm"
#include "code\modules\events\market_crash.dm"
#include "code\modules\events\mass_hallucination.dm"
@@ -3229,7 +3230,6 @@
#include "code\modules\events\scrubber_overflow.dm"
#include "code\modules\events\shuttle_catastrophe.dm"
#include "code\modules\events\shuttle_insurance.dm"
-#include "code\modules\events\shuttle_loan.dm"
#include "code\modules\events\spacevine.dm"
#include "code\modules\events\spider_infestation.dm"
#include "code\modules\events\stray_cargo.dm"
@@ -3265,6 +3265,11 @@
#include "code\modules\events\holiday\halloween.dm"
#include "code\modules\events\holiday\vday.dm"
#include "code\modules\events\holiday\xmas.dm"
+#include "code\modules\events\immovable_rod\immovable_rod.dm"
+#include "code\modules\events\immovable_rod\immovable_rod_event.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\shuttle_loan\shuttle_loan_items.dm"
#include "code\modules\events\wizard\aid.dm"
#include "code\modules\events\wizard\blobies.dm"
#include "code\modules\events\wizard\curseditems.dm"
@@ -5265,7 +5270,6 @@
#include "modular_skyrat\master_files\code\modules\clothing\under\jobs\security.dm"
#include "modular_skyrat\master_files\code\modules\clothing\under\jobs\civilian\civilian.dm"
#include "modular_skyrat\master_files\code\modules\clothing\under\jobs\civilian\suits.dm"
-#include "modular_skyrat\master_files\code\modules\events\disease_outbreak.dm"
#include "modular_skyrat\master_files\code\modules\events\spacevine.dm"
#include "modular_skyrat\master_files\code\modules\food_and_drinks\recipes\food_mixtures.dm"
#include "modular_skyrat\master_files\code\modules\jobs\departments\departments.dm"