[MANUAL MIRROR] Refactors Admin Setups on Forced Events + Refactors Vending Sentience (#19068)

* Refactors Admin Setups on Forced Events + Refactors Vending Sentience + Refactors Shuttle Loans (#72998)

- [x] TEST EVERYTHING
tested:
- Pirates
- Vending Machines
- Shuttle Catastrophe
- Anomalies
- Immovable Rod
- Sandstorms
- Scrubber Overflow
- Stray Meteor
- Madness
- Department Revolt (Well obviously, it is my super robust code after
all)
- Shuttle Loan
- Mass Hallucination
- Heart Attack
- False Alarm

Disease Outbreak is probably fine aha... It correctly reports that there
are no candidates before aborting.

allow you to let the game decide where previously you had to choose!

I need to refactor and datumize how admins set up special conditions on
forced events, so I did! Now `/datum/event_admin_setup` handles admin
settings, with a few prototypes to make it easier to give events admin
options in the future. This was exhausting and what 90% of the pr is.

The code was so bad I could not datumize the admin part of it so I
cleaned it up, making a lot of things in the event get decided in
`setup()` where they should.

The code was so bad I could not datumize the admin part of it so I
cleaned it up AS WELL, by datumizing the shuttle loans. Should be easier
to add more types in the future, actually kinda stoked.

This is preparation for a tgui change to ForceEvent.ts an admin has
requested. Phew!

🆑
refactor: Refactored a bunch of admin-related event code, hopefully you
won't notice much
admin: ... But you specifically may notice some minor differences. Raw
inputs changed into tgui ones, minor soul removal, etc.
/🆑

* remove override

* merge conflict

* dm update

* merge conflict

---------

Co-authored-by: tralezab <40974010+tralezab@users.noreply.github.com>
This commit is contained in:
lessthanthree
2023-02-12 11:37:52 -08:00
committed by GitHub
parent 869d51dfce
commit 0b4e32ec59
27 changed files with 1255 additions and 1001 deletions
+1 -1
View File
@@ -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
-25
View File
@@ -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)
+21 -218
View File
@@ -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"
@@ -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
+19 -15
View File
@@ -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 ..()
+83
View File
@@ -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
+18 -23
View File
@@ -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
+51 -58
View File
@@ -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
+48 -49
View File
@@ -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
+20 -19
View File
@@ -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
+24 -22
View File
@@ -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
@@ -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?"
@@ -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
+53 -56
View File
@@ -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
+20 -22
View File
@@ -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
+10 -7
View File
@@ -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!", "<b>Scrubber Overflow: [initial(custom_reagent.name)]</b>", 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
+8 -7
View File
@@ -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)
-345
View File
@@ -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 = "<b>Objective #1</b>. Liberate all bees on the NT transport vessel 2416/B. <b>Success!</b> <br><b>Objective #2</b>. Escape alive. <b>Failed.</b>"
/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
@@ -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)
@@ -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
@@ -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 = "<b>Objective #1</b>. Liberate all bees on the NT transport vessel 2416/B. <b>Success!</b> <br><b>Objective #2</b>. Escape alive. <b>Failed.</b>"
/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!"
+15 -18
View File
@@ -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
+32 -12
View File
@@ -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
+14 -17
View File
@@ -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