diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm new file mode 100644 index 0000000000..cc6e5bd49a --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm @@ -0,0 +1,3 @@ +/// Called from /mob/living/PushAM -- Called when this mob is about to push a movable, but before it moves +/// (aotm/movable/being_pushed) +#define COMSIG_LIVING_PUSHING_MOVABLE "living_pushing_movable" diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm new file mode 100644 index 0000000000..5d2a471c0a --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm @@ -0,0 +1,2 @@ +///From base of mob/living/MobBump() (mob/living) +#define COMSIG_LIVING_MOB_BUMP "living_mob_bump" diff --git a/code/__DEFINES/movement.dm b/code/__DEFINES/movement.dm index 5bf7de8647..bccbd425dd 100644 --- a/code/__DEFINES/movement.dm +++ b/code/__DEFINES/movement.dm @@ -13,7 +13,7 @@ GLOBAL_VAR_INIT(glide_size_multiplier, 1.0) /// Then that's multiplied by the global glide size multiplier. 1.25 by default feels pretty close to spot on. This is just to try to get byond to behave. /// The whole result is then clamped to within the range above. /// Not very readable but it works -#define DELAY_TO_GLIDE_SIZE(delay) (clamp(((32 / max((delay) / world.tick_lag, 1)) * GLOB.glide_size_multiplier), MIN_GLIDE_SIZE, MAX_GLIDE_SIZE)) +#define DELAY_TO_GLIDE_SIZE(delay) (clamp(((world.icon_size / max((delay) / world.tick_lag, 1)) * GLOB.glide_size_multiplier), MIN_GLIDE_SIZE, MAX_GLIDE_SIZE)) /// Enables smooth movement // #define SMOOTH_MOVEMENT diff --git a/code/__HELPERS/matrices/transform_matrix.dm b/code/__HELPERS/matrices/transform_matrix.dm index 251ef8151f..8f8a67535e 100644 --- a/code/__HELPERS/matrices/transform_matrix.dm +++ b/code/__HELPERS/matrices/transform_matrix.dm @@ -19,7 +19,7 @@ speed /= segments if(parallel) - animate(src, transform = matrices[1], time = speed, loops , flags = ANIMATION_PARALLEL) + animate(src, transform = matrices[1], time = speed, loops, flags = ANIMATION_PARALLEL) else animate(src, transform = matrices[1], time = speed, loops) diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 2771a3270b..0a9e68a790 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -379,6 +379,8 @@ parts += "[FOURSPACES]Shift Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]" parts += "[FOURSPACES]Station Integrity: [mode.station_was_nuked ? "Destroyed" : "[popcount["station_integrity"]]%"]" + if(mode.station_was_nuked && SSevents.holidays && SSevents.holidays[PRIDE_MONTH]) + parts += "[FOURSPACES]Gender revealed: [pick(500; "Male", 500; "Female", "Bigender", "Agender", "Demiboy", "Demigirl", "Genderfluid", "Pangender", "Xenogender", "Clown", 50; "What", 50; "Oh no.", 50; "Excuse me?")]" var/total_players = GLOB.joined_player_list.len if(total_players) parts+= "[FOURSPACES]Total Population: [total_players]" diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index b415b4720f..428784e953 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1176,25 +1176,22 @@ GLOBAL_REAL_VAR(list/stack_trace_storage) var/initialpixely = pixel_y var/shiftx = rand(-pixelshiftx,pixelshiftx) var/shifty = rand(-pixelshifty,pixelshifty) - animate(src, pixel_x = pixel_x + shiftx, pixel_y = pixel_y + shifty, time = 0.2, loop = duration) - pixel_x = initialpixelx - pixel_y = initialpixely + animate(src, pixel_x = shiftx, pixel_y = shifty, time = 0.2, loop = duration, flags = ANIMATION_RELATIVE) + animate(pixel_x = initialpixelx, pixel_y = initialpixely, time = 0.2) -/atom/proc/do_jiggle(targetangle = 45, timer = 20) +/atom/proc/do_jiggle(targetangle = 25, timer = 20) var/matrix/OM = matrix(transform) var/matrix/M = matrix(transform) - var/halftime = timer * 0.5 M.Turn(pick(-targetangle, targetangle)) - animate(src, transform = M, time = halftime, easing = ELASTIC_EASING) - animate(src, transform = OM, time = halftime, easing = ELASTIC_EASING) + animate(src, transform = M, time = timer * 0.1, easing = BACK_EASING | EASE_IN) + animate(transform = OM, time = timer * 0.4, easing = ELASTIC_EASING) /atom/proc/do_squish(squishx = 1.2, squishy = 0.6, timer = 20) var/matrix/OM = matrix(transform) var/matrix/M = matrix(transform) - var/halftime = timer * 0.5 M.Scale(squishx, squishy) - animate(src, transform = M, time = halftime, easing = BOUNCE_EASING) - animate(src, transform = OM, time = halftime, easing = BOUNCE_EASING) + animate(src, transform = M, time = timer * 0.5, easing = ELASTIC_EASING) + animate(transform = OM, time = timer * 0.5, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL) /proc/weightclass2text(var/w_class) switch(w_class) diff --git a/code/__SPLURTCODE/DEFINES/cooldowns.dm b/code/__SPLURTCODE/DEFINES/cooldowns.dm new file mode 100644 index 0000000000..2979db3592 --- /dev/null +++ b/code/__SPLURTCODE/DEFINES/cooldowns.dm @@ -0,0 +1,10 @@ +/* + + Read code\__DEFINES\cooldowns.dm + +*/ + +//INDEXES +#define COOLDOWN_DOMINANT_SNAP "dominant_snap" +#define COOLDOWN_DOMINANT_EXAMINE "dominant_examine" +#define COOLDOWN_EMOTE_FART "emote_fart" diff --git a/code/__SPLURTCODE/DEFINES/dcs/signals.dm b/code/__SPLURTCODE/DEFINES/dcs/signals.dm new file mode 100644 index 0000000000..4b4f351e72 --- /dev/null +++ b/code/__SPLURTCODE/DEFINES/dcs/signals.dm @@ -0,0 +1,6 @@ +#define COMSIG_MOB_EMOTE "mob_emote" // from /mob/emote(): (proc args list) + // used to access COMSIG_MOB_SAY argslist + #define EMOTE_ACT 1 + #define EMOTE_MTYPE 2 + #define EMOTE_MESSAGE 3 + #define EMOTE_INTENTIONAL 4 diff --git a/code/__SPLURTCODE/DEFINES/quirks.dm b/code/__SPLURTCODE/DEFINES/quirks.dm new file mode 100644 index 0000000000..9353f87dc7 --- /dev/null +++ b/code/__SPLURTCODE/DEFINES/quirks.dm @@ -0,0 +1,3 @@ +//Dominant/Well-trained quirks +#define DOMINANT_DETECT_RANGE 5 +#define DOMINANT_SNAP_COOLDOWN 10 SECONDS diff --git a/code/__SPLURTCODE/DEFINES/spans.dm b/code/__SPLURTCODE/DEFINES/spans.dm index 9e004d3972..d3a5934d3b 100644 --- a/code/__SPLURTCODE/DEFINES/spans.dm +++ b/code/__SPLURTCODE/DEFINES/spans.dm @@ -1,2 +1,3 @@ #define span_userlove(str) ("" + str + "") #define span_love(str) ("" + str + "") +#define span_lewd(str) ("" + str + "") diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 692f2317ef..d3d0fb32b6 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -60,7 +60,7 @@ if(client && hud_used) hud_used.reorganize_alerts() thealert.transform = matrix(32, 6, MATRIX_TRANSLATE) - animate(thealert, transform = matrix(), time = 2.5, easing = CUBIC_EASING) + animate(thealert, transform = matrix(), time = 2.5, easing = BACK_EASING) if(thealert.timeout) addtimer(CALLBACK(src, .proc/alert_timeout, thealert, category), thealert.timeout) diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm index ce581685ed..8f237c4a71 100644 --- a/code/_onclick/hud/radial.dm +++ b/code/_onclick/hud/radial.dm @@ -178,7 +178,7 @@ GLOBAL_LIST_EMPTY(radial_menus) starting.Scale(0.1,0.1) E.transform = starting var/matrix/TM = matrix() - animate(E,pixel_x = px,pixel_y = py, transform = TM, time = timing) + animate(E,pixel_x = px,pixel_y = py, transform = TM, time = timing, easing = SINE_EASING | EASE_OUT) else E.pixel_y = py E.pixel_x = px diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 8f3a7ef02c..23486cac29 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -126,6 +126,8 @@ return DISCARD_LAST_ACTION user.do_attack_animation(O) O.attacked_by(src, user) + if(force >= 20) + shake_camera(user, ((force - 15) * 0.01 + 1), ((force - 15) * 0.01)) /atom/movable/proc/attacked_by() return diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 1a5d54a306..79b3010b85 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -320,11 +320,11 @@ SUBSYSTEM_DEF(vote) admintext += "\nIt should be noted that this is not a raw tally of votes but rather the median score plus a tiebreaker!" for(var/i=1,i<=choices.len,i++) var/votes = choices[choices[i]] - admintext += "\n[choices[i]]: [votes]" + admintext += "\n[choices[i]]: [votes ? votes : "0"]" //This is raw data, but the raw data is null by default. If ya don't compensate for it, then it'll look weird! else for(var/i=1,i<=scores.len,i++) var/score = scores[scores[i]] - admintext += "\n[scores[i]]: [score]" + admintext += "\n[scores[i]]: [score ? score : "0"]" message_admins(admintext) return . diff --git a/code/datums/chatmessage.dm b/code/datums/chatmessage.dm index 5eb89f4c10..f4a979c510 100644 --- a/code/datums/chatmessage.dm +++ b/code/datums/chatmessage.dm @@ -202,6 +202,7 @@ message.maptext_height = mheight message.maptext_x = (CHAT_MESSAGE_WIDTH - owner.bound_width) * -0.5 message.maptext = MAPTEXT(complete_text) + message.pixel_x = -owner.pixel_x //Dogborgs and other wide boys have a pixel offset. This accounts for that // View the message LAZYADDASSOC(owned_by.seen_messages, message_loc, src) @@ -212,10 +213,6 @@ scheduled_destruction = world.time + (lifespan - CHAT_MESSAGE_EOL_FADE) enter_subsystem() - var/mob/living/silicon/robot/R = target - if(iscyborg(R)) - if((R.module.dogborg == TRUE || R.dogborg == TRUE) && isturf(R.loc)) //I hate whoever that thought that putting two types of dogborg that don't even sync up properly was good - message.pixel_x = 16 /** * Applies final animations to overlay CHAT_MESSAGE_EOL_FADE deciseconds prior to message deletion diff --git a/code/datums/components/bouncy.dm b/code/datums/components/bouncy.dm index fed603410e..3c4e228b59 100644 --- a/code/datums/components/bouncy.dm +++ b/code/datums/components/bouncy.dm @@ -32,7 +32,7 @@ var/atom/movable/A = parent switch(rand(1, 3)) if(1) - A.do_jiggle(45 + rand(-10, 10) * bouncy_mod, 14) + A.do_jiggle(25 + rand(-5, 5) * bouncy_mod, 14) if(2) var/min_b = 0.6/bouncy_mod var/max_b = 1.2 * bouncy_mod diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm index 98bbdbed05..40daac88cf 100644 --- a/code/datums/components/storage/storage.dm +++ b/code/datums/components/storage/storage.dm @@ -432,25 +432,26 @@ if(M.incapacitated() || !M.canUseStorage()) return var/atom/A = parent - A.add_fingerprint(M) // this must come before the screen objects only block, dunno why it wasn't before if(over_object == M) user_show_to_mob(M, trigger_on_found = TRUE) if(isrevenant(M)) INVOKE_ASYNC(GLOBAL_PROC, .proc/RevenantThrow, over_object, M, source) return + if(check_locked(null, M) || !M.CanReach(A) || (!M.CanReach(over_object) && !istype(over_object, /atom/movable/screen))) + return + playsound(A, "rustle", 50, TRUE, -5) + A.do_jiggle() + A.add_fingerprint(M) if(!istype(over_object, /atom/movable/screen)) INVOKE_ASYNC(src, .proc/dump_content_at, over_object, M) return if(A.loc != M) return - playsound(A, "rustle", 50, TRUE, -5) - A.do_jiggle() if(istype(over_object, /atom/movable/screen/inventory/hand)) var/atom/movable/screen/inventory/hand/H = over_object M.putItemFromInventoryInHandIfPossible(A, H.held_index) return - A.add_fingerprint(M) /datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE, trigger_on_found = FALSE) var/atom/A = parent diff --git a/code/datums/components/virtual_reality.dm b/code/datums/components/virtual_reality.dm index 56e06e3582..c0e6e9dba6 100644 --- a/code/datums/components/virtual_reality.dm +++ b/code/datums/components/virtual_reality.dm @@ -84,9 +84,9 @@ if(VR) VR.level_below = src level_above = VR - M.transfer_ckey(vr_M, FALSE) mastermind = M.mind mastermind.current.audiovisual_redirect = parent + M.transfer_ckey(vr_M, FALSE) RegisterSignal(mastermind, COMSIG_PRE_MIND_TRANSFER, .proc/switch_player) RegisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING), .proc/game_over) RegisterSignal(M, COMSIG_MOB_PRE_PLAYER_CHANGE, .proc/player_hijacked) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 1de7a1576e..4077f86e52 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -1322,7 +1322,7 @@ filters += filter(arglist(arguments)) UNSETEMPTY(filter_data) -/atom/proc/transition_filter(name, time, list/new_params, easing, loop) +/atom/proc/transition_filter(name, time, list/new_params, easing, loop, parallel = TRUE) var/filter = get_filter(name) if(!filter) return @@ -1333,7 +1333,7 @@ for(var/thing in new_params) params[thing] = new_params[thing] - animate(filter, new_params, time = time, easing = easing, loop = loop) + animate(filter, new_params, time = time, easing = easing, loop = loop, flags = (parallel ? ANIMATION_PARALLEL : 0)) for(var/param in params) filter_data[name][param] = params[param] diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 4b137d8b60..0323217341 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -605,11 +605,11 @@ if(throwing && !throw_override) return if(on && !(movement_type & FLOATING)) - animate(src, pixel_y = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) - animate(pixel_y = -2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) + animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) + animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE) setMovetype(movement_type | FLOATING) else if (!on && (movement_type & FLOATING)) - animate(src, pixel_y = initial(pixel_y), time = 10) + animate(src, pixel_z = initial(pixel_y), time = 10) setMovetype(movement_type & ~FLOATING) floating_need_update = FALSE // assume it's done @@ -775,4 +775,4 @@ M.Turn(pick(-30, 30)) animate(I, alpha = 175, pixel_x = to_x, pixel_y = to_y, time = 3, transform = M, easing = CUBIC_EASING) sleep(1) - animate(I, alpha = 0, transform = matrix(), time = 1) + animate(I, alpha = 0, transform = matrix(), time = 1, flags = ANIMATION_PARALLEL) diff --git a/code/game/objects/items/pneumaticCannon.dm b/code/game/objects/items/pneumaticCannon.dm index 595b24d214..2b0b8da670 100644 --- a/code/game/objects/items/pneumaticCannon.dm +++ b/code/game/objects/items/pneumaticCannon.dm @@ -205,6 +205,10 @@ if(!throw_item(target, I, user)) break + if(user) + shake_camera(user, (pressureSetting * 0.75 + 1), (pressureSetting * 0.75)) + + /obj/item/pneumatic_cannon/proc/throw_item(turf/target, obj/item/I, mob/user) if(!istype(I)) return FALSE diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index d48ddf880a..c1f20605a0 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -67,7 +67,7 @@ /obj/structure/proc/do_climb(atom/movable/A) if(climbable) density = FALSE - . = step(A,get_dir(A,src.loc)) + . = step(A, (A.loc == loc ? dir : get_dir(A,src.loc))) density = TRUE /obj/structure/proc/climb_structure(mob/living/user) diff --git a/code/game/sound.dm b/code/game/sound.dm index 38886e4908..02c2936f8d 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -110,7 +110,11 @@ distance_multiplier - Can be used to multiply the distance at which the sound is */ /mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff_exponent = SOUND_FALLOFF_EXPONENT, channel = 0, pressure_affected = TRUE, sound/S, max_distance, - falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, distance_multiplier = SOUND_DEFAULT_DISTANCE_MULTIPLIER, envwet = -10000, envdry = 0) + falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, distance_multiplier = SOUND_DEFAULT_DISTANCE_MULTIPLIER, envwet = -10000, envdry = 0, virtual_hearer) + if(audiovisual_redirect) + virtual_hearer = get_turf(src) + audiovisual_redirect.playsound_local(turf_source, soundin, vol, vary, frequency, falloff_exponent, channel, pressure_affected, S, max_distance, falloff_distance, distance_multiplier, max(0, envwet), -10000, virtual_hearer) + //No return here, as we want to deliberately support the possibility of shenanigans in which mobs with clients can have active AV redirects to completely different players if(!client) return @@ -134,7 +138,7 @@ distance_multiplier - Can be used to multiply the distance at which the sound is S.frequency = get_rand_frequency() if(isturf(turf_source)) - var/turf/T = get_turf(src) + var/turf/T = virtual_hearer || get_turf(src) //sound volume falloff with distance var/distance = get_dist(T, turf_source) diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm index a6a30ba96e..1a3997272a 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm @@ -66,9 +66,21 @@ icon_state = "nuclearbomb_base" anchored = TRUE //stops it being moved +/obj/machinery/nuclearbomb/selfdestruct/Initialize(mapload) + . = ..() + if(SSevents.holidays && SSevents.holidays[PRIDE_MONTH] && prob(10)) + name = "station-wide gender-reveal terminal" + desc = "For when the whole sector deserves to know a gender. But of whom? Don't ask." + /obj/machinery/nuclearbomb/syndicate //ui_style = "syndicate" // actually the nuke op bomb is a stole nt bomb +/obj/machinery/nuclearbomb/syndicate/Initialize(mapload) + . = ..() + if(SSevents.holidays && SSevents.holidays[PRIDE_MONTH] && prob(50)) + name = "tactical gender-reveal device" + desc = "\"But whose gender is it revealing?\" you ponder. Don't worry. That comes later." + /obj/machinery/nuclearbomb/syndicate/get_cinematic_type(off_station) var/datum/game_mode/nuclear/NM = SSticker.mode switch(off_station) diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index 6fc0fabf31..d3ad2ca4c7 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -360,3 +360,12 @@ desc = "Thin, pretty gloves intended for use in sexy feminine attire. A tag on the hem claims they pair great with black stockings." icon_state = "eveningblack" item_state = "eveningblack" + +/obj/item/clothing/gloves/polymaid + name = "polychromic maid gloves" + desc = "Colourable maid gloves!" + icon_state = "maid_arms" + +/obj/item/clothing/gloves/polymaid/ComponentInitialize() + . = ..() + AddElement(/datum/element/polychromic, list("#333333", "#FFFFFF"), 2) diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index 4e7ccb7111..f3868f703f 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -477,6 +477,15 @@ item_state = "maid" dynamic_hair_suffix = "" +/obj/item/clothing/head/maid/polychromic + name = "polychromic maid headband" + icon_state = "polymaid" + item_state = "polymaid" + +/obj/item/clothing/head/maid/polychromic/ComponentInitialize() + . = ..() + AddElement(/datum/element/polychromic, list("#333333", "#FFFFFF"), 2) + /obj/item/clothing/head/widered name = "Wide red hat" desc = "It is both wide, and red. Stylish!" diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm index 7f4de22bb4..7ac2f65205 100644 --- a/code/modules/clothing/neck/_neck.dm +++ b/code/modules/clothing/neck/_neck.dm @@ -259,6 +259,15 @@ name = "Collar Key" desc = "A key for a tiny lock on a collar or bag." +/obj/item/clothing/neck/maid + name = "polychromic maid collar" + desc = "A collar that goes with the polychromic maid outfit." + icon_state = "maid_neck" + +/obj/item/clothing/neck/maid/ComponentInitialize() + . = ..() + AddElement(/datum/element/polychromic, list("#333333", "#FFFFFF"), 2) + ////////////// //DOPE BLING// ////////////// diff --git a/code/modules/clothing/suits/_suits.dm b/code/modules/clothing/suits/_suits.dm index 41bdb3d5ca..6806f73c65 100644 --- a/code/modules/clothing/suits/_suits.dm +++ b/code/modules/clothing/suits/_suits.dm @@ -26,15 +26,12 @@ var/mob/living/carbon/human/M = loc if(ishuman(M) && M.w_uniform) var/obj/item/clothing/under/U = M.w_uniform - //SKYRAT EDIT + //SANDSTORM EDIT if(istype(U) && length(U.attached_accessories)) - var/please_overlay = FALSE for(var/obj/item/clothing/accessory/attached in U.attached_accessories) if(attached.above_suit) - please_overlay = TRUE - if(please_overlay) - . += U.accessory_overlay - //SKYRAT EDIT END + . += U.accessory_overlays + //SANDSTORM EDIT END /obj/item/clothing/suit/update_clothes_damaged_state() ..() diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm index d9a090a9a7..c87095e5ff 100644 --- a/code/modules/clothing/under/_under.dm +++ b/code/modules/clothing/under/_under.dm @@ -22,11 +22,11 @@ var/adjusted = NORMAL_STYLE var/alt_covers_chest = FALSE // for adjusted/rolled-down jumpsuits, FALSE = exposes chest and arms, TRUE = exposes arms only var/dummy_thick = FALSE // is able to hold accessories on its item - //SKYRAT EDIT - Removed the old attached accessory system. We use a list of accessories instead. - var/list/obj/item/clothing/accessory/attached_accessories = list() + //SANDSTORM EDIT - Removed the old attached accessory system. We use a list of accessories instead. var/max_accessories = 3 - //SKYRAT EDIT END - var/mutable_appearance/accessory_overlay + var/list/obj/item/clothing/accessory/attached_accessories = list() + var/list/mutable_appearance/accessory_overlays = list() + //SANDSTORM EDIT END /obj/item/clothing/under/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE) . = ..() @@ -36,8 +36,8 @@ . += mutable_appearance('icons/effects/item_damage.dmi', "damageduniform") if(blood_DNA) . += mutable_appearance('icons/effects/blood.dmi', "uniformblood", color = blood_DNA_to_color(), blend_mode = blood_DNA_to_blend()) - if(accessory_overlay) - . += accessory_overlay + if(length(accessory_overlays)) + . += accessory_overlays /obj/item/clothing/under/attackby(obj/item/I, mob/user, params) if((sensordamage || (has_sensor < HAS_SENSORS && has_sensor != NO_SENSORS)) && istype(I, /obj/item/stack/cable_coil)) @@ -164,14 +164,18 @@ if((flags_inv & HIDEACCESSORY) || (A.flags_inv & HIDEACCESSORY)) return TRUE - //SKYRAT EDIT - accessory_overlay = mutable_appearance('icons/mob/clothing/accessories.dmi', "blank") + //SANDSTORM EDIT + accessory_overlays = list(mutable_appearance('icons/mob/clothing/accessories.dmi', "blank")) for(var/obj/item/clothing/accessory/attached_accessory in attached_accessories) - var/mutable_appearance/Y = mutable_appearance(attached_accessory.mob_overlay_icon, attached_accessory.icon_state, ABOVE_HUD_LAYER) - Y.alpha = attached_accessory.alpha - Y.color = attached_accessory.color - accessory_overlay.add_overlay(Y) - //SKYRAT EDIT END + var/datum/element/polychromic/polychromic = LAZYACCESS(attached_accessory.comp_lookup, "item_worn_overlays") + if(!polychromic) + var/mutable_appearance/accessory_overlay = mutable_appearance(attached_accessory.mob_overlay_icon, attached_accessory.item_state || attached_accessory.icon_state, ABOVE_HUD_LAYER) + accessory_overlay.alpha = attached_accessory.alpha + accessory_overlay.color = attached_accessory.color + accessory_overlays += accessory_overlay + else + polychromic.apply_worn_overlays(attached_accessory, FALSE, attached_accessory.mob_overlay_icon, attached_accessory.item_state || attached_accessory.icon_state, NONE, accessory_overlays) + //SANDSTORM EDIT END if(ishuman(loc)) var/mob/living/carbon/human/H = loc diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm index 63d09a89de..e39c48f80f 100644 --- a/code/modules/clothing/under/accessories.dm +++ b/code/modules/clothing/under/accessories.dm @@ -48,9 +48,9 @@ TakeComponent(detached_pockets) U.armor = U.armor.detachArmor(armor) - //SKYRAT EDIT + //SANDSTORM EDIT current_uniform = null - //SKYRAT EDIT END + //SANDSTORM EDIT END if(isliving(user)) on_uniform_dropped(U, user) @@ -61,18 +61,23 @@ pixel_y = 0 layer = initial(layer) plane = initial(plane) - U.accessory_overlay = null U.cut_overlays() U.attached_accessories -= src + U.accessory_overlays = list() if(length(U.attached_accessories)) - U.accessory_overlay = mutable_appearance('icons/mob/clothing/accessories.dmi', "blank", WRISTS_LAYER, U.plane) + U.accessory_overlays = list(mutable_appearance('icons/mob/clothing/accessories.dmi', "blank")) for(var/obj/item/clothing/accessory/attached_accessory in U.attached_accessories) attached_accessory.force_unto(U) - var/mutable_appearance/Y = mutable_appearance(attached_accessory.mob_overlay_icon, attached_accessory.icon_state, WRISTS_LAYER, U.plane) - Y.alpha = attached_accessory.alpha - Y.color = attached_accessory.color - U.accessory_overlay.add_overlay(Y) -//SKYRAT EDIT + var/datum/element/polychromic/polychromic = LAZYACCESS(attached_accessory.comp_lookup, "item_worn_overlays") + if(!polychromic) + var/mutable_appearance/accessory_overlay = mutable_appearance(attached_accessory.mob_overlay_icon, attached_accessory.item_state || attached_accessory.icon_state, ABOVE_HUD_LAYER) + accessory_overlay.alpha = attached_accessory.alpha + accessory_overlay.color = attached_accessory.color + U.accessory_overlays += accessory_overlay + else + polychromic.apply_worn_overlays(attached_accessory, FALSE, attached_accessory.mob_overlay_icon, attached_accessory.item_state || attached_accessory.icon_state, NONE, U.accessory_overlays) + +//SANDSTORM EDIT /obj/item/clothing/accessory/proc/force_unto(obj/item/clothing/under/U) layer = FLOAT_LAYER plane = FLOAT_PLANE @@ -98,7 +103,7 @@ pixel_x += rand(-16, 16) pixel_y += rand(-16, 16) U.add_overlay(src) -//SKYRAT EDIT END +//SANDSTORM EDIT END /obj/item/clothing/accessory/proc/on_uniform_equip(obj/item/clothing/under/U, user) return @@ -296,6 +301,15 @@ item_state = "maidapron" minimize_when_attached = FALSE +/obj/item/clothing/accessory/maidapron/polychromic + name = "polychromic maid apron" + icon_state = "polymaidapron" + item_state = "polymaidapron" + +/obj/item/clothing/accessory/maidapron/polychromic/ComponentInitialize() + . = ..() + AddElement(/datum/element/polychromic, list("#333333", "#FFFFFF"), 2) + /obj/item/clothing/accessory/sleevecrop name = "one sleeved crop top" desc = "Off the shoulder crop top, for those nights out partying." diff --git a/code/modules/food_and_drinks/recipes/drinks_recipes.dm b/code/modules/food_and_drinks/recipes/drinks_recipes.dm index 363e263ad4..efd9809e1d 100644 --- a/code/modules/food_and_drinks/recipes/drinks_recipes.dm +++ b/code/modules/food_and_drinks/recipes/drinks_recipes.dm @@ -1016,8 +1016,8 @@ /datum/chemical_reaction/pinktea name = "Strawberry Tea" - id = /datum/reagent/consumable/pinktea - results = list(/datum/reagent/consumable/pinktea = 5) + id = /datum/reagent/consumable/tea/pink + results = list(/datum/reagent/consumable/tea/pink = 5) required_reagents = list(/datum/reagent/consumable/strawberryjuice = 1, /datum/reagent/consumable/tea/arnold_palmer = 1, /datum/reagent/consumable/sugar = 1) /datum/chemical_reaction/catnip_tea diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 53a4b0e997..2dcb8ef98f 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -121,7 +121,8 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) remove_verb(src, /mob/dead/observer/verb/boo) remove_verb(src, /mob/dead/observer/verb/possess) - animate(src, pixel_y = 2, time = 10, loop = -1) + animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) + animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE) add_to_dead_mob_list() @@ -539,8 +540,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/stop_orbit(datum/component/orbiter/orbits) . = ..() //restart our floating animation after orbit is done. - pixel_y = 0 - animate(src, pixel_y = 2, time = 10, loop = -1) + pixel_z = 0 + animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) + animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE) /mob/dead/observer/verb/jumptomob() //Moves the ghost instead of just changing the ghosts's eye -Nodrak set category = "Ghost" diff --git a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm index 9563959ebc..ff4a7d2bba 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm @@ -51,7 +51,7 @@ // update_icons() //Handled in update_transform(), leaving this here as a reminder update_transform() -/mob/living/carbon/alien/humanoid/update_transform() //The old method of updating lying/standing was update_icons(). Aliens still expect that. +/mob/living/carbon/alien/humanoid/update_transform(do_animate) //The old method of updating lying/standing was update_icons(). Aliens still expect that. if(lying > 0) lying = 90 //Anything else looks silly ..() diff --git a/code/modules/mob/living/carbon/alien/larva/update_icons.dm b/code/modules/mob/living/carbon/alien/larva/update_icons.dm index e6e7e657e8..85416261c7 100644 --- a/code/modules/mob/living/carbon/alien/larva/update_icons.dm +++ b/code/modules/mob/living/carbon/alien/larva/update_icons.dm @@ -21,7 +21,7 @@ else icon_state = "larva[state]" -/mob/living/carbon/alien/larva/update_transform() //All this is handled in update_icons() +/mob/living/carbon/alien/larva/update_transform(do_animate) //All this is handled in update_icons() ..() return update_icons() diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index d4a701bc68..f44f4564d3 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -292,6 +292,14 @@ if(ishuman(src)) S = dna.species + //SPLURT EDIT - Headpat traits + if(M.has_quirk(/datum/quirk/dominant_aura) && H.has_quirk(/datum/quirk/well_trained)) + if(H.has_quirk(/datum/quirk/headpat_hater)) + H.remove_quirk(/datum/quirk/headpat_hater) + if(!H.has_quirk(/datum/quirk/headpat_slut)) + H.add_quirk(/datum/quirk/headpat_slut) + SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "dom_trained", /datum/mood_event/dominant/good_boy) + if(HAS_TRAIT(H, TRAIT_DISTANT)) //No mood buff since you're not really liking it. M.visible_message("[M] gives [H] a pat on the head to make [p_them()] feel better! They seem annoyed...", \ "You give [H] a pat on the head to make [p_them()] feel better! They seem annoyed as they're now glaring towards you...") @@ -315,12 +323,13 @@ "You give [src] a pat on the head to make [p_them()] feel better! They seem to like it way too much..", target = src, target_message = "[M] gives you a pat on the head to make you feel better!") SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "lewd_headpat", /datum/mood_event/lewd_headpat) - H.add_lust(5) //Headpats are hot af + H.handle_post_sex(5, null, null) //Headpats are hot af else M.visible_message("[M] gives [src] a pat on the head to make [p_them()] feel better!", \ "You give [src] a pat on the head to make [p_them()] feel better!", target = src, target_message = "[M] gives you a pat on the head to make you feel better!") SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "headpat", /datum/mood_event/headpat) + //SPLURT EDIT END if(!(client?.prefs.cit_toggles & NO_AUTO_WAG) && friendly_check) if(S?.can_wag_tail(src) && !dna.species.is_wagging_tail()) diff --git a/code/modules/mob/living/carbon/monkey/punpun.dm b/code/modules/mob/living/carbon/monkey/punpun.dm index c8b8dbbc9d..8fd7b45b65 100644 --- a/code/modules/mob/living/carbon/monkey/punpun.dm +++ b/code/modules/mob/living/carbon/monkey/punpun.dm @@ -46,6 +46,7 @@ ..() /mob/living/carbon/monkey/punpun/proc/Read_Memory() + var/saved_color if(fexists("data/npc_saves/Punpun.sav")) //legacy compatability to convert old format to new var/savefile/S = new /savefile("data/npc_saves/Punpun.sav") S["ancestor_name"] >> ancestor_name @@ -62,6 +63,9 @@ ancestor_chain = json["ancestor_chain"] relic_hat = json["relic_hat"] relic_mask = json["relic_hat"] + saved_color = json["color"] + if(!isnull(saved_color)) + add_atom_colour(json_decode(saved_color), FIXED_COLOUR_PRIORITY) /mob/living/carbon/monkey/punpun/proc/Write_Memory(dead, gibbed) var/json_file = file("data/npc_saves/Punpun.json") @@ -71,10 +75,12 @@ file_data["ancestor_chain"] = null file_data["relic_hat"] = null file_data["relic_mask"] = null + file_data["color"] = null else file_data["ancestor_name"] = ancestor_name ? ancestor_name : name file_data["ancestor_chain"] = dead ? ancestor_chain + 1 : ancestor_chain file_data["relic_hat"] = head ? head.type : null file_data["relic_mask"] = wear_mask ? wear_mask.type : null + file_data["color"] = color ? json_encode(color) : null fdel(json_file) WRITE_FILE(json_file, json_encode(file_data)) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 6efa32b48b..e9150f202d 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -81,6 +81,7 @@ //Called when we bump onto a mob /mob/living/proc/MobBump(mob/M) + SEND_SIGNAL(src, COMSIG_LIVING_MOB_BUMP, M) //Even if we don't push/swap places, we "touched" them, so spread fire spreadFire(M) @@ -88,6 +89,7 @@ return TRUE var/they_can_move = TRUE + if(isliving(M)) var/mob/living/L = M they_can_move = CHECK_MOBILITY(L, MOBILITY_MOVE) @@ -105,16 +107,16 @@ //Should stop you pushing a restrained person out of the way if(L.pulledby && L.pulledby != src && L.restrained()) if(!(world.time % 5)) - to_chat(src, "[L] is restrained, you cannot push past.") - return 1 + to_chat(src, span_warning("[L] is restrained, you cannot push past.")) + return TRUE if(L.pulling) if(ismob(L.pulling)) var/mob/P = L.pulling if(P.restrained()) if(!(world.time % 5)) - to_chat(src, "[L] is restraining [P], you cannot push past.") - return 1 + to_chat(src, span_warning("[L] is restraining [P], you cannot push past.")) + return TRUE //CIT CHANGES START HERE - makes it so resting stops you from moving through standing folks or over prone bodies without a short delay if(!CHECK_MOBILITY(src, MOBILITY_STAND)) @@ -142,7 +144,7 @@ //END OF CIT CHANGES if(moving_diagonally)//no mob swap during diagonal moves. - return 1 + return TRUE //handle micro bumping on help intent if(a_intent == INTENT_HELP) @@ -156,7 +158,8 @@ if(!too_strong) mob_swap = TRUE else - if(M.pulledby == src && a_intent == INTENT_GRAB) + //You can swap with the person you are dragging on grab intent, and restrained people in most cases + if(M.pulledby == src && !too_strong) mob_swap = TRUE //restrained people act if they were on 'help' intent to prevent a person being pulled from being separated from their puller else if((M.restrained() || M.a_intent == INTENT_HELP) && (restrained() || a_intent == INTENT_HELP)) @@ -164,8 +167,8 @@ if(mob_swap) //switch our position with M if(loc && !loc.Adjacent(M.loc)) - return 1 - now_pushing = 1 + return TRUE + now_pushing = TRUE var/oldloc = loc var/oldMloc = M.loc @@ -185,29 +188,33 @@ if(!M_passmob) M.pass_flags &= ~PASSMOB - now_pushing = 0 + now_pushing = FALSE if(!move_failed) - return 1 + return TRUE //okay, so we didn't switch. but should we push? //not if he's not CANPUSH of course if(!(M.status_flags & CANPUSH)) - return 1 + return TRUE if(handle_micro_bump_other(M)) return TRUE if(isliving(M)) var/mob/living/L = M if(HAS_TRAIT(L, TRAIT_PUSHIMMUNE)) - return 1 - //If they're a human, and they're not in help intent, block pushing - if(ishuman(M) && (M.a_intent != INTENT_HELP)) - return TRUE + return TRUE + if(M.a_intent != INTENT_HELP) + //If they're a human, and they're not in help intent, block pushing + if(ishuman(M)) + return TRUE + //if they are a cyborg, and they're alive and not in help intent, block pushing + if(iscyborg(M) && M.stat != DEAD) + return TRUE //anti-riot equipment is also anti-push for(var/obj/item/I in M.held_items) if(!istype(M, /obj/item/clothing)) if(prob(I.block_chance*2)) - return 1 + return TRUE /mob/living/get_photo_description(obj/item/camera/camera) var/list/mob_details = list() @@ -238,21 +245,40 @@ if(!client && (mob_size < MOB_SIZE_SMALL)) return now_pushing = TRUE - var/t = get_dir(src, AM) + SEND_SIGNAL(src, COMSIG_LIVING_PUSHING_MOVABLE, AM) + var/dir_to_target = get_dir(src, AM) + + // If there's no dir_to_target then the player is on the same turf as the atom they're trying to push. + // This can happen when a player is stood on the same turf as a directional window. All attempts to push + // the window will fail as get_dir will return 0 and the player will be unable to move the window when + // it should be pushable. + // In this scenario, we will use the facing direction of the /mob/living attempting to push the atom as + // a fallback. + if(!dir_to_target) + dir_to_target = dir + var/push_anchored = FALSE if((AM.move_resist * MOVE_FORCE_CRUSH_RATIO) <= force) - if(move_crush(AM, move_force, t)) + if(move_crush(AM, move_force, dir_to_target)) push_anchored = TRUE - if((AM.move_resist * MOVE_FORCE_FORCEPUSH_RATIO) <= force) //trigger move_crush and/or force_push regardless of if we can push it normally - if(force_push(AM, move_force, t, push_anchored)) + if((AM.move_resist * MOVE_FORCE_FORCEPUSH_RATIO) <= force) //trigger move_crush and/or force_push regardless of if we can push it normally + if(force_push(AM, move_force, dir_to_target, push_anchored)) push_anchored = TRUE + if(ismob(AM)) + var/mob/mob_to_push = AM + var/atom/movable/mob_buckle = mob_to_push.buckled + // If we can't pull them because of what they're buckled to, make sure we can push the thing they're buckled to instead. + // If neither are true, we're not pushing anymore. + if(mob_buckle && (mob_buckle.buckle_prevents_pull || (force < (mob_buckle.move_resist * MOVE_FORCE_PUSH_RATIO)))) + now_pushing = FALSE + return if((AM.anchored && !push_anchored) || (force < (AM.move_resist * MOVE_FORCE_PUSH_RATIO))) now_pushing = FALSE return - if (istype(AM, /obj/structure/window)) + if(istype(AM, /obj/structure/window)) var/obj/structure/window/W = AM if(W.fulltile) - for(var/obj/structure/window/win in get_step(W,t)) + for(var/obj/structure/window/win in get_step(W, dir_to_target)) now_pushing = FALSE return if(pulling == AM) @@ -260,8 +286,9 @@ var/current_dir if(isliving(AM)) current_dir = AM.dir - if(step(AM, t) && Process_Spacemove(t)) - step(src, t) + if(AM.Move(get_step(AM.loc, dir_to_target), dir_to_target, glide_size)) + AM.add_fingerprint(src) + Move(get_step(loc, dir_to_target), dir_to_target) if(current_dir) AM.setDir(current_dir) now_pushing = FALSE @@ -361,29 +388,33 @@ offset = GRAB_PIXEL_SHIFT_NECK if(GRAB_KILL) offset = GRAB_PIXEL_SHIFT_NECK - M.setDir(get_dir(M, src)) - switch(M.dir) - if(NORTH) - animate(M, pixel_x = 0, pixel_y = offset, 3) - if(SOUTH) - animate(M, pixel_x = 0, pixel_y = -offset, 3) - if(EAST) - if(M.lying == 270) //update the dragged dude's direction if we've turned - M.lying = 90 - M.update_transform() //force a transformation update, otherwise it'll take a few ticks for update_mobility() to do so - M.lying_prev = M.lying - animate(M, pixel_x = offset, pixel_y = 0, 3) - if(WEST) - if(M.lying == 90) - M.lying = 270 - M.update_transform() - M.lying_prev = M.lying - animate(M, pixel_x = -offset, pixel_y = 0, 3) + var/target_dir = get_dir(M, src) + M.setDir(target_dir) + var/target_x + var/target_y + if(target_dir & NORTH) + target_y += offset + if(target_dir & SOUTH) + target_y -= offset + if(target_dir & EAST) + target_x += offset + if(target_dir & WEST) + target_x -= offset + if(target_x || target_y) + if(0 < target_x && M.lying == 270) + M.lying = 90 + M.update_transform(FALSE) //force a transformation update, otherwise it'll take a few ticks for update_mobility() to do so + M.lying_prev = M.lying + if(0 > target_x && M.lying == 90) + M.lying = 270 + M.update_transform(FALSE) + M.lying_prev = M.lying + animate(M, pixel_x = target_x, pixel_y = target_y, time = 3, flags = ANIMATION_PARALLEL) /mob/living/proc/reset_pull_offsets(mob/living/M, override) if(!override && M.buckled) return - animate(M, pixel_x = 0, pixel_y = 0, 1) + animate(M, pixel_x = 0, pixel_y = 0, time = 3, flags = ANIMATION_PARALLEL) //mob verbs are a lot faster than object verbs //for more info on why this is not atom/pull, see examinate() in mob.dm @@ -901,12 +932,11 @@ if(anchored || (buckled && buckled.anchored)) fixed = 1 if(on && !(movement_type & FLOATING) && !fixed) - animate(src, pixel_y = pixel_y + 2, time = 10, loop = -1) - sleep(10) - animate(src, pixel_y = pixel_y - 2, time = 10, loop = -1) + animate(src, pixel_z = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) + animate(pixel_z = -4, time = 10, loop = -1, flags = ANIMATION_RELATIVE) setMovetype(movement_type | FLOATING) else if(((!on || fixed) && (movement_type & FLOATING))) - animate(src, pixel_y = get_standard_pixel_y_offset(lying), time = 10) + animate(src, pixel_z = get_standard_pixel_y_offset(lying), time = 10) setMovetype(movement_type & ~FLOATING) // The src mob is trying to strip an item from someone @@ -1005,7 +1035,7 @@ var/pixel_y_diff = rand(-amplitude/3, amplitude/3) var/final_pixel_x = get_standard_pixel_x_offset(lying) var/final_pixel_y = get_standard_pixel_y_offset(lying) - animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff , time = 2, loop = 6) + animate(src, pixel_x = pixel_x_diff, pixel_y = pixel_y_diff , time = 2, loop = 6, flags = ANIMATION_PARALLEL | ANIMATION_RELATIVE) animate(pixel_x = final_pixel_x , pixel_y = final_pixel_y , time = 2) floating_need_update = TRUE diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 49a60c0411..f9fcb35377 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -249,7 +249,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list( /mob/living/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source) SEND_SIGNAL(src, COMSIG_MOVABLE_HEAR, args) //parent calls can't overwrite the current proc args. - if(!client) + if(!client && !audiovisual_redirect) return var/deaf_message var/deaf_type diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 0d04d4b562..c1897c3c05 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -136,6 +136,7 @@ ..() /mob/living/simple_animal/pet/cat/Runtime/proc/Read_Memory() + var/saved_color if(fexists("data/npc_saves/Runtime.sav")) //legacy compatability to convert old format to new var/savefile/S = new /savefile("data/npc_saves/Runtime.sav") S["family"] >> family @@ -146,14 +147,21 @@ return var/list/json = json_decode(file2text(json_file)) family = json["family"] + saved_color = json["color"] if(isnull(family)) family = list() + if(!isnull(saved_color)) + add_atom_colour(json_decode(saved_color), FIXED_COLOUR_PRIORITY) /mob/living/simple_animal/pet/cat/Runtime/proc/Write_Memory(dead) var/json_file = file("data/npc_saves/Runtime.json") var/list/file_data = list() family = list() if(!dead) + if(color) + file_data["color"] = json_encode(color) + else + file_data["color"] = null for(var/mob/living/simple_animal/pet/cat/kitten/C in children) if(istype(C,type) || C.stat || !C.z || !C.butcher_results) //That last one is a work around for hologram cats continue @@ -161,6 +169,8 @@ family[C.type] += 1 else family[C.type] = 1 + else + file_data["color"] = null file_data["family"] = family fdel(json_file) WRITE_FILE(json_file, json_encode(file_data)) diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index bce46fe10d..748a182ba3 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -436,6 +436,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( /mob/living/simple_animal/pet/dog/corgi/Ian/proc/Read_Memory() set waitfor = FALSE + var/saved_color if(fexists("data/npc_saves/Ian.sav")) //legacy compatability to convert old format to new var/savefile/S = new /savefile("data/npc_saves/Ian.sav") S["age"] >> age @@ -450,12 +451,15 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( age = json["age"] record_age = json["record_age"] saved_head = json["saved_head"] + saved_color = json["color"] if(isnull(age)) age = 0 if(isnull(record_age)) record_age = 1 if(saved_head) place_on_head(new saved_head) + if(!isnull(saved_color)) + add_atom_colour(json_decode(saved_color), FIXED_COLOUR_PRIORITY) /mob/living/simple_animal/pet/dog/corgi/Ian/proc/Write_Memory(dead) var/json_file = file("data/npc_saves/Ian.json") @@ -470,10 +474,15 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( file_data["saved_head"] = inventory_head.type else file_data["saved_head"] = null + if(color) + file_data["color"] = json_encode(color) + else + file_data["color"] = null else file_data["age"] = 0 file_data["record_age"] = record_age file_data["saved_head"] = null + file_data["color"] = null fdel(json_file) WRITE_FILE(json_file, json_encode(file_data)) diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 1f12195ad6..c05aba8227 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -910,11 +910,13 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( speak += pick("...[longest_survival].", "The things I've seen!", "I have lived many lives!", "What are you before me?") desc += " Old as sin, and just as loud. Claimed to be [rounds_survived]." speak_chance = 20 //His hubris has made him more annoying/easier to justify killing - add_atom_colour("#EEEE22", FIXED_COLOUR_PRIORITY) + if(!color) + add_atom_colour("#EEEE22", FIXED_COLOUR_PRIORITY) else if(rounds_survived == longest_deathstreak) speak += pick("What are you waiting for!", "Violence breeds violence!", "Blood! Blood!", "Strike me down if you dare!") desc += " The squawks of [-rounds_survived] dead parrots ring out in your ears..." - add_atom_colour("#BB7777", FIXED_COLOUR_PRIORITY) + if(!color) + add_atom_colour("#BB7777", FIXED_COLOUR_PRIORITY) else if(rounds_survived > 0) speak += pick("...again?", "No, It was over!", "Let me out!", "It never ends!") desc += " Over [rounds_survived] shifts without a \"terrible\" \"accident\"!" @@ -947,6 +949,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( ..(gibbed) /mob/living/simple_animal/parrot/Poly/proc/Read_Memory() + var/saved_color if(fexists("data/npc_saves/Poly.sav")) //legacy compatability to convert old format to new var/savefile/S = new /savefile("data/npc_saves/Poly.sav") S["phrases"] >> speech_buffer @@ -963,8 +966,11 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( rounds_survived = json["roundssurvived"] longest_survival = json["longestsurvival"] longest_deathstreak = json["longestdeathstreak"] + saved_color = json["color"] if(!islist(speech_buffer)) speech_buffer = list() + if(!isnull(saved_color)) + add_atom_colour(json_decode(saved_color), FIXED_COLOUR_PRIORITY) /mob/living/simple_animal/parrot/Poly/proc/Write_Memory(dead) var/json_file = file("data/npc_saves/Poly.json") @@ -978,6 +984,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( file_data["longestdeathstreak"] = rounds_survived - 1 else file_data["longestdeathstreak"] = longest_deathstreak + file_data["color"] = null else file_data["roundssurvived"] = rounds_survived + 1 if(rounds_survived + 1 > longest_survival) @@ -985,6 +992,10 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( else file_data["longestsurvival"] = longest_survival file_data["longestdeathstreak"] = longest_deathstreak + if(color) + file_data["color"] = json_encode(color) + else + file_data["color"] = null fdel(json_file) WRITE_FILE(json_file, json_encode(file_data)) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 5b487f503e..1671c4bca9 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -482,7 +482,7 @@ update_action_buttons_icon() return mobility_flags -/mob/living/simple_animal/update_transform() +/mob/living/simple_animal/update_transform(do_animate) var/matrix/ntransform = matrix(transform) //aka transform.Copy() var/changed = 0 diff --git a/code/modules/mob/living/update_icons.dm b/code/modules/mob/living/update_icons.dm index d3264c93a2..4ad861bf2b 100644 --- a/code/modules/mob/living/update_icons.dm +++ b/code/modules/mob/living/update_icons.dm @@ -1,5 +1,5 @@ //IMPORTANT: Multiple animate() calls do not stack well, so try to do them all at once if you can. -/mob/living/update_transform() +/mob/living/update_transform(do_animate = TRUE) var/matrix/ntransform = matrix(transform) //aka transform.Copy() var/final_pixel_y = pixel_y var/changed = 0 @@ -25,5 +25,9 @@ resize = RESIZE_DEFAULT_SIZE if(changed) - animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, easing = EASE_IN|EASE_OUT) + if(do_animate) + animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, easing = EASE_IN|EASE_OUT, flags = ANIMATION_PARALLEL) + else + transform = ntransform + pixel_y = final_pixel_y floating_need_update = TRUE diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index f22c87913f..cfc2a6822a 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -141,7 +141,7 @@ return hearers -= ignored_mobs - if(target_message && target && istype(target) && target.client) + if(target_message && target && istype(target) && (target.client || target.audiovisual_redirect)) hearers -= target if(omni) target.show_message(target_message) @@ -158,7 +158,7 @@ if(self_message) hearers -= src for(var/mob/M in hearers) - if(!M.client) + if(!M.client && !M.audiovisual_redirect) continue if(omni) M.show_message(message) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index a3bcdb0e55..f59ed15c88 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -229,17 +229,23 @@ It's fairly easy to fix if dealing with single letters but not so much with comp return copytext_char(sanitize(.),1,MAX_MESSAGE_LEN) /proc/shake_camera(mob/M, duration, strength=1) - if(!M || !M.client || duration < 1) + set waitfor = FALSE + if(!M || !M.client || duration <= 0) return var/client/C = M.client + if (C.prefs.screenshake==0) + return var/oldx = C.pixel_x var/oldy = C.pixel_y - var/max = strength*world.icon_size - var/min = -(strength*world.icon_size) + var/clientscreenshake = (C.prefs.screenshake * 0.01) + var/max = (strength*clientscreenshake) * world.icon_size + var/min = -((strength*clientscreenshake) * world.icon_size) + var/roundedduration = -round(-duration) // round() with only one arg will always round down. so uh. this is Something all right - for(var/i in 0 to duration-1) + for(var/i in 0 to roundedduration-1) + duration-- if (i == 0) - animate(C, pixel_x=rand(min,max), pixel_y=rand(min,max), time=1) + animate(C, pixel_x=(rand(min,max)*duration), pixel_y=(rand(min,max)*duration), time=1) else animate(pixel_x=rand(min,max), pixel_y=rand(min,max), time=1) animate(pixel_x=oldx, pixel_y=oldy, time=1) diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index 836ed3b804..3f2f4d3e65 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -3,6 +3,7 @@ name = "projectile gun" icon_state = "pistol" w_class = WEIGHT_CLASS_NORMAL + recoil = 0.25 var/spawnwithmagazine = TRUE var/mag_type = /obj/item/ammo_box/magazine/m10mm //Removes the need for max_ammo and caliber info var/obj/item/ammo_box/magazine/magazine diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index afb30631e0..fe42fc2d99 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -5,6 +5,7 @@ mag_type = /obj/item/ammo_box/magazine/internal/cylinder fire_sound = "sound/weapons/revolvershot.ogg" casing_ejector = FALSE + recoil = 0.5 /obj/item/gun/ballistic/revolver/Initialize(mapload) . = ..() @@ -285,6 +286,7 @@ item_state = "shotgun" w_class = WEIGHT_CLASS_BULKY weapon_weight = WEAPON_MEDIUM + recoil = 1 force = 10 flags_1 = CONDUCT_1 slot_flags = ITEM_SLOT_BACK diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index c6fd27b103..25e4b6b12a 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -5,6 +5,7 @@ item_state = "shotgun" fire_sound = "sound/weapons/gunshotshotgunshot.ogg" w_class = WEIGHT_CLASS_BULKY + recoil = 1 force = 10 flags_1 = CONDUCT_1 slot_flags = ITEM_SLOT_BACK diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index dd759f9e3c..03dfc46713 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -16,6 +16,7 @@ name = "energy gun" desc = "A basic energy-based gun." icon = 'icons/obj/guns/energy.dmi' + recoil = 0.1 var/obj/item/stock_parts/cell/cell //What type of power cell this uses var/cell_type = /obj/item/stock_parts/cell diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index 3f41ac859f..9b10a843e8 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -8,6 +8,7 @@ item_flags = NONE obj_flags = UNIQUE_RENAME weapon_weight = WEAPON_LIGHT + recoil = 0.5 can_flashlight = 1 flight_x_offset = 15 flight_y_offset = 9 diff --git a/code/modules/projectiles/guns/misc/syringe_gun.dm b/code/modules/projectiles/guns/misc/syringe_gun.dm index 07066023b3..8de7633a79 100644 --- a/code/modules/projectiles/guns/misc/syringe_gun.dm +++ b/code/modules/projectiles/guns/misc/syringe_gun.dm @@ -4,6 +4,7 @@ icon_state = "syringegun" item_state = "syringegun" w_class = WEIGHT_CLASS_NORMAL + recoil = 0.1 throw_speed = 3 throw_range = 7 force = 4 diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm index 3554fc7052..d91a336db0 100644 --- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -1045,13 +1045,13 @@ glass_desc = "Delicious flavored strawberry syrup mixed with milk." value = REAGENT_VALUE_VERY_COMMON -/datum/reagent/consumable/tea/pinkmilk/on_mob_life(mob/living/carbon/M) +/datum/reagent/consumable/pinkmilk/on_mob_life(mob/living/carbon/M) if(prob(15)) to_chat(M, "[pick("You cant help to smile.","You feel nostalgia all of sudden.","You remember to relax.")]") ..() . = 1 -/datum/reagent/consumable/pinktea //Tiny Tim song +/datum/reagent/consumable/tea/pink //Tiny Tim song name = "Strawberry Tea" description = "A timeless classic!" color = "#f76aeb"//rgb(247, 106, 235) @@ -1061,7 +1061,7 @@ glass_name = "mug of strawberry tea" glass_desc = "Delicious traditional tea flavored with strawberries." -/datum/reagent/consumable/tea/pinktea/on_mob_life(mob/living/carbon/M) +/datum/reagent/consumable/tea/pink/on_mob_life(mob/living/carbon/M) if(prob(10)) to_chat(M, "[pick("Diamond skies where white deer fly.","Sipping strawberry tea.","Silver raindrops drift through timeless, Neverending June.","Crystal ... pearls free, with love!","Beaming love into me.")]") ..() diff --git a/config/entries/general.txt b/config/entries/general.txt index 66bf7e8afa..0a4372a9cc 100644 --- a/config/entries/general.txt +++ b/config/entries/general.txt @@ -477,7 +477,7 @@ BOX_RANDOM_ENGINE Box TEG,3 BOX_RANDOM_ENGINE Box Empty,0 BOX_RANDOM_ENGINE Box Antimatter,1 BOX_RANDOM_ENGINE Box P.A.C.M.A.N,1 -BOX_RANDOM_ENGINE Box RBMK,1 +BOX_RANDOM_ENGINE Box RBMK,0 ## Whether the suicide verb is allowed. diff --git a/html/changelogs/archive/2022-06.yml b/html/changelogs/archive/2022-06.yml index 10450d8943..2827914b57 100644 --- a/html/changelogs/archive/2022-06.yml +++ b/html/changelogs/archive/2022-06.yml @@ -120,7 +120,80 @@ BongaTheProto: - tweak: Makes the new player panel a toggle so you can choose between the old one and TG's current. Option in Game Preferences +2022-06-06: SandPoot: - refactor: Completely replaces the new player panel *not the admin one* with TG's. timothyteakettle: - rscadd: adds paper skin and glass bones quirks +2022-06-07: + Bhijn & Myr: + - rscadd: During pride month, station nukes are significantly more efficient at + revealing genders. + - rscadd: Station pets now retain their color between shifts! + - bugfix: Admin vote deobfuscation now properly displays votes as 0 if they were + simply never voted for. + - bugfix: Audiovisual redirection now works exactly as it used to. In laymen's terms, + this means folks in VR sleepers are aware of the world around them again! + - bugfix: The shake animation, jiggle animation, squish animation, jitter animation, + and float animation, have all been fixed. + - bugfix: This also means that storage animations are fully working again. It's + been a few years! + - bugfix: The pull animation no longer interrupts ongoing animations. + - tweak: The pull animation now supports diagonal directions (currently only applies + to the initial grab! pull code is spaghetti) + - bugfix: All screenshake sources now fully support the screenshake pref + - code_imp: cit_screenshake.dm has been fully merged into the base files. + - bugfix: You can no longer remotely apply fingerprints to storage objects by clicking + and dragging it around. Additionally, storage objects now rustle again when + clicking and dragging (only took like,, a year to fix) + - bugfix: The pickup animation now properly slides into your spaceman again, instead + of just kinda disappearing. + - tweak: When pulling a resting mob, they'll now skip the laying animation entirely, + fixing a visual oddity where they shrink and grow to flip. + - tweak: Alerts are now a little snappier and bouncier, as they've been swapped + from sine easing, to back easing. + - tweak: Radial menus now use sine easing, rather than linear easing. This just + looks a little prettier. + - tweak: Runechat now properly respects an object's X offset. Previously, it relied + on a hardcoded check for dogborgs. + - tweak: The float animation now uses pixel_z instead of pixel_y, fixing issues + where the Y offset gets wiped due to the float animation. This also makes floating + fully compatible with ctrl+WASD." + BongaTheProto: + - rscadd: New panting emote + - rscadd: Adds a recipe for the cum donut + - rscadd: Adds a panting emote + - rscadd: Adds Dominant Aura and Well-trained quirks + - rscadd: Snack alt title for assistants + - soundadd: Adds sounds for the kiss them deeply interaction + - soundadd: Adds moaning sounds for verb moans + - tweak: Changes bane syndrome's value to -2 + - tweak: Makes xenocommon a selectable language + - tweak: Fucking people's throats gives an actually harmful amount of oxyloss again + - tweak: If you have the voracious trait, the fat moodlet will become a positive + one. + - tweak: headpat slut will now give you an modified wuv element and possibly make + you cum + - bugfix: Fixes the notify verb so it actually removes you from the list if you + want it to + - bugfix: makes the cheesed moodlet actually check if you're a felinid + - bugfix: Gives Bane Syndrome its effects back + - bugfix: You can now actually dispense tea from the Soda Dispenser, rejoice! + - rscdel: deletes the double railing declaration in the code + - code_imp: changes some things to use the cooldown system + - code_imp: puts signal handlers in a couple procs where they needed to be + - code_imp: Adds a signal for when mobs use emotes + SandPoot: + - refactor: Does some extremely minor touches on pulling/pushing code. + timothyteakettle: + - rscadd: updates existing poly maid outfit with tg sprite but polychromatic + - rscadd: adds polychromic maid apron, gloves, collar, headband + - rscadd: adds support for polychromic accessories +2022-06-08: + SandPoot: + - tweak: The "MobInteraction" is now written on typescript. +2022-06-09: + Anonymous: + - rscadd: Players, who somehow ended up controlling a simple mob, now can change + their genital set just like robots and pAIs. + - rscdel: My sanity. diff --git a/icons/mob/clothing/accessories.dmi b/icons/mob/clothing/accessories.dmi index 03849efa5a..f801c483f1 100644 Binary files a/icons/mob/clothing/accessories.dmi and b/icons/mob/clothing/accessories.dmi differ diff --git a/icons/mob/clothing/hands.dmi b/icons/mob/clothing/hands.dmi index ca8a7312fa..9bd206e04e 100644 Binary files a/icons/mob/clothing/hands.dmi and b/icons/mob/clothing/hands.dmi differ diff --git a/icons/mob/clothing/neck.dmi b/icons/mob/clothing/neck.dmi index 20b8576277..2b317737d7 100644 Binary files a/icons/mob/clothing/neck.dmi and b/icons/mob/clothing/neck.dmi differ diff --git a/icons/mob/clothing/uniform.dmi b/icons/mob/clothing/uniform.dmi index 04d9b20a75..ce25963360 100644 Binary files a/icons/mob/clothing/uniform.dmi and b/icons/mob/clothing/uniform.dmi differ diff --git a/icons/obj/clothing/accessories.dmi b/icons/obj/clothing/accessories.dmi index 79cb2bff77..f633f030c3 100644 Binary files a/icons/obj/clothing/accessories.dmi and b/icons/obj/clothing/accessories.dmi differ diff --git a/icons/obj/clothing/gloves.dmi b/icons/obj/clothing/gloves.dmi index d4cd4b4f2f..17073805c9 100644 Binary files a/icons/obj/clothing/gloves.dmi and b/icons/obj/clothing/gloves.dmi differ diff --git a/icons/obj/clothing/neck.dmi b/icons/obj/clothing/neck.dmi index 8540b2f392..c9491af6b2 100644 Binary files a/icons/obj/clothing/neck.dmi and b/icons/obj/clothing/neck.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index c16b416cd8..de7dd234b1 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/modular_citadel/code/game/objects/cit_screenshake.dm b/modular_citadel/code/game/objects/cit_screenshake.dm deleted file mode 100644 index 222de37f82..0000000000 --- a/modular_citadel/code/game/objects/cit_screenshake.dm +++ /dev/null @@ -1,51 +0,0 @@ -//we vlambeer now - -/obj/proc/shake_camera(mob/M, duration, strength=1)//byond's wonky with this shit - set waitfor = FALSE - if(!M || !M.client || duration <= 0) - return - var/client/C = M.client - if (C.prefs.screenshake==0) - return - var/oldx = C.pixel_x - var/oldy = C.pixel_y - var/clientscreenshake = (C.prefs.screenshake * 0.01) - var/max = (strength*clientscreenshake) * world.icon_size - var/min = -((strength*clientscreenshake) * world.icon_size) - - for(var/i in 0 to duration-1) - if (i == 0) - animate(C, pixel_x=rand(min,max), pixel_y=rand(min,max), time=1) - else - animate(pixel_x=rand(min,max), pixel_y=rand(min,max), time=1) - animate(pixel_x=oldx, pixel_y=oldy, time=1) - -/obj/item/gun/energy - recoil = 0.1 - -/obj/item/gun/energy/kinetic_accelerator - recoil = 0.5 - -/obj/item/gun/ballistic - recoil = 0.25 - -/obj/item/gun/ballistic/shotgun - recoil = 1 - -/obj/item/gun/ballistic/revolver - recoil = 0.5 - -/obj/item/gun/ballistic/revolver/doublebarrel - recoil = 1 - -/obj/item/gun/syringe - recoil = 0.1 - -/obj/item/pneumatic_cannon/fire_items(turf/target, mob/user) - . = ..() - shake_camera(user, (pressureSetting * 0.75 + 1), (pressureSetting * 0.75)) - -/obj/item/attack_obj(obj/O, mob/living/user) - . = ..() - if(force >= 20) - shake_camera(user, ((force - 15) * 0.01 + 1), ((force - 15) * 0.01)) diff --git a/modular_citadel/code/modules/client/loadout/backpack.dm b/modular_citadel/code/modules/client/loadout/backpack.dm index 3824993009..0573a1a22a 100644 --- a/modular_citadel/code/modules/client/loadout/backpack.dm +++ b/modular_citadel/code/modules/client/loadout/backpack.dm @@ -175,3 +175,9 @@ /datum/gear/backpack/necklace//this is here because loadout doesn't support proper accessories name = "A renameable necklace" path = /obj/item/clothing/accessory/necklace + +/datum/gear/backpack/polymaidapron //this is ALSO here because loadout doesn't support proper accessories + name = "Polychromic maid apron" + path = /obj/item/clothing/accessory/maidapron/polychromic + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC + loadout_initial_colors = list("#333333", "#FFFFFF") diff --git a/modular_citadel/code/modules/client/loadout/gloves.dm b/modular_citadel/code/modules/client/loadout/gloves.dm index 0b87ec65e6..766c6a7cac 100644 --- a/modular_citadel/code/modules/client/loadout/gloves.dm +++ b/modular_citadel/code/modules/client/loadout/gloves.dm @@ -13,3 +13,9 @@ /datum/gear/gloves/midnight name = "Midnight gloves" path = /obj/item/clothing/gloves/evening/black + +/datum/gear/gloves/maidpoly // WHAT DO YOU EVEN CALL THEM + name = "Polychromic maid gloves" + path = /obj/item/clothing/gloves/polymaid + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC + loadout_initial_colors = list("#333333", "#FFFFFF") diff --git a/modular_citadel/code/modules/client/loadout/head.dm b/modular_citadel/code/modules/client/loadout/head.dm index f2a7ead5be..d0563d2986 100644 --- a/modular_citadel/code/modules/client/loadout/head.dm +++ b/modular_citadel/code/modules/client/loadout/head.dm @@ -58,6 +58,12 @@ name = "Maid headband" path= /obj/item/clothing/head/maid +/datum/gear/head/maidband/poly + name = "Polychromic maid headband" + path= /obj/item/clothing/head/maid/polychromic + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC + loadout_initial_colors = list("#333333", "#FFFFFF") + /datum/gear/head/flakhelm name = "Flak Helmet" path = /obj/item/clothing/head/flakhelm diff --git a/modular_citadel/code/modules/client/loadout/neck.dm b/modular_citadel/code/modules/client/loadout/neck.dm index dc7735de2b..64d1fcdc1f 100644 --- a/modular_citadel/code/modules/client/loadout/neck.dm +++ b/modular_citadel/code/modules/client/loadout/neck.dm @@ -106,3 +106,9 @@ path = /obj/item/clothing/neck/cloak/cancloak/polychromic loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#585858", "#373737", "#BEBEBE") + +/datum/gear/neck/maid + name = "Polychromatic Maid Collar" + path = /obj/item/clothing/neck/maid + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC + loadout_initial_colors = list("#333333", "#FFFFFF") diff --git a/modular_citadel/code/modules/client/loadout/uniform.dm b/modular_citadel/code/modules/client/loadout/uniform.dm index 4404d70bcd..c0c7846112 100644 --- a/modular_citadel/code/modules/client/loadout/uniform.dm +++ b/modular_citadel/code/modules/client/loadout/uniform.dm @@ -52,7 +52,7 @@ name = "Polychromic maid costume" path = /obj/item/clothing/under/rank/civilian/janitor/maid/polychromic loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC - loadout_initial_colors = list("#FFFFFF", "#000000") + loadout_initial_colors = list("#333333", "#FFFFFF") /datum/gear/uniform/mailmanuniform name = "Mailman's jumpsuit" diff --git a/modular_sand/code/datums/interactions/interaction_datums/lewd/facefuck.dm b/modular_sand/code/datums/interactions/interaction_datums/lewd/facefuck.dm index e66cce7f28..8591f2f8a8 100644 --- a/modular_sand/code/datums/interactions/interaction_datums/lewd/facefuck.dm +++ b/modular_sand/code/datums/interactions/interaction_datums/lewd/facefuck.dm @@ -131,8 +131,8 @@ "slams in and out of \the [partner]'s mouth, [u_His] balls slapping off [t_His] face.")]" if(rand(3)) partner.emote("chokes on \the [user]") - if(prob(1) && istype(partner)) - partner.adjustOxyLoss(5) + /*if(prob(1) && istype(partner)) //Handled on modular_splurt + partner.adjustOxyLoss(5)*/ if(partner.a_intent == INTENT_HARM) // adjustBruteLoss(5) retaliation_message = pick( diff --git a/modular_sand/code/modules/clothing/gloves/_gloves.dm b/modular_sand/code/modules/clothing/gloves/_gloves.dm index b1984e9770..65f7de4825 100644 --- a/modular_sand/code/modules/clothing/gloves/_gloves.dm +++ b/modular_sand/code/modules/clothing/gloves/_gloves.dm @@ -1,16 +1,14 @@ /obj/item/clothing/gloves var/dummy_thick = FALSE // is able to hold accessories on its item - // Sandstorm edit - Removed the old attached accessory system. We use a list of accessories instead. - var/list/obj/item/clothing/accessory/ring/attached_accessories = list() var/max_accessories = 1 - // Sandstorm edit END - var/mutable_appearance/accessory_overlay + var/list/obj/item/clothing/accessory/ring/attached_accessories = list() + var/list/mutable_appearance/accessory_overlays = list() /obj/item/clothing/gloves/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE) . = ..() if(!isinhands) - if(accessory_overlay) - . += accessory_overlay + if(length(accessory_overlays)) + . += accessory_overlays /obj/item/clothing/gloves/attackby(obj/item/I, mob/user, params) if(!attach_accessory(I, user)) @@ -20,7 +18,7 @@ . = ..() if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) return - if(length(attached_accessories)) // Sandstorm edit + if(length(attached_accessories)) remove_accessory(user) /obj/item/clothing/gloves/equipped(mob/user, slot) @@ -70,14 +68,16 @@ if((flags_inv & HIDEACCESSORY) || (A.flags_inv & HIDEACCESSORY)) return TRUE - // Sandstorm edit - accessory_overlay = mutable_appearance(I.mob_overlay_icon, I.item_state) - for(var/obj/item/clothing/accessory/ring/attached_accessory in attached_accessories) - var/mutable_appearance/Y = mutable_appearance(attached_accessory.mob_overlay_icon, attached_accessory.icon_state, ABOVE_HUD_LAYER) - Y.alpha = attached_accessory.alpha - Y.color = attached_accessory.color - accessory_overlay.add_overlay(Y) - // Sandstorm edit END + accessory_overlays = list(mutable_appearance('icons/mob/clothing/accessories.dmi', "blank")) + for(var/obj/item/clothing/accessory/attached_accessory in attached_accessories) + var/datum/element/polychromic/polychromic = LAZYACCESS(attached_accessory.comp_lookup, "item_worn_overlays") + if(!polychromic) + var/mutable_appearance/accessory_overlay = mutable_appearance(attached_accessory.mob_overlay_icon, attached_accessory.item_state || attached_accessory.icon_state, ABOVE_HUD_LAYER) + accessory_overlay.alpha = attached_accessory.alpha + accessory_overlay.color = attached_accessory.color + accessory_overlays += accessory_overlay + else + polychromic.apply_worn_overlays(attached_accessory, FALSE, attached_accessory.mob_overlay_icon, attached_accessory.item_state || attached_accessory.icon_state, NONE, accessory_overlays) if(ishuman(loc)) var/mob/living/carbon/human/H = loc @@ -91,10 +91,8 @@ if(!can_use(user)) return - // Sandstorm edit if(length(attached_accessories)) var/obj/item/clothing/accessory/ring/A = attached_accessories[length(attached_accessories)] - // Sandstorm edit END A.detach(src, user) if(user.put_in_hands(A)) to_chat(user, "You detach [A] from [src].") diff --git a/modular_sand/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/modular_sand/code/modules/reagents/chemistry/reagents/drink_reagents.dm index 5b80e1b91c..c0b7ce2ca5 100644 --- a/modular_sand/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/modular_sand/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -145,7 +145,7 @@ /datum/reagent/consumable/pinkmilk hydration = 4 -/datum/reagent/consumable/pinktea +/datum/reagent/consumable/tea/pink hydration = 4 /datum/reagent/consumable/monkey_energy diff --git a/modular_splurt/README.md b/modular_splurt/README.md index 1249b0be0f..c0c251cf64 100644 --- a/modular_splurt/README.md +++ b/modular_splurt/README.md @@ -1,5 +1,5 @@ # About modularizing defines -Since #define clauses can't be properly modularized and need to be loaded first than the rest of the code for it to catch them, the modular_splurt/code/_DEFINES/ folder has been deleted and all of its contents have been moved to code/__DEFINES/splurtcode/ +Since #define clauses can't be properly modularized and need to be loaded first than the rest of the code for it to catch them, the modular_splurt/code/_DEFINES/ folder has been deleted and all of its contents have been moved to code\\__SPLURTCODE\\DEFINES Please use this folder the same way you'd use the _DEFINES folder once found inside this directory diff --git a/modular_splurt/code/datums/elements/smalltalk.dm b/modular_splurt/code/datums/elements/smalltalk.dm index cc236e7036..9ffa626757 100644 --- a/modular_splurt/code/datums/elements/smalltalk.dm +++ b/modular_splurt/code/datums/elements/smalltalk.dm @@ -14,4 +14,6 @@ UnregisterSignal(source, COMSIG_MOB_SAY) /datum/element/smalltalk/proc/handle_speech(datum/source, list/speech_args) + SIGNAL_HANDLER + speech_args[SPEECH_SPANS] |= SPAN_SMALL diff --git a/modular_splurt/code/datums/elements/wuv.dm b/modular_splurt/code/datums/elements/wuv.dm new file mode 100644 index 0000000000..de94b61992 --- /dev/null +++ b/modular_splurt/code/datums/elements/wuv.dm @@ -0,0 +1,13 @@ +/datum/element/wuv/headpat/pet_the_dog(mob/target, mob/user) //For instances where only the headpat applies + if(QDELETED(target) || QDELETED(user) || target.stat != CONSCIOUS) + return + if(!(check_zone(user.zone_selected) == BODY_ZONE_HEAD) || user == target) + return + new /obj/effect/temp_visual/heart(target.loc) + if(pet_emote) + target.emote("me", pet_type, pet_emote) + if(pet_moodlet && !(target.flags_1 & HOLOGRAM_1)) //prevents unlimited happiness petting park exploit. + SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, target, pet_moodlet, target) + +/datum/element/wuv/headpat/kick_the_dog(mob/target, mob/user) + return //No kicking the dog >:(( (until I find an use for this that is) diff --git a/modular_splurt/code/datums/interactions/lewd/_lewd.dm b/modular_splurt/code/datums/interactions/lewd/_lewd.dm index 7f5ecffe14..85fabb32bf 100644 --- a/modular_splurt/code/datums/interactions/lewd/_lewd.dm +++ b/modular_splurt/code/datums/interactions/lewd/_lewd.dm @@ -1,6 +1,21 @@ /mob/living var/has_belly = FALSE +/mob/living/moan() + var/moaned = lastmoan + var/miming = mind ? mind?.miming : FALSE + . = ..() + if((moaned == lastmoan) || is_muzzled() || miming || !prob(50)) + return + var/list/moans + if(isalien(src)) + moans = list('sound/voice/hiss6.ogg') + else if(gender == FEMALE) + moans = list('modular_splurt/sound/voice/moan_f1.ogg', 'modular_splurt/sound/voice/moan_f2.ogg', 'modular_splurt/sound/voice/moan_f3.ogg', 'modular_splurt/sound/voice/moan_f4.ogg', 'modular_splurt/sound/voice/moan_f5.ogg', 'modular_splurt/sound/voice/moan_f6.ogg', 'modular_splurt/sound/voice/moan_f7.ogg') + else + moans = list('modular_splurt/sound/voice/moan_m1.ogg', 'modular_splurt/sound/voice/moan_m2.ogg', 'modular_splurt/sound/voice/moan_m3.ogg') + playlewdinteractionsound(src, pick(moans), 50, 1, 4, 1.2, ignored_mobs = get_unconsenting()) + /mob/living/proc/get_refraction_dif() //Got snapped in upstream, may delete later when I figure something out var/dif = (refractory_period - world.time) if(dif < 0) diff --git a/modular_splurt/code/datums/interactions/lewd/lewd_datums.dm b/modular_splurt/code/datums/interactions/lewd/lewd_datums.dm index b284be8e1f..c11b335955 100644 --- a/modular_splurt/code/datums/interactions/lewd/lewd_datums.dm +++ b/modular_splurt/code/datums/interactions/lewd/lewd_datums.dm @@ -96,6 +96,11 @@ /datum/interaction/lewd/throatfuck/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target) . = ..() + if(istype(target, /mob/living) && user.is_fucking(target, CUM_TARGET_THROAT)) + var/stat_before = target.stat + target.adjustOxyLoss(3) + if(target.stat == UNCONSCIOUS && stat_before != UNCONSCIOUS) + target.visible_message(message = "\The [target] passes out on \The [src]'s cock.", ignored_mobs = user.get_unconsenting()) if(!isclownjob(user)) return @@ -358,6 +363,15 @@ playlewdinteractionsound(target, 'sound/items/bikehorn.ogg', 40, 1, -1) +/datum/interaction/lewd/kiss/display_interaction(mob/living/user, mob/living/partner) + . = ..() + playlewdinteractionsound(partner, pick( + 'modular_splurt/sound/interactions/kiss/kiss1.ogg', + 'modular_splurt/sound/interactions/kiss/kiss2.ogg', + 'modular_splurt/sound/interactions/kiss/kiss3.ogg', + 'modular_splurt/sound/interactions/kiss/kiss4.ogg', + 'modular_splurt/sound/interactions/kiss/kiss5.ogg'), 50, 1, -1, ignored_mobs = user.get_unconsenting()) + //Own stuff /datum/interaction/lewd/oral/selfsuck description = "Suck yourself off." diff --git a/modular_splurt/code/datums/mood_events/dominant_events.dm b/modular_splurt/code/datums/mood_events/dominant_events.dm new file mode 100644 index 0000000000..f8e41e6b42 --- /dev/null +++ b/modular_splurt/code/datums/mood_events/dominant_events.dm @@ -0,0 +1,20 @@ +/datum/mood_event/dominant/need + description = span_warning("I need to be someone's good THING...\n") + mood_change = -2 + timeout = 3 MINUTES + +/datum/mood_event/dominant/good_boy + description = span_nicegreen("I feel like a good THING!\n") + mood_change = 2 + timeout = 3 MINUTES + +/datum/mood_event/dominant/add_effects(param) + . = ..() + var/mob/living/carbon/human/actual_owner = owner_mob() + var/good_x = "pet" + switch(actual_owner.gender) + if(MALE) + good_x = "boy" + if(FEMALE) + good_x = "girl" + description = replacetextEx(description, "THING", good_x) diff --git a/modular_splurt/code/datums/mood_events/generic_negative_events.dm b/modular_splurt/code/datums/mood_events/generic_negative_events.dm index 2e036154fe..c66f79e83d 100644 --- a/modular_splurt/code/datums/mood_events/generic_negative_events.dm +++ b/modular_splurt/code/datums/mood_events/generic_negative_events.dm @@ -7,11 +7,11 @@ /datum/mood_event/creampie/cheesed/add_effects(param) . = ..() - if(!ishuman(owner)) - return . - var/mob/living/carbon/human/H = owner + var/mob/living/carbon/human/actual_owner = owner_mob() - if(iscatperson(H)) + if(!ishuman(actual_owner)) + return . + if(iscatperson(actual_owner)) description = span_warning("CHEESE!!! WAAAAAAAAAAAAAAAAAAAAAAAAAAAA!!!") mood_change = -5 timeout = 5 MINUTES diff --git a/modular_splurt/code/datums/mood_events/mood_event.dm b/modular_splurt/code/datums/mood_events/mood_event.dm new file mode 100644 index 0000000000..961f0dc311 --- /dev/null +++ b/modular_splurt/code/datums/mood_events/mood_event.dm @@ -0,0 +1,8 @@ +/datum/mood_event/proc/owner_mob() + var/mob/living/carbon/human/actual_owner + var/datum/component/mood/wrong_declaration = owner + if(istype(wrong_declaration)) + actual_owner = wrong_declaration.parent + else + actual_owner = owner + return actual_owner diff --git a/modular_splurt/code/datums/mood_events/needs_events.dm b/modular_splurt/code/datums/mood_events/needs_events.dm new file mode 100644 index 0000000000..da5a575ebb --- /dev/null +++ b/modular_splurt/code/datums/mood_events/needs_events.dm @@ -0,0 +1,7 @@ +/datum/mood_event/fat/add_effects(param) + . = ..() + var/mob/living/carbon/human/actual_owner = owner_mob() + if(!HAS_TRAIT(actual_owner, TRAIT_VORACIOUS)) + return + description = span_nicegreen("MORE FOOD!!! MORE FOOD!!! MORE FOOD!!!") + mood_change = 8 diff --git a/modular_splurt/code/datums/traits/good.dm b/modular_splurt/code/datums/traits/good.dm index ba1fa91706..d5ab76b3be 100644 --- a/modular_splurt/code/datums/traits/good.dm +++ b/modular_splurt/code/datums/traits/good.dm @@ -33,3 +33,75 @@ quirk_holder.weather_immunities -= "ash" */ +/datum/quirk/dominant_aura + name = "Dominant Aura" + desc = "Your personality is assertive enough to appear as powerful to other people, so much in fact that the weaker kind can't help but throw themselves at your feet on command." + value = 2 + gain_text = "You feel like making someone your pet" + lose_text = "You feel less assertive than befpre" + +/datum/quirk/dominant_aura/add() + . = ..() + RegisterSignal(quirk_holder, COMSIG_PARENT_EXAMINE, .proc/on_examine_holder) + RegisterSignal(quirk_holder, COMSIG_MOB_EMOTE, .proc/handle_snap) + +/datum/quirk/dominant_aura/remove() + . = ..() + UnregisterSignal(quirk_holder, COMSIG_PARENT_EXAMINE) + UnregisterSignal(quirk_holder, COMSIG_MOB_EMOTE) + +/datum/quirk/dominant_aura/proc/on_examine_holder(atom/source, mob/user, list/examine_list) + SIGNAL_HANDLER + + if(!ishuman(user)) + return + var/mob/living/carbon/human/sub = user + if(!sub.has_quirk(/datum/quirk/well_trained) || (sub == quirk_holder)) + return + + examine_list += span_lewd("\nYou can't look at [quirk_holder.p_them()] for more than three seconds before flustering away.") + if(!TIMER_COOLDOWN_CHECK(user, COOLDOWN_DOMINANT_EXAMINE)) + to_chat(quirk_holder, span_notice("\The [user] tries to look at you but immediately looks away with a red face...")) + TIMER_COOLDOWN_START(user, COOLDOWN_DOMINANT_EXAMINE, 5 SECONDS) + sub.dir = turn(get_dir(sub, quirk_holder), pick(-90, 90)) + +/datum/quirk/dominant_aura/proc/handle_snap(datum/source, list/emote_args) + SIGNAL_HANDLER + + . = FALSE + var/datum/emote/E + E = E.emote_list[lowertext(emote_args[EMOTE_ACT])] + if(TIMER_COOLDOWN_CHECK(quirk_holder, COOLDOWN_DOMINANT_SNAP) || !findtext(E?.key, "snap")) + return + for(var/mob/living/carbon/human/sub in hearers(DOMINANT_DETECT_RANGE, quirk_holder)) + if(!sub.has_quirk(/datum/quirk/well_trained) || (sub == quirk_holder)) + continue + var/good_x = "pet" + switch(sub.gender) + if(MALE) + good_x = "boy" + if(FEMALE) + good_x = "girl" + switch(E?.key) + if("snap") + sub.dir = get_dir(sub, quirk_holder) + sub.emote(pick("blush", "pant")) + sub.visible_message(span_notice("\The [sub] turns shyly towards \the [quirk_holder]."), + span_lewd("You stare into \the [quirk_holder] submissively.")) + if("snap2") + sub.dir = get_dir(sub, quirk_holder) + sub.KnockToFloor() + sub.emote(pick("blush", "pant")) + sub.visible_message(span_lewd("\The [sub] submissively throws [sub.p_them()]self on the floor."), + span_lewd("You throw yourself on the floor like a dog on [quirk_holder]'s command.")) + if("snap3") + sub.KnockToFloor() + step(sub, get_dir(sub, quirk_holder)) + sub.emote(pick("blush", "pant")) + sub.do_jitter_animation(30) //You're being moved anyways + sub.visible_message(span_lewd("\The [sub] crawls closer to \the [quirk_holder] in all fours, following [quirk_holder.p_their()] command"), + span_lewd("You get on your fours and crawl towards \the [quirk_holder] like a good, submissive [good_x].")) + . = TRUE + + if(.) + TIMER_COOLDOWN_START(quirk_holder, COOLDOWN_DOMINANT_SNAP, DOMINANT_SNAP_COOLDOWN) diff --git a/modular_splurt/code/datums/traits/negative.dm b/modular_splurt/code/datums/traits/negative.dm index 0aa149375b..45dafa4261 100644 --- a/modular_splurt/code/datums/traits/negative.dm +++ b/modular_splurt/code/datums/traits/negative.dm @@ -57,3 +57,113 @@ var/datum/component/mood/mood = quirk_holder.GetComponent(/datum/component/mood) if(mood) mood.mood_modifier -= 0.5 + +/datum/quirk/masked_mook + name = "Bane Syndrome" + desc = "For some reason you don't feel well without wearing some kind of gas mask." + gain_text = "You start feeling unwell without any gas mask on." + lose_text = "You no longer have a need to wear some gas mask." + value = -2 + mood_quirk = TRUE + medical_record_text = "Patient feels more secure when wearing a gas mask." + processing_quirk = TRUE + var/mood_category = "masked_mook" + +/datum/quirk/masked_mook/on_process() + var/mob/living/carbon/human/H = quirk_holder + var/obj/item/clothing/mask/gas/gasmask = H.get_item_by_slot(ITEM_SLOT_MASK) + if(istype(gasmask)) + SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, mood_category, /datum/mood_event/masked_mook) + else + SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, mood_category, /datum/mood_event/masked_mook_incomplete) + +/datum/quirk/masked_mook/on_spawn() + . = ..() + var/mob/living/carbon/human/H = quirk_holder + var/obj/item/clothing/mask/gas/gasmask = new(get_turf(quirk_holder)) + H.equip_to_slot(gasmask, ITEM_SLOT_MASK) + H.regenerate_icons() + +/datum/quirk/well_trained + name = "Well-trained" + desc = "You absolutely love being dominated. The thought of someone with a stronger character than yours is enough to make you act up." + value = -2 + gain_text = "You feel like being someone's pet" + lose_text = "You no longer feel like being a pet..." + processing_quirk = TRUE + var/mood_category = "dom_trained" + var/notice_delay = 0 + var/mob/living/carbon/human/last_dom + +/datum/quirk/well_trained/add() + . = ..() + RegisterSignal(quirk_holder, COMSIG_PARENT_EXAMINE, .proc/on_examine_holder) + +/datum/quirk/well_trained/remove() + . = ..() + UnregisterSignal(quirk_holder, COMSIG_PARENT_EXAMINE) + +/datum/quirk/well_trained/proc/on_examine_holder(atom/source, mob/living/user, list/examine_list) + SIGNAL_HANDLER + + if(!istype(user)) + return + if(!user.has_quirk(/datum/quirk/dominant_aura)) + return + examine_list += span_lewd("You can sense submissiveness irradiating from [quirk_holder.p_them()]") + +/datum/quirk/well_trained/on_process() + . = ..() + if(!quirk_holder) + return + + var/good_x = "pet" + switch(quirk_holder.gender) + if(MALE) + good_x = "boy" + if(FEMALE) + good_x = "girl" + + //Check for possible doms with the dominant_aura quirk, and for the closest one if there is + . = FALSE + var/list/mob/living/carbon/human/doms = range(DOMINANT_DETECT_RANGE, quirk_holder) + var/closest_distance + for(var/mob/living/carbon/human/dom in doms) + if(dom != quirk_holder && dom.has_quirk(/datum/quirk/dominant_aura)) + if(!closest_distance || get_dist(quirk_holder, dom) <= closest_distance) + . = dom + closest_distance = get_dist(quirk_holder, dom) + + //Return if no dom is found + if(!.) + last_dom = null + return + + //Handle the mood + var/datum/component/mood/mood = quirk_holder.GetComponent(/datum/component/mood) + if(istype(mood.mood_events[mood_category], /datum/mood_event/dominant/good_boy)) + SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, mood_category, /datum/mood_event/dominant/good_boy) + else + SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, mood_category, /datum/mood_event/dominant/need) + + //Don't do anything if a previous dom was found + if(last_dom) + notice_delay = world.time + 15 SECONDS + return + + last_dom = . + + if(notice_delay > world.time) + return + + //Let them know they're near + var/list/notices = list( + "You feel someone's presence making you more submissive.", + "The thought of being commanded floods you with lust.", + "You really want to be called a good [good_x].", + "Someone's presence is making you all flustered.", + "You start getting excited and sweating." + ) + + to_chat(quirk_holder, span_lewd(pick(notices))) + notice_delay = world.time + 15 SECONDS diff --git a/modular_splurt/code/datums/traits/neutral.dm b/modular_splurt/code/datums/traits/neutral.dm index d816747e71..827432936b 100644 --- a/modular_splurt/code/datums/traits/neutral.dm +++ b/modular_splurt/code/datums/traits/neutral.dm @@ -49,6 +49,14 @@ value = 0 medical_record_text = "Patient seems overly affectionate." +/datum/quirk/headpat_slut/add() + . = ..() + quirk_holder.AddElement(/datum/element/wuv/headpat, null, null, /datum/mood_event/pet_animal) + +/datum/quirk/headpat_slut/remove() + . = ..() + quirk_holder.RemoveElement(/datum/element/wuv/headpat) + /datum/quirk/in_heat name = "In Heat" desc = "Your system burns with the desire to be bred. Satisfying your lust will make you happy, but ignoring it may cause you to become sad and needy." @@ -284,29 +292,3 @@ . = ..() var/obj/item/implant/genital_fluid/put_in = new put_in.implant(quirk_holder, null, TRUE, TRUE) - -/datum/quirk/masked_mook - name = "Bane Syndrome" - desc = "For some reason you don't feel well without wearing some kind of gas mask." - gain_text = "You start feeling unwell without any gas mask on." - lose_text = "You no longer have a need to wear some gas mask." - value = 0 - mood_quirk = TRUE - medical_record_text = "Patient feels more secure when wearing a gas mask." - -/datum/quirk/masked_mook/on_process() - var/mob/living/carbon/human/H = quirk_holder - var/obj/item/clothing/mask/gas/gasmask = H.get_item_by_slot(ITEM_SLOT_MASK) - if(istype(gasmask)) - SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "masked_mook_incomplete") - SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "masked_mook", /datum/mood_event/masked_mook) - else - SEND_SIGNAL(quirk_holder, COMSIG_CLEAR_MOOD_EVENT, "masked_mook") - SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "masked_mook_incomplete", /datum/mood_event/masked_mook_incomplete) - -/datum/quirk/masked_mook/on_spawn() - . = ..() - var/mob/living/carbon/human/H = quirk_holder - var/obj/item/clothing/mask/gas/gasmask = new(get_turf(quirk_holder)) - H.equip_to_slot(gasmask, ITEM_SLOT_MASK) - H.regenerate_icons() diff --git a/modular_splurt/code/game/object/structures/railings.dm b/modular_splurt/code/game/object/structures/railings.dm deleted file mode 100644 index ca1e6e2c9e..0000000000 --- a/modular_splurt/code/game/object/structures/railings.dm +++ /dev/null @@ -1,198 +0,0 @@ -//ported from virgo - -/obj/structure/railing - name = "railing" - desc = "A railing to stop people from falling" - - icon = 'modular_splurt/icons/obj/railings.dmi' - var/icon_modifier = "grey_" - icon_state = "grey_railing0" - - density = FALSE - layer = 4 - anchored = TRUE - flags_1 = ON_BORDER_1 - max_integrity = 250 - var/heat_resistance = 800 - var/health = 70 - var/maxhealth = 70 - - - resistance_flags = ACID_PROOF - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) - CanAtmosPass = ATMOS_PASS_PROC - var/real_explosion_block //ignore this, just use explosion_block - var/breaksound = "shatter" - var/hitsound = 'sound/effects/Glasshit.ogg' - rad_insulation = RAD_VERY_LIGHT_INSULATION - rad_flags = RAD_PROTECT_CONTENTS - var/check = 0 - var/static/list/freepass = typecacheof(list( - /obj/singularity, - /obj/effect/projectile, - /obj/effect/portal, - /obj/effect/abstract, - /obj/effect/hotspot, - /obj/effect/landmark, - /obj/effect/temp_visual, - /obj/effect/light_emitter/tendril, - /obj/effect/collapse, - /obj/effect/particle_effect/ion_trails, - /obj/effect/dummy/phased_mob, - /obj/effect/immovablerod, - /obj/effect/crystalline_reentry - )) //Gotta make sure certain things can phase through it otherwise the railings also block them. - -/obj/structure/railing/CanPass(atom/movable/mover, turf/target) - if(istype(mover) && (mover.pass_flags & PASSGLASS) || is_type_in_typecache(mover, freepass)) - return 1 - if(get_dir(loc, target) == dir) - return 0 - return 1 - -/obj/structure/railing/CheckExit(atom/movable/O, turf/target) - if(istype(O) && (O.pass_flags & PASSGLASS) || is_type_in_typecache(O, freepass)) - return 1 - if(get_dir(O.loc, target) == dir) - return 0 - return 1 - -/obj/structure/railing/Initialize() - . = ..() - if(src.anchored) - update_icon(0) - -/obj/structure/railing/proc/NeighborsCheck(var/UpdateNeighbors = 1) - check = 0 - //if (!anchored) return - var/Rturn = turn(src.dir, -90) - var/Lturn = turn(src.dir, 90) - - for(var/obj/structure/railing/R in src.loc) - if ((R.dir == Lturn) && R.anchored) - check |= 32 - if (UpdateNeighbors) - R.update_icon(0) - if ((R.dir == Rturn) && R.anchored) - check |= 2 - if (UpdateNeighbors) - R.update_icon(0) - - for (var/obj/structure/railing/R in get_step(src, Lturn)) - if ((R.dir == src.dir) && R.anchored) - check |= 16 - if (UpdateNeighbors) - R.update_icon(0) - for (var/obj/structure/railing/R in get_step(src, Rturn)) - if ((R.dir == src.dir) && R.anchored) - check |= 1 - if (UpdateNeighbors) - R.update_icon(0) - - for (var/obj/structure/railing/R in get_step(src, (Lturn + src.dir))) - if ((R.dir == Rturn) && R.anchored) - check |= 64 - if (UpdateNeighbors) - R.update_icon(0) - for (var/obj/structure/railing/R in get_step(src, (Rturn + src.dir))) - if ((R.dir == Lturn) && R.anchored) - check |= 4 - if (UpdateNeighbors) - R.update_icon(0) - -/obj/structure/railing/update_icon(var/UpdateNeighgors = 1) - NeighborsCheck(UpdateNeighgors) - overlays.Cut() - if (!check || !anchored)//|| !anchored - icon_state = "[icon_modifier]railing0" - else - icon_state = "[icon_modifier]railing1" - if (check & 32) - overlays += image ('modular_splurt/icons/obj/railings.dmi', src, "[icon_modifier]corneroverlay") - if ((check & 16) || !(check & 32) || (check & 64)) - overlays += image ('modular_splurt/icons/obj/railings.dmi', src, "[icon_modifier]frontoverlay_l") - if (!(check & 2) || (check & 1) || (check & 4)) - overlays += image ('modular_splurt/icons/obj/railings.dmi', src, "[icon_modifier]frontoverlay_r") - if(check & 4) - switch (src.dir) - if (NORTH) - overlays += image ('modular_splurt/icons/obj/railings.dmi', src, "[icon_modifier]mcorneroverlay", pixel_x = 32) - if (SOUTH) - overlays += image ('modular_splurt/icons/obj/railings.dmi', src, "[icon_modifier]mcorneroverlay", pixel_x = -32) - if (EAST) - overlays += image ('modular_splurt/icons/obj/railings.dmi', src, "[icon_modifier]mcorneroverlay", pixel_y = -32) - if (WEST) - overlays += image ('modular_splurt/icons/obj/railings.dmi', src, "[icon_modifier]mcorneroverlay", pixel_y = 32) - -/obj/structure/railing/examine(mob/user) - . = ..() - if(health < maxhealth) - switch(health / maxhealth) - if(0.0 to 0.5) - . += "It looks severely damaged!" - if(0.25 to 0.5) - . += "It looks damaged!" - if(0.5 to 1.0) - . += "It has a few scrapes and dents." - -/obj/structure/railing/take_damage(amount) - health -= amount - if(health <= 0) - visible_message("\The [src] breaks down!") - playsound(src, 'sound/effects/grillehit.ogg', 50, 1) - new /obj/item/stack/rods(get_turf(src)) - qdel(src) - -/obj/structure/railing/MouseDrop_T(mob/living/M, mob/living/user) - if(!istype(user)) - return - if(!isliving(user)) - return - - usr.visible_message("[user] starts climbing onto \the [src]!") - - if(!do_after(user, 15, target = src)) - return - - if(get_turf(user) == get_turf(src)) - usr.dir = get_dir(usr.loc, get_step(src, src.dir))//turn and face railing - usr.forceMove(get_step(src, src.dir)) - else - usr.dir = get_dir(usr.loc, loc)//turn and face railing - usr.forceMove(get_turf(src)) - - usr.visible_message("[user] climbed over \the [src]!") - usr.do_twist(targetangle = 45, timer = 8) - -/obj/structure/railing/handrail - name = "handrail" - desc = "A waist high handrail, perhaps you could climb over it." - - icon = 'modular_splurt/icons/obj/railings.dmi' - icon_modifier = "hand_" - icon_state = "hand_railing0" - max_integrity = 100 - -/obj/structure/railing/handrail/update_icon(var/UpdateNeighgors = 1) - NeighborsCheck(UpdateNeighgors) - overlays.Cut() - if (!check || !anchored)//|| !anchored - icon_state = "[icon_modifier]railing0" - else - icon_state = "[icon_modifier]railing1" - if (check & 32) - overlays += image ('modular_splurt/icons/obj/railings.dmi', src, "[icon_modifier]corneroverlay") - if ((check & 16) || !(check & 32) || (check & 64)) - overlays += image ('modular_splurt/icons/obj/railings.dmi', src, "[icon_modifier]frontoverlay_l") - if (!(check & 2) || (check & 1) || (check & 4)) - overlays += image ('modular_splurt/icons/obj/railings.dmi', src, "[icon_modifier]frontoverlay_r") - if(check & 4) - switch (src.dir) - if (NORTH) - overlays += image ('modular_splurt/icons/obj/railings.dmi', src, "[icon_modifier]mcorneroverlay", pixel_x = 32) - if (SOUTH) - overlays += image ('modular_splurt/icons/obj/railings.dmi', src, "[icon_modifier]mcorneroverlay", pixel_x = -32) - if (EAST) - overlays += image ('modular_splurt/icons/obj/railings.dmi', src, "[icon_modifier]mcorneroverlay", pixel_y = -32) - if (WEST) - overlays += image ('modular_splurt/icons/obj/railings.dmi', src, "[icon_modifier]mcorneroverlay", pixel_y = 32) diff --git a/modular_splurt/code/modules/discord/toggle_notify.dm b/modular_splurt/code/modules/discord/toggle_notify.dm index cc08974060..ddfd3dc8db 100644 --- a/modular_splurt/code/modules/discord/toggle_notify.dm +++ b/modular_splurt/code/modules/discord/toggle_notify.dm @@ -23,11 +23,11 @@ return else // Linked - for(var/member in SSdiscord.notify_members) // If they are in the list, take them out - if(member == "[stored_id]") - SSdiscord.notify_members -= "<@[stored_id]>" // The list uses strings because BYOND cannot handle a 17 digit integer - to_chat(src, span_notice("You will no longer be notified when the server restarts")) - return // This is necassary so it doesnt get added again, as it relies on the for loop being unsuccessful to tell us if they are in the list or not + var/mention_index = SSdiscord.notify_members.Find("<@[stored_id]>") + if(mention_index) // If they are in the list, take them out + SSdiscord.notify_members -= SSdiscord.notify_members[mention_index] // The list uses strings because BYOND cannot handle a 17 digit integer + to_chat(src, span_notice("You will no longer be notified when the server restarts")) + return // This is necassary so it doesnt get added again, as it relies on the for loop being unsuccessful to tell us if they are in the list or not // If we got here, they arent in the list. Chuck 'em in! to_chat(src, span_notice("You will now be notified when the server restarts")) diff --git a/modular_splurt/code/modules/food_and_drinks/recipes/tablecraft/recipes_donut.dm b/modular_splurt/code/modules/food_and_drinks/recipes/tablecraft/recipes_donut.dm new file mode 100644 index 0000000000..3bf6f19d95 --- /dev/null +++ b/modular_splurt/code/modules/food_and_drinks/recipes/tablecraft/recipes_donut.dm @@ -0,0 +1,7 @@ +/datum/crafting_recipe/food/donut/cum + name = "\"cream\" donut" + reqs = list( + /datum/reagent/consumable/semen = 10, + /obj/item/reagent_containers/food/snacks/donut/plain = 1 + ) + result = /obj/item/reagent_containers/food/snacks/donut/semen diff --git a/modular_splurt/code/modules/jobs/job_types/_job_alt_titles.dm b/modular_splurt/code/modules/jobs/job_types/_job_alt_titles.dm index 37d905e0ae..6cf1d15bee 100644 --- a/modular_splurt/code/modules/jobs/job_types/_job_alt_titles.dm +++ b/modular_splurt/code/modules/jobs/job_types/_job_alt_titles.dm @@ -79,7 +79,8 @@ "Tourist", "Clerk", "Blacksmith", - "Bard" + "Bard", + "Snack" ) LAZYADD(alt_titles, extra_titles) diff --git a/modular_splurt/code/modules/language/xenocommon.dm b/modular_splurt/code/modules/language/xenocommon.dm new file mode 100644 index 0000000000..c0cf0d69c6 --- /dev/null +++ b/modular_splurt/code/modules/language/xenocommon.dm @@ -0,0 +1,2 @@ +/datum/language/xenocommon + restricted = FALSE //sand, you sometimes know no fun fr diff --git a/modular_splurt/code/modules/mob/emote.dm b/modular_splurt/code/modules/mob/emote.dm new file mode 100644 index 0000000000..a8caa144f9 --- /dev/null +++ b/modular_splurt/code/modules/mob/emote.dm @@ -0,0 +1,3 @@ +/mob/emote(act, m_type, message, intentional) + . = ..() + SEND_SIGNAL(src, COMSIG_MOB_EMOTE, args) diff --git a/modular_splurt/code/modules/mob/living/simple_animal/simple_animal.dm b/modular_splurt/code/modules/mob/living/simple_animal/simple_animal.dm new file mode 100644 index 0000000000..acb57b6c00 --- /dev/null +++ b/modular_splurt/code/modules/mob/living/simple_animal/simple_animal.dm @@ -0,0 +1,23 @@ +/mob/living/simple_animal/verb/toggle_gender() + set name = "Set Gender" + set desc = "Allows you to set your gender." + set category = "IC" + + var/choice = tgui_alert(usr, "Select Gender.", "Gender", list("Both", "Male", "Female", "None")) + switch(choice) + if("Both") + has_penis = TRUE + has_balls = TRUE + has_vagina = TRUE + if("Male") + has_penis = TRUE + has_balls = TRUE + has_vagina = FALSE + if("Female") + has_penis = FALSE + has_balls = FALSE + has_vagina = TRUE + if("None") + has_penis = FALSE + has_balls = FALSE + has_vagina = FALSE diff --git a/modular_splurt/code/modules/mob/splurt_emotes.dm b/modular_splurt/code/modules/mob/splurt_emotes.dm index f7c4bbfe2b..f75a0cecca 100644 --- a/modular_splurt/code/modules/mob/splurt_emotes.dm +++ b/modular_splurt/code/modules/mob/splurt_emotes.dm @@ -1,3 +1,4 @@ +//Main code edits /datum/emote/living/audio_emote/laugh/run_emote(mob/user, params) . = ..() if(. && iscarbon(user)) @@ -27,11 +28,8 @@ message = "farts out shitcode." emote_type = EMOTE_AUDIBLE -/mob/living - var/fart_cooldown = 0 - /datum/emote/living/fart/run_emote(mob/living/user, params, type_override, intentional) - if(user.fart_cooldown) + if(TIMER_COOLDOWN_CHECK(user, COOLDOWN_EMOTE_FART)) to_chat(user, "You try your hardest, but no shart comes out.") return var/list/fart_emotes = list( //cope goonies @@ -82,17 +80,8 @@ . = ..() if(.) playsound(user, pick(GLOB.brap_noises), 50, 1, -1) - var/delay = 3 SECONDS - user.fart_cooldown = TRUE - addtimer(CALLBACK(GLOBAL_PROC, .proc/_fart_renew_msg, user), delay) + TIMER_COOLDOWN_START(user, COOLDOWN_EMOTE_FART, 3 SECONDS) -/proc/_fart_renew_msg(mob/living/user) - if(QDELETED(user)) - return - //to_chat(user, "Your ass feels full, again.") //full o shit you mean - user.fart_cooldown = 0 - -// Hyperstation Emotes /datum/emote/living/cackle key = "cackle" key_third_person = "cackles" @@ -541,3 +530,18 @@ return user.nextsoundemote = world.time + 10 playsound(user, pick('modular_splurt/sound/voice/aauugghh1.ogg', 'modular_splurt/sound/voice/aauugghh2.ogg'), 40, 1, -1) + +/datum/emote/living/pant + key = "pant" + key_third_person = "pants" + message = "pants!" + +/datum/emote/living/pant/run_emote(mob/user, params, type_override, intentional) + var/list/pants = list( + "pants!", + "pants like a dog.", + "lets out soft pants.", + "pulls [user.p_their()] tongue out, panting." + ) + message = pick(pants) + . = ..() diff --git a/modular_splurt/sound/interactions/kiss/kiss1.ogg b/modular_splurt/sound/interactions/kiss/kiss1.ogg new file mode 100644 index 0000000000..f4bd734338 Binary files /dev/null and b/modular_splurt/sound/interactions/kiss/kiss1.ogg differ diff --git a/modular_splurt/sound/interactions/kiss/kiss2.ogg b/modular_splurt/sound/interactions/kiss/kiss2.ogg new file mode 100644 index 0000000000..18f12d6f04 Binary files /dev/null and b/modular_splurt/sound/interactions/kiss/kiss2.ogg differ diff --git a/modular_splurt/sound/interactions/kiss/kiss3.ogg b/modular_splurt/sound/interactions/kiss/kiss3.ogg new file mode 100644 index 0000000000..0f89617f00 Binary files /dev/null and b/modular_splurt/sound/interactions/kiss/kiss3.ogg differ diff --git a/modular_splurt/sound/interactions/kiss/kiss4.ogg b/modular_splurt/sound/interactions/kiss/kiss4.ogg new file mode 100644 index 0000000000..a7c47dd8af Binary files /dev/null and b/modular_splurt/sound/interactions/kiss/kiss4.ogg differ diff --git a/modular_splurt/sound/interactions/kiss/kiss5.ogg b/modular_splurt/sound/interactions/kiss/kiss5.ogg new file mode 100644 index 0000000000..31a48c4d62 Binary files /dev/null and b/modular_splurt/sound/interactions/kiss/kiss5.ogg differ diff --git a/tgstation.dme b/tgstation.dme index ee6da4c85a..7d0486c655 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -154,6 +154,8 @@ #include "code\__DEFINES\dcs\helpers.dm" #include "code\__DEFINES\dcs\signals.dm" #include "code\__DEFINES\dcs\signals\signals_subsystem.dm" +#include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_movement.dm" +#include "code\__DEFINES\dcs\signals\signals_mob\signals_mob_living.dm" #include "code\__DEFINES\mapping\maploader.dm" #include "code\__DEFINES\material\worth.dm" #include "code\__DEFINES\mobs\innate_abilities.dm" @@ -245,6 +247,7 @@ #include "code\__SPLURTCODE\DEFINES\atmospherics.dm" #include "code\__SPLURTCODE\DEFINES\cit_defines.dm" #include "code\__SPLURTCODE\DEFINES\click.dm" +#include "code\__SPLURTCODE\DEFINES\cooldowns.dm" #include "code\__SPLURTCODE\DEFINES\genital_defines.dm" #include "code\__SPLURTCODE\DEFINES\hud.dm" #include "code\__SPLURTCODE\DEFINES\is_helpers.dm" @@ -252,6 +255,7 @@ #include "code\__SPLURTCODE\DEFINES\login.dm" #include "code\__SPLURTCODE\DEFINES\mobs.dm" #include "code\__SPLURTCODE\DEFINES\pregnancy.dm" +#include "code\__SPLURTCODE\DEFINES\quirks.dm" #include "code\__SPLURTCODE\DEFINES\radiation.dm" #include "code\__SPLURTCODE\DEFINES\say.dm" #include "code\__SPLURTCODE\DEFINES\signals.dm" @@ -261,6 +265,7 @@ #include "code\__SPLURTCODE\DEFINES\subsystems.dm" #include "code\__SPLURTCODE\DEFINES\traits.dm" #include "code\__SPLURTCODE\DEFINES\arousal\genitals.dm" +#include "code\__SPLURTCODE\DEFINES\dcs\signals.dm" #include "code\__SPLURTCODE\DEFINES\zeros\species.dm" #include "code\__SPLURTCODE\DEFINES\zeros\traits.dm" #include "code\_globalvars\admin.dm" @@ -3803,7 +3808,6 @@ #include "interface\skin.dmf" #include "modular_citadel\code\datums\components\souldeath.dm" #include "modular_citadel\code\datums\status_effects\chems.dm" -#include "modular_citadel\code\game\objects\cit_screenshake.dm" #include "modular_citadel\code\game\objects\effects\temporary_visuals\souldeath.dm" #include "modular_citadel\code\modules\admin\holder2.dm" #include "modular_citadel\code\modules\admin\secrets.dm" @@ -4245,14 +4249,18 @@ #include "modular_splurt\code\datums\elements\crawl_under.dm" #include "modular_splurt\code\datums\elements\smalltalk.dm" #include "modular_splurt\code\datums\elements\spooky.dm" +#include "modular_splurt\code\datums\elements\wuv.dm" #include "modular_splurt\code\datums\interactions\cuddling.dm" #include "modular_splurt\code\datums\interactions\lewd\_lewd.dm" #include "modular_splurt\code\datums\interactions\lewd\lewd_datums.dm" #include "modular_splurt\code\datums\interactions\lewd\lewd_interactions.dm" #include "modular_splurt\code\datums\looping_sounds\machinery_sounds.dm" +#include "modular_splurt\code\datums\mood_events\dominant_events.dm" #include "modular_splurt\code\datums\mood_events\drug_events.dm" #include "modular_splurt\code\datums\mood_events\generic_negative_events.dm" #include "modular_splurt\code\datums\mood_events\generic_positive_events.dm" +#include "modular_splurt\code\datums\mood_events\mood_event.dm" +#include "modular_splurt\code\datums\mood_events\needs_events.dm" #include "modular_splurt\code\datums\mutations\telekenisis.dm" #include "modular_splurt\code\datums\ruins\lavaland.dm" #include "modular_splurt\code\datums\ruins\station.dm" @@ -4328,7 +4336,6 @@ #include "modular_splurt\code\game\object\structures\ghost_role_spawners.dm" #include "modular_splurt\code\game\object\structures\micro_bricks.dm" #include "modular_splurt\code\game\object\structures\pole.dm" -#include "modular_splurt\code\game\object\structures\railings.dm" #include "modular_splurt\code\game\object\structures\signs.dm" #include "modular_splurt\code\game\object\structures\statues.dm" #include "modular_splurt\code\game\object\structures\table_frames.dm" @@ -4484,6 +4491,7 @@ #include "modular_splurt\code\modules\food_and_drinks\food\snacks_pastry.dm" #include "modular_splurt\code\modules\food_and_drinks\recipes\drink_recipes.dm" #include "modular_splurt\code\modules\food_and_drinks\recipes\tablecraft\recipes_burger.dm" +#include "modular_splurt\code\modules\food_and_drinks\recipes\tablecraft\recipes_donut.dm" #include "modular_splurt\code\modules\hydroponics\grown\towercap.dm" #include "modular_splurt\code\modules\jobs\job_types\_job_alt_titles.dm" #include "modular_splurt\code\modules\jobs\job_types\blueshield.dm" @@ -4497,10 +4505,12 @@ #include "modular_splurt\code\modules\jobs\job_types\security_officer.dm" #include "modular_splurt\code\modules\jobs\job_types\service.dm" #include "modular_splurt\code\modules\keybindings\keybind\movement.dm" +#include "modular_splurt\code\modules\language\xenocommon.dm" #include "modular_splurt\code\modules\mapping\mapping_helpers\baseturf.dm" #include "modular_splurt\code\modules\mining\shelters.dm" #include "modular_splurt\code\modules\mining\equipment\kinetic_crusher.dm" #include "modular_splurt\code\modules\mining\equipment\survival_pod.dm" +#include "modular_splurt\code\modules\mob\emote.dm" #include "modular_splurt\code\modules\mob\mob.dm" #include "modular_splurt\code\modules\mob\mob_defines.dm" #include "modular_splurt\code\modules\mob\splurt_emotes.dm" @@ -4537,6 +4547,7 @@ #include "modular_splurt\code\modules\mob\living\silicon\robot\dogborg_equipment.dm" #include "modular_splurt\code\modules\mob\living\silicon\robot\robot.dm" #include "modular_splurt\code\modules\mob\living\silicon\robot\robot_modules.dm" +#include "modular_splurt\code\modules\mob\living\simple_animal\simple_animal.dm" #include "modular_splurt\code\modules\mob\living\simple_animal\bot\medbot.dm" #include "modular_splurt\code\modules\mob\living\simple_animal\friendly\mouse.dm" #include "modular_splurt\code\modules\mob\living\simple_animal\gremlin\gremlin.dm" diff --git a/tgui/packages/tgui/interfaces/MobInteraction.js b/tgui/packages/tgui/interfaces/MobInteraction.tsx similarity index 88% rename from tgui/packages/tgui/interfaces/MobInteraction.js rename to tgui/packages/tgui/interfaces/MobInteraction.tsx index 125217d898..ca7146740b 100644 --- a/tgui/packages/tgui/interfaces/MobInteraction.js +++ b/tgui/packages/tgui/interfaces/MobInteraction.tsx @@ -5,8 +5,69 @@ import { useBackend, useLocalState } from '../backend'; import { BlockQuote, Button, Flex, LabeledList, Icon, Input, Section, Table, Tabs, Stack } from '../components'; import { Window } from '../layouts'; +type HeaderInfo = { + isTargetSelf: boolean; + interactingWith: string; + selfAttributes: string[]; + theirAttributes: string[]; +} + +type ContentInfo = { + interactions: InteractionData[]; +} + +type InteractionData = { + key: string; + desc: string; + type: number; +} + +type GenitalInfo = { + genitals: GenitalData[]; +} + +type GenitalData = { + name: string, + key: string, + visibility: string, + possible_choices: string[], +} + +type CharacterPrefsInfo = { + erp_pref: number, + noncon_pref: number, + vore_pref: number, + extreme_pref: number, + unholy_pref: number, + extreme_harm: boolean, +} + +type ContentPrefsInfo = { + verb_consent: number, + lewd_verb_sounds: number, + arousable: number, + genital_examine: number, + vore_examine: number, + medihound_sleeper: number, + eating_noises: number, + digestion_noises: number, + trash_forcefeed: number, + forced_fem: number, + forced_masc: number, + hypno: number, + bimbofication: number, + breast_enlargement: number, + penis_enlargement: number, + butt_enlargement: number, + belly_inflation: number, + never_hypno: number, + no_aphro: number, + no_ass_slap: number, + no_auto_wag: number, +} + export const MobInteraction = (props, context) => { - const { act, data } = useBackend(context); + const { act, data } = useBackend(context); const { isTargetSelf, interactingWith, @@ -78,7 +139,7 @@ export const MobInteraction = (props, context) => { }; const InteractionsTab = (props, context) => { - const { act, data } = useBackend(context); + const { act, data } = useBackend(context); const [ searchText, setSearchText, @@ -103,20 +164,20 @@ const InteractionsTab = (props, context) => { { interactions.length ? ( interactions.map((interaction) => ( - +