mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-09 16:14:13 +00:00
deprecate remaining hook handlers to use events instead (#34504)
* deprecate revs hook handler * properly deprecate revs hook, deprecate apes hook, make apes into faction and role datums * make apes into faction and role datums * remove redundant reboot hook handler and hook * handle media setup in login * remove mob hooks * replace MobAreaChange hook * remove rest of hooks and remove files from dme * no more SetupHooks() * MobAreaChanged event and move jukebox hook into proc * fix OnMobAreaChanged proc * byond sux * remove unused event * fix title music --------- Co-authored-by: nervere <sage@lulz>
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#define XENOMORPH_HIVE "alien hivemind"
|
||||
#define JUSTICE_DEPARTMENT "justice department"
|
||||
#define NANOTRASEN "Nanotrasen"
|
||||
#define THE_APES "The Apes"
|
||||
|
||||
//-------
|
||||
#define HIVEMIND "changeling hivemind"
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
// Called when a mob moves from one MASTER area to another.
|
||||
// (Master, as opposed to lighting subareas)
|
||||
/hook/mobAreaChange
|
||||
name = "MobAreaChange"
|
||||
|
||||
/hook/emergencyShuttleDeparture
|
||||
name = "EmergencyShuttleDeparture"
|
||||
@@ -79,6 +79,12 @@
|
||||
// mob/user: The living mob that's logging in.
|
||||
/event/living_login
|
||||
|
||||
// Called by new_player.dm when a character latejoins
|
||||
// Arguments:
|
||||
// mob/living/carbon/human/character: The character that has arrived on the station.
|
||||
// rank: The character's job. Should be something like "Chemist", NOT the job datum.
|
||||
/event/late_arrival
|
||||
|
||||
// Called whenever a mob takes damage.
|
||||
// Truthy return values will prevent the damage.
|
||||
// Arguments:
|
||||
@@ -218,12 +224,6 @@
|
||||
|
||||
/event/ui_act
|
||||
|
||||
// Called when living calls a life() tick
|
||||
// Arguments:
|
||||
// mob/living/L: thing that ticker
|
||||
// life_ticks: the amounts of lifetick processed
|
||||
/lazy_event/on_life
|
||||
|
||||
// Called by attack_self
|
||||
// Arguments:
|
||||
// mob/living/user
|
||||
@@ -262,6 +262,13 @@
|
||||
// atom/movable/exiter: the movable exiting the area
|
||||
/event/area_exited
|
||||
|
||||
// Called by both area/Entered and area/Exited if the atom changing areas is a mob
|
||||
// Arguments:
|
||||
// mob: the mob changing areas
|
||||
// newarea: the new area being entered
|
||||
// oldarea: the old area being left
|
||||
/event/mob_area_changed
|
||||
|
||||
// Note: the following are used by datum/component/ai subtypes to give instructions to each other.
|
||||
// AI components are expected to INVOKE_EVENT these to send commands to other components
|
||||
// on the same datum without having to hold references to them.
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
/************
|
||||
* D2K5-STYLE HOOKS
|
||||
*
|
||||
* BLATANTLY STOLEN FROM D2K5 AND MODIFIED
|
||||
*
|
||||
* SOMEHOW SUCKS LESS THAN BAY'S HOOKS
|
||||
************
|
||||
|
||||
The major change is to standardize them a bit
|
||||
by changing the event prefix to On instead of Hook.
|
||||
|
||||
Oh and it's documented and cleaned up. - N3X
|
||||
*/
|
||||
|
||||
/hook
|
||||
var/name = "DefaultHookName"
|
||||
var/list/handlers = list()
|
||||
|
||||
/hook/proc/Called(var/list/args) // When the hook is called
|
||||
return 0
|
||||
|
||||
/hook/proc/Setup() // Called when the setup things is ran for the hook, objs contain all objects with that is hooking
|
||||
|
||||
/hook_handler
|
||||
// Your hook handler should do this:
|
||||
// proc/OnThingHappened(var/list/args)
|
||||
// return handled // boolean
|
||||
|
||||
var/global/list/hooks = list()
|
||||
|
||||
/proc/SetupHooks()
|
||||
for (var/hook_path in typesof(/hook))
|
||||
var/hook/hook = new hook_path
|
||||
hooks[hook.name] = hook
|
||||
//world.log << "Found hook: " + hook.name
|
||||
for (var/hook_path in typesof(/hook_handler))
|
||||
var/hook_handler/hook_handler = new hook_path
|
||||
for (var/name in hooks)
|
||||
if (hascall(hook_handler, "On" + name))
|
||||
var/hook/hook = hooks[name]
|
||||
hook.handlers += hook_handler
|
||||
//world.log << "Found hook handler for: " + name
|
||||
for (var/hook/hook in hooks)
|
||||
hook.Setup()
|
||||
|
||||
/proc/CallHook(var/name as text, var/list/args)
|
||||
var/hook/hook = hooks[name]
|
||||
if (!hook)
|
||||
//world.log << "WARNING: Hook with name " + name + " does not exist"
|
||||
return
|
||||
if (hook.Called(args))
|
||||
return
|
||||
for (var/hook_handler/hook_handler in hook.handlers)
|
||||
call(hook_handler, "On" + hook.name)(args)
|
||||
@@ -1,5 +0,0 @@
|
||||
/hook/login
|
||||
name = "Login"
|
||||
|
||||
/hook/arrival
|
||||
name = "Arrival"
|
||||
@@ -127,7 +127,6 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
|
||||
sleep(1 SECONDS)
|
||||
//moving this random bullshit into here, because it didn't belong in world/New()
|
||||
generate_radio_frequencies()
|
||||
SetupHooks() // /N3X15 project from 8 years ago (WIP). The jukebox seems to be the only thing using this
|
||||
createDatacore()
|
||||
make_datum_references_lists() //initialises global lists for referencing frequently used datums (so that we only ever do it once)
|
||||
Holiday = Get_Holiday()
|
||||
|
||||
@@ -263,10 +263,15 @@ var/global/datum/emergency_shuttle/emergency_shuttle
|
||||
direction = 2 // heading to centcom
|
||||
settimeleft(SHUTTLETRANSITTIME)
|
||||
|
||||
// Shuttle Radio
|
||||
CallHook("EmergencyShuttleDeparture", list())
|
||||
command_alert(/datum/command_alert/emergency_shuttle_left)
|
||||
vote_preload()
|
||||
|
||||
/* Handle jukebox updates */
|
||||
spawn()
|
||||
for(var/obj/machinery/media/jukebox/superjuke/shuttle/SJ in machines)
|
||||
SJ.playing=1
|
||||
SJ.update_music()
|
||||
SJ.update_icon()
|
||||
|
||||
if(shuttle && istype(shuttle,/datum/shuttle/escape))
|
||||
var/datum/shuttle/escape/E = shuttle
|
||||
|
||||
10
code/datums/gamemode/factions/apes.dm
Normal file
10
code/datums/gamemode/factions/apes.dm
Normal file
@@ -0,0 +1,10 @@
|
||||
/datum/faction/apes
|
||||
name = THE_APES
|
||||
ID = THE_APES
|
||||
logo_state = "monkey-logo"
|
||||
default_admin_voice = "Ape King"
|
||||
admin_voice_style = "rough"
|
||||
|
||||
/datum/faction/apes/OnLateArrival(mob/living/carbon/human/character, rank)
|
||||
if(ape_mode)
|
||||
character.apeify()
|
||||
@@ -159,6 +159,9 @@ var/list/factions_with_hud_icons = list()
|
||||
/datum/faction/proc/CheckObjectives()
|
||||
return objective_holder.GetObjectiveString(check_success = TRUE)
|
||||
|
||||
/datum/faction/proc/OnLateArrival(mob/living/carbon/human/character, rank)
|
||||
return
|
||||
|
||||
/datum/faction/proc/GetScoreboard()
|
||||
var/count = 1
|
||||
var/score_results = ""
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
//________________________________________________
|
||||
|
||||
/datum/faction/revolution
|
||||
name = "Revolutionaries"
|
||||
ID = REVOLUTION
|
||||
@@ -166,21 +164,14 @@
|
||||
if (istype(dynamic_mode))
|
||||
dynamic_mode.update_stillborn_rulesets()
|
||||
|
||||
// Called on arrivals and emergency shuttle departure.
|
||||
/hook_handler/revs
|
||||
|
||||
/hook_handler/revs/proc/OnArrival(var/list/args)
|
||||
/datum/faction/revolution/OnLateArrival(mob/living/carbon/human/character, rank)
|
||||
var/datum/faction/revolution/R = find_active_faction_by_type(/datum/faction/revolution)
|
||||
if (!istype(R))
|
||||
if(!istype(R))
|
||||
return FALSE
|
||||
ASSERT(args["character"])
|
||||
ASSERT(args["rank"])
|
||||
var/mob/living/L = args["character"]
|
||||
if (args["rank"] in command_positions)
|
||||
if(rank in command_positions)
|
||||
var/datum/objective/target/assassinate/orexile/A = new(auto_target = FALSE)
|
||||
if(A.set_target(L.mind))
|
||||
R.AppendObjective(A, TRUE) // We will have more than one kill objective
|
||||
|
||||
if(A.set_target(character.mind))
|
||||
R.AppendObjective(A, TRUE)
|
||||
|
||||
/datum/faction/revolution/proc/end(var/result)
|
||||
. = TRUE
|
||||
|
||||
16
code/datums/gamemode/role/apes.dm
Normal file
16
code/datums/gamemode/role/apes.dm
Normal file
@@ -0,0 +1,16 @@
|
||||
/datum/role/apes
|
||||
name = "Apes"
|
||||
id = THE_APES
|
||||
special_role = THE_APES
|
||||
logo_state = "monkey-logo"
|
||||
greets = null
|
||||
default_admin_voice = "Ape King"
|
||||
admin_voice_style = "rough"
|
||||
|
||||
/datum/role/apes/OnPostSetup(var/laterole = TRUE)
|
||||
if(faction)
|
||||
return
|
||||
var/datum/faction/F = find_active_faction_by_type(/datum/faction/apes)
|
||||
if(!F)
|
||||
F = ticker.mode.CreateFaction(/datum/faction/apes, null, 1)
|
||||
F.HandleRecruitedRole(src)
|
||||
@@ -22,5 +22,4 @@
|
||||
if(player_list.len) //if anybody is in the current round
|
||||
last_time_of_players = world.time
|
||||
if(last_time_of_players && world.time - last_time_of_players > 1 HOURS) //if enough time has passed without them
|
||||
CallHook("Reboot",list())
|
||||
world.Reboot()
|
||||
@@ -447,12 +447,12 @@ var/area/space_area
|
||||
thing.area_entered(src)
|
||||
|
||||
for(var/mob/mob_in_obj in Obj.contents)
|
||||
CallHook("MobAreaChange", list("mob" = mob_in_obj, "new" = src, "old" = oldArea))
|
||||
INVOKE_EVENT(src, /event/mob_area_changed, "mob" = mob_in_obj, "newarea" = src, "oldarea" = oldArea)
|
||||
|
||||
INVOKE_EVENT(src, /event/area_entered, "enterer" = Obj)
|
||||
var/mob/M = Obj
|
||||
if(istype(M))
|
||||
CallHook("MobAreaChange", list("mob" = M, "new" = src, "old" = oldArea)) // /vg/ - EVENTS!
|
||||
INVOKE_EVENT(src, /event/mob_area_changed, "mob" = M, "newarea" = src, "oldarea" = oldArea)
|
||||
if(narrator)
|
||||
narrator.Crossed(M)
|
||||
|
||||
|
||||
@@ -102,7 +102,6 @@ var/global/global_cascade_portal
|
||||
return
|
||||
sleep(300)
|
||||
log_game("Rebooting due to universal collapse")
|
||||
CallHook("Reboot",list())
|
||||
world.Reboot()
|
||||
return
|
||||
|
||||
|
||||
@@ -549,7 +549,6 @@ var/datum/controller/gameticker/ticker
|
||||
else if(!delay_end)
|
||||
sleep(restart_timeout)
|
||||
if(!delay_end)
|
||||
CallHook("Reboot",list())
|
||||
world.Reboot()
|
||||
else
|
||||
to_chat(world, "<span class='notice'><B>An admin has delayed the round end</B></span>")
|
||||
|
||||
@@ -1020,8 +1020,6 @@ var/global/floorIsLava = 0
|
||||
if(blackbox)
|
||||
blackbox.save_all_data_to_sql()
|
||||
|
||||
CallHook("Reboot",list())
|
||||
|
||||
if (watchdog.waiting)
|
||||
to_chat(world, "<span class='notice'><B>Server will shut down for an automatic update in a few seconds.</B></span>")
|
||||
watchdog.signal_ready()
|
||||
@@ -1256,8 +1254,6 @@ var/global/floorIsLava = 0
|
||||
if(blackbox)
|
||||
blackbox.save_all_data_to_sql()
|
||||
|
||||
CallHook("Reboot",list())
|
||||
|
||||
if (watchdog.waiting)
|
||||
to_chat(world, "<span class='notice'><B>Server will shut down for an automatic update in a few seconds.</B></span>")
|
||||
watchdog.signal_ready()
|
||||
|
||||
@@ -4,16 +4,30 @@ var/ape_mode = APE_MODE_OFF
|
||||
set category = "Fun"
|
||||
set name = "Configure Apes"
|
||||
|
||||
var/datum/faction/apes/A = find_active_faction_by_type(/datum/faction/apes)
|
||||
|
||||
switch(alert(usr, "Configure apes:", "Configure Apes", "Turn it off, no apes", "EVERYONE IS APE", "Only new players are apes"))
|
||||
if("Turn it off, no apes")
|
||||
ape_mode = APE_MODE_OFF
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] turned off ape mode.</span>")
|
||||
if(A)
|
||||
for(var/datum/role/apes/R in A.members)
|
||||
R.Drop()
|
||||
A.Dismantle() //it's over
|
||||
else
|
||||
to_chat(usr, "<span class='warning'> Error: No apes faction found!</span>")
|
||||
|
||||
if("EVERYONE IS APE")
|
||||
ape_mode = APE_MODE_EVERYONE
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] turned on ape mode: EVERYONE IS APE.</span>")
|
||||
for(var/mob/living/carbon/human/H in player_list)
|
||||
H.apeify()
|
||||
|
||||
if("Only new players are apes")
|
||||
ape_mode = APE_MODE_NEW_PLAYERS
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] turned on ape mode: Only new players are apes.</span>")
|
||||
for(var/mob/living/carbon/human/H in player_list)
|
||||
H.apeify()
|
||||
var/datum/persistence_task/task = SSpersistence_misc.tasks["/datum/persistence_task/ape_mode"]
|
||||
task.on_shutdown()
|
||||
|
||||
@@ -26,8 +40,6 @@ var/ape_mode = APE_MODE_OFF
|
||||
var/mob/monke = monkeyize()
|
||||
ASSERT(monke)
|
||||
monke.name = monke.mind.name
|
||||
|
||||
/hook_handler/apes/proc/OnArrival(list/args)
|
||||
var/mob/living/dude = args["character"]
|
||||
ASSERT(dude)
|
||||
dude.apeify()
|
||||
var/datum/role/apes/R = new
|
||||
R.AssignToRole(monke.mind, 1, 0)
|
||||
R.OnPostSetup()
|
||||
@@ -257,7 +257,6 @@ var/global/datum/controller/vote/vote = new()
|
||||
feedback_set_details("end_error","restart vote")
|
||||
if(blackbox)
|
||||
blackbox.save_all_data_to_sql()
|
||||
CallHook("Reboot",list())
|
||||
sleep(50)
|
||||
log_game("Rebooting due to restart vote")
|
||||
world.Reboot()
|
||||
|
||||
@@ -70,44 +70,12 @@ function SetMusic(url, time, volume) {
|
||||
</script>"}
|
||||
|
||||
/proc/stop_all_media()
|
||||
log_startup_progress("Stopping all playing media...")
|
||||
log_debug("Stopping all playing media...")
|
||||
for(var/mob/M in mob_list)
|
||||
if(M && M.client)
|
||||
M.stop_all_music()
|
||||
|
||||
// Hook into the events we desire.
|
||||
// Set up player on login
|
||||
/hook_handler/soundmanager/proc/OnLogin(var/list/args)
|
||||
//testing("Received OnLogin.")
|
||||
var/client/C = args["client"]
|
||||
C.media = new /datum/media_manager(args["mob"])
|
||||
C.media.open()
|
||||
C.media.update_music()
|
||||
|
||||
/hook_handler/soundmanager/proc/OnReboot(var/list/args)
|
||||
//testing("Received OnReboot.")
|
||||
log_startup_progress("Stopping all playing media...")
|
||||
// Stop all music.
|
||||
stop_all_media()
|
||||
// SHITTY HACK TO AVOID RACE CONDITION WITH SERVER REBOOT.
|
||||
sleep(10)
|
||||
|
||||
// Update when moving between areas.
|
||||
/hook_handler/soundmanager/proc/OnMobAreaChange(var/list/args)
|
||||
var/mob/M = args["mob"]
|
||||
//if(istype(M, /mob/living/carbon/human)||istype(M, /mob/dead/observer))
|
||||
// testing("Received OnMobAreaChange for [M.type] [M] (M.client=[M.client==null?"null":"/client"]).")
|
||||
if(M.client && M.client.media && !M.client.media.forced)
|
||||
spawn()
|
||||
M.update_music()
|
||||
|
||||
|
||||
/hook_handler/shuttlejukes/proc/OnEmergencyShuttleDeparture(var/list/args)
|
||||
spawn(0)
|
||||
for(var/obj/machinery/media/jukebox/superjuke/shuttle/SJ in machines)
|
||||
SJ.playing=1
|
||||
SJ.update_music()
|
||||
SJ.update_icon()
|
||||
|
||||
/mob/proc/update_music()
|
||||
if (client && client.media && !client.media.forced)
|
||||
client.media.update_music()
|
||||
|
||||
@@ -109,7 +109,13 @@
|
||||
|
||||
if(M_FARSIGHT in mutations)
|
||||
client.changeView(max(client.view, world.view+1))
|
||||
CallHook("Login", list("client" = src.client, "mob" = src))
|
||||
|
||||
/* Handle media initialization */
|
||||
client.media = new /datum/media_manager(src)
|
||||
client.media.open()
|
||||
client.media.update_music()
|
||||
|
||||
register_event(/event/mob_area_changed, src, nameof(src::OnMobAreaChanged()))
|
||||
|
||||
if(spell_masters)
|
||||
for(var/obj/abstract/screen/movable/spell_master/spell_master in spell_masters)
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
if(client && client.media)
|
||||
client.media.stop_music()
|
||||
|
||||
unregister_event(/event/mob_area_changed, src, nameof(src::OnMobAreaChanged()))
|
||||
|
||||
if(admin_datums[src.ckey])
|
||||
message_admins("Admin logout: [key_name(src)]")
|
||||
if (ticker && ticker.current_state == GAME_STATE_PLAYING) //Only report this stuff if we are currently playing.
|
||||
|
||||
@@ -2269,5 +2269,10 @@ Use this proc preferably at the end of an equipment loadout
|
||||
/mob/proc/isBloodedAnimal()
|
||||
return FALSE
|
||||
|
||||
/mob/proc/OnMobAreaChanged()
|
||||
if(src.client && src.client.media && !src.client.media.forced)
|
||||
spawn()
|
||||
src.update_music()
|
||||
|
||||
#undef MOB_SPACEDRUGS_HALLUCINATING
|
||||
#undef MOB_MINDBREAKER_HALLUCINATING
|
||||
|
||||
@@ -18,6 +18,14 @@
|
||||
change_sight(adding = SEE_TURFS)
|
||||
player_list |= src
|
||||
|
||||
/* Handle media initialization */
|
||||
client.media = new /datum/media_manager(src)
|
||||
client.media.open()
|
||||
client.media.update_music()
|
||||
if(client)
|
||||
spawn()
|
||||
client.playtitlemusic()
|
||||
|
||||
/*
|
||||
var/list/watch_locations = list()
|
||||
for(var/obj/effect/landmark/landmark in landmarks_list)
|
||||
@@ -30,6 +38,7 @@
|
||||
new_player_panel()
|
||||
if(ckey in deadmins)
|
||||
client.verbs += /client/proc/readmin
|
||||
|
||||
#if SHOW_CHANGELOG_ON_NEW_PLAYER_LOGIN
|
||||
spawn(0)
|
||||
if(client)
|
||||
@@ -60,5 +69,4 @@
|
||||
src << browse('html/changelog.html', "window=changes;size=675x650")
|
||||
client.prefs.SetChangelog(ckey, changelog_hash)
|
||||
winset(client, "rpane.changelog", "background-color=none;font-style=;")
|
||||
client.playtitlemusic()
|
||||
#endif
|
||||
|
||||
@@ -434,6 +434,9 @@
|
||||
to_chat(character, "<span class='notice'>Tip: Use the BBD in your suit's pocket to place bombs.</span>")
|
||||
to_chat(character, "<span class='notice'>Try to keep your BBD and escape this hell hole alive!</span>")
|
||||
|
||||
for(var/datum/faction/F in ticker.mode.factions) /* Ensure all existing factions receive notice of the latejoin to handle what they need to. */
|
||||
register_event(/event/late_arrival, F, nameof(F::OnLateArrival())) //Wrapped in nameof() to ensure that the parent proc doesn't get called. Possibly a BYOND bug?
|
||||
|
||||
if(character.mind.assigned_role != "MODE")
|
||||
if(character.mind.assigned_role != "Cyborg")
|
||||
data_core.manifest_inject(character)
|
||||
@@ -449,7 +452,7 @@
|
||||
handle_render(M,"<span class='game say'>PDA Message - <span class='name'>Trader [character.real_name] has arrived in the sector from space.</span></span>",character) //handle_render generates a Follow link
|
||||
else
|
||||
AnnounceArrival(character, rank)
|
||||
CallHook("Arrival", list("character" = character, "rank" = rank))
|
||||
INVOKE_EVENT(src, /event/late_arrival, "character" = character, "rank" = rank)
|
||||
character.DormantGenes(20,10,0,0) // 20% chance of getting a dormant bad gene, in which case they also get 10% chance of getting a dormant good gene
|
||||
else
|
||||
character.Robotize()
|
||||
|
||||
@@ -199,13 +199,13 @@ var/auxtools_path
|
||||
..()
|
||||
|
||||
/world/proc/pre_shutdown()
|
||||
stop_all_media()
|
||||
|
||||
for(var/datum/html_interface/D in html_interfaces)
|
||||
D.closeAll()
|
||||
|
||||
Master.Shutdown()
|
||||
|
||||
stop_all_media()
|
||||
|
||||
end_credits.on_world_reboot_start()
|
||||
sleep(max(10, end_credits.audio_post_delay))
|
||||
end_credits.on_world_reboot_end()
|
||||
|
||||
@@ -129,10 +129,7 @@
|
||||
#include "code\__HELPERS\sorts\InsertSort.dm"
|
||||
#include "code\__HELPERS\sorts\MergeSort.dm"
|
||||
#include "code\__HELPERS\sorts\TimSort.dm"
|
||||
#include "code\_hooks\area.dm"
|
||||
#include "code\_hooks\events.dm"
|
||||
#include "code\_hooks\hooks.dm"
|
||||
#include "code\_hooks\mob.dm"
|
||||
#include "code\_onclick\adjacent.dm"
|
||||
#include "code\_onclick\ai.dm"
|
||||
#include "code\_onclick\click.dm"
|
||||
@@ -369,6 +366,7 @@
|
||||
#include "code\datums\gamemode\dynamic\dynamic_rulesets_midround.dm"
|
||||
#include "code\datums\gamemode\dynamic\dynamic_rulesets_roundstart.dm"
|
||||
#include "code\datums\gamemode\dynamic\dynamic_stats.dm"
|
||||
#include "code\datums\gamemode\factions\apes.dm"
|
||||
#include "code\datums\gamemode\factions\blob.dm"
|
||||
#include "code\datums\gamemode\factions\clockwork.dm"
|
||||
#include "code\datums\gamemode\factions\faction.dm"
|
||||
@@ -484,6 +482,7 @@
|
||||
#include "code\datums\gamemode\powers\powers.dm"
|
||||
#include "code\datums\gamemode\powers\vampire.dm"
|
||||
#include "code\datums\gamemode\role\alien.dm"
|
||||
#include "code\datums\gamemode\role\apes.dm"
|
||||
#include "code\datums\gamemode\role\blob.dm"
|
||||
#include "code\datums\gamemode\role\catbeast.dm"
|
||||
#include "code\datums\gamemode\role\changeling.dm"
|
||||
|
||||
Reference in New Issue
Block a user