diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 1c60d0084d1..f42d2a5932f 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -84,9 +84,10 @@ #define shuttle_time_in_station 1800 // 3 minutes in the station #define shuttle_time_to_arrive 6000 // 10 minutes to arrive -#define EVENT_LEVEL_MUNDANE 1 -#define EVENT_LEVEL_MODERATE 2 -#define EVENT_LEVEL_MAJOR 3 +#define EVENT_LEVEL_ROUNDSTART 1 +#define EVENT_LEVEL_MUNDANE 2 +#define EVENT_LEVEL_MODERATE 3 +#define EVENT_LEVEL_MAJOR 4 //defines #define RESIZE_DEFAULT_SIZE 1 @@ -183,6 +184,8 @@ #define COORD(A) "([A.x],[A.y],[A.z])" +#define RUNE_WORDS list("travel", "blood", "join", "hell", "destroy", "technology", "self", "see", "other", "hide") + //Error handler defines #define ERROR_USEFUL_LEN 2 @@ -216,6 +219,16 @@ #define PLASMAGUN_OVERCHARGE 30100 +#define VAR_SWAP(A, B)\ + var/temp = A;\ + A = B;\ + B = temp;\ + +#define LOC_SWAP(A, B)\ + var/atom/temp = A.loc;\ + A.forceMove(B.loc);\ + B.forceMove(temp);\ + //! ## Overlays subsystem ///Compile all the overlays for an atom from the cache lists diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 0114c5ef722..84f7cb21108 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -202,7 +202,7 @@ Turf and target are seperate in case you want to teleport some distance from a t break //update our pda and id if we have them on our person - var/list/searching = GetAllContents(searchDepth = 3) + var/list/searching = GetAllContents() var/search_id = 1 var/search_pda = 1 @@ -569,16 +569,43 @@ Turf and target are seperate in case you want to teleport some distance from a t sleep(max(sleeptime, 15)) qdel(animation) -//Will return the contents of an atom recursivly to a depth of 'searchDepth' -/atom/proc/GetAllContents(searchDepth = 5) - var/list/toReturn = list() - - for(var/atom/part in contents) - toReturn += part - if(part.contents.len && searchDepth) - toReturn += part.GetAllContents(searchDepth - 1) - - return toReturn +///Returns the src and all recursive contents as a list. +/atom/proc/GetAllContents() + . = list(src) + var/i = 0 + while(i < length(.)) + var/atom/A = .[++i] + . += A.contents + +/atom/proc/GetAreaAllContents() + . = list(src) + var/i = 0 + while(i < length(.)) // They will collect all content of area that include *items on the turf* + var/atom/A = .[++i] // then all content on the turf will be collected, and this is again *items on the turf*. + . |= A.contents // |= ensures that there are no duplicates + +///identical to getallcontents but returns a list of atoms of the type passed in the argument. +/atom/proc/get_all_contents_type(type) + var/list/processing_list = list(src) + . = list() + while(length(processing_list)) + var/atom/A = processing_list[1] + processing_list.Cut(1, 2) + processing_list += A.contents + if(istype(A, type)) + . += A + +/atom/proc/GetAllContentsIgnoring(list/ignore_typecache) + if(!length(ignore_typecache)) + return GetAllContents() + var/list/processing = list(src) + . = list() + var/i = 0 + while(i < length(processing)) + var/atom/A = processing[++i] + if(!ignore_typecache[A.type]) + processing += A.contents + . += A //Step-towards method of determining whether one atom can see another. Similar to viewers() /proc/can_see(atom/source, atom/target, length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate. @@ -659,7 +686,7 @@ Turf and target are seperate in case you want to teleport some distance from a t //Takes: Area type as text string or as typepath OR an instance of the area. //Returns: A list of all turfs in areas of that type of that type in the world. -/proc/get_area_turfs(areatype, subtypes=TRUE, target_z = 0) +/proc/get_area_turfs(areatype, subtypes=TRUE, target_z = 0, list/black_list) if(istext(areatype)) areatype = text2path(areatype) else if(isarea(areatype)) @@ -676,6 +703,8 @@ Turf and target are seperate in case you want to teleport some distance from a t if(!cache[A.type]) continue for(var/turf/T in A) + if(black_list && (T.type in black_list)) + continue if(target_z == 0 || target_z == T.z) turfs += T else @@ -684,6 +713,8 @@ Turf and target are seperate in case you want to teleport some distance from a t if(A.type != areatype) continue for(var/turf/T in A) + if(black_list && (T.type in black_list)) + continue if(target_z == 0 || target_z == T.z) turfs += T return turfs diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index f56cad878a0..09ca2006f66 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -137,15 +137,18 @@ var/list/net_announcer_secret = list() var/expected_round_length = 90 MINUTES // If the first delay has a custom start time // No custom time - var/list/event_first_run = list(EVENT_LEVEL_MUNDANE = null, + var/list/event_first_run = list(EVENT_LEVEL_ROUNDSTART = null, + EVENT_LEVEL_MUNDANE = null, EVENT_LEVEL_MODERATE = null, EVENT_LEVEL_MAJOR = list("lower" = 50 MINUTES, "upper" = 70 MINUTES)) // The lowest delay until next event - var/list/event_delay_lower = list(EVENT_LEVEL_MUNDANE = 10 MINUTES, + var/list/event_delay_lower = list(EVENT_LEVEL_ROUNDSTART = null, + EVENT_LEVEL_MUNDANE = 10 MINUTES, EVENT_LEVEL_MODERATE = 30 MINUTES, EVENT_LEVEL_MAJOR = 50 MINUTES) // The upper delay until next event - var/list/event_delay_upper = list(EVENT_LEVEL_MUNDANE = 15 MINUTES, + var/list/event_delay_upper = list(EVENT_LEVEL_ROUNDSTART = null, + EVENT_LEVEL_MUNDANE = 15 MINUTES, EVENT_LEVEL_MODERATE = 45 MINUTES, EVENT_LEVEL_MAJOR = 70 MINUTES) diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index 40b1fa20dfc..6d2d4a77ec0 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -10,15 +10,23 @@ SUBSYSTEM_DEF(events) var/list/finished_events = list() var/list/allEvents = list() var/list/event_containers = list( - EVENT_LEVEL_MUNDANE = new/datum/event_container/mundane, - EVENT_LEVEL_MODERATE = new/datum/event_container/moderate, - EVENT_LEVEL_MAJOR = new/datum/event_container/major + EVENT_LEVEL_ROUNDSTART = new/datum/event_container/roundstart, + EVENT_LEVEL_MUNDANE = new/datum/event_container/mundane, + EVENT_LEVEL_MODERATE = new/datum/event_container/moderate, + EVENT_LEVEL_MAJOR = new/datum/event_container/major, ) var/datum/event_meta/new_event = new /datum/controller/subsystem/events/Initialize() - allEvents = subtypesof(/datum/event) - /datum/event/anomaly + var/list/black_types = list( + /datum/event/anomaly, + /datum/event/roundstart, + /datum/event/roundstart/area, + /datum/event/roundstart/area/replace, + /datum/event/roundstart/area/maintenance_spawn, + ) + allEvents = subtypesof(/datum/event) - black_types return ..() /datum/controller/subsystem/events/fire() @@ -29,6 +37,11 @@ SUBSYSTEM_DEF(events) var/datum/event_container/EC = event_containers[i] EC.process() +/datum/controller/subsystem/events/proc/start_roundstart_event() + var/datum/event_container/roundstart/EC = event_containers[EVENT_LEVEL_ROUNDSTART] + for(var/i in 1 to rand(1, 3)) + EC.start_event() + /datum/controller/subsystem/events/proc/event_complete(datum/event/E) if(!E.event_meta) // datum/event is used here and there for random reasons, maintaining "backwards compatibility" log_debug("Event of '[E.type]' with missing meta-data has completed.") @@ -41,7 +54,7 @@ SUBSYSTEM_DEF(events) if(!E.severity) theseverity = EVENT_LEVEL_MODERATE - if(!E.severity == EVENT_LEVEL_MUNDANE && !E.severity == EVENT_LEVEL_MODERATE && !E.severity == EVENT_LEVEL_MAJOR) + if(E.severity != EVENT_LEVEL_ROUNDSTART && E.severity != EVENT_LEVEL_MUNDANE && E.severity != EVENT_LEVEL_MODERATE && E.severity != EVENT_LEVEL_MAJOR) theseverity = EVENT_LEVEL_MODERATE //just to be careful if(E.severity) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index bd2a63d9272..46c5a794905 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -265,6 +265,8 @@ SUBSYSTEM_DEF(ticker) spawn(0)//Forking here so we dont have to wait for this to finish mode.post_setup() + SSevents.start_roundstart_event() + for(var/mob/dead/new_player/N in new_player_list) if(N.client) N.show_titlescreen() diff --git a/code/datums/helper_datums/events.dm b/code/datums/helper_datums/events.dm index 68eb54a6530..11b0ea6c97f 100644 --- a/code/datums/helper_datums/events.dm +++ b/code/datums/helper_datums/events.dm @@ -24,7 +24,7 @@ return addEventType(event_type) var/list/event = events[event_type] - var/datum/event/E = new /datum/event(proc_holder,proc_name) + var/datum/event_mecha/E = new /datum/event_mecha(proc_holder,proc_name) event += E return E @@ -35,12 +35,12 @@ var/list/event = listgetindex(events,args[1]) if(istype(event)) spawn(-1) - for(var/datum/event/E in event) + for(var/datum/event_mecha/E in event) if(!E.Fire(arglist(args.Copy(2)))) clearEvent(args[1],E) return -// Arguments: event_type as text, E as /datum/event +// Arguments: event_type as text, E as /datum/event_mecha // Returns: 1 if event cleared, null on error /datum/events/proc/clearEvent(event_type, datum/event/E) if(!event_type || !E) @@ -50,16 +50,16 @@ return 1 -/datum/event +/datum/event_mecha var/listener var/proc_name -/datum/event/New(tlistener,tprocname) +/datum/event_mecha/New(tlistener,tprocname) listener = tlistener proc_name = tprocname return ..() -/datum/event/proc/Fire() +/datum/event_mecha/proc/Fire() //world << "Event fired" if(listener) call(listener,proc_name)(arglist(args)) diff --git a/code/game/gamemodes/abduction/abduction_gear.dm b/code/game/gamemodes/abduction/abduction_gear.dm index 8ae9f07d81e..db20ef9096b 100644 --- a/code/game/gamemodes/abduction/abduction_gear.dm +++ b/code/game/gamemodes/abduction/abduction_gear.dm @@ -274,12 +274,10 @@ radio_off_mob(M) /obj/item/device/abductor/silencer/proc/radio_off_mob(mob/living/carbon/human/M) - var/list/all_items = M.GetAllContents() + var/list/all_items = M.get_all_contents_type(/obj/item/device/radio) - for(var/obj/I in all_items) - if(istype(I,/obj/item/device/radio)) - var/obj/item/device/radio/r = I - r.on = 0 + for(var/obj/item/device/radio/R in all_items) + R.on = 0 //RECALL IMPLANT diff --git a/code/game/gamemodes/cult/cult_datums.dm b/code/game/gamemodes/cult/cult_datums.dm index b444294f9ce..4a1a99e9f57 100644 --- a/code/game/gamemodes/cult/cult_datums.dm +++ b/code/game/gamemodes/cult/cult_datums.dm @@ -5,7 +5,7 @@ // Used only for sprite generation var/list/words = list() - var/static/list/all_words = list("travel", "blood", "join", "hell", "destroy", "technology", "self", "see", "other", "hide") + var/static/list/all_words = RUNE_WORDS /datum/rune/New(holder) src.holder = holder diff --git a/code/game/gamemodes/cult/structures/rune.dm b/code/game/gamemodes/cult/structures/rune.dm index c18102ad2c9..38d633cd7b5 100644 --- a/code/game/gamemodes/cult/structures/rune.dm +++ b/code/game/gamemodes/cult/structures/rune.dm @@ -11,7 +11,7 @@ var/datum/religion/religion var/mob/creator -/obj/effect/rune/atom_init(mapload, datum/religion/R, mob/user) +/obj/effect/rune/atom_init(mapload, datum/religion/R, mob/user, rand_icon = FALSE) . = ..() if(R) ASSERT(user) @@ -25,6 +25,13 @@ var/list/L = religion.runes_by_mob[creator] L += src + if(rand_icon) + var/list/all_words = RUNE_WORDS + var/list/words = list() + for(var/i in 1 to 3) + words += pick_n_take(all_words) + icon = get_uristrune_cult(TRUE, words) + var/image/I = image('icons/effects/blood.dmi', src, "mfloor[rand(1, 7)]", 2) I.override = TRUE I.color = "#a10808" diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 77a750f8be3..5c87004b08f 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -622,8 +622,9 @@ var/list/airlock_overlays = list() var/obj/structure/door_assembly/da = new assembly_type(loc) da.anchored = 0 var/target = da.loc - for(var/i in 1 to 4) - target = get_turf(get_step(target,user.dir)) + if(user) + for(var/i in 1 to 4) + target = get_turf(get_step(target,user.dir)) da.throw_at(target, 200, 100, spin = FALSE) if(mineral) da.change_mineral_airlock_type(mineral) diff --git a/code/game/magic/Uristrunes.dm b/code/game/magic/Uristrunes.dm index 17b6a9bfa34..4366c8058cc 100644 --- a/code/game/magic/Uristrunes.dm +++ b/code/game/magic/Uristrunes.dm @@ -4,7 +4,7 @@ word_to_uristrune_table = list() var/bit = 1 - var/list/words = list("travel", "blood", "join", "hell", "destroy", "technology", "self", "see", "other", "hide") + var/list/words = RUNE_WORDS while(length(words)) var/w = pick(words) diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index d89d4c6b6b1..c2ce3d88dbe 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -517,3 +517,11 @@ for(var/obj/O in contents) remove_from_storage(O, T) INVOKE_ASYNC(O, /obj.proc/tumble_async, 2) + +/obj/item/weapon/storage/proc/make_empty(delete = TRUE) + var/turf/T = get_turf(src) + for(var/A in contents) + if(delete) + qdel(A) + else + remove_from_storage(A, T) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index c86fd18c094..a303ce41a30 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -195,6 +195,10 @@ icon_broken = "secbroken" icon_off = "secoff" +/obj/structure/closet/secure_closet/security/atom_init(mapload) + . = ..() + sec_closets_list += src + /obj/structure/closet/secure_closet/security/PopulateContents() if(prob(50)) new /obj/item/weapon/storage/backpack/security(src) diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm index 978aba3ec46..d7898ad37ad 100644 --- a/code/game/objects/structures/tank_dispenser.dm +++ b/code/game/objects/structures/tank_dispenser.dm @@ -22,6 +22,8 @@ . = ..() update_icon() + tank_dispenser_list += src + /obj/structure/dispenser/update_icon() cut_overlays() diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 82aa141a4f1..e7e48c8ed08 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -16,6 +16,7 @@ . = ..() open = round(rand(0, 1)) update_icon() + toilet_list += src /obj/structure/toilet/attack_hand(mob/living/user) user.SetNextMove(CLICK_CD_MELEE * 1.5) diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index a7a4e241570..5b1052bdfe3 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -167,10 +167,7 @@ event_meta = EM severity = event_meta.severity - if(severity < EVENT_LEVEL_MUNDANE) - severity = EVENT_LEVEL_MUNDANE - if(severity > EVENT_LEVEL_MAJOR) - severity = EVENT_LEVEL_MAJOR + severity = clamp(severity, EVENT_LEVEL_ROUNDSTART, EVENT_LEVEL_MAJOR) startedAt = world.time diff --git a/code/modules/events/_event_container.dm b/code/modules/events/_event_container.dm index 5c142c3d0c3..7bf34f3ea2f 100644 --- a/code/modules/events/_event_container.dm +++ b/code/modules/events/_event_container.dm @@ -4,6 +4,7 @@ #define ASSIGNMENT_ENGINEER "Engineer" #define ASSIGNMENT_BOTANIST "Botanist" #define ASSIGNMENT_JANITOR "Janitor" +#define ASSIGNMENT_CLOWN "Clown" #define ASSIGNMENT_MEDICAL "Medical" #define ASSIGNMENT_SCIENTIST "Scientist" #define ASSIGNMENT_SECURITY "Security" @@ -11,7 +12,7 @@ #define ONESHOT 1 #define DISABLED 0 -var/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT_LEVEL_MODERATE = "Moderate", EVENT_LEVEL_MAJOR = "Major") +var/list/severity_to_string = list(EVENT_LEVEL_ROUNDSTART = "RoundStart", EVENT_LEVEL_MUNDANE = "Mundane", EVENT_LEVEL_MODERATE = "Moderate", EVENT_LEVEL_MAJOR = "Major") /datum/event_container var/severity = -1 @@ -60,7 +61,7 @@ var/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT_LEVEL_ /datum/event_container/proc/acquire_event() if(available_events.len == 0) return - var/active_with_role = number_active_with_role() + var/list/active_with_role = number_active_with_role() var/list/possible_events = list() for(var/datum/event_meta/EM in available_events) @@ -131,10 +132,51 @@ var/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT_LEVEL_ next_event = EM return EM +/datum/event_container/roundstart + severity = EVENT_LEVEL_ROUNDSTART + available_events = list( + // /datum/event_meta/New(event_severity, event_name, datum/event/type, event_weight, list/job_weights, is_one_shot = 0, event_enabled = 1, min_event_players = 0, min_event_weight = 0, max_event_weight = 0) + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Roundstart Nothing", /datum/event/nothing, 1500), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Break Light", /datum/event/roundstart/area/break_light, 50, list(ASSIGNMENT_ENGINEER = 10, ASSIGNMENT_JANITOR = 40)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Dirt Bay", /datum/event/roundstart/area/dirt, 10, list(ASSIGNMENT_JANITOR = 100)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Randomize Cargo Storage", /datum/event/roundstart/area/cargo_storage, 10), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Armory Mess", /datum/event/roundstart/area/armory_mess, 10), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "MineField", /datum/event/roundstart/area/minefield, 5, list(ASSIGNMENT_MEDICAL = 2), , list(ASSIGNMENT_SECURITY = 2)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Lasertag ED-209", /datum/event/roundstart/area/lasertag_ed, 10),list(ASSIGNMENT_ANY = 2), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Stolen Weapon", /datum/event/roundstart/area/replace/sec_weapons, 20, list(ASSIGNMENT_SECURITY = 5)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Stolen First AID", /datum/event/roundstart/area/replace/med_storage, 10, list(ASSIGNMENT_MEDICAL = 1)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Old Morgue", /datum/event/roundstart/area/replace/med_morgue, 10), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Broken Airlocks", /datum/event/roundstart/area/replace/airlock, 10, list(ASSIGNMENT_ENGINEER = 20)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Chewed Cables", /datum/event/roundstart/area/replace/del_cable, 10, list(ASSIGNMENT_ENGINEER = 20)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Clondike", /datum/event/roundstart/area/replace/vault_gold, 10), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Deathly Sec.", /datum/event/roundstart/area/replace/deathly_sec, 5, list(ASSIGNMENT_CLOWN = 50)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Forgotten Surgeon Tools", /datum/event/roundstart/area/replace/del_surgeon_tools, 10, list(ASSIGNMENT_MEDICAL = 2)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Anti meat", /datum/event/roundstart/area/replace/mince_back, 10), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Invasion In Mainteance", /datum/event/roundstart/area/maintenance_spawn/invasion, 10, list(ASSIGNMENT_SECURITY = 50)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Sign of Antagonists", /datum/event/roundstart/area/maintenance_spawn/antag_meta, 10, list(ASSIGNMENT_SECURITY = 50)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Forgotten Headset", /datum/event/roundstart/headset, 10, list(ASSIGNMENT_ANY = 5)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Forgotten Survival Box", /datum/event/roundstart/survbox, 10, list(ASSIGNMENT_ANY = 5)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Forgotten Fueltanks", /datum/event/roundstart/fueltank, 10, list(ASSIGNMENT_ENGINEER = 20)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Forgotten Watertanks", /datum/event/roundstart/watertank, 10, list(ASSIGNMENT_BOTANIST = 10)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Forgotten Cleaners", /datum/event/roundstart/cleaner, 10, list(ASSIGNMENT_JANITOR = 100)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Forgotten Extinguishers", /datum/event/roundstart/extinguisher, 10), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Forgotten Scraps", /datum/event/roundstart/del_scrap, 10), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Forgotten Toilets", /datum/event/roundstart/del_toilet, 10), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Leaked Pipe", /datum/event/roundstart/leaked_pipe, 10), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Die Monkey", /datum/event/roundstart/dead_monkeys, 10, list(ASSIGNMENT_SCIENTIST = 5)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Engine Mess", /datum/event/roundstart/PA, 10, list(ASSIGNMENT_ENGINEER = 10)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Forgottens Tanks", /datum/event/roundstart/tank_dispenser, 10, list(ASSIGNMENT_ENGINEER = 5, ASSIGNMENT_SCIENTIST = 10)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Forgotten Sec. Equimp.", /datum/event/roundstart/sec_equipment, 10, list(ASSIGNMENT_SECURITY = 10)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Products Inflation", /datum/event/roundstart/vending_products, 10), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "BlueScreen APC", /datum/event/roundstart/apc, 10, list(ASSIGNMENT_ENGINEER = 5)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Accounting Got It Wrong", /datum/event/roundstart/salary, 10, list(ASSIGNMENT_ANY = 2)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Last Clown Jokes", /datum/event/roundstart/airlock_joke, 10, list(ASSIGNMENT_CLOWN = 50)), + new /datum/event_meta(EVENT_LEVEL_ROUNDSTART, "Chiefs Animals", /datum/event/roundstart/head_animals, 10), + ) + /datum/event_container/mundane severity = EVENT_LEVEL_MUNDANE available_events = list( - // /datum/event_meta/New(event_severity, event_name, datum/event/type, event_weight, list/job_weights, is_one_shot = 0, event_enabled = 1, min_event_players = 0, min_event_weight = 0, max_event_weight = 0) new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Nothing", /datum/event/nothing, 1100), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "PDA Spam", /datum/event/pda_spam, 0, list(ASSIGNMENT_ANY = 4), 0, 1, 0, 25, 50), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Lotto", /datum/event/money_lotto, 0, list(ASSIGNMENT_ANY = 1), ONESHOT, 1, 0, 5, 15), diff --git a/code/modules/events/_event_procs.dm b/code/modules/events/_event_procs.dm index 8da2bcdd06f..6477b057133 100644 --- a/code/modules/events/_event_procs.dm +++ b/code/modules/events/_event_procs.dm @@ -29,6 +29,7 @@ active_with_role["AI"] = 0 active_with_role["Cyborg"] = 0 active_with_role["Janitor"] = 0 + active_with_role["Clown"] = 0 active_with_role["Botanist"] = 0 active_with_role["Any"] = player_list.len @@ -68,6 +69,9 @@ if(M.mind.assigned_role == "Cyborg") active_with_role["Cyborg"]++ + if(M.mind.assigned_role == "Clown") + active_with_role["Clown"]++ + if(M.mind.assigned_role == "Janitor") active_with_role["Janitor"]++ diff --git a/code/modules/events/roundstart_events/area/area_event.dm b/code/modules/events/roundstart_events/area/area_event.dm new file mode 100644 index 00000000000..ef7cf745e14 --- /dev/null +++ b/code/modules/events/roundstart_events/area/area_event.dm @@ -0,0 +1,38 @@ +/datum/event/roundstart/area + // number of random areas if no special_area_types + var/num_rand_areas = 1 + // if not specified, then random + var/list/special_area_types + // allows you pick a one random area from special_area_types + var/rand_special_area = FALSE + + // refs + var/list/area/targeted_areas = list() + +/datum/event/roundstart/area/setup() + ..() + SHOULD_CALL_PARENT(TRUE) + if(special_area_types?.len) + var/list/area_types = list() + + if(rand_special_area) + var/type = pick(special_area_types) + special_area_types = list(type) + + for(var/type in special_area_types) + area_types |= typesof(type) + + for(var/area_type in area_types) + targeted_areas += get_area_by_type(area_type) + else + for(var/i in 1 to num_rand_areas) + targeted_areas += findEventArea() + + if(!targeted_areas.len) + CRASH("No valid areas for roundstart event found.") + + var/list/names = list() + for(var/area/A in targeted_areas) + names += A.name + + log_game("RoundStart Event: Selected areas is [english_list(names)]") diff --git a/code/modules/events/roundstart_events/area/armory_mess.dm b/code/modules/events/roundstart_events/area/armory_mess.dm new file mode 100644 index 00000000000..daa398ee121 --- /dev/null +++ b/code/modules/events/roundstart_events/area/armory_mess.dm @@ -0,0 +1,22 @@ +/datum/event/roundstart/area/armory_mess + special_area_types = list(/area/station/security/warden, /area/station/security/armoury) + +/datum/event/roundstart/area/armory_mess/start() + for(var/area/target_area in targeted_areas) + for(var/obj/machinery/door/window/brigdoor/B in target_area) + qdel(B) + + for(var/obj/item/weapon/storage/S in target_area) + S.make_empty(FALSE) + + for(var/obj/item/ammo_box/AB in target_area) + AB.make_empty(FALSE) + + for(var/obj/item/I in target_area) + if(istype(I, /obj/item/device/radio/intercom)) + continue + for(var/i in 1 to rand(2, 8)) + step(I, pick(alldirs)) + + message_admins("RoundStart Event: All items in armory are scattered.") + log_game("RoundStart Event: All items in armory are scattered.") diff --git a/code/modules/events/roundstart_events/area/break_light.dm b/code/modules/events/roundstart_events/area/break_light.dm new file mode 100644 index 00000000000..bbe40f57900 --- /dev/null +++ b/code/modules/events/roundstart_events/area/break_light.dm @@ -0,0 +1,5 @@ +/datum/event/roundstart/area/break_light/start() + for(var/area/target_area in targeted_areas) + message_admins("RoundStart Event: All light break in [target_area]") + for(var/obj/machinery/light/L in target_area) + L.broken(TRUE) diff --git a/code/modules/events/roundstart_events/area/cargo_storage.dm b/code/modules/events/roundstart_events/area/cargo_storage.dm new file mode 100644 index 00000000000..5ac1fe31f47 --- /dev/null +++ b/code/modules/events/roundstart_events/area/cargo_storage.dm @@ -0,0 +1,41 @@ +/datum/event/roundstart/area/cargo_storage + special_area_types = list(/area/station/cargo/storage) + +/datum/event/roundstart/area/cargo_storage/start() + for(var/area/target_area in targeted_areas) + message_admins("RoundStart Event: Change [target_area]") + log_game("RoundStart Event: Change [target_area]") + var/list/all_atoms = target_area.GetAreaAllContents() + for(var/A in all_atoms) + if(istype(A, /obj/structure/closet/crate)) + if(prob(50)) + qdel(A) + else if(istype(A, /obj/item/device/flashlight/lamp/fir)) + if(prob(50)) + qdel(A) + else if(istype(A, /obj/structure/rack)) + var/obj/structure/rack/R = A + if(prob(50)) + new /obj/item/weapon/storage/toolbox/mechanical(R.loc) + if(prob(20)) + new /obj/item/clothing/gloves/fyellow(R.loc) + if(prob(30)) + new /obj/item/device/flashlight(R.loc) + if(prob(40)) + new /obj/item/device/multitool(R.loc) + if(prob(40)) + new /obj/item/toy/gun(R.loc) + if(prob(10)) + var/type = pick(subtypesof(/obj/item/ammo_box)) + var/obj/item/ammo_box/AB = new type(R.loc) + AB.make_empty(TRUE) + else if(istype(A, /turf/simulated/floor)) + if(prob(5)) + var/list/types = list(/mob/living/simple_animal/lizard, /mob/living/simple_animal/mouse, /mob/living/simple_animal/hostile/carp, /mob/living/simple_animal/headcrab, /mob/living/simple_animal/borer, /mob/living/simple_animal/hostile/giant_spider, /mob/living/carbon/monkey, /mob/living/simple_animal/chicken, /mob/living/simple_animal/cow) + var/type = pick(types) + var/mob/M = new type(A) + M.death() + if(prob(2)) + var/type = pick(subtypesof(/obj/structure/closet/critter)) + var/obj/structure/closet/critter/C = new type(A) + C.crit_fail = TRUE diff --git a/code/modules/events/roundstart_events/area/dirt.dm b/code/modules/events/roundstart_events/area/dirt.dm new file mode 100644 index 00000000000..b671620cce1 --- /dev/null +++ b/code/modules/events/roundstart_events/area/dirt.dm @@ -0,0 +1,19 @@ +/datum/event/roundstart/area/dirt/setup() + num_rand_areas = rand(2, 5) + . = ..() + +/datum/event/roundstart/area/dirt/start() + var/list/black_types = list( + /obj/effect/decal/cleanable/cellular/bluespace, /obj/effect/decal/cleanable/cellular/necro, + /obj/effect/decal/cleanable/bluespace, /obj/effect/decal/cleanable/blood/trail_holder + ) + black_types += typesof(/obj/effect/decal/cleanable/blood/tracks) + + var/list/possible_dirt_types = subtypesof(/obj/effect/decal/cleanable) - black_types + for(var/area/target_area in targeted_areas) + message_admins("RoundStart Event: Dirt appears in [target_area]") + var/list/turf/all_turfs = get_area_turfs(target_area, TRUE, black_list=list(/turf/simulated/wall, /turf/simulated/wall/r_wall)) + for(var/turf/T in all_turfs) + if(prob(15)) + var/type = pick(possible_dirt_types) + new type(T) diff --git a/code/modules/events/roundstart_events/area/lasertag_ed.dm b/code/modules/events/roundstart_events/area/lasertag_ed.dm new file mode 100644 index 00000000000..4e413af19eb --- /dev/null +++ b/code/modules/events/roundstart_events/area/lasertag_ed.dm @@ -0,0 +1,15 @@ +/datum/event/roundstart/area/lasertag_ed + special_area_types = list(/area/station/security/lobby) + +/datum/event/roundstart/area/lasertag_ed/start() + for(var/area/target_area in targeted_areas) + var/list/all_turfs = get_area_turfs(target_area, black_list=list(/turf/simulated/wall/r_wall, /turf/simulated/wall)) + + var/turf/T1 = pick(all_turfs) + var/turf/T2 = pick(all_turfs) + + new /obj/machinery/bot/secbot/ed209/bluetag(T1) + new /obj/machinery/bot/secbot/ed209/redtag(T2) + + message_admins("RoundStart Event: Lasertag ED-209 was spawned in [target_area].") + log_game("RoundStart Event: Lasertag ED-209 was spawned in [target_area].") diff --git a/code/modules/events/roundstart_events/area/maintenance.dm b/code/modules/events/roundstart_events/area/maintenance.dm new file mode 100644 index 00000000000..403b338fd35 --- /dev/null +++ b/code/modules/events/roundstart_events/area/maintenance.dm @@ -0,0 +1,65 @@ +/datum/event/roundstart/area/maintenance_spawn + special_area_types = list(/area/station/maintenance) + var/list/possible_types = list() + var/nums = 3 + +/datum/event/roundstart/area/maintenance_spawn/proc/spawn_atom(type, turf/T) + if(T) + message_admins("RoundStart Event: \"[event_meta.name]\" spawn '[type]' in [COORD(T)] - [ADMIN_JMP(T)]") + log_game("RoundStart Event: \"[event_meta.name]\" spawn '[type]' in [COORD(T)]") + new type(T) + +/datum/event/roundstart/area/maintenance_spawn/start() + for(var/i in 1 to nums) + var/area/area = get_area_by_type(pick_n_take(targeted_areas)) + var/list/all_turfs = get_area_turfs(area, FALSE, black_list=list(/turf/simulated/wall, /turf/simulated/wall/r_wall)) + // to prevent spawn in glass or grinds + for(var/turf/T in all_turfs) + if(T.contents.len == 1) // any turfs has a single instance of lighting_object, for at some optimization, i need to skip such turfs + continue + if(!T.CanPass(null, T)) + all_turfs -= T + + spawn_atom(pick(possible_types), pick(all_turfs)) + +/datum/event/roundstart/area/maintenance_spawn/invasion + possible_types = list( + /mob/living/simple_animal/hostile/giant_spider, + /mob/living/simple_animal/hostile/pylon, + /mob/living/simple_animal/hostile/xenomorph/drone, + /mob/living/simple_animal/hostile/xenomorph, + /mob/living/simple_animal/hostile/hivebot, + /mob/living/carbon/slime, + ) + +/datum/event/roundstart/area/maintenance_spawn/invasion/setup() + nums = rand(1, 3) + . = ..() + +/datum/event/roundstart/area/maintenance_spawn/antag_meta + possible_types = list( + /obj/effect/rune, + /obj/item/weapon/kitchenknife/ritual, + /obj/item/clothing/head/wizard, + /obj/structure/alien/resin/wall/shadowling, + /obj/structure/alien/resin/wall, + /obj/structure/alien/weeds/node, + /obj/item/weapon/card/emag_broken, + ) + +/datum/event/roundstart/area/maintenance_spawn/antag_meta/setup() + nums = rand(1, 3) + possible_types += subtypesof(/obj/item/weapon/storage/box/syndie_kit) + . = ..() + +/datum/event/roundstart/area/maintenance_spawn/antag_meta/spawn_atom(type, turf/T) + if(ispath(type, /obj/effect/rune)) + new /obj/effect/rune(T, null, null, TRUE) + else if(ispath(type, /obj/item/weapon/storage)) + var/obj/item/weapon/storage/S = new type(T) + S.make_empty(TRUE) + else + new type(T) + + message_admins("RoundStart Event: \"[event_meta.name]\" spawn '[type]' in [COORD(T)] - [ADMIN_JMP(T)]") + log_game("RoundStart Event: \"[event_meta.name]\" spawn '[type]' in [COORD(T)]") diff --git a/code/modules/events/roundstart_events/area/minefield.dm b/code/modules/events/roundstart_events/area/minefield.dm new file mode 100644 index 00000000000..6e940b962d6 --- /dev/null +++ b/code/modules/events/roundstart_events/area/minefield.dm @@ -0,0 +1,16 @@ +/datum/event/roundstart/area/minefield/setup() + num_rand_areas = rand(1, 3) + . = ..() + +/datum/event/roundstart/area/minefield/start() + var/list/types = list(/obj/item/mine/emp/anchored, /obj/item/mine/incendiary/anchored, /obj/item/mine/shock/anchored, /obj/item/mine/anchored) + for(var/area/target_area in targeted_areas) + var/list/all_turfs = get_area_turfs(target_area, black_list=list(/turf/simulated/wall/r_wall, /turf/simulated/wall)) + for(var/i in 1 to rand(1, 2)) + var/turf/T = pick_n_take(all_turfs) + var/type = pick(types) + + var/obj/item/mine/M = new type(T) + + message_admins("RoundStart Event: [M] was spawned in [COORD(T)] - [ADMIN_JMP(T)].") + log_game("RoundStart Event: [M] was spawned in [COORD(T)].") diff --git a/code/modules/events/roundstart_events/area/replace/deathly_sec.dm b/code/modules/events/roundstart_events/area/replace/deathly_sec.dm new file mode 100644 index 00000000000..5358dfbb606 --- /dev/null +++ b/code/modules/events/roundstart_events/area/replace/deathly_sec.dm @@ -0,0 +1,3 @@ +/datum/event/roundstart/area/replace/deathly_sec + special_area_types = list(/area/station/security/main) + replace_types = list(/obj/item/weapon/melee/baton = /obj/item/weapon/reagent_containers/food/snacks/candy/yumbaton) diff --git a/code/modules/events/roundstart_events/area/replace/del_cable.dm b/code/modules/events/roundstart_events/area/replace/del_cable.dm new file mode 100644 index 00000000000..df799f7b336 --- /dev/null +++ b/code/modules/events/roundstart_events/area/replace/del_cable.dm @@ -0,0 +1,26 @@ +/datum/event/roundstart/area/replace/del_cable + special_area_types = list(/area/station/maintenance) + replace_types = list(/obj/structure/cable = null) + num_replaceable = 1 + +/datum/event/roundstart/area/replace/del_cable/setup() + . = ..() + num_replaceable = rand(1, 2) + replace_callback = CALLBACK(src, .proc/remove_wire) + +/datum/event/roundstart/area/replace/del_cable/proc/remove_wire(obj/structure/cable/C) + var/turf/T = get_turf(C) + C.remove_cable(T) + + var/turf/spawn_turf + var/mob/living/simple_animal/mouse/M + for(var/dir in shuffle(alldirs)) + spawn_turf = get_step(T, dir) + if(spawn_turf.is_mob_placeable()) + M = new(spawn_turf) + break + + // if it is not possible to spawn the mouse around the wire + if(!M) + M = new(T) + M.death() diff --git a/code/modules/events/roundstart_events/area/replace/del_surgeon_tools.dm b/code/modules/events/roundstart_events/area/replace/del_surgeon_tools.dm new file mode 100644 index 00000000000..5dc2212a27e --- /dev/null +++ b/code/modules/events/roundstart_events/area/replace/del_surgeon_tools.dm @@ -0,0 +1,7 @@ +/datum/event/roundstart/area/replace/del_surgeon_tools + special_area_types = list(/area/station/medical/surgery2, /area/station/medical/surgery) + replace_types = list(/obj/item = null) + +/datum/event/roundstart/area/replace/del_surgeon_tools/setup() + . = ..() + num_replaceable = rand(3, 8) diff --git a/code/modules/events/roundstart_events/area/replace/med_morgue.dm b/code/modules/events/roundstart_events/area/replace/med_morgue.dm new file mode 100644 index 00000000000..2bbeea2574f --- /dev/null +++ b/code/modules/events/roundstart_events/area/replace/med_morgue.dm @@ -0,0 +1,3 @@ +/datum/event/roundstart/area/replace/med_morgue + special_area_types = list(/area/station/medical/morgue) + replace_types = list(/obj/structure/morgue = /obj/structure/closet/coffin) diff --git a/code/modules/events/roundstart_events/area/replace/med_storage.dm b/code/modules/events/roundstart_events/area/replace/med_storage.dm new file mode 100644 index 00000000000..0009322c06f --- /dev/null +++ b/code/modules/events/roundstart_events/area/replace/med_storage.dm @@ -0,0 +1,8 @@ +/datum/event/roundstart/area/replace/med_storage + special_area_types = list(/area/station/medical/storage) + +/datum/event/roundstart/area/replace/med_storage/setup() + . = ..() + random_replaceable_types = typesof(/obj/item/weapon/storage/firstaid) + + replace_types[find_replaceable_type()] = /obj/item/weapon/reagent_containers/syringe/inaprovaline diff --git a/code/modules/events/roundstart_events/area/replace/mince_back.dm b/code/modules/events/roundstart_events/area/replace/mince_back.dm new file mode 100644 index 00000000000..f36ddb53d0f --- /dev/null +++ b/code/modules/events/roundstart_events/area/replace/mince_back.dm @@ -0,0 +1,10 @@ +/datum/event/roundstart/area/replace/mince_back + special_area_types = list(/area/station/civilian/cold_room, /area/station/civilian/kitchen) + replace_types = list(/obj/item/weapon/reagent_containers/food/snacks/meat = /mob/living/simple_animal/chick) + +/datum/event/roundstart/area/replace/mince_back/setup() + . = ..() + new_atom_callback = CALLBACK(src, .proc/make_death) + +/datum/event/roundstart/area/replace/mince_back/proc/make_death(mob/M) + M.death() diff --git a/code/modules/events/roundstart_events/area/replace/random_airlock.dm b/code/modules/events/roundstart_events/area/replace/random_airlock.dm new file mode 100644 index 00000000000..eb7ffd265ee --- /dev/null +++ b/code/modules/events/roundstart_events/area/replace/random_airlock.dm @@ -0,0 +1,10 @@ +/datum/event/roundstart/area/replace/airlock + replace_types = list(/obj/machinery/door/airlock = null) + num_replaceable = 2 + +/datum/event/roundstart/area/replace/airlock/setup() + . = ..() + replace_callback = CALLBACK(src, .proc/make_rupture) + +/datum/event/roundstart/area/replace/airlock/proc/make_rupture(obj/machinery/door/airlock/A) + A.door_rupture() diff --git a/code/modules/events/roundstart_events/area/replace/replace.dm b/code/modules/events/roundstart_events/area/replace/replace.dm new file mode 100644 index 00000000000..2cb5592e0ff --- /dev/null +++ b/code/modules/events/roundstart_events/area/replace/replace.dm @@ -0,0 +1,60 @@ +/datum/event/roundstart/area/replace + // replace: left_type on right_type (a = b) + var/list/replace_types = list() + // called before deleting replaceable item + var/datum/callback/replace_callback + // called after deleting replaced item for new item + var/datum/callback/new_atom_callback + // number of items to replace, -1 for infinity + var/num_replaceable = -1 + // finds a random item that exists in the area by these types + var/list/random_replaceable_types = list() + +/datum/event/roundstart/area/replace/proc/find_replaceable_type() + for(var/objects_type in random_replaceable_types) + // Collect all atoms so that later can choose a completely random type for a future replacement + var/list/all_atoms = list() + for(var/area/A in targeted_areas) + all_atoms |= A.get_all_contents_type(objects_type) + if(!all_atoms.len) + continue + shuffle(all_atoms) + var/atom/A = pick(all_atoms) + return A.type + return null + +/datum/event/roundstart/area/replace/proc/get_replace_type(atom/A) + for(var/type in replace_types) + if(istype(A, type)) + return type + return null + +/datum/event/roundstart/area/replace/proc/replace(atom/A) + var/replace_type = get_replace_type(A) + if(!replace_type) + return FALSE + + var/B_type = replace_types[replace_type] + message_admins("RoundStart Event: \"[event_meta.name]\" replace [A] on [B_type ? "[B_type]" : "OTHER"] in [COORD(A)] - [ADMIN_JMP(A.loc)]") + log_game("RoundStart Event: \"[event_meta.name]\" replace [A] on [B_type ? "[B_type]" : "OTHER"] in [COORD(A)]") + if(replace_callback) + replace_callback.Invoke(A) + if(B_type) + var/B = new B_type(A.loc) + if(new_atom_callback) + new_atom_callback.Invoke(B) + + if(!QDELETED(A)) + qdel(A) + return TRUE + +/datum/event/roundstart/area/replace/start() + var/count = 0 + for(var/area/target_area in targeted_areas) + var/list/area_atoms = shuffle(target_area.GetAreaAllContents()) + for(var/atom/A in area_atoms) + if(replace(A)) + count++ + + if(count == num_replaceable) + return diff --git a/code/modules/events/roundstart_events/area/replace/sec_weapons.dm b/code/modules/events/roundstart_events/area/replace/sec_weapons.dm new file mode 100644 index 00000000000..ba82de9f826 --- /dev/null +++ b/code/modules/events/roundstart_events/area/replace/sec_weapons.dm @@ -0,0 +1,7 @@ +/datum/event/roundstart/area/replace/sec_weapons + special_area_types = list(/area/station/security/warden, /area/station/security/armoury) + random_replaceable_types = list(/obj/item/weapon/gun, /obj/item/ammo_box, /obj/item/clothing/head, /obj/item/clothing/suit) + +/datum/event/roundstart/area/replace/sec_weapons/setup() + . = ..() + replace_types[find_replaceable_type()] = null diff --git a/code/modules/events/roundstart_events/area/replace/vault_gold.dm b/code/modules/events/roundstart_events/area/replace/vault_gold.dm new file mode 100644 index 00000000000..bc730edb52c --- /dev/null +++ b/code/modules/events/roundstart_events/area/replace/vault_gold.dm @@ -0,0 +1,9 @@ +/datum/event/roundstart/area/replace/vault_gold + special_area_types = list(/area/station/bridge/nuke_storage) + replace_types = list( + /obj/item/weapon/coin/silver = /obj/item/stack/sheet/mineral/gold, + /obj/item/weapon/spacecash = /obj/item/stack/sheet/mineral/gold, + /obj/item/weapon/storage/belt/champion = /obj/item/stack/sheet/mineral/gold, + /obj/item/clothing/under/color/yellow = /obj/item/stack/sheet/mineral/gold, + /obj/item/toy/katana = /obj/item/stack/sheet/mineral/gold, + ) // without golden extinguisher diff --git a/code/modules/events/roundstart_events/misc_events.dm b/code/modules/events/roundstart_events/misc_events.dm new file mode 100644 index 00000000000..19949543ef6 --- /dev/null +++ b/code/modules/events/roundstart_events/misc_events.dm @@ -0,0 +1,198 @@ +/datum/event/roundstart/headset/start() + for(var/mob/living/carbon/human/H in human_list) + if((H.l_ear || H.r_ear) && prob(10)) + var/headset_to_del = H.l_ear ? H.l_ear : H.r_ear + message_admins("RoundStart Event: [headset_to_del] was removed from [H]") + log_game("RoundStart Event: [headset_to_del] was removed from [H]") + qdel(headset_to_del) + H.update_inv_ears() + +/datum/event/roundstart/survbox/start() + for(var/mob/living/carbon/human/H in human_list) + if(!prob(10)) + continue + var/list/boxs = H.get_all_contents_type(/obj/item/weapon/storage/box/survival) + if(!boxs.len) + continue + for(var/box in boxs) + message_admins("RoundStart Event: [box] was removed from [H]") + log_game("RoundStart Event: [box] was removed from [H]") + qdel(box) + +var/global/list/fueltank_list = list() +/datum/event/roundstart/fueltank/start() + for(var/atom/fueltank in fueltank_list) + if(prob(10)) + message_admins("RoundStart Event: [fueltank] was removed from [COORD(fueltank)]") + log_game("RoundStart Event: [fueltank] was removed from [COORD(fueltank)]") + qdel(fueltank) + +var/global/list/watertank_list = list() +/datum/event/roundstart/watertank/start() + for(var/atom/watertank in watertank_list) + if(prob(10)) + message_admins("RoundStart Event: [watertank] was removed from [COORD(watertank)]") + log_game("RoundStart Event: [watertank] was removed from [COORD(watertank)]") + qdel(watertank) + +var/global/list/cleaners_list = list() +/datum/event/roundstart/cleaner/start() + for(var/atom/cleaner in cleaners_list) + if(prob(50)) + message_admins("RoundStart Event: [cleaner] was removed from [COORD(cleaner)]") + log_game("RoundStart Event: [cleaner] was removed from [COORD(cleaner)]") + qdel(cleaner) + +var/global/list/extinguisher_list = list() +/datum/event/roundstart/extinguisher/start() + for(var/obj/item/weapon/reagent_containers/spray/extinguisher/E in extinguisher_list) + if(istype(E, /obj/item/weapon/reagent_containers/spray/extinguisher/golden)) + continue + if(prob(60)) + E.reagents.remove_reagent(E.reagent_inside, rand(200, 600), TRUE) + message_admins("RoundStart Event: [E] has changed amount of reagents in [COORD(E.loc)]") + log_game("RoundStart Event: [E] has changed amount of reagents in [COORD(E.loc)]") + else if(prob(30)) + if(istype(E.loc, /obj/structure/extinguisher_cabinet)) + var/obj/structure/extinguisher_cabinet/EC = E.loc + message_admins("RoundStart Event: [E] was removed from [COORD(EC)]") + log_game("RoundStart Event: [E] was removed from [COORD(EC)]") + qdel(E) + EC.update_icon() + +var/global/list/particle_accelerator_list = list() +/datum/event/roundstart/PA/start() + for(var/atom/PA in particle_accelerator_list) + if(!prob(60)) + continue + var/old_loc = COORD(PA) + for(var/i in 1 to rand(3, 5)) + step(PA, pick(NORTH, SOUTH, EAST, WEST)) + message_admins("RoundStart Event: [PA] was moved from [old_loc] to [COORD(PA)]") + log_game("RoundStart Event: [PA] was moved from [old_loc] to [COORD(PA)]") + +var/global/list/tank_dispenser_list = list() +/datum/event/roundstart/tank_dispenser/start() + for(var/obj/structure/dispenser/D in tank_dispenser_list) + if(!prob(50)) + continue + if(D.oxygentanks) + for(var/i in 1 to rand(1, D.oxygentanks)) + D.oxygentanks-- + message_admins("RoundStart Event: [D] has reduced of oxygen tanks in [COORD(D)]") + log_game("RoundStart Event: [D] has reduced of oxygen tanks in [COORD(D)]") + if(D.phorontanks) + for(var/i in 1 to rand(1, D.phorontanks)) + D.phorontanks-- + message_admins("RoundStart Event: [D] has reduced of phoron tanks in [COORD(D)]") + log_game("RoundStart Event: [D] has reduced of phoron tanks in [COORD(D)]") + D.update_icon() + +var/global/list/sec_closets_list = list() +/datum/event/roundstart/sec_equipment/start() + for(var/obj/structure/closet/closet in sec_closets_list) + message_admins("RoundStart Event: Random items has been removed from [closet] in [COORD(closet)]") + for(var/obj/item/I in closet) + if(prob(20)) + log_game("RoundStart Event: [I] was removed from [closet] in [COORD(closet)]") + qdel(I) + +/datum/event/roundstart/vending_products/start() + for(var/obj/machinery/vending/V in machines) + if(!prob(40)) + continue + for(var/datum/data/vending_product/VP in V.product_records) + if(!prob(30)) + continue + VP.amount = rand(0, VP.amount) + VP.price = rand(0, VP.amount**2) + message_admins("RoundStart Event: [VP.product_name] has changed amount and price in [V] [COORD(V)].") + log_game("RoundStart Event: [VP.product_name] has changed amount and price in [V] [COORD(V)].") + +/datum/event/roundstart/apc/start() + for(var/obj/machinery/power/apc/A in apc_list) + if(!prob(3)) + continue + // bluescreen + A.emagged = TRUE + A.locked = FALSE + A.update_icon() + message_admins("RoundStart Event: [A] has bluescreen in [COORD(A)].") + log_game("RoundStart Event: [A] bluescreen in [COORD(A)].") + +/datum/event/roundstart/dead_monkeys/start() + for(var/mob/M in monkey_list) + if(prob(20)) + message_admins("RoundStart Event: [M] was killed in [COORD(M)]") + log_game("RoundStart Event: [M] was killed in [COORD(M)]") + M.death() + +/datum/event/roundstart/salary/start() + for(var/i in 1 to all_money_accounts.len) + if(!prob(20)) + continue + + var/datum/money_account/account1 = pick(all_money_accounts) + var/datum/money_account/account2 = pick(all_money_accounts) + if(account1 != account2) + VAR_SWAP(account1.owner_salary, account2.owner_salary) + + message_admins("RoundStart Event: [account1.owner_name] and [account2.owner_name] salaries has been swapped.") + log_game("RoundStart Event: [account1.owner_name] and [account2.owner_name] salaries has been swapped.") + +/datum/event/roundstart/airlock_joke/start() + var/list/possible_types = list(/obj/item/weapon/bananapeel, /obj/item/device/assembly/mousetrap, /obj/item/weapon/legcuffs/beartrap, /obj/effect/decal/cleanable/blood/oil) + for(var/obj/machinery/door/airlock/A in airlock_list) + if(!is_station_level(A.z)) + continue + if(prob(5)) + var/type = pick(possible_types) + var/atom/atom = new type(get_turf(A)) + + message_admins("RoundStart Event: Spawned '[atom]' in [COORD(atom)] - [ADMIN_JMP(atom.loc)].") + log_game("RoundStart Event: Spawned '[atom]' in [COORD(atom)].") + +var/global/list/chief_animal_list = list() +/datum/event/roundstart/head_animals/start() + for(var/i in 1 to chief_animal_list.len) + if(!prob(40)) + continue + var/mob/M1 = pick(chief_animal_list) + var/mob/M2 = pick(chief_animal_list) + if(M1 != M2) + LOC_SWAP(M1, M2) + + message_admins("RoundStart Event: [M1] and [M2] has been swapped.") + log_game("RoundStart Event: [M1] and [M2] has been swapped.") + +var/global/list/scrap_list = list() +/datum/event/roundstart/del_scrap/start() + for(var/A in scrap_list) + qdel(A) + + message_admins("RoundStart Event: All scrap was deleted.") + log_game("RoundStart Event: All scrap was deleted.") + +var/global/list/toilet_list = list() +/datum/event/roundstart/del_toilet/start() + for(var/atom/A in toilet_list) + if(is_station_level(A.z)) + qdel(A) + + message_admins("RoundStart Event: All toilets was deleted.") + log_game("RoundStart Event: All toilets was deleted.") + +/datum/event/roundstart/leaked_pipe/start() + for(var/atom/A in toilet_list) + if(is_station_level(A.z) && !prob(50)) + continue + + var/turf/T = get_turf(A) + for(var/thing in RANGE_TURFS(1, T)) + var/obj/effect/fluid/F = locate() in thing + if(!F) + F = new(thing) + F.set_depth(4000) + + message_admins("RoundStart Event: Water was spawned in [COORD(T)] - [ADMIN_JMP(T)].") + log_game("RoundStart Event: Water was spawned in [COORD(T)].") diff --git a/code/modules/events/roundstart_events/roundstart.dm b/code/modules/events/roundstart_events/roundstart.dm new file mode 100644 index 00000000000..28a89a81a82 --- /dev/null +++ b/code/modules/events/roundstart_events/roundstart.dm @@ -0,0 +1 @@ +/datum/event/roundstart diff --git a/code/modules/mob/living/carbon/ian/ian.dm b/code/modules/mob/living/carbon/ian/ian.dm index 6372a8cedc8..705bf1e089a 100644 --- a/code/modules/mob/living/carbon/ian/ian.dm +++ b/code/modules/mob/living/carbon/ian/ian.dm @@ -61,6 +61,7 @@ . = ..() verbs += /mob/living/carbon/proc/crawl + chief_animal_list += src /mob/living/carbon/ian/UnarmedAttack(atom/A) ..() diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index b82a51cffec..9df56b98148 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -140,6 +140,10 @@ name = "Runtime" desc = "Its fur has the look and feel of velvet, and its tail quivers occasionally." +/mob/living/simple_animal/cat/Runtime/atom_init() + . = ..() + chief_animal_list += src + /mob/living/simple_animal/cat/Syndi name = "SyndiCat" desc = "It's a SyndiCat droid." diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm index f4a572e2233..d6ed161faa9 100644 --- a/code/modules/mob/living/simple_animal/friendly/corgi.dm +++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm @@ -114,6 +114,10 @@ butcher_results = list() var/emagged = 0 +/mob/living/simple_animal/corgi/borgi/atom_init() + . = ..() + chief_animal_list += src + /mob/living/simple_animal/corgi/borgi/emag_act(mob/user) if(!emagged && emagged < 2) emagged = 1 diff --git a/code/modules/mob/living/simple_animal/friendly/fox.dm b/code/modules/mob/living/simple_animal/friendly/fox.dm index 2686a28bd08..2c0194ac896 100644 --- a/code/modules/mob/living/simple_animal/friendly/fox.dm +++ b/code/modules/mob/living/simple_animal/friendly/fox.dm @@ -27,3 +27,7 @@ /mob/living/simple_animal/fox/Renault name = "Renault" desc = "Renault, the Captain's trustworthy fox. I wonder what it says?" + +/mob/living/simple_animal/fox/Renault/atom_init() + . = ..() + chief_animal_list += src diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index a270270afcc..67a01be76e9 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -195,3 +195,7 @@ response_help = "pets" response_disarm = "gently pushes aside" response_harm = "splats" + +/mob/living/simple_animal/mouse/brown/Tom/atom_init() + . = ..() + chief_animal_list += src diff --git a/code/modules/mob/living/simple_animal/friendly/robot.dm b/code/modules/mob/living/simple_animal/friendly/robot.dm index fec3e52904f..1967b2d2fba 100644 --- a/code/modules/mob/living/simple_animal/friendly/robot.dm +++ b/code/modules/mob/living/simple_animal/friendly/robot.dm @@ -32,6 +32,10 @@ var/act_emag var/obj/machinery/computer/rdconsole/rdconsole = null +/mob/living/simple_animal/det5/atom_init() + . = ..() + chief_animal_list += src + /mob/living/simple_animal/det5/Life() ..() if(health <= 0) diff --git a/code/modules/mob/living/simple_animal/friendly/walle.dm b/code/modules/mob/living/simple_animal/friendly/walle.dm index 3f911d3ae62..37205644863 100644 --- a/code/modules/mob/living/simple_animal/friendly/walle.dm +++ b/code/modules/mob/living/simple_animal/friendly/walle.dm @@ -15,3 +15,7 @@ response_help = "pets" response_disarm = "gently pushes aside" response_harm = "kicks" + +/mob/living/simple_animal/walle/atom_init() + . = ..() + chief_animal_list += src diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index e6d3a090575..5c13679da1b 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -708,6 +708,7 @@ else speak += pick("...alive?", "This isn't parrot heaven!", "I live, I die, I live again!", "The void fades!") . = ..() + chief_animal_list += src /mob/living/simple_animal/parrot/Poly/Life() if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved) diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 563dc011a13..f8763ea5b4d 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -103,6 +103,17 @@ By design, d1 is the smallest direction and d2 is the highest /obj/structure/cable/attack_tk(mob/user) return +/obj/structure/cable/proc/remove_cable(turf/T, mob/user) + // 0-X cables are 1 unit, X-X cables are 2 units long + var/atom/newcable = new /obj/item/stack/cable_coil(T, (d1 ? 2 : 1), color) + + if(user) + newcable.fingerprintslast = user.key + user.SetNextMove(CLICK_CD_RAPID) + user.visible_message("[user] cuts the cable.") + + qdel(src) + // Items usable on a cable : // - Wirecutters : cut it duh ! // - Cable coil : merge cables @@ -119,17 +130,7 @@ By design, d1 is the smallest direction and d2 is the highest if (shock(user, 50)) return - var/atom/newcable - if(src.d1) // 0-X cables are 1 unit, X-X cables are 2 units long - newcable = new /obj/item/stack/cable_coil(T, 2, color) - else - newcable = new /obj/item/stack/cable_coil(T, 1, color) - newcable.fingerprintslast = user.key - user.SetNextMove(CLICK_CD_RAPID) - - user.visible_message("[user] cuts the cable.") - - qdel(src) + remove_cable(T, user) return // not needed, but for clarity diff --git a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm index e7c2038deaa..77b3691caf2 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm @@ -69,6 +69,10 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin var/strength = null var/desc_holder = null +/obj/structure/particle_accelerator/atom_init() + . = ..() + particle_accelerator_list += src + /obj/structure/particle_accelerator/Destroy() construction_state = 0 if(master) diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index b4d7685d68c..c31e55a5b99 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -100,6 +100,16 @@ return 1 return 0 +/obj/item/ammo_box/proc/make_empty(deleting = TRUE) + if(deleting) + stored_ammo = list() + update_icon() + else + var/turf/T = get_turf(src) + for(var/obj/ammo in stored_ammo) + stored_ammo -= ammo + ammo.forceMove(T) + /obj/item/ammo_box/attackby(obj/item/I, mob/user, params) var/num_loaded = 0 if(istype(I, /obj/item/ammo_box)) diff --git a/code/modules/reagents/reagent_containers/extinguisher.dm b/code/modules/reagents/reagent_containers/extinguisher.dm index bc6e92d625e..bab927ffc35 100644 --- a/code/modules/reagents/reagent_containers/extinguisher.dm +++ b/code/modules/reagents/reagent_containers/extinguisher.dm @@ -47,10 +47,12 @@ icon_state = "[initial(icon_state)]" reagents.add_reagent(reagent_inside, volume) + extinguisher_list += src + /obj/item/weapon/reagent_containers/spray/extinguisher/station_spawned/atom_init() // Station-spawned, as in, in-cabinets extinguishers shouldn't be full by default. . = ..() reagents.clear_reagents() - reagents.add_reagent("aqueous_foam", rand(volume * 0.5, volume)) + reagents.add_reagent(reagent_inside, rand(volume * 0.5, volume)) /obj/item/weapon/reagent_containers/spray/extinguisher/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/weapon/wrench)) @@ -94,7 +96,7 @@ /obj/item/weapon/reagent_containers/spray/extinguisher/mini/station_spawned/atom_init() // Station-spawned, as in, in-cabinets extinguishers shouldn't be full by default. . = ..() reagents.clear_reagents() - reagents.add_reagent("aqueous_foam", rand(volume * 0.5, volume)) + reagents.add_reagent(reagent_inside, rand(volume * 0.5, volume)) /obj/item/weapon/reagent_containers/spray/extinguisher/golden name = "golden fire extinguisher" diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 8006035649c..0f3300f10ff 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -392,6 +392,8 @@ . = ..() reagents.add_reagent("cleaner", volume) + cleaners_list += src + //pepperspray /obj/item/weapon/reagent_containers/spray/pepper name = "pepperspray" diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index e3a18e643a7..104dcfd03f8 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -204,6 +204,8 @@ . = ..() reagents.add_reagent("water", 1000) + watertank_list += src + /obj/structure/reagent_dispensers/aqueous_foam_tank name = "AFFF tank" desc = "A tank containing Aqueous Film Forming Foam(AFFF)." @@ -224,6 +226,8 @@ . = ..() reagents.add_reagent("fuel",300) + fueltank_list += src + /obj/structure/reagent_dispensers/peppertank name = "Pepper Spray Refiller" desc = "Refill pepper spray canisters." diff --git a/code/modules/scrap/scrap.dm b/code/modules/scrap/scrap.dm index f0266508b36..dcbadd0f9fc 100644 --- a/code/modules/scrap/scrap.dm +++ b/code/modules/scrap/scrap.dm @@ -44,6 +44,7 @@ var/global/list/scrap_base_cache = list() /obj/structure/scrap/atom_init() . = ..() update_icon(1) + scrap_list += src /obj/effect/scrapshot diff --git a/taucetistation.dme b/taucetistation.dme index 1e78819d84c..b822adfe104 100644 --- a/taucetistation.dme +++ b/taucetistation.dme @@ -1333,6 +1333,26 @@ #include "code\modules\events\holidays\Holidays.dm" #include "code\modules\events\holidays\Other.dm" #include "code\modules\events\holidays\valentines\heart_box.dm" +#include "code\modules\events\roundstart_events\misc_events.dm" +#include "code\modules\events\roundstart_events\roundstart.dm" +#include "code\modules\events\roundstart_events\area\area_event.dm" +#include "code\modules\events\roundstart_events\area\armory_mess.dm" +#include "code\modules\events\roundstart_events\area\break_light.dm" +#include "code\modules\events\roundstart_events\area\cargo_storage.dm" +#include "code\modules\events\roundstart_events\area\dirt.dm" +#include "code\modules\events\roundstart_events\area\lasertag_ed.dm" +#include "code\modules\events\roundstart_events\area\maintenance.dm" +#include "code\modules\events\roundstart_events\area\minefield.dm" +#include "code\modules\events\roundstart_events\area\replace\deathly_sec.dm" +#include "code\modules\events\roundstart_events\area\replace\del_cable.dm" +#include "code\modules\events\roundstart_events\area\replace\del_surgeon_tools.dm" +#include "code\modules\events\roundstart_events\area\replace\med_morgue.dm" +#include "code\modules\events\roundstart_events\area\replace\med_storage.dm" +#include "code\modules\events\roundstart_events\area\replace\mince_back.dm" +#include "code\modules\events\roundstart_events\area\replace\random_airlock.dm" +#include "code\modules\events\roundstart_events\area\replace\replace.dm" +#include "code\modules\events\roundstart_events\area\replace\sec_weapons.dm" +#include "code\modules\events\roundstart_events\area\replace\vault_gold.dm" #include "code\modules\ext_scripts\get_webpage.dm" #include "code\modules\ext_scripts\python.dm" #include "code\modules\ext_scripts\shell.dm"