Adds the Odyssey gamemode. (#18972)

https://forums.aurorastation.org/topic/20198-mission-briefing-auroras-gamemode-revolution

To-do:

- [x] Finish storyteller verbs.
- [x] Storyteller landmarks.
- [x] Proper storyteller spawning. Right now the gamemode system is
happy with just picking one storyteller and no actors.
- [x] Antagonist whitelists code.
- [x] Adding the Storyteller whitelist.
- [x] Mission map loading code.
- [x] Map in a bunch of missions.
- [ ] Storyteller adminhelps.

---------

Co-authored-by: Matt Atlas <liermattia@gmail.com>
Co-authored-by: DreamySkrell <>
This commit is contained in:
Matt Atlas
2024-11-26 20:18:43 +00:00
committed by GitHub
co-authored by Matt Atlas DreamySkrell <>
parent e1f5de6298
commit 1da20ad33f
194 changed files with 242505 additions and 1904 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
/mob/proc/on_mob_jump()
return
/mob/abstract/observer/on_mob_jump()
/mob/abstract/ghost/on_mob_jump()
QDEL_NULL(orbiting)
/client/proc/Jump(var/area/A in GLOB.all_areas)
+1 -1
View File
@@ -22,7 +22,7 @@
if(T.mob)
if(istype(T.mob, /mob/abstract/new_player))
targets["(New Player) - [T]"] = T
else if(istype(T.mob, /mob/abstract/observer))
else if(istype(T.mob, /mob/abstract/ghost/observer))
targets["[T.mob.name](Ghost) - [T]"] = T
else
targets["[T.mob.real_name](as [T.mob.name]) - [T]"] = T
+1 -1
View File
@@ -3,7 +3,7 @@
set name = "AOOC"
set desc = "Antagonist OOC"
if (istype(src.mob, /mob/abstract/observer) && !check_rights(R_ADMIN|R_MOD|R_CCIAA, 0))
if (istype(src.mob, /mob/abstract/ghost/observer) && !check_rights(R_ADMIN|R_MOD|R_CCIAA, 0))
to_chat(src, SPAN_WARNING("You cannot use AOOC while ghosting/observing!"))
return
+24 -14
View File
@@ -24,7 +24,8 @@
to_chat(src, "You've used this verb too recently, please wait a moment before trying again.")
return
if(!check_rights(R_DEV|R_ADMIN)) return
if(!check_rights(R_DEV|R_ADMIN))
return
if(!holder)
return //how did they get here?
@@ -35,15 +36,13 @@
bst_cooldown = TRUE
if(istype(mob, /mob/living))
if(!holder.original_mob)
holder.original_mob = mob
//I couldn't get the normal way to work so this works.
//This whole section looks like a hack, I don't like it.
var/T = get_turf(usr)
var/mob/living/carbon/human/bst/bst = new(T)
// bst.original_mob = usr
if(istype(mob, /mob/living))
bst.original_mob = mob
bst.anchored = 1
bst.ckey = usr.ckey
bst.name = "Bluespace Technician"
@@ -138,6 +137,13 @@
universal_understand = 1
status_flags = GODMODE|NOFALL
/// The BST's original mob. Moved here from /datum/holder to support storytellers.
var/mob/original_mob
/mob/living/carbon/human/bst/Destroy(force)
original_mob = null
return ..()
/mob/living/carbon/human/bst/can_inject(var/mob/user, var/error_msg, var/target_zone)
to_chat(user, SPAN_ALERT("The [src] disarms you before you can inject them."))
user.drop_item()
@@ -168,11 +174,11 @@
QDEL_IN(src, 10)
animate(src, alpha = 0, time = 9, easing = QUAD_EASING)
if(key)
if(client.holder && client.holder.original_mob)
client.holder.original_mob.key = key
if(original_mob)
client.key = key
client.init_verbs()
else
var/mob/abstract/observer/ghost = new(src) //Transfer safety to observer spawning proc.
var/mob/abstract/ghost/observer/ghost = new(src, src) //Transfer safety to observer spawning proc.
ghost.key = key
ghost.mind.name = "[ghost.key] BSTech"
ghost.name = "[ghost.key] BSTech"
@@ -320,14 +326,13 @@
set desc = "Jump into bluespace and continue wherever you left off. Deletes the BSTech and returns to your original mob if you have one."
set category = "BST"
var/client/C = src.client
if(C.holder && C.holder.original_mob)
if(C.holder.original_mob.key)//Thanks for kicking Tish off the Server Meow, wouldn't have spotted this otherwise.
if(original_mob)
if(original_mob.key)//Thanks for kicking Tish off the Server Meow, wouldn't have spotted this otherwise.
//suicide()
return
C.holder.original_mob.key = key
C.holder.original_mob = null
original_mob.key = key
original_mob = null
suicide()
/mob/living/carbon/human/bst/verb/tgm()
@@ -519,3 +524,8 @@
/mob/living/carbon/human/bst/restrained()
return 0
/mob/living/carbon/human/bst/vv_edit_var(var_name, var_value)
if(var_name == NAMEOF(src, original_mob))
return FALSE
return ..()
+7 -45
View File
@@ -121,7 +121,7 @@
set name = "Del-All"
// to prevent REALLY stupid deletions
var/blocked = list(/obj, /mob, /mob/living, /mob/living/carbon, /mob/living/carbon/human, /mob/abstract, /mob/abstract/observer, /mob/living/silicon, /mob/living/silicon/robot, /mob/living/silicon/ai)
var/blocked = list(/obj, /mob, /mob/living, /mob/living/carbon, /mob/living/carbon/human, /mob/abstract, /mob/abstract/ghost/observer, /mob/living/silicon, /mob/living/silicon/robot, /mob/living/silicon/ai)
var/hsbitem = input(usr, "Choose an object to delete.", "Delete:") as null|anything in typesof(/obj) + typesof(/mob) - blocked
if(hsbitem)
for(var/atom/O in world)
@@ -177,7 +177,7 @@
if(alert("This mob is being controlled by [M.ckey]. Are you sure you wish to assume control of it? [M.ckey] will be made a ghost.",,"Yes","No") != "Yes")
return
else
var/mob/abstract/observer/ghost = new/mob/abstract/observer(M,1)
var/mob/abstract/ghost/observer/ghost = new/mob/abstract/ghost/observer(M,1)
ghost.ckey = M.ckey
message_admins(SPAN_NOTICE("[key_name_admin(usr)] assumed direct control of [M]."), 1)
log_admin("[key_name(usr)] assumed direct control of [M].")
@@ -301,7 +301,7 @@
for(var/spawn_observer in chosen_observers)
var/mob/living/carbon/human/H = new /mob/living/carbon/human(get_turf(usr))
do_dressing(H)
var/mob/abstract/observer/O = spawn_observer
var/mob/abstract/ghost/observer/O = spawn_observer
H.ckey = O.ckey
qdel(O)
@@ -313,58 +313,20 @@
return
do_dressing(H)
/client/proc/do_dressing(var/mob/living/carbon/human/M = null)
/proc/do_dressing(var/mob/living/carbon/human/M = null)
if(!M || !istype(M))
M = input("Select a mob you would like to dress.", "Set Human Outfit") as null|anything in GLOB.human_mob_list
M = tgui_input_list(usr, "Select a mob you would like to dress.", "Set Human Outfit", GLOB.human_mob_list)
if(!M)
return
var/list/outfit_catagories = list()
switch(alert("Would you like ERT outfits, or standard admin outfits?", "ERT-or-Admin?", "ERT", "Admin", "Cancel"))
if("Cancel")
return
if("ERT")
outfit_catagories["SCC-ERT"] = typesof(/obj/outfit/admin/ert/scc)
outfit_catagories["NT-ERT"] = typesof(/obj/outfit/admin/ert/nanotrasen)
outfit_catagories["Deathsquad"] = typesof(/obj/outfit/admin/deathsquad)
outfit_catagories["TCFL"] = typesof(/obj/outfit/admin/ert/legion)
outfit_catagories["Syndicate"] = typesof(/obj/outfit/admin/deathsquad/syndicate)
outfit_catagories["Freelance Mercenaries"] = typesof(/obj/outfit/admin/ert/mercenary)
outfit_catagories["Free Solarian Fleets Marines"] = typesof(/obj/outfit/admin/ert/fsf)
outfit_catagories["Kataphracts"] = typesof(/obj/outfit/admin/ert/kataphract)
outfit_catagories["Eridani"] = typesof(/obj/outfit/admin/ert/ap_eridani)
outfit_catagories["IAC"] = typesof(/obj/outfit/admin/ert/iac)
outfit_catagories["Kosmostrelki"] = typesof(/obj/outfit/admin/ert/pra_cosmonaut)
outfit_catagories["Elyran Navy"] = typesof(/obj/outfit/admin/ert/elyran_trooper)
if("Admin")
outfit_catagories["Stellar Corporate Conglomerate"] = typesof(/obj/outfit/admin/scc)
outfit_catagories["NanoTrasen"] = typesof(/obj/outfit/admin/nt)
outfit_catagories["Antagonist"] = typesof(/obj/outfit/admin/syndicate)
outfit_catagories["Event"] = typesof(/obj/outfit/admin/event)
outfit_catagories["TCFL"] = typesof(/obj/outfit/admin/tcfl)
outfit_catagories["Killers"] = typesof(/obj/outfit/admin/killer)
outfit_catagories["Job"] = subtypesof(/obj/outfit/job)
outfit_catagories["Megacorps"] = subtypesof(/obj/outfit/admin/megacorp)
outfit_catagories["Pod Survivors"] = subtypesof(/obj/outfit/admin/pod)
outfit_catagories["Miscellaneous"] = typesof(/obj/outfit/admin/random)
outfit_catagories["Miscellaneous"] += /obj/outfit/admin/random_employee
var/chosen_catagory = input("Select an outfit catagory.", "Robust Quick-dress Shop") as null|anything in outfit_catagories
if(isnull(chosen_catagory))
return
var/list/outfit_types = list()
for(var/outfit in outfit_catagories[chosen_catagory])
var/obj/outfit/admin/A = new outfit
outfit_types[A.name] = A
var/chosen_outfit = input("Select an outfit.", "Robust Quick-dress Shop") as null|anything in outfit_types
var/chosen_outfit = tgui_input_list(usr, "Select an outfit.", "Set Human Outfit", GLOB.outfit_cache)
if(isnull(chosen_outfit))
return
feedback_add_details("admin_verb","SEQ") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc
var/obj/outfit/O = outfit_types[chosen_outfit]
var/obj/outfit/O = GLOB.outfit_cache[chosen_outfit]
if(O)
for(var/obj/item/I in M)
if(istype(I, /obj/item/implant))
+17 -17
View File
@@ -239,7 +239,7 @@ Ccomp's first proc.
var/list/ghosts = list()
var/list/sortmob = sortAtom(GLOB.mob_list) // get the mob list.
var/any=0
for(var/mob/abstract/observer/M in sortmob)
for(var/mob/abstract/ghost/observer/M in sortmob)
mobs.Add(M) //filter it where it's only ghosts
any = 1 //if no ghosts show up, any will just be 0
if(!any)
@@ -269,7 +269,7 @@ Ccomp's first proc.
to_chat(src, SPAN_WARNING("You didn't select a ghost!")) // Sanity check, if no ghosts in the list we don't want to edit a null variable and cause a runtime error.)
return
var/mob/abstract/observer/G = ghosts[target]
var/mob/abstract/ghost/observer/G = ghosts[target]
if(G.has_enabled_antagHUD && GLOB.config.antag_hud_restricted)
var/response = alert(src, "Are you sure you wish to allow this individual to play?","Ghost has used AntagHUD","Yes","No")
if(response == "No") return
@@ -330,9 +330,9 @@ Ccomp's first proc.
to_chat(src, "Only administrators may use this command.")
var/action=""
if(GLOB.config.antag_hud_allowed)
for(var/mob/abstract/observer/g in get_ghosts())
for(var/mob/abstract/ghost/observer/g in get_ghosts())
if(!g.client.holder) //Remove the verb from non-admin ghosts
remove_verb(g, /mob/abstract/observer/verb/toggle_antagHUD)
remove_verb(g, /mob/abstract/ghost/observer/verb/toggle_antagHUD)
if(g.antagHUD)
g.antagHUD = 0 // Disable it on those that have it enabled
g.has_enabled_antagHUD = 2 // We'll allow them to respawn
@@ -341,9 +341,9 @@ Ccomp's first proc.
to_chat(src, SPAN_DANGER("AntagHUD usage has been disabled."))
action = "disabled"
else
for(var/mob/abstract/observer/g in get_ghosts())
for(var/mob/abstract/ghost/observer/g in get_ghosts())
if(!g.client.holder) // Add the verb back for all non-admin ghosts
add_verb(g, /mob/abstract/observer/verb/toggle_antagHUD)
add_verb(g, /mob/abstract/ghost/observer/verb/toggle_antagHUD)
to_chat(g, SPAN_NOTICE("<B>The Administrator has enabled AntagHUD.</B>")) // Notify all observers they can now use AntagHUD)
GLOB.config.antag_hud_allowed = 1
action = "enabled"
@@ -363,13 +363,13 @@ Ccomp's first proc.
to_chat(src, "Only administrators may use this command.")
var/action=""
if(GLOB.config.antag_hud_restricted)
for(var/mob/abstract/observer/g in get_ghosts())
for(var/mob/abstract/ghost/observer/g in get_ghosts())
to_chat(g, SPAN_NOTICE("<B>The administrator has lifted restrictions on joining the round if you use AntagHUD</B>"))
action = "lifted restrictions"
GLOB.config.antag_hud_restricted = 0
to_chat(src, SPAN_NOTICE("<B>AntagHUD restrictions have been lifted</B>"))
else
for(var/mob/abstract/observer/g in get_ghosts())
for(var/mob/abstract/ghost/observer/g in get_ghosts())
to_chat(g, SPAN_DANGER("The administrator has placed restrictions on joining the round if you use AntagHUD"))
to_chat(g, SPAN_DANGER("Your AntagHUD has been disabled, you may choose to re-enabled it but will be under restrictions "))
g.antagHUD = 0
@@ -398,8 +398,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(!input)
return
var/mob/abstract/observer/G_found
for(var/mob/abstract/observer/G in GLOB.player_list)
var/mob/abstract/ghost/observer/G_found
for(var/mob/abstract/ghost/observer/G in GLOB.player_list)
if(G.ckey == input)
G_found = G
break
@@ -602,7 +602,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
command_announcement.Announce("[reportbody]", reporttitle, new_sound = 'sound/AI/commandreport.ogg', msg_sanitized = 1);
if("No")
to_world(SPAN_WARNING("New [SSatlas.current_map.company_name] Update available at all communication consoles."))
sound_to(world, ('sound/AI/commandreport.ogg'))
sound_to_playing_players('sound/AI/commandreport.ogg')
log_admin("[key_name(src)] has created a command report: [reportbody]")
message_admins("[key_name_admin(src)] has created a command report", 1)
@@ -621,11 +621,11 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/action = alert(src, "Are you sure you want to delete:\n[O]\nat ([O.x], [O.y], [O.z])?", "Confirmation", "Yes", "No", "Hard Delete")
if (action == "No")
if (action == "No" || !action)
return
if (istype(O, /mob/abstract/observer))
var/mob/abstract/observer/M = O
if (istype(O, /mob/abstract/ghost/observer))
var/mob/abstract/ghost/observer/M = O
if (M.client && alert(src, "They are still connected. Are you sure, they will loose connection.", "Confirmation", "Yes", "No") != "Yes")
return
log_admin("[key_name(usr)] deleted [O] at ([O.x],[O.y],[O.z])")
@@ -720,7 +720,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
log_admin("[key_name(usr)] has gibbed [key_name(M)]")
message_admins("[key_name_admin(usr)] has gibbed [key_name_admin(M)]", 1)
if(istype(M, /mob/abstract/observer))
if(isobserver(M))
gibs(M.loc, M.viruses)
return
@@ -733,7 +733,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
if(confirm == "Yes")
if (istype(mob, /mob/abstract/observer)) // so they don't spam gibs everywhere
if (istype(mob, /mob/abstract/ghost/observer)) // so they don't spam gibs everywhere
return
else
mob.gib()
@@ -751,7 +751,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
if(confirm != "Yes")
if(istype(mob, /mob/abstract/observer))
if(istype(mob, /mob/abstract/ghost/observer))
return
else
mob.dust()