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
@@ -21,7 +21,7 @@
SIGNAL_HANDLER
if(!H || H == src)
return
if(isobserver(H) && !affect_ghosts)
if(isghost(H) && !affect_ghosts)
return
if(!ismob(H) && mobs_only)
return
+7 -2
View File
@@ -84,8 +84,11 @@
if(!length(valid_z_levels) || !valid_z_levels) //Outpost blueprints can initialize before exoplanets, so put this in here to doublecheck it.
set_valid_z_levels()
var/obj/effect/overmap/visitable/sector/exoplanet/E = GLOB.map_sectors["[GET_Z(user)]"]
if(E.generated_name) //Prevent the prefix from being super long with the planet type appended
area_prefix = E.planet_name
if(istype(E))
if(E.generated_name) //Prevent the prefix from being super long with the planet type appended
area_prefix = E.planet_name
else
area_prefix = E.name
else
area_prefix = E.name
. = ..()
@@ -98,6 +101,8 @@
var/area/overmap/map = global.map_overmap
for(var/obj/effect/overmap/visitable/sector/exoplanet/E in map)
valid_z_levels += E.map_z
if(length(SSodyssey.scenario_zlevels))
valid_z_levels += SSodyssey.scenario_zlevels
return TRUE
/obj/item/blueprints/shuttle
@@ -28,8 +28,8 @@
stack_trace("Warning: [src]([type]) initialized multiple times!")
flags_1 |= INITIALIZED_1
var/turf/T = get_turf(src)
var/obj/effect/overmap/visitable/V = GLOB.map_sectors["[T.z]"]
var/sector_z = get_sector_z()
var/obj/effect/overmap/visitable/V = GLOB.map_sectors["[sector_z]"]
if(istype(V) && V.comms_support)
var/freq_name = V.name
if(V.freq_name)
@@ -48,9 +48,18 @@
return INITIALIZE_HINT_NORMAL
/obj/item/device/encryptionkey/ship/proc/get_sector_z()
. = GET_Z(get_turf(src))
/obj/item/device/encryptionkey/ship/common
use_common = TRUE
/obj/item/device/encryptionkey/ship/odyssey/get_sector_z()
if(SSodyssey.scenario_zlevels && SSodyssey.scenario_zlevels.len)
. = SSodyssey.scenario_zlevels[1]
else // safe fallback
. = GET_Z(get_turf(src))
/obj/item/device/encryptionkey/ship/coal_navy
additional_channels = list(CHANNEL_COALITION_NAVY = TRUE)
@@ -905,18 +905,34 @@
if(!SSatlas.current_map.use_overmap)
return ..()
var/turf/T = get_turf(src)
var/obj/effect/overmap/visitable/V = GLOB.map_sectors["[T.z]"]
if(istype(V) && V.comms_support)
default_frequency = assign_away_freq(V.name)
if(V.comms_name)
name = "[V.comms_name] radio headset"
var/sector_z = get_sector_z()
var/obj/effect/overmap/visitable/V = GLOB.map_sectors["[sector_z]"]
if(istype(V))
if(V.comms_support)
default_frequency = assign_away_freq(V.name)
if(V.comms_name)
name = "[V.comms_name] radio headset"
else
if(SSodyssey.scenario && (sector_z in SSodyssey.scenario_zlevels))
default_frequency = assign_away_freq(SSodyssey.scenario.radio_frequency_name)
. = ..()
if (use_common)
set_frequency(PUB_FREQ)
/obj/item/device/radio/headset/ship/proc/get_sector_z()
. = GET_Z(get_turf(src))
/obj/item/device/radio/headset/ship/odyssey
ks1type = /obj/item/device/encryptionkey/ship/odyssey
/obj/item/device/radio/headset/ship/odyssey/get_sector_z()
if(SSodyssey.scenario_zlevels && SSodyssey.scenario_zlevels.len)
. = SSodyssey.scenario_zlevels[1]
else // safe fallback
. = GET_Z(get_turf(src))
/obj/item/device/radio/headset/ship/coalition_navy
icon_state = "coal_headset"
ks1type = /obj/item/device/encryptionkey/ship/coal_navy
@@ -295,7 +295,7 @@ var/global/list/default_interrogation_channels = list(
var/obj/item/card/id/I = GetIdCard()
return has_access(list(), req_one_accesses, I ? I.GetAccess() : list())
/mob/abstract/observer/has_internal_radio_channel_access(var/list/req_one_accesses)
/mob/abstract/ghost/observer/has_internal_radio_channel_access(var/list/req_one_accesses)
return can_admin_interact()
/obj/item/device/radio/proc/text_wires()
+2 -2
View File
@@ -85,13 +85,13 @@
var/answered = FALSE
/obj/item/eightball/haunted/start_shaking(mob/user)
for(var/mob/abstract/observer/O in GLOB.player_list)
for(var/mob/abstract/ghost/observer/O in GLOB.player_list)
if(O.client)
to_chat(O, "[ghost_follow_link(user, O)] <span class='deadsay'><font size=3><b>\The [user] is shaking \the [src], hoping to get an answer to \"[question]\".<a href='?src=[REF(src)];candidate=[REF(O)]'>(Answer)</a></b></font></span>")
/obj/item/eightball/haunted/Topic(href, href_list)
if(href_list["candidate"])
var/mob/abstract/observer/candidate = locate(href_list["candidate"])
var/mob/abstract/ghost/observer/candidate = locate(href_list["candidate"])
if(!candidate)
return
if(candidate != usr)
+1 -1
View File
@@ -23,7 +23,7 @@
forceMove(get_turf(usr))
usr.put_in_hands(src)
/obj/item/spirit_board/attack_ghost(var/mob/abstract/observer/user)
/obj/item/spirit_board/attack_ghost(var/mob/abstract/ghost/user)
spirit_board_pick_letter(user)
return ..()
@@ -650,6 +650,12 @@ var/const/NO_EMAG_ACT = -50
icon_state = "coalition_card"
overlay_state = "nothing"
/obj/item/card/id/generic
name = "identification card"
desc = "A card with a soft metallic sheen, used to identify people and determine access."
icon_state = "data"
overlay_state = "data"
/obj/item/card/id/tcaf // For ghostroles, rather than ERTs.
name = "\improper Tau Ceti Armed Forces identification card"
desc = "An old-fashioned, practical plastic card. Cheaply produced for Tau Ceti's finest."
@@ -3,7 +3,7 @@
desc = "A small slip of plastic with an embedded chip. It is commonly used to store small amounts of research data."
desc_info = "This item is to be used in the destructive analyzer to gain research points."
icon = 'icons/obj/item/tools/research_slip.dmi'
icon_state = "slip"
icon_state = "slip_nt"
contained_sprite = TRUE
/obj/item/research_slip/Initialize(mapload, var/list/research_levels)
@@ -199,7 +199,7 @@
/obj/item/storage/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
if(isobserver(user))
if(isghost(user))
. += "It contains: [counting_english_list(contents)]"
/obj/item/storage/MouseDrop(obj/over_object)
@@ -136,7 +136,7 @@
content_size += Ceiling(I.w_class/2)
. += content_info(user, content_size)
if(!src.opened && isobserver(user))
if(!src.opened && isghost(user))
. += "It contains: [counting_english_list(contents)]"
if(src.opened && linked_teleporter && is_adjacent)
+1 -1
View File
@@ -167,7 +167,7 @@
set category = "Object"
set src in oview(1)
if(isobserver(usr) || usr.restrained() || !usr.Adjacent(src))
if(isghost(usr) || usr.restrained() || !usr.Adjacent(src))
return
verbs -= /obj/structure/inflatable/verb/hand_deflate