diff --git a/.vscode/launch.json b/.vscode/launch.json index e01beb71714e..39f599fd9c67 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,6 +7,13 @@ "name": "Launch DreamSeeker", "preLaunchTask": "Build All", "dmb": "${workspaceFolder}/${command:CurrentDMB}" + }, + { + "type": "byond", + "request": "launch", + "name": "Launch DreamSeeker (TRACY)", + "preLaunchTask": "Build All (TRACY)", + "dmb": "${workspaceFolder}/${command:CurrentDMB}" }, { "type": "byond", @@ -45,6 +52,13 @@ "preLaunchTask": "Build All (LOWMEMORYMODE)", "dmb": "${workspaceFolder}/${command:CurrentDMB}", "dreamDaemon": true + }, + { + "type": "byond", + "request": "launch", + "name": "Launch DreamSeeker (LOWMEMORYMODE + TRACY)", + "preLaunchTask": "Build All (LOWMEMORYMODE TRACY)", + "dmb": "${workspaceFolder}/${command:CurrentDMB}" } ] } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 155c69ee991a..5c8886b0c9d9 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -24,6 +24,31 @@ "dependsOn": "dm: reparse", "label": "Build All" }, + { + "type": "process", + "command": "tools/build/build", + "windows": { + "command": ".\\tools\\build\\build.bat" + }, + "options": { + "env": { + "DM_EXE": "${config:dreammaker.byondPath}" + } + }, + "problemMatcher": [ + "$dreammaker", + "$tsc", + "$eslint-stylish" + ], + "group": { + "kind": "build" + }, + "dependsOn": "dm: reparse", + "args": [ + "-DUSE_BYOND_TRACY" + ], + "label": "Build All (TRACY)" + }, { "type": "process", "command": "tools/build/build", @@ -74,6 +99,32 @@ ], "label": "Build All (LOWMEMORYMODE)" }, + { + "type": "process", + "command": "tools/build/build", + "windows": { + "command": ".\\tools\\build\\build.bat" + }, + "options": { + "env": { + "DM_EXE": "${config:dreammaker.byondPath}" + } + }, + "problemMatcher": [ + "$dreammaker", + "$tsc", + "$eslint-stylish" + ], + "group": { + "kind": "build" + }, + "dependsOn": "dm: reparse", + "args": [ + "-DLOWMEMORYMODE", + "-DUSE_BYOND_TRACY" + ], + "label": "Build All (LOWMEMORYMODE TRACY)" + }, { "type": "dreammaker", "dme": "tgstation.dme", diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 7d2c094bbd92..27f303f2c3fa 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -588,13 +588,11 @@ if((character.mind.assigned_role == "Cyborg") || (character.mind.assigned_role == character.mind.special_role) || (character.mind.assigned_role == "Stowaway")) return - //Skyrat changes var/displayed_rank = rank - if(character.client && character.client.prefs && character.client.prefs.alt_titles_preferences[rank]) - displayed_rank = character.client.prefs.alt_titles_preferences[rank] + if(character.client && character.client.prefs && character.client?.prefs?.alt_titles_preferences[rank]) + displayed_rank = character.client?.prefs?.alt_titles_preferences[rank] var/obj/machinery/announcement_system/announcer = pick(GLOB.announcement_systems) - announcer.announce("ARRIVAL", character.real_name, displayed_rank, list()) //make the list empty to make it announce it in common - //End of skyrat changes + announcer.announce("ARRIVAL", character.real_name, rank, displayed_rank, list()) //make the list empty to make it announce it in common /proc/lavaland_equipment_pressure_check(turf/T) . = FALSE diff --git a/code/_compile_options.dm b/code/_compile_options.dm index 832241f47952..04b730c9be8e 100644 --- a/code/_compile_options.dm +++ b/code/_compile_options.dm @@ -50,6 +50,10 @@ //#define UNIT_TESTS //If this is uncommented, we do a single run though of the game setup and tear down process with unit tests in between +// If this is uncommented, will attempt to load and initialize prof.dll/libprof.so. +// We do not ship byond-tracy. Build it yourself here: https://github.com/mafemergency/byond-tracy/ +//#define USE_BYOND_TRACY + #ifndef PRELOAD_RSC //set to: #define PRELOAD_RSC 2 // 0 to allow using external resources or on-demand behaviour; #endif // 1 to use the default behaviour; diff --git a/code/controllers/master.dm b/code/controllers/master.dm index b6fb14a69592..e695b0fd0bb8 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -292,7 +292,8 @@ GLOBAL_REAL(Master, /datum/controller/master) = new SS.state = SS_IDLE if (SS.flags & SS_TICKER) tickersubsystems += SS - timer += world.tick_lag * rand(1, 5) + // Timer subsystems aren't allowed to bunch up, so we offset them a bit + timer += world.tick_lag * rand(0, 1) SS.next_fire = timer continue @@ -371,14 +372,16 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/checking_runlevel = current_runlevel if(cached_runlevel != checking_runlevel) //resechedule subsystems + var/list/old_subsystems = current_runlevel_subsystems cached_runlevel = checking_runlevel current_runlevel_subsystems = runlevel_sorted_subsystems[cached_runlevel] - var/stagger = world.time - for(var/I in current_runlevel_subsystems) - var/datum/controller/subsystem/SS = I - if(SS.next_fire <= world.time) - stagger += world.tick_lag * rand(1, 5) - SS.next_fire = stagger + + //now we'll go through all the subsystems we want to offset and give them a next_fire + for(var/datum/controller/subsystem/SS as anything in current_runlevel_subsystems) + //we only want to offset it if it's new and also behind + if(SS.next_fire > world.time || (SS in old_subsystems)) + continue + SS.next_fire = world.time + world.tick_lag * rand(0, DS2TICKS(min(SS.wait, 2 SECONDS))) subsystems_to_check = current_runlevel_subsystems else diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index dd0a29bdb220..0efd5b1e1c72 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -477,12 +477,10 @@ SUBSYSTEM_DEF(job) else handle_auto_deadmin_roles(M.client, rank) - //Skyrat changes var/display_rank = rank - if(M.client && M.client.prefs && M.client.prefs.alt_titles_preferences[rank]) - display_rank = M.client.prefs.alt_titles_preferences[rank] - //End of skyrat changes - to_chat(M, "You are the [display_rank].") //Skyrat change + if(M.client && M.client.prefs && M.client?.prefs?.alt_titles_preferences[rank]) + display_rank = M.client?.prefs?.alt_titles_preferences[rank] + to_chat(M, "You are the [display_rank].") if(job) to_chat(M, "As the [display_rank] you answer directly to [job.supervisors]. Special circumstances may change this.") //Skyrat change job.radio_help_message(M) diff --git a/code/datums/components/storage/concrete/rped.dm b/code/datums/components/storage/concrete/rped.dm index 47549be56511..70298d4e25f7 100644 --- a/code/datums/components/storage/concrete/rped.dm +++ b/code/datums/components/storage/concrete/rped.dm @@ -1,3 +1,5 @@ +#define MAX_STACK_PICKUP 30 + /datum/component/storage/concrete/rped collection_mode = COLLECT_EVERYTHING allow_quick_gather = TRUE @@ -9,13 +11,61 @@ max_items = 100 display_numerical_stacking = TRUE + var/static/list/allowed_material_types = list( + /obj/item/stack/sheet/glass, + /obj/item/stack/sheet/plasteel, + /obj/item/stack/cable_coil, + ) + + var/static/list/allowed_bluespace_types = list( + /obj/item/stack/ore/bluespace_crystal, + /obj/item/stack/sheet/bluespace_crystal, + ) + /datum/component/storage/concrete/rped/can_be_inserted(obj/item/I, stop_messages, mob/M) . = ..() - if(!I.get_part_rating()) - if (!stop_messages) - to_chat(M, "[parent] only accepts machine parts!") + if(!.) + return . + + //we check how much of glass,plasteel & cable the user can insert + if(isstack(I)) + //user tried to insert invalid stacktype + if(!is_type_in_list(I, allowed_material_types) && !is_type_in_list(I, allowed_bluespace_types)) + return FALSE + + var/obj/item/stack/the_stack = I + var/present_amount = 0 + + //we try to count & limit how much the user can insert of each type to prevent them from using it as an normal storage medium + for(var/obj/item/stack/stack_content in parent) + //is user trying to insert any of these listed bluespace stuff + if(is_type_in_list(I, allowed_bluespace_types)) + //if yes count total bluespace stuff is the RPED and then compare the total amount to the value the user is trying to insert + if(is_type_in_list(stack_content, allowed_bluespace_types)) + present_amount += stack_content.amount + //count other normal stack stuff + else if(istype(I,stack_content.type)) + present_amount = stack_content.amount + break + + //no more storage for this specific stack type + if(MAX_STACK_PICKUP - present_amount == 0) + return FALSE + + //we want the user to insert the exact stack amount which is available so we dont have to bother subtracting & leaving left overs for the user + var/available = MAX_STACK_PICKUP-present_amount + if(available - the_stack.amount < 0) + return FALSE + + else if(istype(I, /obj/item/circuitboard/machine) || istype(I, /obj/item/circuitboard/computer)) + return TRUE + + //check normal insertion of other stock parts + else if(!I.get_part_rating()) return FALSE + return . + /datum/component/storage/concrete/rped/quick_empty(mob/M) var/atom/A = parent if(!M.canUseStorage() || !A.Adjacent(M) || M.incapacitated()) @@ -52,13 +102,60 @@ max_items = 350 display_numerical_stacking = TRUE + var/static/list/allowed_material_types = list( + /obj/item/stack/sheet/glass, + /obj/item/stack/sheet/plasteel, + /obj/item/stack/cable_coil, + ) + + var/static/list/allowed_bluespace_types = list( + /obj/item/stack/ore/bluespace_crystal, + /obj/item/stack/sheet/bluespace_crystal, + ) + /datum/component/storage/concrete/bluespace/rped/can_be_inserted(obj/item/I, stop_messages, mob/M) . = ..() - if(!I.get_part_rating()) - if (!stop_messages) - to_chat(M, "[parent] only accepts machine parts!") + if(!.) + return . + + //we check how much of glass,plasteel & cable the user can insert + if(isstack(I)) + //user tried to insert invalid stacktype + if(!is_type_in_list(I, allowed_material_types) && !is_type_in_list(I, allowed_bluespace_types)) + return FALSE + + var/obj/item/stack/the_stack = I + var/present_amount = 0 + + //we try to count & limit how much the user can insert of each type to prevent them from using it as an normal storage medium + for(var/obj/item/stack/stack_content in parent) + //is user trying to insert any of these listed bluespace stuff + if(is_type_in_list(I, allowed_bluespace_types)) + //if yes count total bluespace stuff is the RPED and then compare the total amount to the value the user is trying to insert + if(is_type_in_list(stack_content, allowed_bluespace_types)) + present_amount += stack_content.amount + //count other normal stack stuff + else if(istype(I,stack_content.type)) + present_amount = stack_content.amount + break + + //no more storage for this specific stack type + if(MAX_STACK_PICKUP - present_amount == 0) + return FALSE + + //we want the user to insert the exact stack amount which is available so we dont have to bother subtracting & leaving left overs for the user + var/available = MAX_STACK_PICKUP-present_amount + if(available - the_stack.amount < 0) + return FALSE + + else if(istype(I, /obj/item/circuitboard/machine) || istype(I, /obj/item/circuitboard/computer)) + return TRUE + + //check normal insertion of other stock parts + else if(!I.get_part_rating()) return FALSE + return . /datum/component/storage/concrete/bluespace/rped/quick_empty(mob/M) var/atom/A = parent @@ -85,3 +182,5 @@ stoplag(1) progress.end_progress() A.do_squish(0.8, 1.2) + +#undef MAX_STACK_PICKUP diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index b6a6d776be84..63e8f0c68268 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -142,16 +142,18 @@ var/static/list/show_directions = list(SOUTH, WEST) if(H.mind && (H.mind.assigned_role != H.mind.special_role) && (H.mind.assigned_role != "Stowaway")) var/assignment + var/displayed_rank if(H.mind.assigned_role) assignment = H.mind.assigned_role else if(H.job) assignment = H.job else assignment = "Unassigned" - //Skyrat changes - if(C && C.prefs && C.prefs.alt_titles_preferences[assignment]) - assignment = C.prefs.alt_titles_preferences[assignment] - //End of skyrat changes + if(C && C.prefs && C.prefs.alt_titles_preferences[assignment]) + assignment = C.prefs.alt_titles_preferences[assignment] + + if(assignment) + displayed_rank = C.prefs.alt_titles_preferences[assignment] var/static/record_id_num = 1001 var/id = num2hex(record_id_num++,6) @@ -174,7 +176,7 @@ var/datum/data/record/G = new() G.fields["id"] = id G.fields["name"] = H.real_name - G.fields["rank"] = assignment + G.fields["rank"] = displayed_rank G.fields["age"] = H.age G.fields["species"] = H.dna.species.name G.fields["fingerprint"] = md5(H.dna.uni_identity) @@ -221,7 +223,7 @@ var/datum/data/record/L = new() L.fields["id"] = md5("[H.real_name][H.mind.assigned_role]") //surely this should just be id, like the others? L.fields["name"] = H.real_name - L.fields["rank"] = H.mind.assigned_role + L.fields["rank"] = displayed_rank L.fields["age"] = H.age if(H.gender == MALE) G.fields["gender"] = "Male" diff --git a/code/datums/elements/cleaning.dm b/code/datums/elements/cleaning.dm index fd48f582dd17..21ea954f2122 100644 --- a/code/datums/elements/cleaning.dm +++ b/code/datums/elements/cleaning.dm @@ -1,66 +1,73 @@ -/datum/element/cleaning/Attach(datum/target) +/datum/element/cleaning + element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH + id_arg_index = 2 + /// Range of cleaning on moving + var/range = 0 + +/datum/element/cleaning/Attach(atom/movable/cleaner, cleaning_range) . = ..() - if(!ismovable(target)) + if(!istype(cleaner)) return ELEMENT_INCOMPATIBLE - RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(Clean)) + if(cleaning_range) + range = cleaning_range + RegisterSignal(cleaner, COMSIG_MOVABLE_MOVED, PROC_REF(Clean)) -/datum/element/cleaning/Detach(datum/target) +/datum/element/cleaning/Detach(atom/movable/cleaner) . = ..() - UnregisterSignal(target, COMSIG_MOVABLE_MOVED) + UnregisterSignal(cleaner, COMSIG_MOVABLE_MOVED) -/datum/element/cleaning/proc/Clean(datum/source) - var/atom/movable/AM = source - var/turf/T = AM.loc - SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) - for(var/A in T) - if(is_cleanable(A)) - qdel(A) - else if(isitem(A)) - var/obj/item/cleaned_item = A - SEND_SIGNAL(cleaned_item, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) - cleaned_item.clean_blood() - if(ismob(cleaned_item.loc)) - var/mob/M = cleaned_item.loc - M.regenerate_icons() - else if(ishuman(A)) - var/mob/living/carbon/human/cleaned_human = A - if(cleaned_human.lying) - if(cleaned_human.head) - SEND_SIGNAL(cleaned_human.head, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) - cleaned_human.head.clean_blood() - cleaned_human.update_inv_head() - if(cleaned_human.wear_suit) - SEND_SIGNAL(cleaned_human.wear_suit, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) - cleaned_human.wear_suit.clean_blood() - cleaned_human.update_inv_wear_suit() - else if(cleaned_human.w_uniform) - SEND_SIGNAL(cleaned_human.w_uniform, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) - cleaned_human.w_uniform.clean_blood() - cleaned_human.update_inv_w_uniform() - //skyrat edit - else if(cleaned_human.w_underwear) - SEND_SIGNAL(cleaned_human.w_underwear, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) - cleaned_human.w_underwear.clean_blood() - cleaned_human.update_inv_w_underwear() - else if(cleaned_human.w_socks) - SEND_SIGNAL(cleaned_human.w_socks, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) - cleaned_human.w_socks.clean_blood() - cleaned_human.update_inv_w_socks() - else if(cleaned_human.w_shirt) - SEND_SIGNAL(cleaned_human.w_shirt, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) - cleaned_human.w_shirt.clean_blood() - cleaned_human.update_inv_w_shirt() - else if(cleaned_human.wrists) - SEND_SIGNAL(cleaned_human.wrists, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) - cleaned_human.w_shirt.clean_blood() - cleaned_human.update_inv_wrists() - // - if(cleaned_human.shoes) - SEND_SIGNAL(cleaned_human.shoes, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) - cleaned_human.shoes.clean_blood() - cleaned_human.update_inv_shoes() - SEND_SIGNAL(cleaned_human, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) - cleaned_human.clean_blood() - cleaned_human.wash_cream() - cleaned_human.regenerate_icons() - to_chat(cleaned_human, "[AM] cleans your face!") +/datum/element/cleaning/proc/Clean(atom/movable/cleaner) + for (var/turf/turf in RANGE_TURFS(range, cleaner.loc)) + SEND_SIGNAL(turf, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) + for(var/atom/atom as anything in turf) + if(is_cleanable(atom)) + qdel(atom) + else if(isitem(atom)) + var/obj/item/cleaned_item = atom + SEND_SIGNAL(cleaned_item, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) + cleaned_item.clean_blood() + if(ismob(cleaned_item.loc)) + var/mob/mob = cleaned_item.loc + mob.regenerate_icons() + else if(ishuman(atom)) + var/mob/living/carbon/human/cleaned_human = atom + if(cleaned_human.lying) + if(cleaned_human.head) + SEND_SIGNAL(cleaned_human.head, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) + cleaned_human.head.clean_blood() + cleaned_human.update_inv_head() + if(cleaned_human.wear_suit) + SEND_SIGNAL(cleaned_human.wear_suit, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) + cleaned_human.wear_suit.clean_blood() + cleaned_human.update_inv_wear_suit() + else if(cleaned_human.w_uniform) + SEND_SIGNAL(cleaned_human.w_uniform, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) + cleaned_human.w_uniform.clean_blood() + cleaned_human.update_inv_w_uniform() + //skyrat edit + else if(cleaned_human.w_underwear) + SEND_SIGNAL(cleaned_human.w_underwear, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) + cleaned_human.w_underwear.clean_blood() + cleaned_human.update_inv_w_underwear() + else if(cleaned_human.w_socks) + SEND_SIGNAL(cleaned_human.w_socks, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) + cleaned_human.w_socks.clean_blood() + cleaned_human.update_inv_w_socks() + else if(cleaned_human.w_shirt) + SEND_SIGNAL(cleaned_human.w_shirt, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) + cleaned_human.w_shirt.clean_blood() + cleaned_human.update_inv_w_shirt() + else if(cleaned_human.wrists) + SEND_SIGNAL(cleaned_human.wrists, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) + cleaned_human.w_shirt.clean_blood() + cleaned_human.update_inv_wrists() + // + if(cleaned_human.shoes) + SEND_SIGNAL(cleaned_human.shoes, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) + cleaned_human.shoes.clean_blood() + cleaned_human.update_inv_shoes() + SEND_SIGNAL(cleaned_human, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK) + cleaned_human.clean_blood() + cleaned_human.wash_cream() + cleaned_human.regenerate_icons() + to_chat(cleaned_human, span_danger("[cleaner] cleans your face!")) diff --git a/code/datums/emotes.dm b/code/datums/emotes.dm index a26e345e957e..08d08a20c0d8 100644 --- a/code/datums/emotes.dm +++ b/code/datums/emotes.dm @@ -63,12 +63,13 @@ //msg = "[user] " + msg //SKYRAT CHANGE var/dchatmsg = "[user] [msg]" //SKYRAT CHANGE - for(var/mob/M in GLOB.dead_mob_list) - if(!M.client || isnewplayer(M)) - continue - var/T = get_turf(user) - if(M.stat == DEAD && M.client && (M.client.prefs && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT)) && !(M in viewers(T, null)) && (user.client)) //SKYRAT CHANGE - only user controlled mobs show their emotes to all-seeing ghosts, to reduce chat spam - M.show_message(dchatmsg) //SKYRAT CHANGE + if(user.client) + for(var/mob/M in GLOB.dead_mob_list) + if(!M.client || isnewplayer(M)) + continue + var/T = get_turf(user) + if(M.stat == DEAD && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) && !(M in viewers(T, null))) + M.show_message(dchatmsg) if(emote_type == EMOTE_AUDIBLE) user.audible_message(dchatmsg, runechat_popup = chat_popup, rune_msg = msg) diff --git a/code/game/machinery/announcement_system.dm b/code/game/machinery/announcement_system.dm index d65e41b3bc83..69cdabe65fff 100644 --- a/code/game/machinery/announcement_system.dm +++ b/code/game/machinery/announcement_system.dm @@ -17,9 +17,9 @@ GLOBAL_LIST_EMPTY(announcement_systems) circuit = /obj/item/circuitboard/machine/announcement_system var/obj/item/radio/headset/radio - var/arrival = "%PERSON has signed up as %RANK" + var/arrival = "%PERSON has signed up as %DISP_RANK (%RANK)" var/arrivalToggle = TRUE - var/newhead = "%PERSON, %RANK, is the department head." + var/newhead = "%PERSON, %DISP_RANK (%RANK), is the department head." var/newheadToggle = TRUE var/cryostorage = "%PERSON, %RANK, has been moved into cryogenic storage." // this shouldnt be changed var/cryostorage_tele = "%PERSON, %RANK, has been teleported to CentCom." // you saying it hat man. @@ -71,12 +71,13 @@ GLOBAL_LIST_EMPTY(announcement_systems) else return ..() -/obj/machinery/announcement_system/proc/CompileText(str, user, rank) //replaces user-given variables with actual thingies. +/obj/machinery/announcement_system/proc/CompileText(str, user, rank, displayed_rank) //replaces user-given variables with actual thingies. str = replacetext(str, "%PERSON", "[user]") str = replacetext(str, "%RANK", "[rank]") + str = replacetext(str, "%DISP_RANK", "[displayed_rank]") return str -/obj/machinery/announcement_system/proc/announce(message_type, user, rank, list/channels) +/obj/machinery/announcement_system/proc/announce(message_type, user, rank, displayed_rank, list/channels) if(!is_operational()) return @@ -87,13 +88,13 @@ GLOBAL_LIST_EMPTY(announcement_systems) rank = "Unknown" if(message_type == "ARRIVAL" && arrivalToggle) - message = CompileText(arrival, user, rank) + message = CompileText(arrival, user, rank, displayed_rank) else if(message_type == "NEWHEAD" && newheadToggle) - message = CompileText(newhead, user, rank) + message = CompileText(newhead, user, rank, displayed_rank) else if(message_type == "CRYOSTORAGE") - message = CompileText(cryostorage, user, rank) + message = CompileText(cryostorage, user, rank, displayed_rank) else if(message_type == "CRYOSTORAGE_TELE") - message = CompileText(cryostorage_tele, user, rank) + message = CompileText(cryostorage_tele, user, rank, displayed_rank) else if(message_type == "ARRIVALS_BROKEN") message = "The arrivals shuttle has been damaged. Docking for repairs..." diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index d07a5ecd178e..30f7e244aac1 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -404,7 +404,7 @@ GLOBAL_LIST_EMPTY(cryopod_computers) // Make an announcement and log the person entering storage. if(GLOB.announcement_systems.len) var/obj/machinery/announcement_system/announcer = pick(GLOB.announcement_systems) - announcer.announce(is_teleporter ? "CRYOSTORAGE_TELE" : "CRYOSTORAGE", mob_occupant.real_name, announce_rank, list()) + announcer.announce(is_teleporter ? "CRYOSTORAGE_TELE" : "CRYOSTORAGE", mob_occupant.real_name, announce_rank, announce_rank, list()) if (pod) pod.visible_message(span_notice("\The [pod] hums and hisses as it [is_teleporter ? "teleports" : "moves"] [mob_occupant.real_name] [is_teleporter ? "to centcom" : "into storage"].")) diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index a52bbb75f35f..d2fb3172de9a 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -560,6 +560,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM . += lighter_overlay /obj/item/lighter/ignition_effect(atom/A, mob/user) + playsound(src, 'modular_sand/sound/items/lighter/light.ogg', 50, 0) if(get_temperature()) . = "With a single flick of [user.p_their()] wrist, [user] smoothly lights [A] with [src]. Damn [user.p_theyre()] cool." @@ -583,6 +584,9 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/lighter/attack_self(mob/living/user) if(user.is_holding(src)) if(!lit) + // SANDSTORM EDIT + playsound(src, 'modular_sand/sound/items/lighter/open.ogg', 50, 0) + // End of edit set_lit(TRUE) if(fancy) user.visible_message("Without even breaking stride, [user] flips open and lights [src] in one smooth movement.", "Without even breaking stride, you flip open and light [src] in one smooth movement.") @@ -606,6 +610,9 @@ CIGARETTE PACKETS ARE IN FANCY.DM SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "burnt_thumb", /datum/mood_event/burnt_thumb) else + // SANDSTORM EDIT + playsound(src, 'modular_sand/sound/items/lighter/close.ogg', 50, 0) + // Edit end set_lit(FALSE) if(fancy) user.visible_message("You hear a quiet click, as [user] shuts off [src] without even looking at what [user.p_theyre()] doing. Wow.", "You quietly shut off [src] without even looking at what you're doing. Wow.") diff --git a/code/game/world.dm b/code/game/world.dm index 430e8d4ada08..cabb344867ff 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -13,6 +13,12 @@ GLOBAL_LIST(topic_status_cache) if (dll) LIBCALL(dll, "auxtools_init")() enable_debugging() + +#ifdef USE_BYOND_TRACY + #warn USE_BYOND_TRACY is enabled + init_byond_tracy() +#endif + world.Profile(PROFILE_START) log_world("World loaded at [TIME_STAMP("hh:mm:ss", FALSE)]!") @@ -378,19 +384,18 @@ GLOBAL_LIST(topic_status_cache) /world/proc/on_tickrate_change() SStimer?.reset_buckets() -#ifdef TRACY_PROFILING -/proc/prof_init() - var/lib +/world/proc/init_byond_tracy() + var/library - switch(world.system_type) - if(MS_WINDOWS) lib = "prof.dll" - if(UNIX) lib = "libprof.so" - else CRASH("unsupported platform") + switch (system_type) + if (MS_WINDOWS) + library = "prof.dll" + if (UNIX) + library = "libprof.so" + else + CRASH("Unsupported platform: [system_type]") - var/init = LIBCALL(lib, "init")() - if("0" != init) CRASH("[lib] init error: [init]") + var/init_result = call_ext(library, "init")("block") + if (init_result != "0") + CRASH("Error initializing byond-tracy: [init_result]") -/world/New() - prof_init() - . = ..() -#endif diff --git a/code/modules/antagonists/slaughter/slaughterevent.dm b/code/modules/antagonists/slaughter/slaughterevent.dm index 9b62de57bfd0..8d1f92faac4f 100644 --- a/code/modules/antagonists/slaughter/slaughterevent.dm +++ b/code/modules/antagonists/slaughter/slaughterevent.dm @@ -8,6 +8,7 @@ category = EVENT_CATEGORY_ENTITIES description = "Spawns a slaughter demon, to hunt by travelling through pools of blood." +/* /datum/round_event_control/slaughter/canSpawnEvent() weight = initial(src.weight) var/list/allowed_turf_typecache = typecacheof(/turf/open) - typecacheof(/turf/open/space) @@ -24,6 +25,7 @@ weight += 0.03 CHECK_TICK return ..() +*/ /datum/round_event/ghost_role/slaughter minimum_required = 1 diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index ef2b2b348cca..0c910556df08 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -107,6 +107,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/pda_style = MONO var/pda_color = "#808000" var/pda_skin = PDA_SKIN_ALT + var/list/alt_titles_preferences = list() // Added by SPLURT (Custom Blood Color) var/custom_blood_color = FALSE @@ -132,7 +133,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/view_pixelshift = FALSE var/enable_personal_chat_color = FALSE var/personal_chat_color = "#ffffff" - var/list/alt_titles_preferences = list() var/lust_tolerance = 100 var/sexual_potency = 15 //Sandstorm CHANGES END @@ -1810,11 +1810,9 @@ GLOBAL_LIST_EMPTY(preferences_datums) HTML += "" var/rank = job.title - //Skyrat changes var/displayed_rank = rank if(job.alt_titles.len && (rank in alt_titles_preferences)) displayed_rank = alt_titles_preferences[rank] - //End of skyrat changes lastJob = job if(jobban_isbanned(user, rank)) HTML += "[rank] BANNED" @@ -1836,16 +1834,15 @@ GLOBAL_LIST_EMPTY(preferences_datums) if((job_preferences["[SSjob.overflow_role]"] == JP_LOW) && (rank != SSjob.overflow_role) && !jobban_isbanned(user, SSjob.overflow_role)) HTML += "[rank]" continue - //Skyrat changes var/rank_title_line = "[displayed_rank]" if((rank in GLOB.command_positions) || (rank == "AI"))//Bold head jobs rank_title_line = "[rank_title_line]" if(job.alt_titles.len) rank_title_line = "[rank_title_line]" + else rank_title_line = "[rank_title_line]" //Make it dark if we're not adding a button for alt titles HTML += rank_title_line - //End of skyrat changes HTML += "" @@ -2099,7 +2096,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) SetChoices(user) if("setJobLevel") UpdateJobPreference(user, href_list["text"], text2num(href_list["level"])) - //SKYRAT CHANGES if("alt_title") var/job_title = href_list["job_title"] var/titles_list = list(job_title) @@ -2115,7 +2111,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) else alt_titles_preferences[job_title] = chosen_title SetChoices(user) - //END OF SKYRAT CHANGES else SetChoices(user) return TRUE diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index bf2fd5654199..8ab8c39df594 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -1121,6 +1121,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car if(json_from_file) belly_prefs = json_from_file["belly_prefs"] + S["alt_titles_preferences"] >> alt_titles_preferences //gear loadout if(istext(S["loadout"])) loadout_data = safe_json_decode(S["loadout"]) @@ -1386,9 +1387,16 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["pregnancy_inflation"] >> pregnancy_inflation S["pregnancy_breast_growth"] >> pregnancy_breast_growth //SPLURT EDIT END - + loadout_slot = sanitize_num_clamp(loadout_slot, 1, MAXIMUM_LOADOUT_SAVES, 1, TRUE) + alt_titles_preferences = SANITIZE_LIST(alt_titles_preferences) + if(SSjob) + for(var/datum/job/job in SSjob.occupations) + if(alt_titles_preferences[job.title]) + if(!(alt_titles_preferences[job.title] in job.alt_titles)) + alt_titles_preferences.Remove(job.title) + cit_character_pref_load(S) splurt_character_pref_load(S) @@ -1553,6 +1561,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["feature_neckfire"], features["neckfire"]) WRITE_FILE(S["feature_neckfire_color"], features["neckfire_color"]) + WRITE_FILE(S["alt_titles_preferences"], alt_titles_preferences) + WRITE_FILE(S["feature_ooc_notes"], features["ooc_notes"]) WRITE_FILE(S["feature_color_scheme"], features["color_scheme"]) diff --git a/code/modules/jobs/job_titles.dm b/code/modules/jobs/job_titles.dm new file mode 100644 index 000000000000..a230fc4d3139 --- /dev/null +++ b/code/modules/jobs/job_titles.dm @@ -0,0 +1,99 @@ +//This file also determines the order for the choose your occupation chances screen. + +//Engineering +/datum/job/chief_engineer + alt_titles = list("Head Engineer", "Construction Coordinator", "Project Manager", "Power Plant Director") + +/datum/job/engineer + alt_titles = list("Maintenance Technician", "Engine Technician", "Electrician", "Structural Engineer", "Mechanic", "Station Architect", "Nuclear Plant Operator") + +/datum/job/atmos + alt_titles = list("Firefighter", "Life Support Specialist", "Disposals Technician") + +//Service +/datum/job/assistant + alt_titles = list("Civilian", "Morale Officer", "Off-Duty", "Visitor", "Businessman", "Trader", "Entertainer", "Tourist") + +/datum/job/cook + alt_titles = list("Culinary Artist", "Butcher", "Chef de partie", "Poissonier", "Baker", "Taste Tester") + +/datum/job/hydro + alt_titles = list("Gardener", "Herbalist", "Botanical Researcher", "Hydroponicist", "Farmer", "Beekeeper", "Vintner") + +/datum/job/curator + alt_titles = list("Journalist", "Librarian", "Keeper") + +/datum/job/chaplain + alt_titles = list("Priest", "Priestess", "Prior", "Monk", "Nun", "Counselor") + +/datum/job/janitor + alt_titles = list("Custodian", "Sanitation Technician", "Maid", "Trash Can", "Disposal Unit") + +/datum/job/lawyer + alt_titles = list("Human Resources Agent", "Internal Affairs Agent", "Attorney") + +/datum/job/clown + alt_titles = list("Jester", "Comedian") + +/datum/job/mime + alt_titles = list("Performer", "Pantomime", "Mimic") + +/datum/job/bartender + alt_titles = list("Mixologist", "Sommelier", "Bar Owner", "Barmaid", "Expediter") + +//Science +/datum/job/rd + alt_titles = list("Research Manager", "Science Administrator") + +/datum/job/scientist + alt_titles = list("Circuitry Designer", "Xenobiologist", "Xenobotanist", "Xenoarcheologist", "Chemical Researcher", "Researcher", "Pyrotechnician") + +/datum/job/roboticist + alt_titles = list("Biomechanical Engineer", "Mechatronic Engineer", "Mechanic") + +//Medical +/datum/job/cmo + alt_titles = list("Medical Director", "Medical Administrator") + +/datum/job/doctor + alt_titles = list("Nurse", "Surgeon", "Physician", "Paramedic", "Trophologist", "Nutritionist", "Therapist", "Psychiatrist") + +/datum/job/chemist + alt_titles = list("Pharmacist", "Pharmacologist") + +/datum/job/virologist + alt_titles = list("Microbiologist", "Biochemist", "Pathologist") + +/datum/job/geneticist + alt_titles = list("Gene Therapist", "Genetics Researcher") + +//Security +/datum/job/hos + alt_titles = list("Chief of Security", "Security Commander", "Sheriff") + +/datum/job/warden + alt_titles = list("Prison Chief", "Armory Manager", "Prison Administrator", "Brig Superintendent") + +/datum/job/officer + alt_titles = list("Security Agent", "Probation Officer", "Security Peacekeeper", "Security Guard", "Guardsman", "Security Cadet") + +/datum/job/detective + alt_titles = list("Forensics Technician", "Private Investigator", "Gumshoe") + + +//Supply +/datum/job/qm + alt_titles = list("Supply Chief") + +/datum/job/cargo_tech + alt_titles = list("Mail Man", "Mail Woman", "Mailroom Technician", "Deliveries Officer", "Logistics Technician") + +/datum/job/mining + alt_titles = list("Exotic Ore Miner", "Fauna Hunter", "Explorer", "Digger") //Just because you're a hunter does not excuse you from rock collecting!!!!!!!!!!!! + +//Command +/datum/job/captain + alt_titles = list("Station Director", "Station Commander", "Station Overseer", "Stationmaster", "Commissar") + +/datum/job/hop + alt_titles = list("Personnel Manager", "Staff Administrator", "Records Administrator") diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm index d81684044c9d..ecc6a553925f 100644 --- a/code/modules/jobs/job_types/_job.dm +++ b/code/modules/jobs/job_types/_job.dm @@ -63,6 +63,9 @@ var/list/mind_traits // Traits added to the mind of the mob assigned this job var/list/blacklisted_quirks //list of quirk typepaths blacklisted. + /// What alternate titles does this job currently have? + var/list/alt_titles = list() + /// Should this job be allowed to be picked for the bureaucratic error event? var/allow_bureaucratic_error = TRUE @@ -211,7 +214,7 @@ /datum/job/proc/announce_head(var/mob/living/carbon/human/H, var/channels) //tells the given channel that the given mob is the new department head. See communications.dm for valid channels. if(H && GLOB.announcement_systems.len) //timer because these should come after the captain announcement - SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(_addtimer), CALLBACK(pick(GLOB.announcement_systems), TYPE_PROC_REF(/obj/machinery/announcement_system, announce), "NEWHEAD", H.real_name, H.job, channels), 1)) + SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(_addtimer), CALLBACK(pick(GLOB.announcement_systems), TYPE_PROC_REF(/obj/machinery/announcement_system, announce), "NEWHEAD", H.real_name, H.job, H.client?.prefs.alt_titles_preferences[H.job], channels), 1)) //If the configuration option is set to require players to be logged as old enough to play certain jobs, then this proc checks that they are, otherwise it just returns 1 /datum/job/proc/player_old_enough(client/C) @@ -313,14 +316,13 @@ C.access = J.get_access() shuffle_inplace(C.access) // Shuffle access list to make NTNet passkeys less predictable C.registered_name = H.real_name - //Skyrat change + C.assignment = J.title if(preference_source && preference_source.prefs && preference_source.prefs.alt_titles_preferences[J.title]) - C.assignment = preference_source.prefs.alt_titles_preferences[J.title] + C.update_label(C.registered_name, preference_source.prefs.alt_titles_preferences[J.title]) else - C.assignment = J.title - //End of skyrat change - C.update_label() - if(J.title != "Stowaway") + C.update_label() + + if(J.title != "Stowaway") //SPLURT EDIT for(var/A in SSeconomy.bank_accounts) var/datum/bank_account/B = A if(B.account_id == H.account_id) @@ -332,12 +334,10 @@ var/obj/item/pda/PDA = H.get_item_by_slot(pda_slot) if(istype(PDA)) PDA.owner = H.real_name - //Skyrat change if(preference_source && preference_source.prefs && preference_source.prefs.alt_titles_preferences[J.title]) PDA.ownjob = preference_source.prefs.alt_titles_preferences[J.title] else PDA.ownjob = J.title - //End of skyrat change PDA.update_label() if(preference_source && !PDA.equipped) //PDA's screen color, font style and look depend on client preferences. PDA.update_style(preference_source) diff --git a/code/modules/jobs/job_types/captain.dm b/code/modules/jobs/job_types/captain.dm index 08bcf38c87b3..cdc188093555 100644 --- a/code/modules/jobs/job_types/captain.dm +++ b/code/modules/jobs/job_types/captain.dm @@ -50,7 +50,10 @@ /datum/job/captain/announce(mob/living/carbon/human/H) ..() - SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(minor_announce), "Captain [H.nameless ? "" : "[H.real_name] "]on deck!")) + var/displayed_rank = H.client?.prefs?.alt_titles_preferences[title] + if(!displayed_rank) //Default to Captain + displayed_rank = "Captain" + SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(minor_announce), "[displayed_rank] [H.nameless ? "" : "[H.real_name] "]on deck!")) /datum/outfit/job/captain name = "Captain" diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index b001d08d9c21..41e54ea109de 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -610,15 +610,14 @@ var/command_bold = "" if(job in GLOB.command_positions) command_bold = " command" - //Sandstorm changes - var/jobline = "[job_datum.title]" if(job_datum in SSjob.prioritized_jobs) - jobline = "[jobline]" - if(client && client.prefs && client.prefs.alt_titles_preferences[job_datum.title]) - jobline = "[jobline]
(as [client.prefs.alt_titles_preferences[job_datum.title]])" - jobline = "[jobline] ([num_positions_current]/[num_positions_total])" - dept_dat += jobline - //End of Sandstorm changes + dept_dat += "[job_datum.title] ([num_positions_current]/[num_positions_total])" + else + dept_dat += "[job_datum.title] ([num_positions_current]/[num_positions_total])" + if(client && client.prefs && client?.prefs?.alt_titles_preferences[job_datum.title]) + dept_dat += "
as [client?.prefs?.alt_titles_preferences[job_datum.title]]" + dept_dat += "
" + if(!dept_dat.len) dept_dat += "No positions open." dat += jointext(dept_dat, "") diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index d6a35116d4f2..c2505565ac71 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1650,7 +1650,15 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) H.Jitter(5) hunger_rate = 3 * HUNGER_FACTOR hunger_rate *= H.physiology.hunger_mod - H.adjust_nutrition(-hunger_rate) + + // SANDSTORM EDIT + if (H.client) + H.adjust_nutrition(-hunger_rate) + else + // Do not allow SSD players to get too hungry. + if (H.nutrition >= NUTRITION_LEVEL_FED) + H.adjust_nutrition(-hunger_rate) + // End of sandstorm edit if (H.nutrition > NUTRITION_LEVEL_FULL) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 3c37003394a5..44f8236aac29 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -1032,7 +1032,7 @@ if(GLOB.announcement_systems.len) // Sends an announcement the AI has cryoed. var/obj/machinery/announcement_system/announcer = pick(GLOB.announcement_systems) - announcer.announce("CRYOSTORAGE", src.real_name, announce_rank, list()) + announcer.announce("CRYOSTORAGE", src.real_name, announce_rank, announce_rank, list()) new /obj/structure/ai_core/latejoin_inactive(loc) if(src.mind) //Handle job slot/tater cleanup. diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 4eff3fab6779..e4b86ff584b0 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -926,7 +926,7 @@ status_flags &= ~CANPUSH if(module.clean_on_move) - AddElement(/datum/element/cleaning) + AddElement(/datum/element/cleaning, cleaning_range = 1) else RemoveElement(/datum/element/cleaning) @@ -1196,8 +1196,8 @@ var/mob/unbuckle_me_now = i unbuckle_mob(unbuckle_me_now, FALSE) -/mob/living/silicon/robot/proc/TryConnectToAI() - set_connected_ai(select_active_ai_with_fewest_borgs(z)) +/mob/living/silicon/robot/proc/TryConnectToAI(mob/living/silicon/ai/connect_to) + set_connected_ai(connect_to || select_active_ai_with_fewest_borgs(z)) if(connected_ai) lawsync() lawupdate = TRUE diff --git a/config/config.txt b/config/config.txt index f9a588e63ad0..e491231d0730 100644 --- a/config/config.txt +++ b/config/config.txt @@ -40,9 +40,9 @@ $include entries/urls.txt $include entries/vote.txt $include plushies/defines.txt -# Special Sandstorm configs -$include sandstorm/config.txt -$include sandstorm/balance.txt + +# Sandstorm configs +$include sandstorm/includes.txt # Special SPLURT configs $include splurt/fetish_content.txt diff --git a/config/sandstorm/includes.txt b/config/sandstorm/includes.txt new file mode 100644 index 000000000000..adf290da66dc --- /dev/null +++ b/config/sandstorm/includes.txt @@ -0,0 +1,4 @@ +# This file is mostly so main config file relays to here, and this one relays to the rest +$include sandstorm/balance.txt +$include sandstorm/config.txt +$include sandstorm/qol.txt diff --git a/config/sandstorm/qol.txt b/config/sandstorm/qol.txt new file mode 100644 index 000000000000..4f2b082bd25c --- /dev/null +++ b/config/sandstorm/qol.txt @@ -0,0 +1,7 @@ +### +## AI +### + +## How many shells would an AI gain at roundstart +## Comment to disable +ROUNDSTART_AI_SHELLS 1 diff --git a/html/changelogs/archive/2024-11.yml b/html/changelogs/archive/2024-11.yml index cfcb7124ceb4..98c160e85c7e 100644 --- a/html/changelogs/archive/2024-11.yml +++ b/html/changelogs/archive/2024-11.yml @@ -12,3 +12,18 @@ LeDrascol: - code_imp: Modular quirks are now in separate files - code_imp: Modularized edits to upstream quirks +2024-11-20: + Arrhythmia_V: + - rscadd: Blade tail now available in character creator (Ported from VOREstation) +2024-11-25: + Mosley: + - bugfix: Fixes the arrivals announcements +2024-11-27: + Mosley: + - bugfix: Fixes the rest of the announcement systems from the update +2024-11-28: + xTheLifex: + - rscadd: AIs will now spawn with a AI Shell + - tweak: SSD Players will no longer decrease hunger below normal stats. + - soundadd: Added sounds to lighters + - code_imp: Cleaning element now supports a range variable. diff --git a/modular_citadel/code/modules/client/preferences_savefile.dm b/modular_citadel/code/modules/client/preferences_savefile.dm index dc5e559ee18c..191e89eeafd9 100644 --- a/modular_citadel/code/modules/client/preferences_savefile.dm +++ b/modular_citadel/code/modules/client/preferences_savefile.dm @@ -20,14 +20,6 @@ S["lust_tolerance"] >> lust_tolerance S["sexual_potency"] >> sexual_potency - S["alt_titles_preferences"] >> alt_titles_preferences - alt_titles_preferences = SANITIZE_LIST(alt_titles_preferences) - if(SSjob) - for(var/datum/job/job in sort_list(SSjob.occupations, GLOBAL_PROC_REF(cmp_job_display_asc))) - if(alt_titles_preferences[job.title]) - if(!(alt_titles_preferences[job.title] in job.alt_titles)) - alt_titles_preferences.Remove(job.title) - erppref = sanitize_inlist(S["erp_pref"], GLOB.lewd_prefs_choices, "Ask") nonconpref = sanitize_inlist(S["noncon_pref"], GLOB.lewd_prefs_choices, "Ask") vorepref = sanitize_inlist(S["vore_pref"], GLOB.lewd_prefs_choices, "Ask") @@ -79,7 +71,6 @@ WRITE_FILE(S["extreme_harm"], extremeharm) WRITE_FILE(S["enable_personal_chat_color"], enable_personal_chat_color) WRITE_FILE(S["personal_chat_color"], personal_chat_color) - WRITE_FILE(S["alt_titles_preferences"], alt_titles_preferences) WRITE_FILE(S["lust_tolerance"], lust_tolerance) WRITE_FILE(S["sexual_potency"], sexual_potency) WRITE_FILE(S["silicon_lawset"], silicon_lawset) diff --git a/modular_sand/code/controllers/configuration/entries/sandstorm.dm b/modular_sand/code/controllers/configuration/entries/sandstorm.dm index 155cfb32c52b..b8461801e454 100644 --- a/modular_sand/code/controllers/configuration/entries/sandstorm.dm +++ b/modular_sand/code/controllers/configuration/entries/sandstorm.dm @@ -28,3 +28,6 @@ value_mode = VALUE_MODE_TYPE splitter = " | " lowercase_key = FALSE + +/datum/config_entry/number/roundstart_ai_shells // Per AI, if you ever do get a triumvirate! + min_val = 0 diff --git a/modular_sand/code/modules/jobs/job_types/_job.dm b/modular_sand/code/modules/jobs/job_types/_job.dm deleted file mode 100644 index cfb86b707274..000000000000 --- a/modular_sand/code/modules/jobs/job_types/_job.dm +++ /dev/null @@ -1,2 +0,0 @@ -/datum/job - var/list/alt_titles = list() diff --git a/modular_sand/code/modules/jobs/job_types/_job_alt_titles.dm b/modular_sand/code/modules/jobs/job_types/_job_alt_titles.dm index 3b2e238e8325..e22152175bd6 100644 --- a/modular_sand/code/modules/jobs/job_types/_job_alt_titles.dm +++ b/modular_sand/code/modules/jobs/job_types/_job_alt_titles.dm @@ -1,207 +1,204 @@ +// Great, since upstream got titles, we gotta do this differently. +// If you downstream, got conflicts from this, good, it means +// you'll know that you need to make changes as well +// Although, why are you modifying it here, go be doing shit modularly + //Command -/datum/job/captain - alt_titles = list( +/datum/job/captain/New() + alt_titles += list( "Colony Overseer", "Senator", "Consul" - ) + ) + return ..() -/datum/job/chief_engineer - alt_titles = list( +/datum/job/chief_engineer/New() + alt_titles += list( "Senior Engineer" - ) + ) + return ..() -/datum/job/hop - alt_titles = list( +/datum/job/hop/New() + alt_titles += list( "Crew Resource Officer", "Executive Officer" - ) + ) + return ..() -/datum/job/hos - alt_titles = list( - "Chief of Security", - "Sheriff", +/datum/job/hos/New() + alt_titles += list( "Praetor", - "Tarkhan" //If this reference is an issue I will remove it - ) + "Tarkhan" + ) + return ..() -/datum/job/qm - alt_titles = list( +/datum/job/qm/New() + alt_titles += list( "Resource Manager", "Logistics Supervisor" - ) + ) + return ..() -/datum/job/rd - alt_titles = list( +/datum/job/rd/New() + alt_titles += list( "Chief Science Officer", "Research Overseer" - ) - -//Engineering -/datum/job/atmos - alt_titles = list( - "Firefighter", - "Life Support Specialist" - ) - -/datum/job/engineer - alt_titles = list( - "Maintenance Technician", - "Engine Technician", - "Electrician" - ) - -//Service -/datum/job/assistant - alt_titles = list( - "Civilian", - "Visitor", - "Businessman", - "Trader", - "Entertainer", + ) + return ..() + +// Re-enable once we have our unique again +/* +/datum/job/atmos/New() + alt_titles += list( + ) + return ..() + +/datum/job/engineer/New() + alt_titles += list( + ) + return ..() +*/ + +/datum/job/assistant/New() + alt_titles += list( "Intern", - "Off-Duty Civilian" - ) + ) + return ..() -/datum/job/bartender - alt_titles = list( +/datum/job/bartender/New() + alt_titles += list( "Barista" - ) + ) + return ..() -/datum/job/chaplain - alt_titles = list( - "Priest", +/datum/job/chaplain/New() + alt_titles += list( "Cult Leader", "Pope", - "Bishop", // How about you actually say something about it instead of crying on a downstream's comments i won't read. + "Bishop", "Pontiff" - ) + ) + return ..() -/datum/job/clown //The most useless role in the game, delet this - alt_titles = list( +/datum/job/clown/New() + alt_titles += list( "Entertainer" - ) + ) + return ..() -/datum/job/cook - alt_titles = list( - "Culinary Artist", - "Butcher", +/datum/job/cook/New() + alt_titles += list( "Chef", "Nutritionist" - ) - -/datum/job/curator - alt_titles = list( - "Journalist", - "Librarian" - ) - -/datum/job/hydro - alt_titles = list( - "Gardener", - "Herbalist", - "Botanical Researcher", + ) + return ..() + +/* +/datum/job/curator/New() + alt_titles += list( + ) + return ..() +*/ + +/datum/job/hydro/New() + alt_titles += list( "Florist" - ) - -/datum/job/janitor - alt_titles = list( - "Custodian", - "Sanitation Technician", - "Maid" - ) - -/datum/job/lawyer - alt_titles = list( - "Human Resources Agent", - "Internal Affairs Agent" - ) - -/datum/job/mime - alt_titles = list( - "Performer" - ) - -//Science -/datum/job/roboticist - alt_titles = list( - "Biomechanical Engineer", - "Mechatronic Engineer", - "Mechanic", + ) + return ..() + +/* +/datum/job/janitor/New() + alt_titles += list( + ) + return ..() + +/datum/job/lawyer/New() + alt_titles += list( + ) + return ..() + +/datum/job/mime/New() + alt_titles += list( + ) + return ..() +*/ + +/datum/job/roboticist/New() + alt_titles += list( "Robotics Operator", "MODsuit Engineer" - ) - -/datum/job/scientist - alt_titles = list( - "Circuitry Designer", - "Xenobiologist", - "Xenobotanist", - "Chemical Researcher" - ) - -//Medical -/datum/job/chemist - alt_titles = list( - "Pharmacist", - "Pharmacologist" - ) - -/datum/job/doctor - alt_titles = list( - "Nurse", - "Surgeon", + ) + return ..() + +/* +/datum/job/scientist/New() + alt_titles += list( + ) + return ..() + +/datum/job/chemist/New() + alt_titles += list( + ) + return ..() +*/ + +/datum/job/doctor/New() + alt_titles += list( "Medical Secretary", "Emergency Physician", - "Field Surgeon" - ) + "Field Surgeon" + ) + return ..() -/datum/job/geneticist - alt_titles = list( - "Genetic Therapist", +/datum/job/geneticist/New() + alt_titles += list( "Bioengineer" - ) + ) + return ..() -/datum/job/paramedic - alt_titles = list( +/datum/job/paramedic/New() + alt_titles += list( "Emergency Medical Technician", "Advanced Emergency Medical Technician" - ) - -/datum/job/virologist - alt_titles = list( - "Pathologist" - ) - -//Security -/datum/job/detective - alt_titles = list( - "Forensics Technician", - "Private Investigator" - ) - -/datum/job/officer - alt_titles = list( - "Security Cadet", - "Security Guard", + ) + return ..() + +/* +/datum/job/virologist/New() + alt_titles += list( + ) + return ..() + +/datum/job/detective/New() + alt_titles += list( + ) + return ..() +*/ + +/datum/job/officer/New() + alt_titles += list( "Peacekeeper", "Enforcer" - ) + ) + return ..() -/datum/job/warden - alt_titles = list( +/datum/job/warden/New() + alt_titles += list( "Brig Chief" - ) - -//Cargo + ) + return ..() -/datum/job/cargo_tech - alt_titles = list( +/datum/job/cargo_tech/New() + alt_titles += list( "Shipping Specialist", "Delivery Manager" - ) + ) + return ..() -/datum/job/mining - alt_titles = list( +/* +/datum/job/mining/New() + alt_titles += list( "Explorer" - ) + ) + return ..() +*/ diff --git a/modular_sand/code/modules/jobs/job_types/ai.dm b/modular_sand/code/modules/jobs/job_types/ai.dm index 5f80699ea7fe..df0f3ff8429a 100644 --- a/modular_sand/code/modules/jobs/job_types/ai.dm +++ b/modular_sand/code/modules/jobs/job_types/ai.dm @@ -1,6 +1,21 @@ /datum/job/ai/after_spawn(mob/living/silicon/ai/AI, client/player_client, latejoin) . = ..() - if(!istype(AI)) + setup_silicon_law_prefs(AI, player_client) + + if(latejoin) return - setup_silicon_law_prefs(AI, player_client) + var/free_shells = CONFIG_GET(number/roundstart_ai_shells) + if(!free_shells) + return + + var/turf/open/turf = locate() in RANGE_TURFS(1, AI) + + // Why the fuck is the station AI completely blocked + var/turf/where = turf || get_turf(AI) + + // Creating AI shells for the AI. + for(var/iteration in 1 to free_shells) + var/mob/living/silicon/robot/free_borg = new(where) + free_borg.shell = TRUE + free_borg.TryConnectToAI(AI) diff --git a/modular_sand/code/modules/mob/dead/new_player/sprite_accessories/tails.dm b/modular_sand/code/modules/mob/dead/new_player/sprite_accessories/tails.dm index 8f50ffc97b8c..758d6bfcdf82 100644 --- a/modular_sand/code/modules/mob/dead/new_player/sprite_accessories/tails.dm +++ b/modular_sand/code/modules/mob/dead/new_player/sprite_accessories/tails.dm @@ -51,3 +51,15 @@ icon = 'modular_sand/icons/mob/mam_tails.dmi' color_src = MATRIXED matrixed_sections = MATRIX_RED_GREEN + +/datum/sprite_accessory/tails/mam_tails/blade //Ported from Vorestation + name = "Blade" + icon_state = "blade" + icon = 'modular_sand/icons/mob/mam_tails.dmi' + color_src = MUTCOLORS + +/datum/sprite_accessory/tails_animated/mam_tails_animated/blade //Ported from Vorestation + name = "Blade" + icon_state = "blade" + icon = 'modular_sand/icons/mob/mam_tails.dmi' + color_src = MUTCOLORS diff --git a/modular_sand/code/modules/mob/living/carbon/human/species.dm b/modular_sand/code/modules/mob/living/carbon/human/species.dm index e40880f1285f..6f3ba0c8a5c8 100644 --- a/modular_sand/code/modules/mob/living/carbon/human/species.dm +++ b/modular_sand/code/modules/mob/living/carbon/human/species.dm @@ -3,7 +3,12 @@ return //Put more things here if you plan on adding more things. I know this proc is a bit empty at the moment - H.adjust_thirst(-THIRST_FACTOR) + if (H.client) + H.adjust_thirst(-THIRST_FACTOR) + else + // Do not allow SSD players to too thirsty. + if (H.thirst >= THIRST_LEVEL_QUENCHED) + H.adjust_thirst(-THIRST_FACTOR) /* switch(get_thirst(src)) if(THIRST_LEVEL_THIRSTY to INFINITY) diff --git a/modular_sand/icons/mob/mam_tails.dmi b/modular_sand/icons/mob/mam_tails.dmi index 121df70b4f79..98abc12b7978 100644 Binary files a/modular_sand/icons/mob/mam_tails.dmi and b/modular_sand/icons/mob/mam_tails.dmi differ diff --git a/modular_sand/sound/items/lighter/close.ogg b/modular_sand/sound/items/lighter/close.ogg new file mode 100644 index 000000000000..2435711fa75f Binary files /dev/null and b/modular_sand/sound/items/lighter/close.ogg differ diff --git a/modular_sand/sound/items/lighter/light.ogg b/modular_sand/sound/items/lighter/light.ogg new file mode 100644 index 000000000000..9ca5270bc794 Binary files /dev/null and b/modular_sand/sound/items/lighter/light.ogg differ diff --git a/modular_sand/sound/items/lighter/open.ogg b/modular_sand/sound/items/lighter/open.ogg new file mode 100644 index 000000000000..79b2c00a6150 Binary files /dev/null and b/modular_sand/sound/items/lighter/open.ogg differ diff --git a/prof.dll b/prof.dll new file mode 100644 index 000000000000..3182f4dfc736 Binary files /dev/null and b/prof.dll differ diff --git a/tgstation.dme b/tgstation.dme index 5c173c5b341e..fb5bb8baed38 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -2562,6 +2562,7 @@ #include "code\modules\jobs\access.dm" #include "code\modules\jobs\job_exp.dm" #include "code\modules\jobs\job_report.dm" +#include "code\modules\jobs\job_titles.dm" #include "code\modules\jobs\jobs.dm" #include "code\modules\jobs\job_types\_job.dm" #include "code\modules\jobs\job_types\ai.dm" @@ -4302,7 +4303,6 @@ #include "modular_sand\code\modules\integrated_electronics\subtypes\input.dm" #include "modular_sand\code\modules\integrated_electronics\subtypes\manipulation.dm" #include "modular_sand\code\modules\integrated_electronics\subtypes\output.dm" -#include "modular_sand\code\modules\jobs\job_types\_job.dm" #include "modular_sand\code\modules\jobs\job_types\_job_alt_titles.dm" #include "modular_sand\code\modules\jobs\job_types\ai.dm" #include "modular_sand\code\modules\jobs\job_types\cyborg.dm"