mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2025-12-14 12:12:37 +00:00
Adds event regions to GameMaster events (#8334)
* Configures gm events to be selectable by "region" * Configures event regions for existing events * Configures event selection to filter by region
This commit is contained in:
10
code/__defines/events.dm
Normal file
10
code/__defines/events.dm
Normal file
@@ -0,0 +1,10 @@
|
||||
// Event defines
|
||||
|
||||
#define EVENT_REGION_SPACESTATION "near_space" // In space, but easy access
|
||||
#define EVENT_REGION_DEEPSPACE "overmap" // Deep in space, far from others
|
||||
#define EVENT_REGION_PLANETSURFACE "planetside" // Somewhere on a planet
|
||||
#define EVENT_REGION_SUBTERRANEAN "mining" // Somewhere explicitly subterranean, like the mining Z
|
||||
#define EVENT_REGION_PLAYER_MAIN_AREA "player_main_area" // The main area that players are expected to be in
|
||||
|
||||
// Universal events disregard
|
||||
#define EVENT_REGION_UNIVERSAL "universal"
|
||||
@@ -238,19 +238,17 @@ This actually tests if they have the same entries and values.
|
||||
//Pretends to pick an element based on its weight but really just seems to pick a random element.
|
||||
/proc/pickweight(list/L)
|
||||
var/total = 0
|
||||
var/item
|
||||
for (item in L)
|
||||
if (!L[item])
|
||||
for(var/item in L)
|
||||
if(!L[item])
|
||||
L[item] = 1
|
||||
total += L[item]
|
||||
|
||||
total = rand(1, total)
|
||||
for (item in L)
|
||||
total -=L [item]
|
||||
if (total <= 0)
|
||||
for(var/item in L)
|
||||
total -= L[item]
|
||||
if(total <= 0)
|
||||
return item
|
||||
|
||||
return null
|
||||
|
||||
//Pick a random element from the list and remove it from the list.
|
||||
/proc/pick_n_take(list/listfrom)
|
||||
|
||||
@@ -10,8 +10,12 @@
|
||||
/datum/game_master/default/choose_event()
|
||||
log_game_master("Now starting event decision.")
|
||||
|
||||
var/list/regions = metric.assess_player_regions()
|
||||
if(!LAZYLEN(regions))
|
||||
regions = list(EVENT_REGION_UNIVERSAL = 100)
|
||||
|
||||
var/list/most_active_departments = metric.assess_all_departments(3, list(last_department_used))
|
||||
var/list/best_events = decide_best_events(most_active_departments)
|
||||
var/list/best_events = decide_best_events(most_active_departments, regions)
|
||||
|
||||
if(LAZYLEN(best_events))
|
||||
log_game_master("Got [best_events.len] choice\s for the next event.")
|
||||
@@ -32,33 +36,45 @@
|
||||
last_department_used = LAZYACCESS(choice.departments, 1)
|
||||
return choice
|
||||
|
||||
/datum/game_master/default/proc/decide_best_events(list/most_active_departments)
|
||||
/datum/game_master/default/proc/decide_best_events(list/most_active_departments, var/list/regions)
|
||||
if(!LAZYLEN(most_active_departments)) // Server's empty?
|
||||
log_game_master("Game Master failed to find any active departments.")
|
||||
return list()
|
||||
|
||||
var/list/best_events = list()
|
||||
// Filter by generic factors
|
||||
var/list/available_events = filter_events_generic()
|
||||
|
||||
// Filter by player regions. Lots of people in the mines = favor subterranean events
|
||||
var/list/best_events = filter_events_by_region(available_events, pickweight(regions))
|
||||
if(!LAZYLEN(best_events))
|
||||
best_events = filter_events_by_region(available_events, EVENT_REGION_UNIVERSAL)
|
||||
if(!LAZYLEN(best_events))
|
||||
log_game_master("Game Master failed to find a suitable event, something very wrong is going on.")
|
||||
return list()
|
||||
available_events = best_events
|
||||
|
||||
// Filter events by department. Lots of engineering = break things on the station
|
||||
if(most_active_departments.len >= 2)
|
||||
var/list/top_two = list(most_active_departments[1], most_active_departments[2])
|
||||
best_events = filter_events_by_departments(top_two)
|
||||
best_events = filter_events_by_departments(available_events, top_two)
|
||||
|
||||
if(LAZYLEN(best_events)) // We found something for those two, let's do it.
|
||||
return best_events
|
||||
|
||||
// Otherwise we probably couldn't find something for the second highest group, so let's ignore them.
|
||||
best_events = filter_events_by_departments(most_active_departments[1])
|
||||
best_events = filter_events_by_departments(available_events, list(most_active_departments[1]))
|
||||
|
||||
if(LAZYLEN(best_events))
|
||||
return best_events
|
||||
|
||||
// At this point we should expand our horizons.
|
||||
best_events = filter_events_by_departments(list(DEPARTMENT_EVERYONE))
|
||||
best_events = filter_events_by_departments(available_events, list(DEPARTMENT_EVERYONE))
|
||||
|
||||
if(LAZYLEN(best_events))
|
||||
return best_events
|
||||
|
||||
// Just give a random event if for some reason it still can't make up its mind.
|
||||
best_events = filter_events_by_departments()
|
||||
best_events = filter_events_by_departments(available_events)
|
||||
|
||||
if(LAZYLEN(best_events))
|
||||
return best_events
|
||||
@@ -66,10 +82,8 @@
|
||||
log_game_master("Game Master failed to find a suitable event, something very wrong is going on.")
|
||||
return list()
|
||||
|
||||
// Filters the available events down to events for specific departments.
|
||||
// Pass DEPARTMENT_EVERYONE if you want events that target the general population, like gravity failure.
|
||||
// If no list is passed, all the events will be returned.
|
||||
/datum/game_master/default/proc/filter_events_by_departments(list/departments)
|
||||
// Filters events by availability, enable, and chaos
|
||||
/datum/game_master/default/proc/filter_events_generic()
|
||||
. = list()
|
||||
for(var/E in SSgame_master.available_events)
|
||||
var/datum/event2/meta/event = E
|
||||
@@ -78,12 +92,21 @@
|
||||
if(event.chaotic_threshold && !ignore_round_chaos)
|
||||
if(SSgame_master.danger > event.chaotic_threshold)
|
||||
continue
|
||||
. += event
|
||||
|
||||
// Filters the available events down to events for specific departments.
|
||||
// Pass DEPARTMENT_EVERYONE if you want events that target the general population, like gravity failure.
|
||||
// If no list is passed, all the events will be returned.
|
||||
/datum/game_master/default/proc/filter_events_by_departments(list/available_events, list/departments)
|
||||
. = list()
|
||||
for(var/datum/event2/meta/event in available_events)
|
||||
// An event has to involve all of these departments to pass.
|
||||
var/viable = TRUE
|
||||
if(LAZYLEN(departments))
|
||||
for(var/department in departments)
|
||||
if(!LAZYFIND(departments, department))
|
||||
viable = FALSE
|
||||
break
|
||||
if(viable)
|
||||
if(!LAZYLEN(departments) || (departments ~= (event.departments & departments)))
|
||||
. += event
|
||||
|
||||
// Filters the available events by the region those events target.
|
||||
/datum/game_master/default/proc/filter_events_by_region(list/available_events, var/target_region)
|
||||
. = list()
|
||||
for(var/datum/event2/meta/event in available_events)
|
||||
if(target_region in event.regions)
|
||||
. += event
|
||||
@@ -76,20 +76,13 @@ This allows for events that have their announcement happen after the end itself.
|
||||
|
||||
|
||||
/datum/event2/event/proc/is_planet_z_level(z_level)
|
||||
var/datum/planet/P = LAZYACCESS(SSplanets.z_to_planet, z_level)
|
||||
if(!istype(P))
|
||||
return FALSE
|
||||
return TRUE
|
||||
return istype(LAZYACCESS(SSplanets.z_to_planet, z_level), /datum/planet)
|
||||
|
||||
// Returns a list of empty turfs in the same area.
|
||||
/datum/event2/event/proc/find_random_turfs(minimum_free_space = 5, list/specific_areas = list(), ignore_occupancy = FALSE)
|
||||
var/list/area/grand_list_of_areas = find_random_areas(specific_areas)
|
||||
|
||||
if(!LAZYLEN(grand_list_of_areas))
|
||||
return list()
|
||||
|
||||
for(var/thing in grand_list_of_areas)
|
||||
var/list/A = thing
|
||||
for(var/area/A in grand_list_of_areas)
|
||||
var/list/turfs = list()
|
||||
for(var/turf/T in A)
|
||||
if(!T.check_density())
|
||||
@@ -98,7 +91,6 @@ This allows for events that have their announcement happen after the end itself.
|
||||
if(turfs.len < minimum_free_space)
|
||||
continue // Not enough free space.
|
||||
return turfs
|
||||
|
||||
return list()
|
||||
|
||||
/datum/event2/event/proc/find_random_areas(list/specific_areas = list(), ignore_occupancy = FALSE)
|
||||
@@ -107,8 +99,7 @@ This allows for events that have their announcement happen after the end itself.
|
||||
|
||||
var/list/area/grand_list_of_areas = get_all_existing_areas_of_types(specific_areas)
|
||||
. = list()
|
||||
for(var/thing in shuffle(grand_list_of_areas))
|
||||
var/area/A = thing
|
||||
for(var/area/A in shuffle(grand_list_of_areas))
|
||||
if(A.forbid_events)
|
||||
continue
|
||||
if(!(A.z in get_location_z_levels()))
|
||||
@@ -182,7 +173,7 @@ This allows for events that have their announcement happen after the end itself.
|
||||
return
|
||||
|
||||
if(!check_rights(R_ADMIN|R_EVENT|R_DEBUG))
|
||||
message_admins("[usr] has attempted to manipulate an event without sufficent privilages.")
|
||||
message_admins("[usr] has attempted to manipulate an event without sufficent privileges.")
|
||||
return
|
||||
|
||||
if(href_list["abort"])
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
chaos = -10 // A helpful event.
|
||||
reusable = TRUE
|
||||
event_type = /datum/event2/event/shipping_error
|
||||
regions = list(EVENT_REGION_UNIVERSAL)
|
||||
|
||||
/datum/event2/meta/shipping_error/get_weight()
|
||||
return (metric.count_people_with_job(/datum/job/cargo_tech) + metric.count_people_with_job(/datum/job/qm)) * 30
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
chaos = 10
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_LOW_IMPACT
|
||||
event_type = /datum/event2/event/manifest_malfunction
|
||||
regions = list(EVENT_REGION_UNIVERSAL)
|
||||
|
||||
/datum/event2/meta/manifest_malfunction/get_weight()
|
||||
var/security = metric.count_people_in_department(DEPARTMENT_SECURITY)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
chaos = 10
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_LOW_IMPACT
|
||||
event_type = /datum/event2/event/money_hacker
|
||||
regions = list(EVENT_REGION_UNIVERSAL)
|
||||
|
||||
/datum/event2/meta/money_hacker/get_weight()
|
||||
var/command = metric.count_people_with_job(/datum/job/hop) + metric.count_people_with_job(/datum/job/captain)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
departments = list(DEPARTMENT_COMMAND, DEPARTMENT_CARGO)
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_LOW_IMPACT
|
||||
event_type = /datum/event2/event/raise_funds
|
||||
regions = list(EVENT_REGION_UNIVERSAL)
|
||||
|
||||
/datum/event2/meta/raise_funds/get_weight()
|
||||
var/command = metric.count_people_in_department(DEPARTMENT_COMMAND)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_MEDIUM_IMPACT
|
||||
event_type = /datum/event2/event/airlock_failure
|
||||
var/needs_medical = FALSE
|
||||
regions = list(EVENT_REGION_PLAYER_MAIN_AREA)
|
||||
|
||||
/datum/event2/meta/airlock_failure/emag
|
||||
name = "airlock failure - emag"
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
// In the distant future, if a mechanical skill system were to come into being, these vars could be replaced with skill checks so off duty people could count.
|
||||
var/required_fighters = 2 // Fighters refers to engineering OR security.
|
||||
var/required_support = 1 // Support refers to doctors AND roboticists, depending on fighter composition.
|
||||
regions = list(EVENT_REGION_PLAYER_MAIN_AREA)
|
||||
|
||||
/datum/event2/meta/blob/hard
|
||||
name = "harder blob"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
chaos = 10
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_LOW_IMPACT
|
||||
event_type = /datum/event2/event/brand_intelligence
|
||||
regions = list(EVENT_REGION_UNIVERSAL)
|
||||
|
||||
/datum/event2/meta/brand_intelligence/get_weight()
|
||||
return 10 + (metric.count_people_in_department(DEPARTMENT_ENGINEERING) * 20)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_LOW_IMPACT
|
||||
reusable = TRUE
|
||||
event_type = /datum/event2/event/camera_damage
|
||||
regions = list(EVENT_REGION_PLAYER_MAIN_AREA)
|
||||
|
||||
/datum/event2/meta/camera_damage/get_weight()
|
||||
return 30 + (metric.count_people_in_department(DEPARTMENT_ENGINEERING) * 20) + (metric.count_people_in_department(DEPARTMENT_SYNTHETIC) * 40)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_LOW_IMPACT
|
||||
reusable = TRUE
|
||||
event_type = /datum/event2/event/canister_leak
|
||||
regions = list(EVENT_REGION_PLAYER_MAIN_AREA)
|
||||
|
||||
/datum/event2/meta/canister_leak/get_weight()
|
||||
return metric.count_people_in_department(DEPARTMENT_ENGINEERING) * 30
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_LOW_IMPACT
|
||||
reusable = TRUE
|
||||
event_type = /datum/event2/event/dust
|
||||
regions = list(EVENT_REGION_SPACESTATION)
|
||||
|
||||
/datum/event2/meta/dust/get_weight()
|
||||
return metric.count_people_in_department(DEPARTMENT_ENGINEERING) * 20
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_LOW_IMPACT
|
||||
reusable = TRUE
|
||||
event_type = /datum/event2/event/gas_leak
|
||||
regions = list(EVENT_REGION_PLAYER_MAIN_AREA)
|
||||
|
||||
/datum/event2/meta/gas_leak/get_weight()
|
||||
// Synthetics are counted in higher value because they can wirelessly connect to alarms.
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_LOW_IMPACT
|
||||
reusable = TRUE
|
||||
event_type = /datum/event2/event/grid_check
|
||||
regions = list(EVENT_REGION_PLAYER_MAIN_AREA)
|
||||
|
||||
// Having the turbines be way over their rated limit makes grid checks more likely.
|
||||
/datum/event2/meta/grid_check/proc/get_overpower()
|
||||
|
||||
@@ -1,83 +1,84 @@
|
||||
// This event gives the station an advance warning about meteors, so that they can prepare in various ways.
|
||||
|
||||
/datum/event2/meta/meteor_defense
|
||||
name = "meteor defense"
|
||||
departments = list(DEPARTMENT_ENGINEERING, DEPARTMENT_CARGO)
|
||||
chaos = 50
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_HIGH_IMPACT
|
||||
event_class = "meteor defense"
|
||||
event_type = /datum/event2/event/meteor_defense
|
||||
|
||||
/datum/event2/meta/meteor_defense/get_weight()
|
||||
// Engineers count as 20.
|
||||
var/engineers = metric.count_people_in_department(DEPARTMENT_ENGINEERING)
|
||||
if(engineers < 3) // There -must- be at least three engineers for this to be possible.
|
||||
return 0
|
||||
|
||||
. = engineers * 20
|
||||
|
||||
// Cargo and AI/borgs count as 10.
|
||||
var/cargo = metric.count_people_with_job(/datum/job/cargo_tech) + metric.count_people_with_job(/datum/job/qm)
|
||||
var/bots = metric.count_people_in_department(DEPARTMENT_SYNTHETIC)
|
||||
|
||||
. += (cargo + bots) * 10
|
||||
|
||||
|
||||
/datum/event2/event/meteor_defense
|
||||
start_delay_lower_bound = 10 MINUTES
|
||||
start_delay_upper_bound = 15 MINUTES
|
||||
var/soon_announced = FALSE
|
||||
var/direction = null // Actual dir used for which side the meteors come from.
|
||||
var/dir_text = null // Direction shown in the announcement.
|
||||
var/list/meteor_types = null
|
||||
var/waves = null // How many times to send meteors.
|
||||
var/last_wave_time = null // world.time of latest wave.
|
||||
var/wave_delay = 10 SECONDS
|
||||
var/wave_upper_bound = 8 // Max amount of meteors per wave.
|
||||
var/wave_lower_bound = 4 // Min amount.
|
||||
|
||||
/datum/event2/event/meteor_defense/proc/set_meteor_types()
|
||||
meteor_types = meteors_threatening.Copy()
|
||||
|
||||
/datum/event2/event/meteor_defense/set_up()
|
||||
direction = pick(cardinal) // alldirs doesn't work with current meteor code unfortunately.
|
||||
waves = rand(3, 6)
|
||||
switch(direction)
|
||||
if(NORTH)
|
||||
dir_text = "aft" // For some reason this is needed.
|
||||
if(SOUTH)
|
||||
dir_text = "fore"
|
||||
if(EAST)
|
||||
dir_text = "port"
|
||||
if(WEST)
|
||||
dir_text = "starboard"
|
||||
set_meteor_types()
|
||||
|
||||
/datum/event2/event/meteor_defense/announce()
|
||||
var/announcement = "Meteors are expected to approach from the [dir_text] side, in approximately [DisplayTimeText(time_to_start - world.time, 60)]."
|
||||
command_announcement.Announce(announcement, "Meteor Alert", new_sound = 'sound/AI/meteors.ogg')
|
||||
|
||||
/datum/event2/event/meteor_defense/wait_tick()
|
||||
if(!soon_announced)
|
||||
if((time_to_start - world.time) <= 5 MINUTES)
|
||||
soon_announced = TRUE
|
||||
var/announcement = "The incoming meteors are expected to approach from the [dir_text] side. \
|
||||
ETA to arrival is approximately [DisplayTimeText(time_to_start - world.time, 60)]."
|
||||
command_announcement.Announce(announcement, "Meteor Alert - Update")
|
||||
|
||||
/datum/event2/event/meteor_defense/start()
|
||||
command_announcement.Announce("Incoming meteors approach from \the [dir_text] side!", "Meteor Alert - Update")
|
||||
|
||||
/datum/event2/event/meteor_defense/event_tick()
|
||||
if(world.time > last_wave_time + wave_delay)
|
||||
last_wave_time = world.time
|
||||
waves--
|
||||
message_admins("[waves] more wave\s of meteors remain.")
|
||||
// Dir is reversed because the direction describes where meteors are going, not what side it's gonna hit.
|
||||
spawn_meteors(rand(wave_upper_bound, wave_lower_bound), meteor_types, reverse_dir[direction])
|
||||
|
||||
/datum/event2/event/meteor_defense/should_end()
|
||||
return waves <= 0
|
||||
|
||||
/datum/event2/event/meteor_defense/end()
|
||||
command_announcement.Announce("\The [location_name()] will clear the incoming meteors in a moment.", "Meteor Alert - Update")
|
||||
// This event gives the station an advance warning about meteors, so that they can prepare in various ways.
|
||||
|
||||
/datum/event2/meta/meteor_defense
|
||||
name = "meteor defense"
|
||||
departments = list(DEPARTMENT_ENGINEERING, DEPARTMENT_CARGO)
|
||||
chaos = 50
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_HIGH_IMPACT
|
||||
event_class = "meteor defense"
|
||||
event_type = /datum/event2/event/meteor_defense
|
||||
regions = list(EVENT_REGION_SPACESTATION)
|
||||
|
||||
/datum/event2/meta/meteor_defense/get_weight()
|
||||
// Engineers count as 20.
|
||||
var/engineers = metric.count_people_in_department(DEPARTMENT_ENGINEERING)
|
||||
if(engineers < 3) // There -must- be at least three engineers for this to be possible.
|
||||
return 0
|
||||
|
||||
. = engineers * 20
|
||||
|
||||
// Cargo and AI/borgs count as 10.
|
||||
var/cargo = metric.count_people_with_job(/datum/job/cargo_tech) + metric.count_people_with_job(/datum/job/qm)
|
||||
var/bots = metric.count_people_in_department(DEPARTMENT_SYNTHETIC)
|
||||
|
||||
. += (cargo + bots) * 10
|
||||
|
||||
|
||||
/datum/event2/event/meteor_defense
|
||||
start_delay_lower_bound = 10 MINUTES
|
||||
start_delay_upper_bound = 15 MINUTES
|
||||
var/soon_announced = FALSE
|
||||
var/direction = null // Actual dir used for which side the meteors come from.
|
||||
var/dir_text = null // Direction shown in the announcement.
|
||||
var/list/meteor_types = null
|
||||
var/waves = null // How many times to send meteors.
|
||||
var/last_wave_time = null // world.time of latest wave.
|
||||
var/wave_delay = 10 SECONDS
|
||||
var/wave_upper_bound = 8 // Max amount of meteors per wave.
|
||||
var/wave_lower_bound = 4 // Min amount.
|
||||
|
||||
/datum/event2/event/meteor_defense/proc/set_meteor_types()
|
||||
meteor_types = meteors_threatening.Copy()
|
||||
|
||||
/datum/event2/event/meteor_defense/set_up()
|
||||
direction = pick(cardinal) // alldirs doesn't work with current meteor code unfortunately.
|
||||
waves = rand(3, 6)
|
||||
switch(direction)
|
||||
if(NORTH)
|
||||
dir_text = "aft" // For some reason this is needed.
|
||||
if(SOUTH)
|
||||
dir_text = "fore"
|
||||
if(EAST)
|
||||
dir_text = "port"
|
||||
if(WEST)
|
||||
dir_text = "starboard"
|
||||
set_meteor_types()
|
||||
|
||||
/datum/event2/event/meteor_defense/announce()
|
||||
var/announcement = "Meteors are expected to approach from the [dir_text] side, in approximately [DisplayTimeText(time_to_start - world.time, 60)]."
|
||||
command_announcement.Announce(announcement, "Meteor Alert", new_sound = 'sound/AI/meteors.ogg')
|
||||
|
||||
/datum/event2/event/meteor_defense/wait_tick()
|
||||
if(!soon_announced)
|
||||
if((time_to_start - world.time) <= 5 MINUTES)
|
||||
soon_announced = TRUE
|
||||
var/announcement = "The incoming meteors are expected to approach from the [dir_text] side. \
|
||||
ETA to arrival is approximately [DisplayTimeText(time_to_start - world.time, 60)]."
|
||||
command_announcement.Announce(announcement, "Meteor Alert - Update")
|
||||
|
||||
/datum/event2/event/meteor_defense/start()
|
||||
command_announcement.Announce("Incoming meteors approach from \the [dir_text] side!", "Meteor Alert - Update")
|
||||
|
||||
/datum/event2/event/meteor_defense/event_tick()
|
||||
if(world.time > last_wave_time + wave_delay)
|
||||
last_wave_time = world.time
|
||||
waves--
|
||||
message_admins("[waves] more wave\s of meteors remain.")
|
||||
// Dir is reversed because the direction describes where meteors are going, not what side it's gonna hit.
|
||||
spawn_meteors(rand(wave_upper_bound, wave_lower_bound), meteor_types, reverse_dir[direction])
|
||||
|
||||
/datum/event2/event/meteor_defense/should_end()
|
||||
return waves <= 0
|
||||
|
||||
/datum/event2/event/meteor_defense/end()
|
||||
command_announcement.Announce("\The [location_name()] will clear the incoming meteors in a moment.", "Meteor Alert - Update")
|
||||
@@ -4,6 +4,7 @@
|
||||
chaos = 10 // There's a really rare chance of vines getting something awful like phoron atmosphere but thats not really controllable.
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_MEDIUM_IMPACT
|
||||
event_type = /datum/event2/event/spacevine
|
||||
regions = list(EVENT_REGION_PLAYER_MAIN_AREA)
|
||||
|
||||
/datum/event2/meta/spacevine/get_weight()
|
||||
return 20 + (metric.count_people_in_department(DEPARTMENT_ENGINEERING) * 10) + (metric.count_people_in_department(DEPARTMENT_EVERYONE) * 5)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
departments = list(DEPARTMENT_ENGINEERING)
|
||||
reusable = TRUE
|
||||
event_type = /datum/event2/event/wallrot
|
||||
regions = list(EVENT_REGION_PLAYER_MAIN_AREA)
|
||||
|
||||
/datum/event2/meta/wallrot/get_weight()
|
||||
return (10 + metric.count_people_in_department(DEPARTMENT_ENGINEERING) * 10) / (times_ran + 1)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
reusable = TRUE
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_MEDIUM_IMPACT
|
||||
event_type = /datum/event2/event/window_break
|
||||
regions = list(EVENT_REGION_PLAYER_MAIN_AREA)
|
||||
|
||||
/datum/event2/meta/window_break/get_weight()
|
||||
return (metric.count_people_in_department(DEPARTMENT_ENGINEERING) * 20) / (times_ran + 1)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_MEDIUM_IMPACT
|
||||
reusable = TRUE
|
||||
event_type = /datum/event2/event/comms_blackout
|
||||
regions = list(EVENT_REGION_UNIVERSAL)
|
||||
|
||||
/datum/event2/meta/comms_blackout/get_weight()
|
||||
return 50 + metric.count_people_in_department(DEPARTMENT_EVERYONE) * 5
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
chaos = 10
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_LOW_IMPACT
|
||||
event_type = /datum/event2/event/electrical_fault
|
||||
regions = list(EVENT_REGION_PLAYER_MAIN_AREA)
|
||||
|
||||
/datum/event2/meta/electrical_fault/get_weight()
|
||||
return 10 + (metric.count_people_in_department(DEPARTMENT_EVERYONE) * 5)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_LOW_IMPACT
|
||||
reusable = TRUE
|
||||
event_type = /datum/event2/event/gravity
|
||||
regions = list(EVENT_REGION_SPACESTATION, EVENT_REGION_DEEPSPACE)
|
||||
|
||||
/datum/event2/meta/gravity/get_weight()
|
||||
return (20 + (metric.count_people_in_department(DEPARTMENT_EVERYONE) * 5)) / (times_ran + 1)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/event2/meta/infestation
|
||||
event_class = "infestation"
|
||||
departments = list(DEPARTMENT_EVERYONE)
|
||||
regions = list(EVENT_REGION_PLAYER_MAIN_AREA)
|
||||
|
||||
/datum/event2/meta/infestation/get_weight()
|
||||
return metric.count_people_in_department(DEPARTMENT_EVERYONE) * 10
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "pda spam"
|
||||
departments = list(DEPARTMENT_EVERYONE)
|
||||
event_type = /datum/event2/event/pda_spam
|
||||
regions = list(EVENT_REGION_UNIVERSAL)
|
||||
|
||||
/datum/event2/meta/pda_spam/get_weight()
|
||||
return metric.count_people_in_department(DEPARTMENT_EVERYONE) * 2
|
||||
@@ -96,7 +97,7 @@
|
||||
message = pick("Luxury watches for Blowout sale prices!",\
|
||||
"Watches, Jewelry & Accessories, Bags & Wallets !",\
|
||||
"Deposit 100$ and get 300$ totally free!",\
|
||||
" 100K NT.|WOWGOLD <20>nly $89 <HOT>",\
|
||||
" 100K NT.|WOWGOLD <20>nly $89 <HOT>",\
|
||||
"We have been filed with a complaint from one of your customers in respect of their business relations with you.",\
|
||||
"We kindly ask you to open the COMPLAINT REPORT (attached) to reply on this complaint..")
|
||||
if(4)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
chaos = 20
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_MEDIUM_IMPACT
|
||||
event_type = /datum/event2/event/radiation_storm
|
||||
regions = list(EVENT_REGION_SPACESTATION, EVENT_REGION_DEEPSPACE)
|
||||
|
||||
/datum/event2/meta/radiation_storm/get_weight()
|
||||
var/medical_factor = metric.count_people_in_department(DEPARTMENT_MEDICAL) * 10
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
departments = list(DEPARTMENT_EVERYONE)
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_MEDIUM_IMPACT
|
||||
event_type = /datum/event2/event/random_antagonist
|
||||
regions = list(EVENT_REGION_UNIVERSAL)
|
||||
|
||||
// This has an abnormally high weight due to antags being very important for the round,
|
||||
// however the weight will decay with more antags, and more attempts to add antags.
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "solar storm"
|
||||
reusable = TRUE
|
||||
event_type = /datum/event2/event/solar_storm
|
||||
regions = list(EVENT_REGION_SPACESTATION, EVENT_REGION_DEEPSPACE)
|
||||
|
||||
/datum/event2/meta/solar_storm/get_weight()
|
||||
var/population_factor = metric.count_people_in_department(DEPARTMENT_ENGINEERING) * 10
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
departments = list(DEPARTMENT_EVERYONE)
|
||||
reusable = TRUE
|
||||
event_type = /datum/event2/event/sudden_weather_shift
|
||||
regions = list(EVENT_REGION_PLANETSURFACE)
|
||||
|
||||
/datum/event2/meta/sudden_weather_shift/get_weight()
|
||||
// The proc name is a bit misleading, it only counts players outside, not all mobs.
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
chaos = 40
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_MEDIUM_IMPACT
|
||||
event_type = /datum/event2/event/appendicitis
|
||||
regions = list(EVENT_REGION_PLAYER_MAIN_AREA)
|
||||
|
||||
/datum/event2/meta/appendicitis/get_weight()
|
||||
var/list/doctors = metric.get_people_with_job(/datum/job/doctor)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
chaos = 40
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_HIGH_IMPACT
|
||||
event_type = /datum/event2/event/virus
|
||||
regions = list(EVENT_REGION_PLAYER_MAIN_AREA)
|
||||
|
||||
/datum/event2/meta/virus/superbug
|
||||
name = "viral superbug"
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
chaos = 30
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_MEDIUM_IMPACT
|
||||
event_type = /datum/event2/event/mob_spawning/carp_migration
|
||||
regions = list(EVENT_REGION_SPACESTATION, EVENT_REGION_DEEPSPACE)
|
||||
|
||||
/datum/event2/meta/carp_migration/get_weight()
|
||||
return 10 + (metric.count_people_in_department(DEPARTMENT_SECURITY) * 20) + (metric.count_all_space_mobs() * 40)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
departments = list(DEPARTMENT_SECURITY, DEPARTMENT_EVERYONE)
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_HIGH_IMPACT // Don't run if we just got hit by meteors.
|
||||
event_type = /datum/event2/event/security_drill
|
||||
regions = list(EVENT_REGION_PLAYER_MAIN_AREA)
|
||||
|
||||
/datum/event2/meta/security_drill/get_weight()
|
||||
var/sec = metric.count_people_in_department(DEPARTMENT_SECURITY)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
// the prison area.
|
||||
var/list/relevant_areas = list()
|
||||
var/list/irrelevant_areas = list()
|
||||
regions = list(EVENT_REGION_PLAYER_MAIN_AREA)
|
||||
|
||||
/datum/event2/meta/prison_break/get_weight()
|
||||
// First, don't do this if nobody can fix the doors.
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
chaos = 40
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_MEDIUM_IMPACT
|
||||
event_type = /datum/event2/event/mob_spawning/rogue_drones
|
||||
regions = list(EVENT_REGION_SPACESTATION, EVENT_REGION_DEEPSPACE)
|
||||
|
||||
/datum/event2/meta/rogue_drones/get_weight()
|
||||
. = 10 // Start with a base weight, since this event does provide some value even if no sec is around.
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
departments = list(DEPARTMENT_SECURITY, DEPARTMENT_EVERYONE)
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_HIGH_IMPACT // So this won't get called in the middle of a crisis.
|
||||
event_type = /datum/event2/event/security_screening
|
||||
regions = list(EVENT_REGION_UNIVERSAL)
|
||||
|
||||
/datum/event2/meta/security_screening/get_weight()
|
||||
. = 0
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
chaos = 30
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_MEDIUM_IMPACT
|
||||
event_type = /datum/event2/event/spider_infestation
|
||||
regions = list(EVENT_REGION_PLAYER_MAIN_AREA)
|
||||
|
||||
/datum/event2/meta/spider_infestation/weak
|
||||
name = "weak spider infestation"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_LOW_IMPACT
|
||||
event_type = /datum/event2/event/ghost_pod_spawner/stowaway
|
||||
var/safe_for_extended = FALSE
|
||||
regions = list(EVENT_REGION_PLAYER_MAIN_AREA)
|
||||
|
||||
/datum/event2/meta/stowaway/normal
|
||||
name = "stowaway - normal"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
chaos = 20
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_MEDIUM_IMPACT
|
||||
event_type = /datum/event2/event/surprise_carp
|
||||
regions = list(EVENT_REGION_SPACESTATION, EVENT_REGION_DEEPSPACE)
|
||||
|
||||
/datum/event2/meta/surprise_carp/get_weight()
|
||||
return metric.count_all_space_mobs() * 50
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_HIGH_IMPACT
|
||||
enabled = FALSE // Turns out they are in fact grossly OP.
|
||||
var/safe_for_extended = FALSE
|
||||
regions = list(EVENT_REGION_SPACESTATION, EVENT_REGION_DEEPSPACE)
|
||||
|
||||
/datum/event2/meta/swarm_boarder/get_weight()
|
||||
if(istype(ticker.mode, /datum/game_mode/extended) && !safe_for_extended)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
chaos = 40
|
||||
chaotic_threshold = EVENT_CHAOS_THRESHOLD_MEDIUM_IMPACT
|
||||
event_type = /datum/event2/event/ion_storm
|
||||
regions = list(EVENT_REGION_SPACESTATION, EVENT_REGION_DEEPSPACE)
|
||||
|
||||
/datum/event2/meta/ion_storm/get_weight()
|
||||
var/list/bots = metric.get_people_in_department(DEPARTMENT_SYNTHETIC)
|
||||
|
||||
@@ -14,6 +14,11 @@
|
||||
// What departments the event attached might affect.
|
||||
var/list/departments = list(DEPARTMENT_EVERYONE)
|
||||
|
||||
// The region affects by this event
|
||||
// Affects event weight by a similar metric to department population:
|
||||
// If everybody is planetside, then a meteor storm on the station doesn't really add as much
|
||||
var/list/regions = list(EVENT_REGION_UNIVERSAL)
|
||||
|
||||
// A guess on how disruptive to a round the event might be. If the action is chosen, the GM's
|
||||
// 'danger' score is increased by this number.
|
||||
// Negative numbers could be used to signify helpful events.
|
||||
|
||||
@@ -91,3 +91,15 @@
|
||||
num++
|
||||
if(num)
|
||||
. = round(. / num, 0.1)
|
||||
|
||||
// Computes activity of players on a per-region basis
|
||||
/datum/metric/proc/assess_player_regions()
|
||||
. = list()
|
||||
for(var/mob/living/L in player_list)
|
||||
var/activity = assess_player_activity(L)
|
||||
for(var/region in L.get_player_regions())
|
||||
.[region] += activity
|
||||
|
||||
// To prevent the universal region from being chosen too often, scale it down
|
||||
// If lots of players are active over a wide set of regions, this should prefer events that cover a wider area
|
||||
.[EVENT_REGION_UNIVERSAL] = round(.[EVENT_REGION_UNIVERSAL] / 2, 1)
|
||||
@@ -1136,3 +1136,23 @@
|
||||
// Each mob does vision a bit differently so this is just for inheritence and also so overrided procs can make the vision apply instantly if they call `..()`.
|
||||
/mob/living/proc/disable_spoiler_vision()
|
||||
handle_vision()
|
||||
|
||||
/mob/living/proc/get_player_regions()
|
||||
// A living player is always in a universal region
|
||||
. = list(EVENT_REGION_UNIVERSAL)
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/effect/overmap/visitable/M = get_overmap_sector(T.z)
|
||||
|
||||
if(istype(M))
|
||||
if(M.in_space)
|
||||
if(T.z in using_map.station_levels)
|
||||
. |= EVENT_REGION_SPACESTATION
|
||||
else
|
||||
. |= EVENT_REGION_DEEPSPACE
|
||||
else
|
||||
. |= EVENT_REGION_PLANETSURFACE
|
||||
|
||||
var/datum/map_z_level/zlevel = using_map.zlevels["[T.z]"]
|
||||
if(istype(zlevel))
|
||||
. |= zlevel.event_regions
|
||||
|
||||
@@ -167,6 +167,7 @@
|
||||
flags = MAP_LEVEL_STATION|MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_CONSOLES
|
||||
holomap_legend_x = 220
|
||||
holomap_legend_y = 160
|
||||
event_regions = list(EVENT_REGION_SPACESTATION, EVENT_REGION_PLAYER_MAIN_AREA)
|
||||
|
||||
/datum/map_z_level/southern_cross/station/station_one
|
||||
z = Z_LEVEL_STATION_ONE
|
||||
@@ -197,24 +198,28 @@
|
||||
name = "Empty"
|
||||
flags = MAP_LEVEL_PLAYER
|
||||
transit_chance = 76
|
||||
event_regions = list(EVENT_REGION_DEEPSPACE)
|
||||
|
||||
/datum/map_z_level/southern_cross/surface
|
||||
z = Z_LEVEL_SURFACE
|
||||
name = "Plains"
|
||||
flags = MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_SEALED|MAP_LEVEL_CONSOLES
|
||||
base_turf = /turf/simulated/floor/outdoors/rocks
|
||||
event_regions = list(EVENT_REGION_PLANETSURFACE, EVENT_REGION_PLAYER_MAIN_AREA)
|
||||
|
||||
/datum/map_z_level/southern_cross/surface_mine
|
||||
z = Z_LEVEL_SURFACE_MINE
|
||||
name = "Mountains"
|
||||
flags = MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_SEALED|MAP_LEVEL_CONSOLES
|
||||
base_turf = /turf/simulated/floor/outdoors/rocks
|
||||
event_regions = list(EVENT_REGION_PLANETSURFACE, EVENT_REGION_SUBTERRANEAN)
|
||||
|
||||
/datum/map_z_level/southern_cross/surface_wild
|
||||
z = Z_LEVEL_SURFACE_WILD
|
||||
name = "Wilderness"
|
||||
flags = MAP_LEVEL_PLAYER|MAP_LEVEL_SEALED|MAP_LEVEL_CONTACT|MAP_LEVEL_CONSOLES
|
||||
base_turf = /turf/simulated/floor/outdoors/rocks
|
||||
event_regions = list(EVENT_REGION_PLANETSURFACE)
|
||||
|
||||
/datum/map_z_level/southern_cross/misc
|
||||
z = Z_LEVEL_MISC
|
||||
|
||||
@@ -113,7 +113,7 @@ var/list/all_maps = list()
|
||||
var/list/unit_test_z_levels //To test more than Z1, set your z-levels to test here.
|
||||
|
||||
var/list/planet_datums_to_make = list() // Types of `/datum/planet`s that will be instantiated by SSPlanets.
|
||||
|
||||
|
||||
/datum/map/New()
|
||||
..()
|
||||
if(zlevel_datum_type)
|
||||
@@ -270,15 +270,19 @@ var/list/all_maps = list()
|
||||
var/turf/base_turf // Type path of the base turf for this z
|
||||
var/transit_chance = 0 // Percentile chance this z will be chosen for map-edge space transit.
|
||||
|
||||
// Holomaps
|
||||
// Holomaps
|
||||
var/holomap_offset_x = -1 // Number of pixels to offset the map right (for centering) for this z
|
||||
var/holomap_offset_y = -1 // Number of pixels to offset the map up (for centering) for this z
|
||||
var/holomap_legend_x = 96 // x position of the holomap legend for this z
|
||||
var/holomap_legend_y = 96 // y position of the holomap legend for this z
|
||||
|
||||
// Skybox
|
||||
// Skybox
|
||||
var/datum/skybox_settings/custom_skybox // Can override skybox type here for this z
|
||||
|
||||
// List of regions for GameMaster events
|
||||
var/list/event_regions = list()
|
||||
|
||||
|
||||
// Default constructor applies itself to the parent map datum
|
||||
/datum/map_z_level/New(var/datum/map/map)
|
||||
if(!z) return
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "code\__defines\crafting.dm"
|
||||
#include "code\__defines\damage_organs.dm"
|
||||
#include "code\__defines\dna.dm"
|
||||
#include "code\__defines\events.dm"
|
||||
#include "code\__defines\flags.dm"
|
||||
#include "code\__defines\gamemode.dm"
|
||||
#include "code\__defines\holomap.dm"
|
||||
@@ -1902,7 +1903,7 @@
|
||||
#include "code\modules\gamemaster\event2\events\engineering\dust.dm"
|
||||
#include "code\modules\gamemaster\event2\events\engineering\gas_leak.dm"
|
||||
#include "code\modules\gamemaster\event2\events\engineering\grid_check.dm"
|
||||
#include "code\modules\gamemaster\event2\events\engineering\meteor_defense.dm"
|
||||
#include "code\modules\gamemaster\event2\events\engineering\space_meteor_defense.dm"
|
||||
#include "code\modules\gamemaster\event2\events\engineering\spacevine.dm"
|
||||
#include "code\modules\gamemaster\event2\events\engineering\wallrot.dm"
|
||||
#include "code\modules\gamemaster\event2\events\engineering\window_break.dm"
|
||||
|
||||
Reference in New Issue
Block a user