Fix halloweens races (#70874)

* Fixes halloween races.
- Fixes a race condition involve checking for holidays befores SSevents is instantiated. Now, holiday checking is done through a helper, which will ensure the holidays list is created and filled before checked.
This commit is contained in:
MrMelbert
2022-10-31 16:01:31 +01:00
committed by GitHub
parent ed55e9ba01
commit a1ab0201ff
35 changed files with 106 additions and 89 deletions
+2 -2
View File
@@ -70,9 +70,9 @@ GLOBAL_VAR(command_name)
random = 999999999 //ridiculously long name in written numbers
// Prefix
var/holiday_name = pick(SSevents.holidays)
var/holiday_name = length(GLOB.holidays) && pick(GLOB.holidays)
if(holiday_name)
var/datum/holiday/holiday = SSevents.holidays[holiday_name]
var/datum/holiday/holiday = GLOB.holidays[holiday_name]
if(istype(holiday, /datum/holiday/friday_thirteenth))
random = 13
name = holiday.getStationPrefix()
+1 -1
View File
@@ -42,7 +42,7 @@ SUBSYSTEM_DEF(communications)
* * user - Mob who called the meeting
*/
/datum/controller/subsystem/communications/proc/can_make_emergency_meeting(mob/living/user)
if(!(SSevents.holidays && SSevents.holidays[APRIL_FOOLS]))
if(!check_holidays(APRIL_FOOLS))
return FALSE
else if(COOLDOWN_FINISHED(src, emergency_meeting_cooldown))
return TRUE
+52 -34
View File
@@ -11,7 +11,6 @@ SUBSYSTEM_DEF(events)
var/frequency_lower = 1800 //3 minutes lower bound.
var/frequency_upper = 6000 //10 minutes upper bound. Basically an event will happen every 3 to 10 minutes.
var/list/holidays //List of all holidays occuring today or null if no holidays
var/wizardmode = FALSE
/datum/controller/subsystem/events/Initialize()
@@ -21,7 +20,9 @@ SUBSYSTEM_DEF(events)
continue //don't want this one! leave it for the garbage collector
control += E //add it to the list of all events (controls)
reschedule()
getHoliday()
// Instantiate our holidays list if it hasn't been already
if(isnull(GLOB.holidays))
fill_holidays()
return SS_INIT_SUCCESS
@@ -92,33 +93,58 @@ SUBSYSTEM_DEF(events)
else if(. == EVENT_READY)
E.runEvent(random = TRUE)
/*
//////////////
// HOLIDAYS //
//////////////
//Uncommenting ALLOW_HOLIDAYS in config.txt will enable holidays
//It's easy to add stuff. Just add a holiday datum in code/modules/holiday/holidays.dm
//You can then check if it's a special day in any code in the game by doing if(SSevents.holidays["Groundhog Day"])
/datum/controller/subsystem/events/proc/toggleWizardmode()
wizardmode = !wizardmode
message_admins("Summon Events has been [wizardmode ? "enabled, events will occur every [SSevents.frequency_lower / 600] to [SSevents.frequency_upper / 600] minutes" : "disabled"]!")
log_game("Summon Events was [wizardmode ? "enabled" : "disabled"]!")
//You can also make holiday random events easily thanks to Pete/Gia's system.
//simply make a random event normally, then assign it a holidayID string which matches the holiday's name.
//Anything with a holidayID, which isn't in the holidays list, will never occur.
//Please, Don't spam stuff up with stupid stuff (key example being april-fools Pooh/ERP/etc),
//And don't forget: CHECK YOUR CODE!!!! We don't want any zero-day bugs which happen only on holidays and never get found/fixed!
/datum/controller/subsystem/events/proc/resetFrequency()
frequency_lower = initial(frequency_lower)
frequency_upper = initial(frequency_upper)
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//ALSO, MOST IMPORTANTLY: Don't add stupid stuff! Discuss bonus content with Project-Heads first please!//
//////////////////////////////////////////////////////////////////////////////////////////////////////////
*/
/**
* HOLIDAYS
*
* Uncommenting ALLOW_HOLIDAYS in config.txt will enable holidays
*
* It's easy to add stuff. Just add a holiday datum in code/modules/holiday/holidays.dm
* You can then check if it's a special day in any code in the game by calling check_holidays("Groundhog Day")
*
* You can also make holiday random events easily thanks to Pete/Gia's system.
* simply make a random event normally, then assign it a holidayID string which matches the holiday's name.
* Anything with a holidayID, which isn't in the holidays list, will never occur.
*
* Please, Don't spam stuff up with stupid stuff (key example being april-fools Pooh/ERP/etc),
* and don't forget: CHECK YOUR CODE!!!! We don't want any zero-day bugs which happen only on holidays and never get found/fixed!
*/
GLOBAL_LIST(holidays)
//sets up the holidays and holidays list
/datum/controller/subsystem/events/proc/getHoliday()
/**
* Checks that the passed holiday is located in the global holidays list.
*
* Returns a holiday datum, or null if it's not that holiday.
*/
/proc/check_holidays(holiday_to_find)
if(!CONFIG_GET(flag/allow_holidays))
return // Holiday stuff was not enabled in the config!
for(var/H in subtypesof(/datum/holiday))
var/datum/holiday/holiday = new H()
if(isnull(GLOB.holidays) && !fill_holidays())
return // Failed to generate holidays, for some reason
return GLOB.holidays[holiday_to_find]
/**
* Fills the holidays list if applicable, or leaves it an empty list.
*/
/proc/fill_holidays()
if(!CONFIG_GET(flag/allow_holidays))
return FALSE // Holiday stuff was not enabled in the config!
GLOB.holidays = list()
for(var/holiday_type in subtypesof(/datum/holiday))
var/datum/holiday/holiday = new holiday_type()
var/delete_holiday = TRUE
for(var/timezone in holiday.timezones)
var/time_in_timezone = world.realtime + timezone HOURS
@@ -130,24 +156,16 @@ SUBSYSTEM_DEF(events)
if(holiday.shouldCelebrate(DD, MM, YYYY, DDD))
holiday.celebrate()
LAZYSET(holidays, holiday.name, holiday)
GLOB.holidays[holiday.name] = holiday
delete_holiday = FALSE
break
if(delete_holiday)
qdel(holiday)
if(holidays)
holidays = shuffle(holidays)
if(GLOB.holidays.len)
shuffle_inplace(GLOB.holidays)
// regenerate station name because holiday prefixes.
set_station_name(new_station_name())
world.update_status()
/datum/controller/subsystem/events/proc/toggleWizardmode()
wizardmode = !wizardmode
message_admins("Summon Events has been [wizardmode ? "enabled, events will occur every [SSevents.frequency_lower / 600] to [SSevents.frequency_upper / 600] minutes" : "disabled"]!")
log_game("Summon Events was [wizardmode ? "enabled" : "disabled"]!")
/datum/controller/subsystem/events/proc/resetFrequency()
frequency_lower = initial(frequency_lower)
frequency_upper = initial(frequency_upper)
return TRUE
+3 -3
View File
@@ -272,10 +272,10 @@ SUBSYSTEM_DEF(ticker)
current_state = GAME_STATE_PLAYING
Master.SetRunLevel(RUNLEVEL_GAME)
if(SSevents.holidays)
if(length(GLOB.holidays))
to_chat(world, span_notice("and..."))
for(var/holidayname in SSevents.holidays)
var/datum/holiday/holiday = SSevents.holidays[holidayname]
for(var/holidayname in GLOB.holidays)
var/datum/holiday/holiday = GLOB.holidays[holidayname]
to_chat(world, "<h4>[holiday.greet()]</h4>")
PostSetup()
@@ -226,17 +226,17 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list(
var/name_part1
var/name_part2
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
if(check_holidays(HALLOWEEN))
name_action = pick_list(ARCADE_FILE, "rpg_action_halloween")
name_part1 = pick_list(ARCADE_FILE, "rpg_adjective_halloween")
name_part2 = pick_list(ARCADE_FILE, "rpg_enemy_halloween")
weapons = strings(ARCADE_FILE, "rpg_weapon_halloween")
else if(SSevents.holidays && SSevents.holidays[CHRISTMAS])
else if(check_holidays(CHRISTMAS))
name_action = pick_list(ARCADE_FILE, "rpg_action_xmas")
name_part1 = pick_list(ARCADE_FILE, "rpg_adjective_xmas")
name_part2 = pick_list(ARCADE_FILE, "rpg_enemy_xmas")
weapons = strings(ARCADE_FILE, "rpg_weapon_xmas")
else if(SSevents.holidays && SSevents.holidays[VALENTINES])
else if(check_holidays(VALENTINES))
name_action = pick_list(ARCADE_FILE, "rpg_action_valentines")
name_part1 = pick_list(ARCADE_FILE, "rpg_adjective_valentines")
name_part2 = pick_list(ARCADE_FILE, "rpg_enemy_valentines")
@@ -220,7 +220,7 @@
return
LAZYREMOVE(messages, LAZYACCESS(messages, message_index))
if ("emergency_meeting")
if(!(SSevents.holidays && SSevents.holidays[APRIL_FOOLS]))
if(!check_holidays(APRIL_FOOLS))
return
if (!authenticated_as_silicon_or_captain(usr))
return
@@ -530,7 +530,7 @@
data["importantActionReady"] = COOLDOWN_FINISHED(src, important_action_cooldown)
data["shuttleCalled"] = FALSE
data["shuttleLastCalled"] = FALSE
data["aprilFools"] = SSevents.holidays && SSevents.holidays[APRIL_FOOLS]
data["aprilFools"] = check_holidays(APRIL_FOOLS)
data["alertLevel"] = SSsecurity_level.get_current_level_as_text()
data["authorizeName"] = authorize_name
data["canLogOut"] = !issilicon(user)
+1 -1
View File
@@ -81,7 +81,7 @@
var/mob/living/carbon/human/human = M
if(!(human.mob_biotypes & (MOB_ROBOTIC|MOB_MINERAL|MOB_UNDEAD|MOB_SPIRIT)))
var/datum/species/species_to_transform = /datum/species/fly
if(SSevents.holidays && SSevents.holidays[MOTH_WEEK])
if(check_holidays(MOTH_WEEK))
species_to_transform = /datum/species/moth
if(human.dna && human.dna.species.id != initial(species_to_transform.id))
to_chat(M, span_hear("You hear a buzzing in your ears."))
@@ -7,16 +7,15 @@
#define PRIDE_ALPHA 60
/obj/effect/turf_decal/tile/Initialize(mapload)
if(SSevents.holidays)
if (SSevents.holidays[APRIL_FOOLS])
color = "#[random_short_color()]"
else if (SSevents.holidays[PRIDE_WEEK])
var/datum/holiday/pride_week/pride_week = SSevents.holidays[PRIDE_WEEK]
color = pride_week.get_floor_tile_color(src)
if (check_holidays(APRIL_FOOLS))
color = "#[random_short_color()]"
else if (check_holidays(PRIDE_WEEK))
var/datum/holiday/pride_week/pride_week = GLOB.holidays[PRIDE_WEEK]
color = pride_week.get_floor_tile_color(src)
// It looks garish at different alphas, and it's not possible to get a
// consistent color palette without this.
alpha = PRIDE_ALPHA
// It looks garish at different alphas, and it's not possible to get a
// consistent color palette without this.
alpha = PRIDE_ALPHA
return ..()
#undef PRIDE_ALPHA
@@ -580,7 +579,7 @@
icon_state = "trimline_box"
/obj/effect/turf_decal/trimline/Initialize(mapload)
if(SSevents.holidays && SSevents.holidays[APRIL_FOOLS])
if(check_holidays(APRIL_FOOLS))
color = "#[random_short_color()]"
. = ..()
+1 -1
View File
@@ -204,7 +204,7 @@
/obj/item/food/cookie/sugar/Initialize(mapload)
. = ..()
if(SSevents.holidays && SSevents.holidays[FESTIVE_SEASON])
if(check_holidays(FESTIVE_SEASON))
var/shape = pick("tree", "bear", "santa", "stocking", "present", "cane")
desc = "A sugar cookie in the shape of a [shape]. I hope Santa likes it!"
icon_state = "sugarcookie_[shape]"
@@ -28,7 +28,7 @@
qdel(src)
return TRUE
if(SEND_SIGNAL(target.mind, COMSIG_MINDSHIELD_IMPLANTED, user) & COMPONENT_MINDSHIELD_DECONVERTED)
if(prob(1) || SSevents.holidays && SSevents.holidays[APRIL_FOOLS])
if(prob(1) || check_holidays(APRIL_FOOLS))
target.say("I'm out! I quit! Whose kidneys are these?", forced = "They're out! They quit! Whose kidneys do they have?")
ADD_TRAIT(target, TRAIT_MINDSHIELD, IMPLANT_TRAIT)
@@ -20,9 +20,9 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/calendar, 32)
/obj/structure/sign/calendar/examine(mob/user)
. = ..()
. += span_info("The current date is: [time2text(world.realtime, "DDD, MMM DD")], [CURRENT_STATION_YEAR].")
if(SSevents.holidays)
if(length(GLOB.holidays))
. += span_info("Events:")
for(var/holidayname in SSevents.holidays)
for(var/holidayname in GLOB.holidays)
. += span_info("[holidayname]")
/**
+1 -1
View File
@@ -180,7 +180,7 @@
var/mineralChance = 13
/turf/closed/mineral/random/Initialize(mapload)
if(SSevents.holidays && SSevents.holidays[APRIL_FOOLS])
if(check_holidays(APRIL_FOOLS))
mineralSpawnChanceList[/obj/item/stack/ore/bananium] = 3
mineralSpawnChanceList = typelist("mineralSpawnChanceList", mineralSpawnChanceList)
@@ -22,7 +22,7 @@
var/end_message = "."
var/rendered = begin_message + obj_message + end_message
deadchat_broadcast(rendered, "<b>[L]</b>", follow_target = L, turf_target = get_turf(L), message_type=DEADCHAT_ANNOUNCEMENT)
if(prob(1) || SSevents.holidays && SSevents.holidays[APRIL_FOOLS])
if(prob(1) || check_holidays(APRIL_FOOLS))
L.say("You son of a bitch! I'm in.", forced = "That son of a bitch! They're in.")
/datum/antagonist/brainwashed
+1 -1
View File
@@ -281,7 +281,7 @@ structure_check() searches for nearby cultist structures required for the invoca
H.remove_status_effect(/datum/status_effect/speech/slurring/cult)
H.remove_status_effect(/datum/status_effect/speech/stutter)
if(prob(1) || SSevents.holidays && SSevents.holidays[APRIL_FOOLS])
if(prob(1) || check_holidays(APRIL_FOOLS))
H.say("You son of a bitch! I'm in.", forced = "That son of a bitch! They're in.")
if(isshade(convertee))
convertee.icon_state = "shade_cult"
@@ -220,7 +220,7 @@
/mob/living/simple_animal/hostile/imp/slaughter/laughter/Initialize(mapload)
. = ..()
if(SSevents.holidays && SSevents.holidays[APRIL_FOOLS])
if(check_holidays(APRIL_FOOLS))
icon_state = "honkmon"
/mob/living/simple_animal/hostile/imp/slaughter/laughter/ex_act(severity)
+1 -1
View File
@@ -298,7 +298,7 @@
//If this proc fires the mob must be a revhead
var/datum/antagonist/rev/head/converter = aggressor.mind.has_antag_datum(/datum/antagonist/rev/head)
if(converter.add_revolutionary(victim.mind))
if(prob(1) || SSevents.holidays && SSevents.holidays[APRIL_FOOLS])
if(prob(1) || check_holidays(APRIL_FOOLS))
victim.say("You son of a bitch! I'm in.", forced = "That son of a bitch! They're in.")
times_used -- //Flashes less likely to burn out for headrevs when used for conversion
else
+2 -2
View File
@@ -13,12 +13,12 @@
/obj/item/clothing/suit/costume/ghost_sheet/Initialize(mapload)
. = ..()
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
if(check_holidays(HALLOWEEN))
update_icon(UPDATE_OVERLAYS)
/obj/item/clothing/suit/costume/ghost_sheet/worn_overlays(mutable_appearance/standing, isinhands, icon_file)
. = ..()
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
if(check_holidays(HALLOWEEN))
if(!isinhands)
. += emissive_appearance('icons/mob/simple/mob.dmi', "ghost", offset_spokesman = src, alpha = src.alpha)
+1 -1
View File
@@ -51,7 +51,7 @@
return FALSE
if(players_amt < min_players)
return FALSE
if(holidayID && (!SSevents.holidays || !SSevents.holidays[holidayID]))
if(holidayID && !check_holidays(holidayID))
return FALSE
if(EMERGENCY_ESCAPED_OR_ENDGAMED)
return FALSE
+1 -1
View File
@@ -37,7 +37,7 @@
if(istype(affected_area, /area/station/service/kitchen))
for(var/turf/open/kitchen in affected_area)
kitchen.set_light(1, 0.75)
if(!prob(1) && !SSevents.holidays?[APRIL_FOOLS])
if(!prob(1) && !check_holidays(APRIL_FOOLS))
continue
var/obj/machinery/oven/roast_ruiner = locate() in affected_area
if(roast_ruiner)
+2 -2
View File
@@ -56,9 +56,9 @@
/obj/effect/spawner/xmastree/Initialize(mapload)
. = ..()
if((CHRISTMAS in SSevents.holidays) && christmas_tree)
if(check_holidays(CHRISTMAS) && christmas_tree)
new christmas_tree(get_turf(src))
else if((FESTIVE_SEASON in SSevents.holidays) && festive_tree)
else if(check_holidays(FESTIVE_SEASON) && festive_tree)
new festive_tree(get_turf(src))
/obj/effect/spawner/xmastree/rdrod
+1 -1
View File
@@ -34,7 +34,7 @@
if("threatening")
wave_type = GLOB.meteors_threatening
if("catastrophic")
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
if(check_holidays(HALLOWEEN))
wave_type = GLOB.meteorsSPOOKY
else
wave_type = GLOB.meteors_catastrophic
@@ -73,7 +73,7 @@
/datum/outfit/job/hop/pre_equip(mob/living/carbon/human/H)
..()
if(locate(/datum/holiday/ianbirthday) in SSevents.holidays)
if(check_holidays("Ian's Birthday"))
undershirt = /datum/sprite_accessory/undershirt/ian
//only pet worth reviving
+2 -2
View File
@@ -43,12 +43,12 @@
/datum/outfit/job/janitor/pre_equip(mob/living/carbon/human/H, visualsOnly)
. = ..()
if(GARBAGEDAY in SSevents.holidays)
if(check_holidays(GARBAGEDAY))
backpack_contents += list(/obj/item/gun/ballistic/revolver)
r_pocket = /obj/item/ammo_box/a357
/datum/outfit/job/janitor/get_types_to_preload()
. = ..()
if(GARBAGEDAY in SSevents.holidays)
if(check_holidays(GARBAGEDAY))
. += /obj/item/gun/ballistic/revolver
. += /obj/item/ammo_box/a357
+2 -2
View File
@@ -548,7 +548,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava)
var/balloon_clusters = 2
/obj/effect/mapping_helpers/ianbirthday/LateInitialize()
if(locate(/datum/holiday/ianbirthday) in SSevents.holidays)
if(check_holidays("Ian's Birthday"))
birthday()
qdel(src)
@@ -616,7 +616,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava)
icon_state = "iansnewyrshelper"
/obj/effect/mapping_helpers/iannewyear/LateInitialize()
if(SSevents.holidays && SSevents.holidays[NEW_YEAR])
if(check_holidays(NEW_YEAR))
fireworks()
qdel(src)
+1 -1
View File
@@ -277,7 +277,7 @@
/mob/living/carbon/human/get_blood_id()
if(HAS_TRAIT(src, TRAIT_HUSK))
return
if(SSevents.holidays && SSevents.holidays[APRIL_FOOLS] && is_clown_job(mind?.assigned_role))
if(check_holidays(APRIL_FOOLS) && is_clown_job(mind?.assigned_role))
return /datum/reagent/colorful_reagent
if(dna.species.exotic_blood)
return dna.species.exotic_blood
@@ -25,7 +25,7 @@
/datum/species/dullahan/check_roundstart_eligible()
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
if(check_holidays(HALLOWEEN))
return TRUE
return ..()
@@ -811,7 +811,7 @@
..()
/datum/species/golem/cloth/check_roundstart_eligible()
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
if(check_holidays(HALLOWEEN))
return TRUE
return ..()
@@ -115,7 +115,7 @@
return ..()
/datum/species/monkey/check_roundstart_eligible()
if(SSevents.holidays && SSevents.holidays[MONKEYDAY])
if(check_holidays(MONKEYDAY))
return TRUE
return ..()
@@ -29,7 +29,7 @@
)
/datum/species/shadow/check_roundstart_eligible()
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
if(check_holidays(HALLOWEEN))
return TRUE
return ..()
@@ -49,7 +49,7 @@
C.set_safe_hunger_level()
/datum/species/skeleton/check_roundstart_eligible()
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
if(check_holidays(HALLOWEEN))
return TRUE
return ..()
@@ -34,7 +34,7 @@
var/info_text = "You are a <span class='danger'>Vampire</span>. You will slowly but constantly lose blood if outside of a coffin. If inside a coffin, you will slowly heal. You may gain more blood by grabbing a live victim and using your drain ability."
/datum/species/vampire/check_roundstart_eligible()
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
if(check_holidays(HALLOWEEN))
return TRUE
return ..()
@@ -48,7 +48,7 @@
return
/datum/species/zombie/check_roundstart_eligible()
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
if(check_holidays(HALLOWEEN))
return TRUE
return ..()
+1 -1
View File
@@ -261,7 +261,7 @@
/obj/item/mod/module/springlock/bite_of_87/on_suit_activation()
..()
if(SSevents.holidays && SSevents.holidays[APRIL_FOOLS] || prob(1))
if(check_holidays(APRIL_FOOLS) || prob(1))
mod.set_mod_color("#b17f00")
mod.wearer.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) // turns purple guy purple
mod.wearer.add_atom_colour("#704b96", FIXED_COLOUR_PRIORITY)
+1 -1
View File
@@ -42,7 +42,7 @@
/// Returns a fresh piece of paper
/obj/item/paper_bin/proc/generate_paper()
var/obj/item/paper/paper = new papertype
if(SSevents.holidays && SSevents.holidays[APRIL_FOOLS])
if(check_holidays(APRIL_FOOLS))
if(prob(30))
paper.add_raw_text("<font face=\"[CRAYON_FONT]\" color=\"red\"><b>HONK HONK HONK HONK HONK HONK HONK<br>HOOOOOOOOOOOOOOOOOOOOOONK<br>APRIL FOOLS</b></font>")
paper.AddElement(/datum/element/honkspam)
+2 -2
View File
@@ -49,7 +49,7 @@
/obj/structure/reagent_dispensers/Initialize(mapload)
. = ..()
if(icon_state == "water" && SSevents.holidays?[APRIL_FOOLS])
if(icon_state == "water" && check_holidays(APRIL_FOOLS))
icon_state = "water_fools"
/obj/structure/reagent_dispensers/examine(mob/user)
@@ -246,7 +246,7 @@
/obj/structure/reagent_dispensers/fueltank/Initialize(mapload)
. = ..()
if(SSevents.holidays?[APRIL_FOOLS])
if(check_holidays(APRIL_FOOLS))
icon_state = "fuel_fools"
/obj/structure/reagent_dispensers/fueltank/blob_act(obj/structure/blob/B)