diff --git a/Dockerfile b/Dockerfile index 97d2ccf2e7..4d9443971e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,4 @@ -FROM tgstation/byond:512.1448 as base -#above version must be the same as the one in dependencies.sh +FROM tgstation/byond:512.1453 as base FROM base as build_base diff --git a/code/__DEFINES/citadel_defines.dm b/code/__DEFINES/citadel_defines.dm index 7744b24d0f..e5749764e0 100644 --- a/code/__DEFINES/citadel_defines.dm +++ b/code/__DEFINES/citadel_defines.dm @@ -128,3 +128,6 @@ //component stuff #define COMSIG_COMBAT_TOGGLED "combatmode_toggled" //called by combat mode toggle on all equipped items. args: (mob/user, combatmode) + +//belly sound pref things +#define NORMIE_HEARCHECK 4 diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index b7d467c385..62e1cf1b90 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -258,3 +258,5 @@ // /obj/item/bodypart on_mob_life() retval flag #define BODYPART_LIFE_UPDATE_HEALTH (1<<0) + +#define HUMAN_FIRE_STACK_ICON_NUM 3 diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm index faa620613c..d24054a24c 100644 --- a/code/__DEFINES/tgs.dm +++ b/code/__DEFINES/tgs.dm @@ -10,6 +10,10 @@ //Comment this out once you've filled in the below #error TGS API unconfigured +//Uncomment this if you wish to allow the game to interact with TGS 3 +//This will raise the minimum required security level of your game to TGS_SECURITY_TRUSTED due to it utilizing call()() +//#define TGS_V3_API + //Required interfaces (fill in with your codebase equivalent): //create a global variable named `Name` and set it to `Value` @@ -47,7 +51,21 @@ #define TGS_EVENT_PORT_SWAP -2 //before a port change is about to happen, extra parameter is new port #define TGS_EVENT_REBOOT_MODE_CHANGE -1 //before a reboot mode change, extras parameters are the current and new reboot mode enums -//TODO +//See the descriptions for these codes here: https://github.com/tgstation/tgstation-server/blob/master/src/Tgstation.Server.Host/Components/EventType.cs +#define TGS_EVENT_REPO_RESET_ORIGIN 0 +#define TGS_EVENT_REPO_CHECKOUT 1 +#define TGS_EVENT_REPO_FETCH 2 +#define TGS_EVENT_REPO_MERGE_PULL_REQUEST 3 +#define TGS_EVENT_REPO_PRE_SYNCHRONIZE 4 +#define TGS_EVENT_BYOND_INSTALL_START 5 +#define TGS_EVENT_BYOND_INSTALL_FAIL 6 +#define TGS_EVENT_BYOND_ACTIVE_VERSION_CHANGE 7 +#define TGS_EVENT_COMPILE_START 8 +#define TGS_EVENT_COMPILE_CANCELLED 9 +#define TGS_EVENT_COMPILE_FAILURE 10 +#define TGS_EVENT_COMPILE_COMPLETE 11 +#define TGS_EVENT_INSTANCE_AUTO_UPDATE_START 12 +#define TGS_EVENT_REPO_MERGE_CONFLICT 13 //OTHER ENUMS @@ -74,8 +92,8 @@ /world/proc/TgsInitializationComplete() return -//Put this somewhere in /world/Topic(T, Addr, Master, Keys) that is always run before T is modified -#define TGS_TOPIC var/tgs_topic_return = TgsTopic(T); if(tgs_topic_return) return tgs_topic_return +//Put this at the start of /world/Topic() +#define TGS_TOPIC var/tgs_topic_return = TgsTopic(args[1]); if(tgs_topic_return) return tgs_topic_return //Call this at the beginning of world/Reboot(reason) /world/proc/TgsReboot() @@ -177,7 +195,7 @@ //Gets a list of connected tgs_chat_channel /world/proc/TgsChatChannelInfo() return - + //Sends a message to connected game chats //message: The message to send //channels: optional channels to limit the broadcast to @@ -201,24 +219,24 @@ The MIT License Copyright (c) 2017 Jordan Brown -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software and -associated documentation files (the "Software"), to -deal in the Software without restriction, including -without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom -the Software is furnished to do so, +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ \ No newline at end of file diff --git a/code/_compile_options.dm b/code/_compile_options.dm index 67bbe24e38..3ec2510cc7 100644 --- a/code/_compile_options.dm +++ b/code/_compile_options.dm @@ -3,6 +3,11 @@ //#define DATUMVAR_DEBUGGING_MODE //Enables the ability to cache datum vars and retrieve later for debugging which vars changed. +// Comment this out if you are debugging problems that might be obscured by custom error handling in world/Error +#ifdef DEBUG +#define USE_CUSTOM_ERROR_HANDLER +#endif + #ifdef TESTING #define DATUMVAR_DEBUGGING_MODE diff --git a/code/controllers/subsystem/research.dm b/code/controllers/subsystem/research.dm index 4aee87a38f..0836678c0a 100644 --- a/code/controllers/subsystem/research.dm +++ b/code/controllers/subsystem/research.dm @@ -45,7 +45,7 @@ SUBSYSTEM_DEF(research) var/list/errored_datums = list() var/list/point_types = list() //typecache style type = TRUE list //---------------------------------------------- - var/list/single_server_income = list(TECHWEB_POINT_TYPE_GENERIC = 25) //citadel edit - techwebs nerf + var/list/single_server_income = list(TECHWEB_POINT_TYPE_GENERIC = 35) //citadel edit - techwebs nerf var/multiserver_calculation = FALSE var/last_income //^^^^^^^^ ALL OF THESE ARE PER SECOND! ^^^^^^^^ diff --git a/code/datums/mood_events/needs_events.dm b/code/datums/mood_events/needs_events.dm index c67f4bf160..75b7e6931f 100644 --- a/code/datums/mood_events/needs_events.dm +++ b/code/datums/mood_events/needs_events.dm @@ -4,7 +4,7 @@ mood_change = -4 /datum/mood_event/wellfed - description = "My belly feels round and full.\n" + description = "I'm stuffed!\n" mood_change = 6 /datum/mood_event/fed diff --git a/code/datums/position_point_vector.dm b/code/datums/position_point_vector.dm index 7d49db8429..a33d0d2225 100644 --- a/code/datums/position_point_vector.dm +++ b/code/datums/position_point_vector.dm @@ -186,8 +186,8 @@ /datum/point/vector/proc/increment(multiplier = 1) iteration++ - x += mpx * 1 - y += mpy * 1 + x += mpx * (multiplier) + y += mpy * (multiplier) /datum/point/vector/proc/return_vector_after_increments(amount = 7, multiplier = 1, force_simulate = FALSE) var/datum/point/vector/v = copy_to() diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index 7a341ad69a..3af43ffb78 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -222,7 +222,7 @@ var/icon/I = icon(icon, icon_state, dir) holder.pixel_y = I.Height() - world.icon_size holder.icon_state = "hudno_id" - if(wear_id) + if(wear_id?.GetID()) holder.icon_state = "hud[ckey(wear_id.GetJobName())]" sec_hud_set_security_status() diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 41e429319c..7532d18d06 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -378,6 +378,8 @@ GLOBAL_LIST_EMPTY(objectives) for(var/datum/mind/M in owners) if(considered_alive(M)) return FALSE + if(M.current?.suiciding) //killing yourself ISN'T glorious. + return FALSE return TRUE /datum/objective/nuclear diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 69edfcd5ec..9b5aa96b0b 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -91,6 +91,7 @@ Class Procs: verb_yell = "blares" pressure_resistance = 15 max_integrity = 200 + layer = BELOW_OBJ_LAYER //keeps shit coming out of the machine from ending up underneath it. anchored = TRUE interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_UI_INTERACT @@ -120,7 +121,7 @@ Class Procs: armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70) . = ..() GLOB.machines += src - + if(ispath(circuit, /obj/item/circuitboard)) circuit = new circuit circuit.apply_default_parts(src) diff --git a/code/game/machinery/harvester.dm b/code/game/machinery/harvester.dm index 17f355b5ad..1f40672e05 100644 --- a/code/game/machinery/harvester.dm +++ b/code/game/machinery/harvester.dm @@ -131,18 +131,24 @@ playsound(src, 'sound/machines/microwave/microwave-end.ogg', 100, 0) /obj/machinery/harvester/screwdriver_act(mob/living/user, obj/item/I) - . = ..() - if(.) - return TRUE - if(!state_open && !occupant) - if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), I)) - return + . = TRUE + if(..()) + return + if(occupant) + to_chat(user, "[src] is currently occupied!") + return + if(state_open) + to_chat(user, "[src] must be closed to [panel_open ? "close" : "open"] it's maintenance hatch!") + return + if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), I)) + return + return FALSE /obj/machinery/harvester/crowbar_act(mob/living/user, obj/item/I) if(default_pry_open(I)) - return + return TRUE if(default_deconstruction_crowbar(I)) - return + return TRUE /obj/machinery/harvester/default_pry_open(obj/item/I) //wew . = !(state_open || panel_open || (flags_1 & NODECONSTRUCT_1)) && I.tool_behaviour == TOOL_CROWBAR //We removed is_operational() here @@ -181,4 +187,4 @@ if(state_open) to_chat(user, "[src] must be closed before harvesting.") else if(!harvesting) - to_chat(user, "Alt-click [src] to start harvesting.") + to_chat(user, "Alt-click [src] to start harvesting.") \ No newline at end of file diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index e4967b494d..30b1ca3399 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -95,7 +95,33 @@ var/atom/A = target if(!proximity && prox_check) return - A.emag_act(user) + //Citadel changes: modular code misfiring, so we're bypassing into main code. + if(!uses) + user.visible_message("[src] emits a weak spark. It's burnt out!") + playsound(src, 'sound/effects/light_flicker.ogg', 100, 1) + return + else if(uses <= 3) + playsound(src, 'sound/effects/light_flicker.ogg', 30, 1) //Tiiiiiiny warning sound to let ya know your emag's almost dead + + if(isturf(A)) + return + if(istype(A,/obj/item/storage/lockbox)) + A.emag_act(user) + uses = max(uses - 1, 0) + if(!uses) + user.visible_message("[src] fizzles and sparks. It seems like it's out of charges.") + playsound(src, 'sound/effects/light_flicker.ogg', 100, 1) + if(istype(A,/obj/item/storage)) + return + if(!(isobj(A) || issilicon(A) || isbot(A) || isdrone(A))) + return + else + A.emag_act(user) + uses = max(uses - 1, 0) + if(!uses) + user.visible_message("[src] fizzles and sparks. It seems like it's out of charges.") + playsound(src, 'sound/effects/light_flicker.ogg', 100, 1) + /obj/item/card/emagfake desc = "It's a card with a magnetic strip attached to some circuitry. Closer inspection shows that this card is a poorly made replica, with a \"DonkCo\" logo stamped on the back." diff --git a/code/game/objects/items/devices/dogborg_sleeper.dm b/code/game/objects/items/devices/dogborg_sleeper.dm index e12344fa53..30a3e5a9a2 100644 --- a/code/game/objects/items/devices/dogborg_sleeper.dm +++ b/code/game/objects/items/devices/dogborg_sleeper.dm @@ -13,11 +13,13 @@ var/cleaning = FALSE var/cleaning_cycles = 10 var/patient_laststat = null - var/list/injection_chems = list("antitoxin", "epinephrine", "morphine", "salbutamol", "bicaridine", "kelotane") + var/list/injection_chems = list("antitoxin", "epinephrine", "salbutamol", "bicaridine", "kelotane") var/eject_port = "ingestion" var/escape_in_progress = FALSE var/message_cooldown var/breakout_time = 300 + var/tmp/last_hearcheck = 0 + var/tmp/list/hearing_mobs var/list/items_preserved = list() var/static/list/important_items = typecacheof(list( /obj/item/hand_tele, @@ -45,10 +47,16 @@ // Bags are prohibited from this due to the potential explotation of objects, same with brought -/obj/item/dogborg/sleeper/New() - ..() +/obj/item/dogborg/sleeper/Initialize() + . = ..() update_icon() item_flags |= NOBLUDGEON //No more attack messages + START_PROCESSING(SSobj, src) + +/obj/item/dogborg/sleeper/Destroy() + STOP_PROCESSING(SSobj, src) + go_out() //just... sanity I guess, edge case shit + return ..() /obj/item/dogborg/sleeper/Exit(atom/movable/O) return 0 @@ -59,7 +67,7 @@ return if(!iscarbon(target)) return - if(!(target.client && target.client.prefs && target.client.prefs.toggles && (target.client.prefs.toggles & MEDIHOUND_SLEEPER))) + if(!target.client || !(target.client.prefs.cit_toggles & MEDIHOUND_SLEEPER)) to_chat(user, "This person is incompatible with our equipment.") return if(target.buckled) @@ -86,7 +94,6 @@ target.forceMove(src) target.reset_perspective(src) update_gut() - START_PROCESSING(SSobj, src) user.visible_message("[hound.name]'s medical pod lights up and expands as [target.name] slips inside into their [src.name].", "Your medical pod lights up as [target] slips into your [src]. Life support functions engaged.") message_admins("[key_name(hound)] has sleeper'd [key_name(patient)] as a dogborg. [ADMIN_JMP(src)]") playsound(hound, 'sound/effects/bin_close.ogg', 100, 1) @@ -137,7 +144,8 @@ else //You clicked eject with nothing in you, let's just reset stuff to be sure. items_preserved.Cut() cleaning = FALSE - update_gut() + update_gut() + /obj/item/dogborg/sleeper/attack_self(mob/user) if(..()) @@ -265,7 +273,6 @@ patient_laststat = null patient = null hound.update_icons() - return //Gurgleborg process /obj/item/dogborg/sleeper/proc/clean_cycle() @@ -274,6 +281,10 @@ if(!(I in contents)) items_preserved -= I var/list/touchable_items = contents - items_preserved + var/sound/prey_digest = sound(get_sfx("digest_prey")) + var/sound/prey_death = sound(get_sfx("death_prey")) + var/sound/pred_digest = sound(get_sfx("digest_pred")) + var/sound/pred_death = sound(get_sfx("death_pred")) if(cleaning_cycles) cleaning_cycles-- cleaning = TRUE @@ -293,10 +304,19 @@ to_chat(hound,"You feel your belly slowly churn around [T], breaking them down into a soft slurry to be used as power for your systems.") to_chat(T,"You feel [hound]'s belly slowly churn around your form, breaking you down into a soft slurry to be used as power for [hound]'s systems.") hound.cell.give(30000) //Fueeeeellll - T.stop_sound_channel(CHANNEL_PRED) - playsound(get_turf(hound),"death_pred",50,0,-6,0,channel=CHANNEL_PRED,ignore_walls = FALSE) - T.stop_sound_channel(CHANNEL_PRED) - T.playsound_local("death_prey",60) + if((world.time - NORMIE_HEARCHECK) > last_hearcheck) + var/turf/source = get_turf(hound) + LAZYCLEARLIST(hearing_mobs) + for(var/mob/H in get_hearers_in_view(3, source)) + if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) + continue + LAZYADD(hearing_mobs, H) + last_hearcheck = world.time + for(var/mob/H in hearing_mobs) + if(!istype(H.loc, /obj/item/dogborg/sleeper)) + H.playsound_local(source, null, 45, falloff = 0, S = pred_death) + else if(H in contents) + H.playsound_local(source, null, 65, falloff = 0, S = prey_death) for(var/belly in T.vore_organs) var/obj/belly/B = belly for(var/atom/movable/thing in B) @@ -328,15 +348,22 @@ to_chat(hound, "Your [src] is now clean. Ending self-cleaning cycle.") cleaning = FALSE update_gut() - return //sound effects - for(var/mob/living/M in contents) - if(prob(50)) - M.stop_sound_channel(CHANNEL_PRED) - playsound(get_turf(hound),"digest_pred",35,0,-6,0,channel=CHANNEL_PRED,ignore_walls = FALSE) - M.stop_sound_channel(CHANNEL_PRED) - M.playsound_local("digest_prey",60) + if(prob(50)) + if((world.time - NORMIE_HEARCHECK) > last_hearcheck) + var/turf/source = get_turf(hound) + LAZYCLEARLIST(hearing_mobs) + for(var/mob/H in get_hearers_in_view(3, source)) + if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) + continue + LAZYADD(hearing_mobs, H) + last_hearcheck = world.time + for(var/mob/H in hearing_mobs) + if(!istype(H.loc, /obj/item/dogborg/sleeper)) + H.playsound_local(source, null, 45, falloff = 0, S = pred_digest) + else if(H in contents) + H.playsound_local(source, null, 65, falloff = 0, S = prey_digest) if(cleaning) addtimer(CALLBACK(src, .proc/clean_cycle), 50) @@ -407,7 +434,6 @@ brigman.forceMove(src) brigman.reset_perspective(src) update_gut() - START_PROCESSING(SSobj, src) user.visible_message("[hound.name]'s mobile brig clunks in series as [brigman] slips inside.", "Your mobile brig groans lightly as [brigman] slips inside.") playsound(hound, 'sound/effects/bin_close.ogg', 80, 1) // Really don't need ERP sound effects for robots return @@ -481,7 +507,6 @@ trashman.forceMove(src) trashman.reset_perspective(src) update_gut() - START_PROCESSING(SSobj, src) user.visible_message("[hound.name]'s garbage processor groans lightly as [trashman] slips inside.", "Your garbage compactor groans lightly as [trashman] slips inside.") playsound(hound, 'sound/effects/bin_close.ogg', 80, 1) return diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index d66d64cde5..a6a6c5f699 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -167,6 +167,10 @@ L.stop_pulling() else if(istype(AM, /obj/structure/closet)) return + + else if(istype(AM, /obj/effect)) + return + else if(isobj(AM)) if (istype(AM, /obj/item)) var/obj/item/I = AM diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index df3df8ad14..067b1b0eb1 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -96,6 +96,7 @@ /obj/structure/closet/crate/freezer/blood name = "blood freezer" desc = "A freezer containing packs of blood." + icon_state = "surgery" /obj/structure/closet/crate/freezer/blood/PopulateContents() . = ..() diff --git a/code/modules/atmospherics/environmental/LINDA_fire.dm b/code/modules/atmospherics/environmental/LINDA_fire.dm index 9ca822b5ce..f816866070 100644 --- a/code/modules/atmospherics/environmental/LINDA_fire.dm +++ b/code/modules/atmospherics/environmental/LINDA_fire.dm @@ -37,7 +37,7 @@ active_hotspot = new /obj/effect/hotspot(src) active_hotspot.temperature = exposed_temperature - active_hotspot.volume = exposed_volume + active_hotspot.volume = exposed_volume*25 active_hotspot.just_spawned = (current_cycle < SSair.times_fired) //remove just_spawned protection if no longer processing this cell diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index 61f189e236..00cb2678cd 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -54,7 +54,10 @@ if(damaged_clothes) . += mutable_appearance('icons/effects/item_damage.dmi', "damagedshoe") if(bloody) - . += mutable_appearance('icons/effects/blood.dmi', "shoeblood") + if(adjusted == NORMAL_STYLE) + . += mutable_appearance('icons/effects/blood.dmi', "shoeblood") + else + . += mutable_appearance('modular_citadel/icons/mob/digishoes.dmi', "shoeblood") /obj/item/clothing/shoes/equipped(mob/user, slot) . = ..() diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm index 1748813f56..b53ec05dda 100644 --- a/code/modules/clothing/suits/utility.dm +++ b/code/modules/clothing/suits/utility.dm @@ -20,6 +20,7 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/extinguisher, /obj/item/crowbar) slowdown = 1 + armor = list("melee" = 15, "bullet" = 5, "laser" = 20, "energy" = 10, "bomb" = 20, "bio" = 10, "rad" = 20, "fire" = 100, "acid" = 50) flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS diff --git a/code/modules/events/pirates.dm b/code/modules/events/pirates.dm index 80b8373887..910e94f680 100644 --- a/code/modules/events/pirates.dm +++ b/code/modules/events/pirates.dm @@ -148,6 +148,7 @@ new /obj/item/stack/spacecash/c200(drop_location()) credits_stored -= 200 to_chat(user,"You retrieve the siphoned credits!") + credits_stored = 0 /obj/machinery/shuttle_scrambler/proc/send_notification() diff --git a/code/modules/food_and_drinks/food/snacks_other.dm b/code/modules/food_and_drinks/food/snacks_other.dm index ecb3cfb2ba..a2f5b06042 100644 --- a/code/modules/food_and_drinks/food/snacks_other.dm +++ b/code/modules/food_and_drinks/food/snacks_other.dm @@ -156,7 +156,7 @@ icon_state = "mint" bitesize = 1 trash = /obj/item/trash/plate - list_reagents = list("minttoxin" = 1) + list_reagents = list("minttoxin" = 2) filling_color = "#800000" foodtype = TOXIC | SUGAR diff --git a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm index 3bcc8d7659..1445f79aa2 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm @@ -10,6 +10,8 @@ active_power_usage = 100 circuit = /obj/item/circuitboard/machine/microwave pass_flags = PASSTABLE + light_color = LIGHT_COLOR_YELLOW + light_power = 3 var/operating = FALSE // Is it on? var/dirty = 0 // = {0..100} Does it need cleaning? var/broken = 0 // ={0,1,2} How broken is it??? @@ -267,12 +269,14 @@ soundloop.start() operating = TRUE icon_state = "mw1" + set_light(1.5) updateUsrDialog() /obj/machinery/microwave/proc/abort() operating = FALSE // Turn it off again aferwards icon_state = "mw" updateUsrDialog() + set_light(0) soundloop.stop() /obj/machinery/microwave/proc/stop() @@ -298,6 +302,7 @@ if(prob(50)) new /obj/item/reagent_containers/food/snacks/badrecipe(src) qdel(S) + set_light(0) soundloop.stop() /obj/machinery/microwave/proc/broke() @@ -310,6 +315,7 @@ flags_1 = null //So you can't add condiments operating = FALSE // Turn it off again aferwards updateUsrDialog() + set_light(0) soundloop.stop() /obj/machinery/microwave/Topic(href, href_list) diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm index 2c7eaf09ba..d155994379 100644 --- a/code/modules/mining/equipment/explorer_gear.dm +++ b/code/modules/mining/equipment/explorer_gear.dm @@ -121,7 +121,7 @@ /****************SEVA Suit and Mask****************/ /obj/item/clothing/suit/hooded/seva - name = "SEVA suit" + name = "SEVA Suit" desc = "A fire-proof suit for exploring hot environments." icon_state = "seva" item_state = "seva" @@ -135,7 +135,7 @@ resistance_flags = FIRE_PROOF | GOLIATH_WEAKNESS /obj/item/clothing/head/hooded/seva - name = "SEVA hood" + name = "SEVA Hood" desc = "A fire-proof hood for exploring hot environments." icon_state = "seva" item_state = "seva" @@ -145,6 +145,19 @@ armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 25, "bio" = 50, "rad" = 25, "fire" = 100, "acid" = 25) resistance_flags = FIRE_PROOF | GOLIATH_WEAKNESS +/obj/item/clothing/mask/gas/seva + name = "SEVA Mask" + desc = "A face-covering plate that can be connected to an air supply. Intended for use with the SEVA Suit." + icon_state = "seva" + clothing_flags = BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS + flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEFACIALHAIR + w_class = WEIGHT_CLASS_NORMAL + item_state = "seva" + gas_transfer_coefficient = 0.01 + permeability_coefficient = 0.01 + flags_cover = MASKCOVERSEYES | MASKCOVERSMOUTH + resistance_flags = FIRE_PROOF + /****************Exo-Suit and Mask****************/ /obj/item/clothing/suit/hooded/exo diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index 69b1bcaab4..2e695e6772 100644 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -73,6 +73,9 @@ /obj/item/twohanded/required/kinetic_crusher/afterattack(atom/target, mob/living/user, proximity_flag, clickparams) . = ..() + if(istype(target, /obj/item/crusher_trophy)) + var/obj/item/crusher_trophy/T = target + T.add_to(src, user) if(!proximity_flag && charged)//Mark a target, or mine a tile. var/turf/proj_turf = user.loc if(!isturf(proj_turf)) diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm index 63f7a7e414..64d2eed557 100644 --- a/code/modules/mining/machine_vending.dm +++ b/code/modules/mining/machine_vending.dm @@ -310,6 +310,7 @@ new /obj/item/clothing/suit/hooded/exo(drop_location) if("SEVA suit") new /obj/item/clothing/suit/hooded/seva(drop_location) + new /obj/item/clothing/mask/gas/seva(drop_location) SSblackbox.record_feedback("tally", "suit_voucher_redeemed", 1, selection) qdel(voucher) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 763487f7ed..99615e9543 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -53,3 +53,4 @@ var/creamed = FALSE //to use with creampie overlays var/static/list/can_ride_typecache = typecacheof(list(/mob/living/carbon/human, /mob/living/simple_animal/slime, /mob/living/simple_animal/parrot)) var/lastpuke = 0 + var/last_fire_update diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 789a52250c..a50fb4fe79 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -122,6 +122,12 @@ ///FIRE CODE /mob/living/carbon/human/handle_fire() + if(!last_fire_update) + last_fire_update = fire_stacks + if((fire_stacks > HUMAN_FIRE_STACK_ICON_NUM && last_fire_update <= HUMAN_FIRE_STACK_ICON_NUM) || (fire_stacks <= HUMAN_FIRE_STACK_ICON_NUM && last_fire_update > HUMAN_FIRE_STACK_ICON_NUM)) + last_fire_update = fire_stacks + update_fire() + ..() if(dna) dna.species.handle_fire(src) @@ -154,6 +160,7 @@ /mob/living/carbon/human/ExtinguishMob() if(!dna || !dna.species.ExtinguishMob(src)) + last_fire_update = null ..() //END FIRE CODE diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 6c5f030313..fc3c0cb00e 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1020,7 +1020,7 @@ client.move_delay = world.time + movement_delay() lying_prev = lying if(canmove && !intentionalresting && iscarbon(src) && client && client.prefs && client.prefs.autostand)//CIT CHANGE - adds autostanding as a preference - resist_a_rest(TRUE)//CIT CHANGE - ditto + addtimer(CALLBACK(src, .proc/resist_a_rest, TRUE), 0) //CIT CHANGE - ditto return canmove /mob/living/proc/AddAbility(obj/effect/proc_holder/A) diff --git a/code/modules/reagents/reagent_containers/patch.dm b/code/modules/reagents/reagent_containers/patch.dm index b11ef878b6..d4111467ba 100644 --- a/code/modules/reagents/reagent_containers/patch.dm +++ b/code/modules/reagents/reagent_containers/patch.dm @@ -14,6 +14,8 @@ /obj/item/reagent_containers/pill/patch/attack(mob/living/L, mob/user) if(ishuman(L)) var/obj/item/bodypart/affecting = L.get_bodypart(check_zone(user.zone_selected)) + if(!L.can_inject(user, 1, affecting)) //like monkey code, thickmaterial stops patches + return if(!affecting) to_chat(user, "The limb is missing!") return diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 4b28ecd048..ffcb67800f 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -151,6 +151,16 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL +/datum/design/holobarrier_med + name = "PENLITE holobarrier projector" + desc = "PENLITE holobarriers, a device that halts individuals with malicious diseases." + build_type = PROTOLATHE + build_path = /obj/item/holosign_creator/medical + materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 100) //a hint of silver since it can troll 2 antags (bad viros and sentient disease) + id = "holobarrier_med" + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + /datum/design/alienscalpel name = "Alien Scalpel" desc = "An advanced scalpel obtained through Abductor technology." @@ -577,12 +587,94 @@ surgery = /datum/surgery/advanced/necrotic_revival research_icon_state = "surgery_head" -/datum/design/holobarrier_med - name = "PENLITE holobarrier projector" - desc = "PENLITE holobarriers, a device that halts individuals with malicious diseases." +///////////////////////////////////////// +////////////Medical Prosthetics////////// +///////////////////////////////////////// + +/datum/design/basic_l_arm + name = "Surplus prosthetic left arm" + desc = "Basic outdated and fragile prosthetic left arm." + id = "basic_l_arm" build_type = PROTOLATHE - build_path = /obj/item/holosign_creator/medical - materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 100) //a hint of silver since it can troll 2 antags (bad viros and sentient disease) - id = "holobarrier_med" + materials = list(MAT_METAL = 5000, MAT_GLASS = 2500) + construction_time = 20 + build_path = /obj/item/bodypart/l_arm/robot/surplus category = list("Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL \ No newline at end of file + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/basic_r_arm + name = "Surplus prosthetic right arm" + desc = "Basic outdated and fragile prosthetic left arm." + id = "basic_r_arm" + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_GLASS = 2500) + construction_time = 20 + build_path = /obj/item/bodypart/r_arm/robot/surplus + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/basic_l_leg + name = "Surplus prosthetic left leg" + desc = "Basic outdated and fragile prosthetic left leg." + id = "basic_l_leg" + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_GLASS = 2500) + construction_time = 20 + build_path = /obj/item/bodypart/l_leg/robot/surplus + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/basic_r_leg + name = "Surplus prosthetic right leg" + desc = "Basic outdated and fragile prosthetic right leg." + id = "basic_r_leg" + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_GLASS = 2500) + construction_time = 20 + build_path = /obj/item/bodypart/r_leg/robot/surplus + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/adv_r_leg + name = "Advanced prosthetic right leg" + desc = "A renforced prosthetic right leg." + id = "adv_r_leg" + build_type = PROTOLATHE + materials = list(MAT_METAL = 6000, MAT_GLASS = 3500, MAT_GOLD = 500, MAT_TITANIUM = 800) + construction_time = 40 + build_path = /obj/item/bodypart/r_leg/robot/surplus_upgraded + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/adv_l_leg + name = "Advanced prosthetic left leg" + desc = "A renforced prosthetic left leg." + id = "adv_l_leg" + build_type = PROTOLATHE + materials = list(MAT_METAL = 6000, MAT_GLASS = 3500, MAT_GOLD = 500, MAT_TITANIUM = 800) + construction_time = 40 + build_path = /obj/item/bodypart/l_leg/robot/surplus_upgraded + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/adv_l_arm + name = "Advanced prosthetic left arm" + desc = "A renforced prosthetic left arm." + id = "adv_l_arm" + build_type = PROTOLATHE + materials = list(MAT_METAL = 6000, MAT_GLASS = 3500, MAT_GOLD = 500, MAT_TITANIUM = 800) + construction_time = 40 + build_path = /obj/item/bodypart/l_arm/robot/surplus_upgraded + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/adv_r_arm + name = "Advanced prosthetic right arm" + desc = "A renforced prosthetic right arm." + id = "adv_r_arm" + build_type = PROTOLATHE + materials = list(MAT_METAL = 6000, MAT_GLASS = 3500, MAT_GOLD = 500, MAT_TITANIUM = 800) + construction_time = 40 + build_path = /obj/item/bodypart/r_arm/robot/surplus_upgraded + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 7dcbb6775a..cd01bd1f20 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -71,6 +71,24 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 +/datum/techweb_node/surplus_lims + id = "surplus_lims" + display_name = "Basic Prosthetics" + description = "Basic fragile lims for the impaired." + prereq_ids = list("biotech") + design_ids = list("basic_l_arm", "basic_r_arm", "basic_r_leg", "basic_l_leg") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000) // You can knock them off with a glass shard... + export_price = 5000 + +/datum/techweb_node/advance_lims + id = "advance_lims" + display_name = "Upgraded Prosthetics" + description = "Reinforced prosthetics for the impaired." + prereq_ids = list("adv_biotech", "surplus_lims") + design_ids = list("adv_l_arm", "adv_r_arm", "adv_r_leg", "adv_l_leg") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + export_price = 5000 + /////////////////////////Advanced Surgery///////////////////////// /datum/techweb_node/adv_surgery id = "adv_surgery" diff --git a/code/modules/surgery/bodyparts/robot_bodyparts.dm b/code/modules/surgery/bodyparts/robot_bodyparts.dm index c535ef4a20..ab31d64034 100644 --- a/code/modules/surgery/bodyparts/robot_bodyparts.dm +++ b/code/modules/surgery/bodyparts/robot_bodyparts.dm @@ -235,7 +235,7 @@ - +// Surplus lims /obj/item/bodypart/l_arm/robot/surplus name = "surplus prosthetic left arm" desc = "A skeletal, robotic limb. Outdated and fragile, but it's still better than nothing." @@ -268,6 +268,38 @@ burn_reduction = 0 max_damage = 20 +// Upgraded Surplus lims +/obj/item/bodypart/l_arm/robot/surplus_upgraded + name = "reinforced surplus prosthetic left arm" + desc = "A skeletal, robotic limb. This one is reinforced to provide better protection." + icon = 'icons/mob/augmentation/surplus_augments.dmi' + brute_reduction = 1 + burn_reduction = 1 + max_damage = 30 + +/obj/item/bodypart/r_arm/robot/surplus_upgraded + name = "reinforced surplus prosthetic right arm" + desc = "A skeletal, robotic limb. This one is reinforced to provide better protection." + icon = 'icons/mob/augmentation/surplus_augments.dmi' + brute_reduction = 1 + burn_reduction = 1 + max_damage = 30 + +/obj/item/bodypart/l_leg/robot/surplus_upgraded + name = "reinforced surplus prosthetic left leg" + desc = "A skeletal, robotic limb. This one is reinforced to provide better protection." + icon = 'icons/mob/augmentation/surplus_augments.dmi' + brute_reduction = 1 + burn_reduction = 1 + max_damage = 30 + +/obj/item/bodypart/r_leg/robot/surplus_upgraded + name = "reinforced surplus prosthetic right leg" + desc = "A skeletal, robotic limb. This one is reinforced to provide better protection." + icon = 'icons/mob/augmentation/surplus_augments.dmi' + brute_reduction = 1 + burn_reduction = 1 + max_damage = 30 #undef ROBOTIC_LIGHT_BRUTE_MSG #undef ROBOTIC_MEDIUM_BRUTE_MSG diff --git a/dependencies.sh b/dependencies.sh index 1b61b37c88..644cdd3acc 100644 --- a/dependencies.sh +++ b/dependencies.sh @@ -3,11 +3,12 @@ #Project dependencies file #Final authority on what's required to fully build the project -#byond version -#note, this also needs to be changed in the Dockerfile's initial FROM command -#If someone has an idea for how to set that version within the Dockerfile itself without any other dependencies, feel free to PR it -export BYOND_MAJOR=512 -export BYOND_MINOR=1448 +# byond version +# Extracted from the Dockerfile. Change by editing Dockerfile's FROM command. +LIST=($(sed -n 's/.*byond:\([0-9]\+\)\.\([0-9]\+\).*/\1 \2/p' Dockerfile)) +export BYOND_MAJOR=${LIST[0]} +export BYOND_MINOR=${LIST[1]} +unset LIST #rust_g git tag export RUST_G_VERSION=0.4.1 diff --git a/html/changelogs/AutoChangeLog-pr-7625.yml b/html/changelogs/AutoChangeLog-pr-7625.yml new file mode 100644 index 0000000000..a6e72eab8f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7625.yml @@ -0,0 +1,7 @@ +author: "Poojawa" +delete-after: True +changes: + - refactor: "improved vore sound responsiveness to preference choices." + - balance: "removed morphine from Medihound sleeper chemical list" + - bugfix: "fixed preference setting being broken" + - refactor: "Medihound sleepers are Initialized properly, and icons update correctly now on eject" diff --git a/html/changelogs/AutoChangeLog-pr-7640.yml b/html/changelogs/AutoChangeLog-pr-7640.yml new file mode 100644 index 0000000000..7360022b33 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7640.yml @@ -0,0 +1,4 @@ +author: "Poojawa" +delete-after: True +changes: + - balance: "Added sanity checks to emag usage" diff --git a/html/changelogs/AutoChangeLog-pr-7650.yml b/html/changelogs/AutoChangeLog-pr-7650.yml new file mode 100644 index 0000000000..ba84b55d33 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7650.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - bugfix: "Autostand no longer makes you invulnerable to dropping items when being knocked down with a force greater than 80" diff --git a/html/changelogs/AutoChangeLog-pr-7652.yml b/html/changelogs/AutoChangeLog-pr-7652.yml new file mode 100644 index 0000000000..4695db6186 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-7652.yml @@ -0,0 +1,6 @@ +author: "Toriate" +delete-after: True +changes: + - imageadd: "All regular crates are now 3/4ths ToriCrates +iamgeadd: Unused plastic crate sprite added" + - rscadd: "Blood freezer crates now have unique sprites." diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index 39726a6ece..45e19bbc39 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi index 46b229388d..507f818195 100644 Binary files a/icons/mob/mask.dmi and b/icons/mob/mask.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index 4bc07f86f5..fc7c7f9ad0 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index a9d1398c20..0e5c42c5f7 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index 12dd04004b..fecf761062 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index 3737ee694e..d469bbbe22 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/crates.dmi b/icons/obj/crates.dmi index 508ae18c60..1d7945e3f2 100644 Binary files a/icons/obj/crates.dmi and b/icons/obj/crates.dmi differ diff --git a/modular_citadel/code/game/objects/ids.dm b/modular_citadel/code/game/objects/ids.dm index 5d67c18416..89a3c0f0c2 100644 --- a/modular_citadel/code/game/objects/ids.dm +++ b/modular_citadel/code/game/objects/ids.dm @@ -81,16 +81,3 @@ to_chat(user, "[ER] has no charges left.") return . = ..() - -/obj/item/card/emag/afterattack(atom/target, mob/user, proximity) - if(!uses) - user.visible_message("[src] emits a weak spark. It's burnt out!") - playsound(src, 'sound/effects/light_flicker.ogg', 100, 1) - return - . = ..() - uses = max(uses - 1, 0) - if(!uses) - user.visible_message("[src] fizzles and sparks. It seems like it's out of charges.") - playsound(src, 'sound/effects/light_flicker.ogg', 100, 1) - else if(uses <= 3) - playsound(src, 'sound/effects/light_flicker.ogg', 30, 1) //Tiiiiiiny warning sound to let ya know your emag's almost dead diff --git a/modular_citadel/code/modules/admin/chat_commands.dm b/modular_citadel/code/modules/admin/chat_commands.dm index 9cd25d328c..639077c439 100644 --- a/modular_citadel/code/modules/admin/chat_commands.dm +++ b/modular_citadel/code/modules/admin/chat_commands.dm @@ -4,7 +4,7 @@ /datum/tgs_chat_command/wheelofsalt/Run(datum/tgs_chat_user/sender, params) var/saltresult = "The wheel of salt [pick("clatters","vibrates","clanks","groans","moans","squeaks","emits a[pick(" god-forsaken"," lewd"," creepy"," generic","n orgasmic")] [pick("airhorn","bike horn","trumpet","clown","latex","vore","dog")] noise")] as it spins violently... And it seems the salt of the day is the " - var/saltprimarysubject = "[pick("combat","medical","grab","furry","wall","orgasm","cat","ERP","lizard","dog","latex","vision cone","atmospherics","table","chem","vore","dogborg","Skylar Lineman","Mekhi Anderson","Peppermint","rework","cum","dick","cockvore")]" - var/saltsecondarysubject = "[pick("rework","changes","r34","ban","removal","addition","leak","proposal","fanart","introduction","tabling","ERP")]" + var/saltprimarysubject = "[pick("combat","medical","grab","furry","wall","orgasm","cat","ERP","lizard","dog","latex","vision cone","atmospherics","table","chem","vore","dogborg","Skylar Lineman","Mekhi Anderson","Peppermint","rework","cum","dick","cockvore","Medihound","sleeper","belly sleeper","door wires","flightsuit","coder privilege","Developer abuse","ban reason","github self merge")]" + var/saltsecondarysubject = "[pick("rework","changes","r34","ban","removal","addition","leak","proposal","fanart","introduction","tabling","ERP","bikeshedding","sprites","semen keg","argument")]" saltresult += "[saltprimarysubject] [saltsecondarysubject]" return "[saltresult]!" diff --git a/modular_citadel/code/modules/client/loadout/__donator.dm b/modular_citadel/code/modules/client/loadout/__donator.dm index 8135532d85..28ff93c05a 100644 --- a/modular_citadel/code/modules/client/loadout/__donator.dm +++ b/modular_citadel/code/modules/client/loadout/__donator.dm @@ -331,4 +331,11 @@ datum/gear/darksabresheath name = "Divine robes" category = SLOT_W_UNIFORM path = /obj/item/clothing/under/lunasune - ckeywhitelist = list("invader4352") \ No newline at end of file + ckeywhitelist = list("invader4352") + +/datum/gear/gothcoat + name = "Goth Coat" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/suit/gothcoat + ckeywhitelist = list("norko") + diff --git a/modular_citadel/code/modules/vore/eating/belly_obj_vr.dm b/modular_citadel/code/modules/vore/eating/belly_obj_vr.dm index 2ae5308835..1aa8122be5 100644 --- a/modular_citadel/code/modules/vore/eating/belly_obj_vr.dm +++ b/modular_citadel/code/modules/vore/eating/belly_obj_vr.dm @@ -48,6 +48,8 @@ var/tmp/list/items_preserved = list() // Stuff that wont digest so we shouldn't process it again. var/tmp/next_emote = 0 // When we're supposed to print our next emote, as a belly controller tick # var/tmp/recent_sound = FALSE // Prevent audio spam + var/tmp/last_hearcheck = 0 + var/tmp/list/hearing_mobs // Don't forget to watch your commas at the end of each line if you change these. var/list/struggle_messages_outside = list( @@ -167,7 +169,7 @@ //Sound w/ antispam flag setting if(!silent && !recent_sound) for(var/mob/M in get_hearers_in_view(5, get_turf(owner))) - if(M.client && M.client.prefs.cit_toggles & EATING_NOISES) + if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES)) playsound(get_turf(owner),"[src.vore_sound]",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED) recent_sound = TRUE @@ -200,7 +202,7 @@ AM.forceMove(destination) // Move the belly contents into the same location as belly's owner. count++ for(var/mob/M in get_hearers_in_view(5, get_turf(owner))) - if(M.client && M.client.prefs.cit_toggles & EATING_NOISES) + if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES)) playsound(get_turf(owner),"[src.release_sound]",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED) if(!silent) owner.visible_message("[owner] expels everything from their [lowertext(name)]!") @@ -220,7 +222,7 @@ items_preserved -= M if(release_sound) for(var/mob/H in get_hearers_in_view(5, get_turf(owner))) - if(H.client && H.client.prefs.cit_toggles & EATING_NOISES) + if(H.client && (H.client.prefs.cit_toggles & EATING_NOISES)) playsound(get_turf(owner),"[src.release_sound]",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED) if(istype(M,/mob/living)) @@ -296,7 +298,7 @@ target.nom_mob(content, target.owner) if(!silent) for(var/mob/M in get_hearers_in_view(5, get_turf(owner))) - if(M.client && M.client.prefs.cit_toggles & EATING_NOISES) + if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES)) playsound(get_turf(owner),"[src.vore_sound]",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED) owner.updateVRPanel() for(var/mob/living/M in contents) @@ -510,7 +512,7 @@ if(!silent) for(var/mob/M in get_hearers_in_view(5, get_turf(owner))) - if(M.client && M.client.prefs.cit_toggles & EATING_NOISES) + if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES)) playsound(get_turf(owner),"struggle_sound",35,0,-5,1,ignore_walls = FALSE,channel=CHANNEL_PRED) R.stop_sound_channel(CHANNEL_PRED) var/sound/prey_struggle = sound(get_sfx("prey_struggle")) diff --git a/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm b/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm index 8b8781cb02..6c528f75a9 100644 --- a/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm +++ b/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm @@ -45,6 +45,9 @@ ////////////////////////// Sound vars ///////////////////////////// var/sound/prey_digest = sound(get_sfx("digest_prey")) var/sound/prey_death = sound(get_sfx("death_prey")) + var/sound/pred_digest = sound(get_sfx("digest_pred")) + var/sound/pred_death = sound(get_sfx("death_pred")) + var/turf/source = get_turf(owner) ///////////////////////////// DM_HOLD ///////////////////////////// @@ -55,12 +58,18 @@ else if(digest_mode == DM_DIGEST) for (var/mob/living/M in contents) if(prob(25)) - M.stop_sound_channel(CHANNEL_DIGEST) - for(var/mob/H in get_hearers_in_view(5, get_turf(owner))) - if(H.client && H.client.prefs.cit_toggles & DIGESTION_NOISES) - playsound(get_turf(owner),"digest_pred",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_DIGEST) - M.stop_sound_channel(CHANNEL_DIGEST) - M.playsound_local(get_turf(M), prey_digest, 45) + if((world.time - NORMIE_HEARCHECK) > last_hearcheck) + LAZYCLEARLIST(hearing_mobs) + for(var/mob/H in get_hearers_in_view(3, source)) + if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) + continue + LAZYADD(hearing_mobs, H) + last_hearcheck = world.time + for(var/mob/H in hearing_mobs) + if(!isbelly(H.loc)) + H.playsound_local(source, null, 45, falloff = 0, S = pred_digest) + else if(H in contents) + H.playsound_local(source, null, 65, falloff = 0, S = prey_digest) //Pref protection! if (!M.digestable || M.absorbed) @@ -86,13 +95,19 @@ M.visible_message("You watch as [owner]'s form loses its additions.") owner.nutrition += 400 // so eating dead mobs gives you *something*. - M.stop_sound_channel(DIGESTION_NOISES) - for(var/mob/H in get_hearers_in_view(5, get_turf(owner))) - if(H.client && H.client.prefs.cit_toggles & DIGESTION_NOISES) - playsound(get_turf(owner),"death_pred",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_DIGEST) - M.stop_sound_channel(DIGESTION_NOISES) + if((world.time - NORMIE_HEARCHECK) > last_hearcheck) + LAZYCLEARLIST(hearing_mobs) + for(var/mob/H in get_hearers_in_view(3, source)) + if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) + continue + LAZYADD(hearing_mobs, H) + last_hearcheck = world.time + for(var/mob/H in hearing_mobs) + if(!isbelly(H.loc)) + H.playsound_local(source, null, 45, falloff = 0, S = pred_death) + else if(H in contents) + H.playsound_local(source, null, 65, falloff = 0, S = prey_death) M.stop_sound_channel(CHANNEL_PREYLOOP) - M.playsound_local(get_turf(M), prey_death, 65) digestion_death(M) owner.update_icons() continue @@ -115,12 +130,18 @@ if(digest_mode == DM_HEAL) for (var/mob/living/M in contents) if(prob(25)) - M.stop_sound_channel(CHANNEL_DIGEST) - for(var/mob/H in get_hearers_in_view(5, get_turf(owner))) - if(H.client && H.client.prefs.cit_toggles & DIGESTION_NOISES) - playsound(get_turf(owner),"digest_pred",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_DIGEST) - M.stop_sound_channel(CHANNEL_DIGEST) - M.playsound_local(get_turf(M), prey_digest, 65) + if((world.time - NORMIE_HEARCHECK) > last_hearcheck) + LAZYCLEARLIST(hearing_mobs) + for(var/mob/H in get_hearers_in_view(3, source)) + if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) + continue + LAZYADD(hearing_mobs, H) + last_hearcheck = world.time + for(var/mob/H in hearing_mobs) + if(!isbelly(H.loc)) + H.playsound_local(source, null, 45, falloff = 0, S = pred_digest) + else if(H in contents) + H.playsound_local(source, null, 65, falloff = 0, S = prey_digest) if(M.stat != DEAD) if(owner.nutrition >= NUTRITION_LEVEL_STARVING && (M.health < M.maxHealth)) @@ -132,14 +153,19 @@ ////////////////////////// DM_NOISY ///////////////////////////////// //for when you just want people to squelch around if(digest_mode == DM_NOISY) - for (var/mob/living/M in contents) - if(prob(35)) - M.stop_sound_channel(CHANNEL_DIGEST) - for(var/mob/H in get_hearers_in_view(5, get_turf(owner))) - if(H.client && H.client.prefs.cit_toggles & DIGESTION_NOISES) - playsound(get_turf(owner),"digest_pred",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_DIGEST) - M.stop_sound_channel(CHANNEL_PRED) - M.playsound_local(get_turf(M), prey_digest, 65) + if(prob(35)) + if((world.time - NORMIE_HEARCHECK) > last_hearcheck) + LAZYCLEARLIST(hearing_mobs) + for(var/mob/H in get_hearers_in_view(3, source)) + if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) + continue + LAZYADD(hearing_mobs, H) + last_hearcheck = world.time + for(var/mob/H in hearing_mobs) + if(!isbelly(H.loc)) + H.playsound_local(source, null, 45, falloff = 0, S = pred_digest) + else if(H in contents) + H.playsound_local(source, null, 65, falloff = 0, S = prey_digest) //////////////////////////// DM_ABSORB //////////////////////////// @@ -147,13 +173,19 @@ for (var/mob/living/M in contents) - if(prob(10)) //Less often than gurgles. People might leave this on forever. - M.stop_sound_channel(CHANNEL_DIGEST) - for(var/mob/H in get_hearers_in_view(5, get_turf(owner))) - if(H.client && H.client.prefs.toggles & DIGESTION_NOISES) - playsound(get_turf(owner),"digest_pred",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_DIGEST) - M.stop_sound_channel(CHANNEL_PRED) - M.playsound_local(get_turf(M), prey_digest, 65) + if(prob(10))//Less often than gurgles. People might leave this on forever. + if((world.time - NORMIE_HEARCHECK) > last_hearcheck) + LAZYCLEARLIST(hearing_mobs) + for(var/mob/H in get_hearers_in_view(3, source)) + if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) + continue + LAZYADD(hearing_mobs, H) + last_hearcheck = world.time + for(var/mob/H in hearing_mobs) + if(!isbelly(H.loc)) + H.playsound_local(source, null, 45, falloff = 0, S = pred_digest) + else if(H in contents) + H.playsound_local(source, null, 65, falloff = 0, S = prey_digest) if(M.absorbed) continue @@ -180,12 +212,18 @@ if(digest_mode == DM_DRAGON) for (var/mob/living/M in contents) if(prob(55)) //if you're hearing this, you're a vore ho anyway. - M.stop_sound_channel(CHANNEL_DIGEST) - for(var/mob/H in get_hearers_in_view(5, get_turf(owner))) - if(H.client && H.client.prefs.cit_toggles & DIGESTION_NOISES) - playsound(get_turf(owner),"digest_pred",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_DIGEST) - M.stop_sound_channel(CHANNEL_DIGEST) - M.playsound_local(get_turf(M), prey_digest, 65) + if((world.time - NORMIE_HEARCHECK) > last_hearcheck) + LAZYCLEARLIST(hearing_mobs) + for(var/mob/H in get_hearers_in_view(3, source)) + if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) + continue + LAZYADD(hearing_mobs, H) + last_hearcheck = world.time + for(var/mob/H in hearing_mobs) + if(!isbelly(H.loc)) + H.playsound_local(source, null, 45, falloff = 0, S = pred_digest) + else if(H in contents) + H.playsound_local(source, null, 65, falloff = 0, S = prey_digest) //No digestion protection for megafauna. @@ -207,13 +245,18 @@ to_chat(owner, "[digest_alert_owner]") to_chat(M, "[digest_alert_prey]") M.visible_message("You watch as [owner]'s guts loudly rumble as it finishes off a meal.") - - M.stop_sound_channel(CHANNEL_DIGEST) - for(var/mob/H in get_hearers_in_view(5, get_turf(owner))) - if(H.client && H.client.prefs.cit_toggles & DIGESTION_NOISES) - playsound(get_turf(owner),"death_pred",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_DIGEST) - M.stop_sound_channel(CHANNEL_DIGEST) - M.playsound_local(get_turf(M), prey_death, 65) + if((world.time - NORMIE_HEARCHECK) > last_hearcheck) + LAZYCLEARLIST(hearing_mobs) + for(var/mob/H in get_hearers_in_view(3, source)) + if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) + continue + LAZYADD(hearing_mobs, H) + last_hearcheck = world.time + for(var/mob/H in hearing_mobs) + if(!isbelly(H.loc)) + H.playsound_local(source, null, 45, falloff = 0, S = pred_death) + else if(H in contents) + H.playsound_local(source, null, 65, falloff = 0, S = prey_death) M.spill_organs(FALSE,TRUE,TRUE) M.stop_sound_channel(CHANNEL_PREYLOOP) digestion_death(M) diff --git a/modular_citadel/icons/mob/digishoes.dmi b/modular_citadel/icons/mob/digishoes.dmi index 49988f88f6..a499db6262 100644 Binary files a/modular_citadel/icons/mob/digishoes.dmi and b/modular_citadel/icons/mob/digishoes.dmi differ diff --git a/modular_citadel/icons/mob/mam_ears.dmi b/modular_citadel/icons/mob/mam_ears.dmi index 270ecc11de..51ffd28bbc 100644 Binary files a/modular_citadel/icons/mob/mam_ears.dmi and b/modular_citadel/icons/mob/mam_ears.dmi differ diff --git a/modular_citadel/icons/mob/suit_digi.dmi b/modular_citadel/icons/mob/suit_digi.dmi index 9fe7a447aa..abaa0d1a42 100644 Binary files a/modular_citadel/icons/mob/suit_digi.dmi and b/modular_citadel/icons/mob/suit_digi.dmi differ diff --git a/strings/phobia.json b/strings/phobia.json index 3be9794bf9..3f56751333 100644 --- a/strings/phobia.json +++ b/strings/phobia.json @@ -268,5 +268,33 @@ "let go", "i'll catch you", "slip" + ], + +"anime": [ + "anime", + "manga", + "baka", + "desu", + "sugoi", + "katana", + "weeb", + "otaku", + "catgirl", + "catgirls", + "ninja", + "uguu", + "waifu", + "husbando", + "best girl", + "worst girl", + "subs", + "dubs", + "season two when", + "cosplay", + "nya", + "nyaa", + "neet", + "ora", + "~" ] -} +} \ No newline at end of file diff --git a/tools/mapmerge2/dmm.py b/tools/mapmerge2/dmm.py index 421ffb4cd1..1c1f907171 100644 --- a/tools/mapmerge2/dmm.py +++ b/tools/mapmerge2/dmm.py @@ -370,7 +370,7 @@ def _parse(map_raw_text): continue elif in_comment_line: continue - elif char == "\t": + elif char in "\r\t": continue if char == "/" and not in_quote_block: @@ -478,6 +478,9 @@ def _parse(map_raw_text): # grid block for char in it: + if char == "\r": + continue + if in_coord_block: if char == ",": if reading_coord == "x":