diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index 26556306fd53c..c91658d62ab07 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -74302,8 +74302,8 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/cable, -/obj/structure/disposalpipe/junction/flip{ - dir = 4 +/obj/structure/disposalpipe/junction{ + dir = 8 }, /turf/open/floor/iron, /area/station/hallway/primary/starboard) diff --git a/code/__DEFINES/diseases.dm b/code/__DEFINES/diseases.dm index 047bb79582de4..fe05a30e0fd83 100644 --- a/code/__DEFINES/diseases.dm +++ b/code/__DEFINES/diseases.dm @@ -81,28 +81,28 @@ DEFINE_BITFIELD(spread_flags, list( //// Adjust to make it faster or slower to cure once the virus has reached its peak. #define DISEASE_PEAKED_RECOVERY_MULTIPLIER 1.2 /// Slowdown Recovery Bonus - set this to the maximum extra chance per tick you want people to get to recover from spaceacillin or other slowdown/virus resistance effects -#define DISEASE_SLOWDOWN_RECOVERY_BONUS 1 -/// Slowdown Recovery Bonus Duration - set this to the maximum # of cycles you want things that cause slowdown/virus resistance to be able to add a bonus up to DISEASE_SLOWDOWN_RECOVERY_BONUS.______qdel_list_wrapper(list/L) +#define DISEASE_SLOWDOWN_RECOVERY_BONUS 3 +/// Slowdown Recovery Bonus Duration - set this to the maximum # of cycles you want things that cause slowdown/virus resistance to be able to add a bonus up to DISEASE_SLOWDOWN_RECOVERY_BONUS. //// Scales down linearly over time. -#define DISEASE_SLOWDOWN_RECOVERY_BONUS_DURATION 100 +#define DISEASE_SLOWDOWN_RECOVERY_BONUS_DURATION 200 /// Negative Malnutrition Recovery Penalty //// Flat penalty to recovery chance if malnourished or starving -#define DISEASE_MALNUTRITION_RECOVERY_PENALTY 1.5 +#define DISEASE_MALNUTRITION_RECOVERY_PENALTY 3 /// Satiety Recovery Multiplier - added chance to recover based on positive satiety //// Multiplier of satiety/max_satiety if satiety is positive or zero. Increase to make satiety more valuable, decrease for less. -#define DISEASE_SATIETY_RECOVERY_MULTIPLIER 1 +#define DISEASE_SATIETY_RECOVERY_MULTIPLIER 3 /// Good Sleeping Recovery Bonus - additive benefits for various types of good sleep (blanket, bed, darkness, pillows.) //// Raise to make each factor add this much chance to recover. -#define DISEASE_GOOD_SLEEPING_RECOVERY_BONUS 0.2 +#define DISEASE_GOOD_SLEEPING_RECOVERY_BONUS 0.6 /// Sleeping Recovery Multiplier - multiplies ALL recovery chance effects by this amount. //// Set to 1 for no effect on recovery chances from sleeping. -#define DISEASE_SLEEPING_RECOVERY_MULTIPLIER 2 +#define DISEASE_SLEEPING_RECOVERY_MULTIPLIER 6 /// Final Cure Chance Multiplier - multiplies the disease's cure chance to get the probability of moving from stage 1 to a final cure. //// Must be greater than zero for diseases to self cure. -#define DISEASE_FINAL_CURE_CHANCE_MULTIPLIER 3 +#define DISEASE_FINAL_CURE_CHANCE_MULTIPLIER 6 /// Symptom Offset Duration - number of cycles over which sleeping/having spaceacillin or a slowdown effect can prevent symptoms appearing //// Set to maximum # of cycles you want to be able to offset symptoms. Scales down linearly over time. -#define DISEASE_SYMPTOM_OFFSET_DURATION 100 +#define DISEASE_SYMPTOM_OFFSET_DURATION 200 /// Symptom Frequency Modifier //// Raise to make symptoms fire less frequently, lower to make them fire more frequently. Keep at 0 or above. diff --git a/code/_onclick/click_alt.dm b/code/_onclick/click_alt.dm index 7f762a6e920ea..dfda35ebda9c8 100644 --- a/code/_onclick/click_alt.dm +++ b/code/_onclick/click_alt.dm @@ -24,8 +24,14 @@ client.loot_panel.open(tile) return - // Turfs don't have a click_alt currently, so this saves some time. - if(!isturf(target) && can_perform_action(target, (target.interaction_flags_click | SILENT_ADJACENCY))) + var/can_use_click_action = FALSE + if(isturf(target)) + // Turfs are special because they can't be used with can_perform_action + can_use_click_action = can_perform_turf_action(target) + else + can_use_click_action = can_perform_action(target, (target.interaction_flags_click | SILENT_ADJACENCY)) + + if(can_use_click_action) // If it has a signal handler that returns a click action, done. if(SEND_SIGNAL(target, COMSIG_CLICK_ALT, src) & CLICK_ACTION_ANY) return @@ -38,6 +44,13 @@ if(HAS_TRAIT(src, TRAIT_MOVE_VENTCRAWLING)) return + /// No loot panel if it's on our person + if(isobj(target) && isliving(src)) + var/mob/living/user = src + if(target in user.get_all_gear()) + to_chat(user, span_warning("You can't search for this item, it's already in your inventory! Take it off first.")) + return + client.loot_panel.open(tile) @@ -71,3 +84,15 @@ /atom/proc/click_alt(mob/user) SHOULD_CALL_PARENT(FALSE) return NONE + + +/// Helper proc to validate turfs. Used because can_perform_action does not support turfs. +/mob/proc/can_perform_turf_action(turf/target) + if(!CanReach(target)) // No error message for parity with SILENT_ADJACENCY + return FALSE + + if(incapacitated()) + to_chat(src, span_warning("You can't use this!")) + return FALSE + + return TRUE diff --git a/code/_onclick/hud/parallax/parallax.dm b/code/_onclick/hud/parallax/parallax.dm index 506226b41ead0..bcdcd0e74fed1 100644 --- a/code/_onclick/hud/parallax/parallax.dm +++ b/code/_onclick/hud/parallax/parallax.dm @@ -11,6 +11,10 @@ for(var/atom/movable/screen/plane_master/parallax as anything in get_true_plane_masters(PLANE_SPACE_PARALLAX)) parallax.unhide_plane(screenmob) + if(isnull(C.parallax_rock)) + C.parallax_rock = new(null, src) + C.screen |= C.parallax_rock + if(!length(C.parallax_layers_cached)) C.parallax_layers_cached = list() C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_1(null, src) @@ -25,7 +29,7 @@ if (length(C.parallax_layers) > C.parallax_layers_max) C.parallax_layers.len = C.parallax_layers_max - C.screen |= (C.parallax_layers) + C.parallax_rock.vis_contents = C.parallax_layers // We could do not do parallax for anything except the main plane group // This could be changed, but it would require refactoring this whole thing // And adding non client particular hooks for all the inputs, and I do not have the time I'm sorry :( @@ -44,7 +48,7 @@ /datum/hud/proc/remove_parallax(mob/viewmob) var/mob/screenmob = viewmob || mymob var/client/C = screenmob.client - C.screen -= (C.parallax_layers_cached) + C.screen -= (C.parallax_rock) for(var/atom/movable/screen/plane_master/plane_master as anything in screenmob.hud_used.get_true_plane_masters(PLANE_SPACE)) if(screenmob != mymob) C.screen -= locate(/atom/movable/screen/plane_master/parallax_white) in C.screen @@ -104,83 +108,65 @@ update_parallax(screen_mob) // This sets which way the current shuttle is moving (returns true if the shuttle has stopped moving so the caller can append their animation) -/datum/hud/proc/set_parallax_movedir(new_parallax_movedir = 0, skip_windups, mob/viewmob) +/datum/hud/proc/set_parallax_movedir(new_parallax_movedir = NONE, skip_windups, mob/viewmob) . = FALSE var/mob/screenmob = viewmob || mymob var/client/C = screenmob.client if(new_parallax_movedir == C.parallax_movedir) return - var/animatedir = new_parallax_movedir - if(new_parallax_movedir == FALSE) - var/animate_time = 0 - for(var/thing in C.parallax_layers) - var/atom/movable/screen/parallax_layer/L = thing - L.icon_state = initial(L.icon_state) - L.update_o(C.view) - var/T = PARALLAX_LOOP_TIME / L.speed - if (T > animate_time) - animate_time = T - C.dont_animate_parallax = world.time + min(animate_time, PARALLAX_LOOP_TIME) - animatedir = C.parallax_movedir - - var/matrix/newtransform - switch(animatedir) + + var/animation_dir = new_parallax_movedir || C.parallax_movedir + var/matrix/new_transform + switch(animation_dir) if(NORTH) - newtransform = matrix(1, 0, 0, 0, 1, 480) + new_transform = matrix(1, 0, 0, 0, 1, 480) if(SOUTH) - newtransform = matrix(1, 0, 0, 0, 1,-480) + new_transform = matrix(1, 0, 0, 0, 1,-480) if(EAST) - newtransform = matrix(1, 0, 480, 0, 1, 0) + new_transform = matrix(1, 0, 480, 0, 1, 0) if(WEST) - newtransform = matrix(1, 0,-480, 0, 1, 0) - - var/shortesttimer - if(!skip_windups) - for(var/thing in C.parallax_layers) - var/atom/movable/screen/parallax_layer/L = thing - - var/T = PARALLAX_LOOP_TIME / L.speed - if (isnull(shortesttimer)) - shortesttimer = T - if (T < shortesttimer) - shortesttimer = T - L.transform = newtransform - animate(L, transform = matrix(), time = T, easing = QUAD_EASING | (new_parallax_movedir ? EASE_IN : EASE_OUT), flags = ANIMATION_END_NOW) - if (new_parallax_movedir) - L.transform = newtransform - animate(transform = matrix(), time = T) //queue up another animate so lag doesn't create a shutter + new_transform = matrix(1, 0,-480, 0, 1, 0) + + var/longest_timer = 0 + for(var/key in C.parallax_animate_timers) + deltimer(C.parallax_animate_timers[key]) + C.parallax_animate_timers = list() + for(var/atom/movable/screen/parallax_layer/layer as anything in C.parallax_layers) + var/scaled_time = PARALLAX_LOOP_TIME / layer.speed + if(new_parallax_movedir == NONE) // If we're stopping, we need to stop on the same dime, yeah? + scaled_time = PARALLAX_LOOP_TIME + longest_timer = max(longest_timer, scaled_time) + + if(skip_windups) + update_parallax_motionblur(C, layer, new_parallax_movedir, new_transform) + continue - C.parallax_movedir = new_parallax_movedir - if (C.parallax_animate_timer) - deltimer(C.parallax_animate_timer) - var/datum/callback/CB = CALLBACK(src, PROC_REF(update_parallax_motionblur), C, animatedir, new_parallax_movedir, newtransform) - if(skip_windups) - CB.Invoke() - else - C.parallax_animate_timer = addtimer(CB, min(shortesttimer, PARALLAX_LOOP_TIME), TIMER_CLIENT_TIME|TIMER_STOPPABLE) + layer.transform = new_transform + animate(layer, transform = matrix(), time = scaled_time, easing = QUAD_EASING | (new_parallax_movedir ? EASE_IN : EASE_OUT)) + if (new_parallax_movedir == NONE) + continue + //queue up another animate so lag doesn't create a shutter + animate(transform = new_transform, time = 0) + animate(transform = matrix(), time = scaled_time / 2) + C.parallax_animate_timers[layer] = addtimer(CALLBACK(src, PROC_REF(update_parallax_motionblur), C, layer, new_parallax_movedir, new_transform), scaled_time, TIMER_CLIENT_TIME|TIMER_STOPPABLE) + C.dont_animate_parallax = world.time + min(longest_timer, PARALLAX_LOOP_TIME) + C.parallax_movedir = new_parallax_movedir -/datum/hud/proc/update_parallax_motionblur(client/C, animatedir, new_parallax_movedir, matrix/newtransform) +/datum/hud/proc/update_parallax_motionblur(client/C, atom/movable/screen/parallax_layer/layer, new_parallax_movedir, matrix/new_transform) if(!C) return - C.parallax_animate_timer = FALSE - for(var/thing in C.parallax_layers) - var/atom/movable/screen/parallax_layer/L = thing - if (!new_parallax_movedir) - animate(L) - continue - - var/newstate = initial(L.icon_state) - var/T = PARALLAX_LOOP_TIME / L.speed - - if (newstate in icon_states(L.icon)) - L.icon_state = newstate - L.update_o(C.view) - - L.transform = newtransform - - animate(L, transform = L.transform, time = 0, loop = -1, flags = ANIMATION_END_NOW) - animate(transform = matrix(), time = T) + C.parallax_animate_timers -= layer + + // If we are moving in a direction, we used the QUAD_EASING function with EASE_IN + // This means our position function is x^2. This is always LESS then the linear we're using here + // But if we just used the same time delay, our rate of change would mismatch. f'(1) = 2x for quad easing, rather then the 1 we get for linear + // (This is because of how derivatives work right?) + // Because of this, while our actual rate of change from before was PARALLAX_LOOP_TIME, our perceived rate of change was PARALLAX_LOOP_TIME / 2 (lower == faster). + // Let's account for that here + var/scaled_time = (PARALLAX_LOOP_TIME / layer.speed) / 2 + animate(layer, transform = new_transform, time = 0, loop = -1, flags = ANIMATION_END_NOW) + animate(transform = matrix(), time = scaled_time) /datum/hud/proc/update_parallax(mob/viewmob) var/mob/screenmob = viewmob || mymob @@ -217,36 +203,41 @@ var/our_speed = parallax_layer.speed var/change_x var/change_y + var/old_x = parallax_layer.offset_x + var/old_y = parallax_layer.offset_y if(parallax_layer.absolute) // We use change here so the typically large absolute objects (just lavaland for now) don't jitter so much - change_x = (posobj.x - SSparallax.planet_x_offset) * our_speed + parallax_layer.offset_x - change_y = (posobj.y - SSparallax.planet_y_offset) * our_speed + parallax_layer.offset_y + change_x = (posobj.x - SSparallax.planet_x_offset) * our_speed + old_x + change_y = (posobj.y - SSparallax.planet_y_offset) * our_speed + old_y else change_x = offset_x * our_speed change_y = offset_y * our_speed // This is how we tile parralax sprites // It doesn't use change because we really don't want to animate this - if(parallax_layer.offset_x - change_x > 240) + if(old_x - change_x > 240) parallax_layer.offset_x -= 480 - else if(parallax_layer.offset_x - change_x < -240) + parallax_layer.pixel_w = parallax_layer.offset_x + else if(old_x - change_x < -240) parallax_layer.offset_x += 480 - if(parallax_layer.offset_y - change_y > 240) + parallax_layer.pixel_w = parallax_layer.offset_x + if(old_y - change_y > 240) parallax_layer.offset_y -= 480 - else if(parallax_layer.offset_y - change_y < -240) + parallax_layer.pixel_z = parallax_layer.offset_y + else if(old_y - change_y < -240) parallax_layer.offset_y += 480 + parallax_layer.pixel_z = parallax_layer.offset_y - // Now that we have our offsets, let's do our positioning parallax_layer.offset_x -= change_x parallax_layer.offset_y -= change_y - - parallax_layer.screen_loc = "CENTER-7:[round(parallax_layer.offset_x, 1)],CENTER-7:[round(parallax_layer.offset_y, 1)]" - - // We're going to use a transform to "glide" that last movement out, so it looks nicer + // Now that we have our offsets, let's do our positioning + // We're going to use an animate to "glide" that last movement out, so it looks nicer // Don't do any animates if we're not actually moving enough distance yeah? thanks lad if(run_parralax && (largest_change * our_speed > 1)) - parallax_layer.transform = matrix(1,0,change_x, 0,1,change_y) - animate(parallax_layer, transform=matrix(), time = glide_rate) + animate(parallax_layer, pixel_w = round(parallax_layer.offset_x, 1), pixel_z = round(parallax_layer.offset_y, 1), time = glide_rate) + else + parallax_layer.pixel_w = round(parallax_layer.offset_x, 1) + parallax_layer.pixel_z = round(parallax_layer.offset_y, 1) /atom/movable/proc/update_parallax_contents() for(var/mob/client_mob as anything in client_mobs_in_contents) @@ -258,6 +249,15 @@ var/area/areaobj = get_area(client.eye) hud_used.set_parallax_movedir(areaobj.parallax_movedir, TRUE) +// Root object for parallax, all parallax layers are drawn onto this +INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_home) +/atom/movable/screen/parallax_home + icon = null + blend_mode = BLEND_ADD + plane = PLANE_SPACE_PARALLAX + screen_loc = "CENTER-7,CENTER-7" + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + // We need parallax to always pass its args down into initialize, so we immediate init it INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) /atom/movable/screen/parallax_layer @@ -266,9 +266,9 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) var/offset_x = 0 var/offset_y = 0 var/absolute = FALSE + appearance_flags = APPEARANCE_UI | KEEP_TOGETHER blend_mode = BLEND_ADD plane = PLANE_SPACE_PARALLAX - screen_loc = "CENTER-7,CENTER-7" mouse_opacity = MOUSE_OPACITY_TRANSPARENT /atom/movable/screen/parallax_layer/Initialize(mapload, datum/hud/hud_owner, template = FALSE) @@ -302,15 +302,17 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) // Turn the view size into a grid of correctly scaled overlays var/list/viewscales = getviewsize(view) - var/countx = CEILING((viewscales[1] / 2) * parallax_scaler, 1) + 1 - var/county = CEILING((viewscales[2] / 2) * parallax_scaler, 1) + 1 + // This could be half the size but we need to provide space for parallax movement on mob movement, and movement on scroll from shuttles, so like this instead + var/countx = (CEILING((viewscales[1] / 2) * parallax_scaler, 1) + 1) + var/county = (CEILING((viewscales[2] / 2) * parallax_scaler, 1) + 1) var/list/new_overlays = new for(var/x in -countx to countx) for(var/y in -county to county) if(x == 0 && y == 0) continue var/mutable_appearance/texture_overlay = mutable_appearance(icon, icon_state) - texture_overlay.transform = matrix(1, 0, x*480, 0, 1, y*480) + texture_overlay.pixel_w += 480 * x + texture_overlay.pixel_z += 480 * y new_overlays += texture_overlay cut_overlays() add_overlay(new_overlays) diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index ea22327f13592..6f30f2a51355d 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -793,7 +793,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/splash) food_image = image(icon = food_icon, icon_state = food_icon_state, pixel_x = -5) food_image.plane = plane food_image.appearance_flags |= KEEP_APART // To be unaffected by filters applied to src - food_image.add_filter("simple_outline", 2, outline_filter(1, COLOR_BLACK)) + food_image.add_filter("simple_outline", 2, outline_filter(1, COLOR_BLACK, OUTLINE_SHARP)) underlays += food_image // To be below filters applied to src SetInvisibility(INVISIBILITY_ABSTRACT, name) // Start invisible, update later diff --git a/code/controllers/subsystem/profiler.dm b/code/controllers/subsystem/profiler.dm index dc06c2bc6ae7f..46d5b0fd57ba5 100644 --- a/code/controllers/subsystem/profiler.dm +++ b/code/controllers/subsystem/profiler.dm @@ -1,11 +1,8 @@ -#define PROFILER_FILENAME "profiler.json" -#define SENDMAPS_FILENAME "sendmaps.json" - SUBSYSTEM_DEF(profiler) name = "Profiler" init_order = INIT_ORDER_PROFILER runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY - wait = 3000 + wait = 300 SECONDS var/fetch_cost = 0 var/write_cost = 0 @@ -56,12 +53,12 @@ SUBSYSTEM_DEF(profiler) if(!length(current_profile_data)) //Would be nice to have explicit proc to check this stack_trace("Warning, profiling stopped manually before dump.") - var/prof_file = file("[GLOB.log_directory]/[PROFILER_FILENAME]") + var/prof_file = file("[GLOB.log_directory]/profiler/profiler-[round(world.time * 0.1, 10)].json") if(fexists(prof_file)) fdel(prof_file) if(!length(current_sendmaps_data)) //Would be nice to have explicit proc to check this stack_trace("Warning, sendmaps profiling stopped manually before dump.") - var/sendmaps_file = file("[GLOB.log_directory]/[SENDMAPS_FILENAME]") + var/sendmaps_file = file("[GLOB.log_directory]/profiler/sendmaps-[round(world.time * 0.1, 10)].json") if(fexists(sendmaps_file)) fdel(sendmaps_file) @@ -70,5 +67,3 @@ SUBSYSTEM_DEF(profiler) WRITE_FILE(sendmaps_file, current_sendmaps_data) write_cost = MC_AVERAGE(write_cost, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) -#undef PROFILER_FILENAME -#undef SENDMAPS_FILENAME diff --git a/code/datums/actions/cooldown_action.dm b/code/datums/actions/cooldown_action.dm index 18fe9f22e8024..1c290c5f224c1 100644 --- a/code/datums/actions/cooldown_action.dm +++ b/code/datums/actions/cooldown_action.dm @@ -171,6 +171,9 @@ next_use_time = world.time + override_cooldown_time else next_use_time = world.time + cooldown_time + // Don't start a cooldown if we have a cooldown time of 0 seconds + if(next_use_time == world.time) + return build_all_button_icons(UPDATE_BUTTON_STATUS) START_PROCESSING(SSfastprocess, src) diff --git a/code/datums/actions/mobs/ground_slam.dm b/code/datums/actions/mobs/ground_slam.dm new file mode 100644 index 0000000000000..e00799196b589 --- /dev/null +++ b/code/datums/actions/mobs/ground_slam.dm @@ -0,0 +1,32 @@ +/datum/action/cooldown/mob_cooldown/ground_slam + name = "Ground Slam" + button_icon = 'icons/mob/actions/actions_items.dmi' + button_icon_state = "sniper_zoom" + desc = "Slams the ground sending out a shockwave around you." + cooldown_time = 10 SECONDS + /// The range of the slam + var/range = 5 + /// The delay before the shockwave expands it's range + var/delay = 3 + /// How far hit targets are thrown + var/throw_range = 8 + /// Whether the target can move or not while the slam is occurring + var/can_move = FALSE + +/datum/action/cooldown/mob_cooldown/ground_slam/Activate(atom/target_atom) + disable_cooldown_actions() + RegisterSignal(owner, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(on_move), override = TRUE) + do_slam(target_atom) + UnregisterSignal(owner, COMSIG_MOVABLE_PRE_MOVE) + StartCooldown() + enable_cooldown_actions() + return TRUE + +/// Slams the ground around the source throwing back enemies caught nearby, delay is for the radius increase +/datum/action/cooldown/mob_cooldown/ground_slam/proc/do_slam(atom/target) + wendigo_slam(owner, range, delay, throw_range) + +/datum/action/cooldown/mob_cooldown/ground_slam/proc/on_move(atom/source, atom/new_loc) + SIGNAL_HANDLER + if(!can_move) + return COMPONENT_MOVABLE_BLOCK_PRE_MOVE diff --git a/code/datums/actions/mobs/projectileattack.dm b/code/datums/actions/mobs/projectileattack.dm index be7eff8963363..d8f8e6bdf6427 100644 --- a/code/datums/actions/mobs/projectileattack.dm +++ b/code/datums/actions/mobs/projectileattack.dm @@ -16,14 +16,23 @@ var/default_projectile_spread = 0 /// The multiplier to the projectiles speed (a value of 2 makes it twice as slow, 0.5 makes it twice as fast) var/projectile_speed_multiplier = 1 + /// Whether the target can move or not while the attack is occurring + var/can_move = TRUE /datum/action/cooldown/mob_cooldown/projectile_attack/Activate(atom/target_atom) disable_cooldown_actions() + RegisterSignal(owner, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(on_move), override = TRUE) attack_sequence(owner, target_atom) + UnregisterSignal(owner, COMSIG_MOVABLE_PRE_MOVE) StartCooldown() enable_cooldown_actions() return TRUE +/datum/action/cooldown/mob_cooldown/projectile_attack/proc/on_move(atom/source, atom/new_loc) + SIGNAL_HANDLER + if(!can_move) + return COMPONENT_MOVABLE_BLOCK_PRE_MOVE + /datum/action/cooldown/mob_cooldown/projectile_attack/proc/attack_sequence(mob/living/firer, atom/target) shoot_projectile(firer, target, null, firer, rand(-default_projectile_spread, default_projectile_spread), null) @@ -151,6 +160,25 @@ SLEEP_CHECK_DEATH(1.5 SECONDS, owner) return ..() +/datum/action/cooldown/mob_cooldown/projectile_attack/spiral_shots/wendigo + cooldown_time = 10 SECONDS + projectile_type = /obj/projectile/colossus/wendigo_shockwave/spiral + can_move = FALSE + +/datum/action/cooldown/mob_cooldown/projectile_attack/spiral_shots/wendigo/create_spiral_attack(mob/living/firer, atom/target, negative = pick(TRUE, FALSE)) + wendigo_scream(firer) + var/shots_spiral = 40 + var/angle_to_target = get_angle(firer, target) + var/spiral_direction = pick(-1, 1) + for(var/shot in 1 to shots_spiral) + var/shots_per_tick = 5 - enraged * 3 + var/angle_change = (5 + enraged * shot / 6) * spiral_direction + for(var/count in 1 to shots_per_tick) + var/angle = angle_to_target + shot * angle_change + count * 360 / shots_per_tick + shoot_projectile(firer, target, angle, firer, null, null) + SLEEP_CHECK_DEATH(1, firer) + SLEEP_CHECK_DEATH(3 SECONDS, firer) + /datum/action/cooldown/mob_cooldown/projectile_attack/random_aoe name = "All Directions" button_icon = 'icons/effects/effects.dmi' @@ -192,6 +220,13 @@ shoot_projectile(firer, target, null, firer, spread, null) +/datum/action/cooldown/mob_cooldown/projectile_attack/shotgun_blast/wendigo + cooldown_time = 10 SECONDS + projectile_type = /obj/projectile/colossus/wendigo_shockwave + shot_angles = list(-20, -10, 0, 10, 20) + projectile_speed_multiplier = 4 + + /datum/action/cooldown/mob_cooldown/projectile_attack/shotgun_blast/colossus cooldown_time = 0.5 SECONDS @@ -327,3 +362,54 @@ colossus.telegraph() colossus.dir_shots.attack_sequence(firer, target) SLEEP_CHECK_DEATH(1 SECONDS, firer) + +/datum/action/cooldown/mob_cooldown/projectile_attack/alternating_circle + name = "Alternating Shots" + button_icon = 'icons/mob/actions/actions_items.dmi' + button_icon_state = "sniper_zoom" + desc = "Fires projectiles around you in an alternating fashion." + cooldown_time = 10 SECONDS + projectile_type = /obj/projectile/colossus/wendigo_shockwave + can_move = FALSE + var/enraged = FALSE + +/datum/action/cooldown/mob_cooldown/projectile_attack/alternating_circle/attack_sequence(mob/living/firer, atom/target) + wendigo_scream(firer) + if(enraged) + projectile_speed_multiplier = 1 + else + projectile_speed_multiplier = 1.5 + var/shots_per = 24 + for(var/shoot_times in 1 to 8) + var/offset = shoot_times % 2 + for(var/shot in 1 to shots_per) + var/angle = shot * 360 / shots_per + (offset * 360 / shots_per) * 0.5 + shoot_projectile(firer, target, angle, firer, null, null) + SLEEP_CHECK_DEATH(6 - enraged * 2, firer) + SLEEP_CHECK_DEATH(3 SECONDS, firer) + +/datum/action/cooldown/mob_cooldown/projectile_attack/wave + name = "Wave Shots" + button_icon = 'icons/mob/actions/actions_items.dmi' + button_icon_state = "sniper_zoom" + desc = "Fires projectiles around you in a circular wave." + cooldown_time = 10 SECONDS + projectile_type = /obj/projectile/colossus/wendigo_shockwave/wave + can_move = FALSE + +/datum/action/cooldown/mob_cooldown/projectile_attack/wave/attack_sequence(mob/living/firer, atom/target) + wendigo_scream(firer) + var/shots_per = 7 + var/difference = 360 / shots_per + var/wave_direction = pick(-1, 1) + switch(wave_direction) + if(-1) + projectile_type = /obj/projectile/colossus/wendigo_shockwave/wave/alternate + if(1) + projectile_type = /obj/projectile/colossus/wendigo_shockwave/wave + for(var/shoot_times in 1 to 32) + for(var/shot in 1 to shots_per) + var/angle = shot * difference + shoot_times * 5 * wave_direction * -1 + shoot_projectile(firer, target, angle, firer, null, null) + SLEEP_CHECK_DEATH(2, firer) + SLEEP_CHECK_DEATH(3 SECONDS, firer) diff --git a/code/datums/actions/mobs/teleport.dm b/code/datums/actions/mobs/teleport.dm new file mode 100644 index 0000000000000..7b7ffddf30b3d --- /dev/null +++ b/code/datums/actions/mobs/teleport.dm @@ -0,0 +1,25 @@ +/datum/action/cooldown/mob_cooldown/teleport + name = "Teleport" + button_icon = 'icons/mob/actions/actions_items.dmi' + button_icon_state = "sniper_zoom" + desc = "Allows you to teleport a certain distance away from a position in a random direction." + cooldown_time = 10 SECONDS + /// The distance from the target + var/radius = 6 + +/datum/action/cooldown/mob_cooldown/teleport/Activate(atom/target_atom) + disable_cooldown_actions() + teleport_to(target_atom) + StartCooldown() + enable_cooldown_actions() + return TRUE + +/// Handles randomly teleporting the owner around the target in view +/datum/action/cooldown/mob_cooldown/teleport/proc/teleport_to(atom/teleport_target) + var/list/possible_ends = view(radius, teleport_target.loc) - view(radius - 1, teleport_target.loc) + for(var/turf/closed/cant_teleport_turf in possible_ends) + possible_ends -= cant_teleport_turf + if(!possible_ends.len) + return + var/turf/end = pick(possible_ends) + do_teleport(owner, end, 0, channel=TELEPORT_CHANNEL_BLUESPACE, forced = TRUE) diff --git a/code/datums/components/echolocation.dm b/code/datums/components/echolocation.dm index 60a6d0fa8aa3c..020c47ad875e1 100644 --- a/code/datums/components/echolocation.dm +++ b/code/datums/components/echolocation.dm @@ -4,11 +4,11 @@ /// Time between echolocations. IMPORTANT!! The effective time in local and the effective time in live are very different. The second is noticeably slower, var/cooldown_time = 1 SECONDS /// Time for the image to start fading out. - var/image_expiry_time = 1.4 SECONDS + var/image_expiry_time = 0.7 SECONDS /// Time for the image to fade in. - var/fade_in_time = 0.4 SECONDS + var/fade_in_time = 0.2 SECONDS /// Time for the image to fade out and delete itself. - var/fade_out_time = 0.4 SECONDS + var/fade_out_time = 0.3 SECONDS /// Are images static? If yes, spawns them on the turf and makes them not change location. Otherwise they change location and pixel shift with the original. var/images_are_static = TRUE /// With mobs that have this echo group in their echolocation receiver trait, we share echo images. @@ -105,7 +105,7 @@ for(var/mob/living/viewer in filtered) if(blocking_trait && HAS_TRAIT(viewer, blocking_trait)) continue - if(HAS_TRAIT_FROM(viewer, TRAIT_ECHOLOCATION_RECEIVER, echo_group)) + if(HAS_TRAIT_FROM(viewer, TRAIT_ECHOLOCATION_RECEIVER, echo_group) && isnull(receivers[viewer])) receivers[viewer] = list() for(var/atom/filtered_atom as anything in filtered) show_image(saved_appearances["[filtered_atom.icon]-[filtered_atom.icon_state]"] || generate_appearance(filtered_atom), filtered_atom, current_time) @@ -175,6 +175,7 @@ for(var/atom/rendered_atom as anything in receivers[echolocate_receiver]) if(receivers[echolocate_receiver][rendered_atom]["time"] <= from_when && echolocate_receiver.client) echolocate_receiver.client.images -= receivers[echolocate_receiver][rendered_atom]["image"] + receivers[echolocate_receiver] -= rendered_atom if(!length(receivers[echolocate_receiver])) receivers -= echolocate_receiver diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm index bc60049e73ea6..da0a849989ec1 100644 --- a/code/datums/diseases/_disease.dm +++ b/code/datums/diseases/_disease.dm @@ -140,9 +140,9 @@ if(affected_mob.mob_mood) // this and most other modifiers below a shameless rip from sleeping healing buffs, but feeling good helps make it go away quicker switch(affected_mob.mob_mood.sanity_level) if(SANITY_LEVEL_GREAT) - recovery_prob += 0.2 + recovery_prob += 0.4 if(SANITY_LEVEL_NEUTRAL) - recovery_prob += 0.1 + recovery_prob += 0.2 if(SANITY_LEVEL_DISTURBED) recovery_prob += 0 if(SANITY_LEVEL_UNSTABLE) diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm index 93edea10b41c6..3d8bfdf8837dd 100644 --- a/code/datums/diseases/advance/advance.dm +++ b/code/datums/diseases/advance/advance.dm @@ -266,12 +266,13 @@ properties["severity"] = round((properties["severity"] / 2), 1) properties["severity"] *= (symptoms.len / VIRUS_SYMPTOM_LIMIT) //fewer symptoms, less severity properties["severity"] = clamp(properties["severity"], 1, 7) + properties["capacity"] = get_symptom_weights() // Assign the properties that are in the list. /datum/disease/advance/proc/assign_properties() if(properties?.len) - if(properties["stealth"] >= 2) + if(properties["stealth"] >= properties["severity"]) visibility_flags |= HIDDEN_SCANNER else visibility_flags &= ~HIDDEN_SCANNER @@ -287,7 +288,7 @@ spreading_modifier = max(CEILING(0.4 * properties["transmittable"], 1), 1) cure_chance = clamp(7.5 - (0.5 * properties["resistance"]), 1, 10) // can be between 1 and 10 - stage_prob = max(0.5 * properties["stage_rate"], 1) + stage_prob = max(0.3 * properties["stage_rate"], 1) set_severity(round(properties["severity"]), 1) generate_cure(properties) else @@ -341,7 +342,7 @@ // Will generate a random cure, the more resistance the symptoms have, the harder the cure. /datum/disease/advance/proc/generate_cure() if(properties?.len) - var/res = clamp(properties["resistance"] - (symptoms.len / 2), 1, advance_cures.len) + var/res = clamp(properties["resistance"] - (symptoms.len * 0.5), 1, advance_cures.len) if(res == oldres) return cures = list(pick(advance_cures[res])) @@ -402,11 +403,9 @@ // Add a symptom, if it is over the limit we take a random symptom away and add the new one. /datum/disease/advance/proc/AddSymptom(datum/symptom/S) - if(HasSymptom(S)) return - - if(symptoms.len >= VIRUS_SYMPTOM_LIMIT) + while(get_symptom_weights() > VIRUS_SYMPTOM_LIMIT + S.weight) RemoveSymptom(pick(symptoms)) symptoms += S S.OnAdd(src) @@ -423,6 +422,12 @@ S.name += " (neutered)" S.OnRemove(src) +/// How much of the symptom capacity is currently being used? +/datum/disease/advance/proc/get_symptom_weights() + . = 0 + for(var/datum/symptom/symptom as anything in symptoms) + . += symptom.weight + /* Static Procs diff --git a/code/datums/diseases/advance/symptoms/cough.dm b/code/datums/diseases/advance/symptoms/cough.dm index 7368e99acc814..0a29a633a30ae 100644 --- a/code/datums/diseases/advance/symptoms/cough.dm +++ b/code/datums/diseases/advance/symptoms/cough.dm @@ -10,6 +10,7 @@ name = "Cough" desc = "The virus irritates the throat of the host, causing occasional coughing. Each cough will try to infect bystanders who are within 1 tile of the host with the virus." illness = "Jest Infection" + weight = 2 stealth = -1 resistance = 3 stage_speed = 1 diff --git a/code/datums/diseases/advance/symptoms/sneeze.dm b/code/datums/diseases/advance/symptoms/sneeze.dm index 14a087da1238f..6771d57f20bca 100644 --- a/code/datums/diseases/advance/symptoms/sneeze.dm +++ b/code/datums/diseases/advance/symptoms/sneeze.dm @@ -10,6 +10,7 @@ name = "Sneezing" desc = "The virus causes irritation of the nasal cavity, making the host sneeze occasionally. Sneezes from this symptom will spread the virus in a 4 meter cone in front of the host." illness = "Bard Flu" + weight = 2 stealth = -2 resistance = 3 stage_speed = 0 diff --git a/code/datums/diseases/advance/symptoms/symptoms.dm b/code/datums/diseases/advance/symptoms/symptoms.dm index 28ba45f8de4e0..5a4331b3c6183 100644 --- a/code/datums/diseases/advance/symptoms/symptoms.dm +++ b/code/datums/diseases/advance/symptoms/symptoms.dm @@ -39,6 +39,8 @@ var/naturally_occuring = TRUE ///If the symptom requires an organ for the effects to function, robotic organs are immune to disease unless inorganic biology symptom is present var/required_organ + /// How much space does this symptom use? + var/weight = 1 /datum/symptom/New() var/list/S = SSdisease.list_symptoms @@ -106,6 +108,7 @@ var/list/data = list() data["name"] = name data["desc"] = desc + data["weight"] = weight data["stealth"] = stealth data["resistance"] = resistance data["stage_speed"] = stage_speed diff --git a/code/datums/elements/elevation.dm b/code/datums/elements/elevation.dm index 92fba97a09414..b83548c6b5f41 100644 --- a/code/datums/elements/elevation.dm +++ b/code/datums/elements/elevation.dm @@ -18,8 +18,9 @@ if(ismovable(target)) RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) - var/turf/turf = get_turf(target) - if(turf) + var/atom/atom_target = target + if(isturf(atom_target.loc)) + var/turf/turf = atom_target.loc if(!HAS_TRAIT(turf, TRAIT_TURF_HAS_ELEVATED_OBJ(pixel_shift))) RegisterSignal(turf, COMSIG_TURF_RESET_ELEVATION, PROC_REF(check_elevation)) RegisterSignal(turf, COMSIG_TURF_CHANGE, PROC_REF(pre_change_turf)) diff --git a/code/datums/elements/rust.dm b/code/datums/elements/rust.dm index 060de19494fc0..396307197c49d 100644 --- a/code/datums/elements/rust.dm +++ b/code/datums/elements/rust.dm @@ -98,6 +98,8 @@ UnregisterSignal(source, COMSIG_ATOM_EXITED) for(var/obj/effect/glowing_rune/rune_to_remove in source) qdel(rune_to_remove) + for(var/mob/living/victim in source) + victim.remove_status_effect(/datum/status_effect/rust_corruption) /datum/element/rust/heretic/proc/on_entered(turf/source, atom/movable/entered, ...) SIGNAL_HANDLER diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 296a9031ae27e..9b33a901d9ebe 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -353,6 +353,7 @@ created.pixel_x = created.base_pixel_x + rand(-6, 6) created.pixel_y = created.base_pixel_y + rand(-6, 6) created.forceMove(target) + SSblackbox.record_feedback("nested tally", "lathe_printed_items", 1, list("[type]", "[created.type]")) if(is_stack) items_remaining = 0 diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index c3621cd332958..fe03aaaf01e0d 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -454,7 +454,7 @@ if(!COOLDOWN_FINISHED(src, last_holopay_projection)) balloon_alert(user, "still recharging") return - if(can_be_used_in_payment(user)) + if(!can_be_used_in_payment(user)) balloon_alert(user, "no account!") to_chat(user, span_warning("You need a valid bank account to do this.")) return diff --git a/code/modules/admin/verbs/lua/lua_state.dm b/code/modules/admin/verbs/lua/lua_state.dm index 27994d966a7cb..bf2bcbd5a9003 100644 --- a/code/modules/admin/verbs/lua/lua_state.dm +++ b/code/modules/admin/verbs/lua/lua_state.dm @@ -111,8 +111,6 @@ GLOBAL_PROTECT(lua_usr) for(var/path_element in function) new_function_path += path_element function = new_function_path - var/msg = "[key_name(usr)] called the lua function \"[function]\" with arguments: [english_list(call_args)]" - log_lua(msg) var/tmp_usr = GLOB.lua_usr GLOB.lua_usr = usr diff --git a/code/modules/antagonists/malf_ai/malf_ai.dm b/code/modules/antagonists/malf_ai/malf_ai.dm index b76452e6076f3..358b618df99aa 100644 --- a/code/modules/antagonists/malf_ai/malf_ai.dm +++ b/code/modules/antagonists/malf_ai/malf_ai.dm @@ -20,6 +20,8 @@ var/should_give_codewords = TRUE ///since the module purchasing is built into the antag info, we need to keep track of its compact mode here var/module_picker_compactmode = FALSE + ///malf on_gain sound effect. Set here so Infected AI can override + var/malf_sound = 'sound/ambience/antag/malf.ogg' /datum/antagonist/malf_ai/New(give_objectives = TRUE) . = ..() @@ -39,7 +41,8 @@ malfunction_flavor = strings(MALFUNCTION_FLAVOR_FILE, employer) add_law_zero() - owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/malf.ogg', 100, FALSE, pressure_affected = FALSE, use_reverb = FALSE) + if(malf_sound) + owner.current.playsound_local(get_turf(owner.current), malf_sound, 100, FALSE, pressure_affected = FALSE, use_reverb = FALSE) owner.current.grant_language(/datum/language/codespeak, source = LANGUAGE_MALF) var/datum/atom_hud/data/hackyhud = GLOB.huds[DATA_HUD_MALF_APC] @@ -272,6 +275,8 @@ /datum/antagonist/malf_ai/infected name = "Infected AI" employer = "Infected AI" + can_assign_self_objectives = FALSE + malf_sound = null ///The player, to who is this AI slaved var/datum/mind/boss diff --git a/code/modules/cargo/bounties/mining.dm b/code/modules/cargo/bounties/mining.dm index c49fc982a3ab9..933581bfdf9e2 100644 --- a/code/modules/cargo/bounties/mining.dm +++ b/code/modules/cargo/bounties/mining.dm @@ -46,16 +46,17 @@ /datum/bounty/item/mining/watcher_wreath name = "Watcher Wreaths" description = "Station 14's Research Director thinks they're onto a break-through on the cultural icons of some pagan beliefs. Ship them a few watcher wreaths for analysis." + include_subtypes = FALSE reward = CARGO_CRATE_VALUE * 15 required_count = 3 - wanted_types = list(/obj/item/clothing/neck/wreath = FALSE) + wanted_types = list(/obj/item/clothing/neck/wreath = TRUE) /datum/bounty/item/mining/icewing_wreath name = "Icewing Wreath" description = "We're getting some....weird messages from Station 14's Research Director. And most of what they said was incoherent. But they apparently want an icewing wreath. Could you send them one?" reward = CARGO_CRATE_VALUE * 30 required_count = 1 - wanted_types = list(/obj/item/clothing/neck/wreath/icewing = FALSE) + wanted_types = list(/obj/item/clothing/neck/wreath/icewing = TRUE) /datum/bounty/item/mining/bone_dagger name = "Bone Daggers" diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 3272620a86555..97924643604c5 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -197,6 +197,7 @@ var/list/parallax_layers var/list/parallax_layers_cached + var/atom/movable/screen/parallax_home/parallax_rock ///this is the last recorded client eye by SSparallax/fire() var/atom/movable/movingmob var/turf/previous_turf @@ -206,8 +207,8 @@ var/parallax_movedir = 0 /// How many parallax layers to show our client var/parallax_layers_max = 4 - /// Timer for the area directional animation - var/parallax_animate_timer + /// Timers for the area directional animation, one for each layer + var/list/parallax_animate_timers /// Do we want to do parallax animations at all? /// Exists to prevent laptop fires var/do_parallax_animations = TRUE diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index c3163b3e0b169..1de6c330bfce9 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -601,6 +601,9 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( QDEL_NULL(void) QDEL_NULL(tooltips) QDEL_NULL(loot_panel) + QDEL_NULL(parallax_rock) + QDEL_LIST(parallax_layers_cached) + parallax_layers = null seen_messages = null Master.UpdateTickRate() ..() //Even though we're going to be hard deleted there are still some things that want to know the destroy is happening diff --git a/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm b/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm index 8906a6d2555cb..b2e0e16f9a82a 100644 --- a/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm +++ b/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm @@ -302,6 +302,15 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999)) explosive_resistance = INFINITY var/obj/item/hilbertshotel/parentSphere +/turf/closed/indestructible/hoteldoor/Initialize(mapload) + . = ..() + register_context() + +/turf/closed/indestructible/hoteldoor/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + context[SCREENTIP_CONTEXT_ALT_LMB] = "Peek through" + return CONTEXTUAL_SCREENTIP_SET + /turf/closed/indestructible/hoteldoor/proc/promptExit(mob/living/user) if(!isliving(user)) return @@ -345,6 +354,10 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999)) promptExit(user) /turf/closed/indestructible/hoteldoor/click_alt(mob/user) + if(user.is_blind()) + to_chat(user, span_warning("Drats! Your vision is too poor to use this!")) + return CLICK_ACTION_BLOCKING + to_chat(user, span_notice("You peak through the door's bluespace peephole...")) user.reset_perspective(parentSphere) var/datum/action/peephole_cancel/PHC = new diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm index 8b82d4b7d7796..cd5a60a22f2ae 100644 --- a/code/modules/mining/laborcamp/laborstacker.dm +++ b/code/modules/mining/laborcamp/laborstacker.dm @@ -109,7 +109,7 @@ var/datum/record/crew/target = find_record(user_mob.real_name) target?.wanted_status = WANTED_PAROLE - security_radio.talk_into(src, "/p [user_mob.name] returned to the station. Minerals and Prisoner ID card ready for retrieval.", FREQ_SECURITY) + security_radio.talk_into(src, "[user_mob.name] returned to the station. Minerals and Prisoner ID card ready for retrieval.", FREQ_SECURITY) user_mob.log_message("has completed their labor points goal and is now sending the gulag shuttle back to the station.", LOG_GAME) to_chat(user_mob, span_notice("Shuttle received message and will be sent shortly.")) return TRUE diff --git a/code/modules/mob/living/basic/jungle/venus_human_trap.dm b/code/modules/mob/living/basic/jungle/venus_human_trap.dm index 6c0a6e2f9db8c..ec375283fcea0 100644 --- a/code/modules/mob/living/basic/jungle/venus_human_trap.dm +++ b/code/modules/mob/living/basic/jungle/venus_human_trap.dm @@ -216,15 +216,19 @@ QDEL_LIST(vines) return ..() -/datum/action/cooldown/mob_cooldown/projectile_attack/vine_tangle/Activate(atom/target_atom) - if(isturf(target_atom) || istype(target_atom, /obj/structure/spacevine)) +/datum/action/cooldown/mob_cooldown/projectile_attack/vine_tangle/Activate(atom/movable/target_atom) + if(!ismovable(target_atom) || istype(target_atom, /obj/structure/spacevine)) + return + if(target_atom.anchored) + owner.balloon_alert(owner, "can't pull!") return if(get_dist(owner, target_atom) > vine_grab_distance) owner.balloon_alert(owner, "too far!") return - for(var/turf/blockage in get_line(owner, target_atom)) + var/list/target_turfs = get_line(owner, target_atom) - list(get_turf(owner), get_turf(target_atom)) + for(var/turf/blockage in target_turfs) if(blockage.is_blocked_turf(exclude_mobs = TRUE)) - owner.balloon_alert(owner, "something's in the way!") + owner.balloon_alert(owner, "path blocked!") return var/datum/beam/new_vine = owner.Beam(target_atom, icon_state = "vine", time = vine_duration * (ismob(target_atom) ? 1 : 2), beam_type = /obj/effect/ebeam/vine, emissive = FALSE) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/_megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/_megafauna.dm index ea048482e4f1f..31d2e62fba7dc 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/_megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/_megafauna.dm @@ -20,6 +20,10 @@ maxbodytemp = INFINITY vision_range = 5 aggro_vision_range = 18 + // Pale purple, should be red enough to see stuff on lavaland + lighting_cutoff_red = 25 + lighting_cutoff_green = 15 + lighting_cutoff_blue = 35 move_force = MOVE_FORCE_OVERPOWERING move_resist = MOVE_FORCE_OVERPOWERING pull_force = MOVE_FORCE_OVERPOWERING diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm index d39c8a3e52bd9..8fc667df5a876 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm @@ -1,10 +1,4 @@ #define WENDIGO_ENRAGED (health <= maxHealth*0.5) -#define WENDIGO_CIRCLE_SHOTCOUNT 24 -#define WENDIGO_CIRCLE_REPEATCOUNT 8 -#define WENDIGO_SPIRAL_SHOTCOUNT 40 -#define WENDIGO_WAVE_SHOTCOUNT 7 -#define WENDIGO_WAVE_REPEATCOUNT 32 -#define WENDIGO_SHOTGUN_SHOTCOUNT 5 /* @@ -51,9 +45,6 @@ Difficulty: Hard death_message = "falls to the ground in a bloody heap, shaking the arena." death_sound = 'sound/effects/gravhit.ogg' footstep_type = FOOTSTEP_MOB_HEAVY - attack_action_types = list(/datum/action/innate/megafauna_attack/heavy_stomp, - /datum/action/innate/megafauna_attack/teleport, - /datum/action/innate/megafauna_attack/shockwave_scream) summon_line = "GwaHOOOOOOOOOOOOOOOOOOOOO" /// Saves the turf the megafauna was created at (spawns exit portal here) var/turf/starting @@ -61,37 +52,38 @@ Difficulty: Hard var/stomp_range = 1 /// Stores directions the mob is moving, then calls that a move has fully ended when these directions are removed in moved var/stored_move_dirs = 0 - /// If the wendigo is allowed to move - var/can_move = TRUE /// Time before the wendigo can scream again var/scream_cooldown_time = 10 SECONDS + /// Teleport Ability + var/datum/action/cooldown/mob_cooldown/teleport/teleport + /// Shotgun Ability + var/datum/action/cooldown/mob_cooldown/projectile_attack/shotgun_blast/wendigo/shotgun_blast + /// Ground Slam Ability + var/datum/action/cooldown/mob_cooldown/ground_slam/ground_slam + /// Alternating Projectiles Ability + var/datum/action/cooldown/mob_cooldown/projectile_attack/alternating_circle/alternating_circle + /// Spiral Projectiles Ability + var/datum/action/cooldown/mob_cooldown/projectile_attack/spiral_shots/wendigo/spiral + /// Wave Projectiles Ability + var/datum/action/cooldown/mob_cooldown/projectile_attack/wave/wave /// Stores the last scream time so it doesn't spam it COOLDOWN_DECLARE(scream_cooldown) /mob/living/simple_animal/hostile/megafauna/wendigo/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NO_FLOATING_ANIM, INNATE_TRAIT) - -/datum/action/innate/megafauna_attack/heavy_stomp - name = "Heavy Stomp" - button_icon = 'icons/mob/actions/actions_items.dmi' - button_icon_state = "sniper_zoom" - chosen_message = "You are now stomping the ground around you." - chosen_attack_num = 1 - -/datum/action/innate/megafauna_attack/teleport - name = "Teleport" - button_icon = 'icons/effects/bubblegum.dmi' - button_icon_state = "smack ya one" - chosen_message = "You are now teleporting at the target you click on." - chosen_attack_num = 2 - -/datum/action/innate/megafauna_attack/shockwave_scream - name = "Shockwave Scream" - button_icon = 'icons/mob/actions/actions_animal.dmi' - button_icon_state = "expand" - chosen_message = "You are now screeching, disorienting targets around you." - chosen_attack_num = 3 + teleport = new(src) + shotgun_blast = new(src) + ground_slam = new(src) + alternating_circle = new(src) + spiral = new(src) + wave = new(src) + teleport.Grant(src) + shotgun_blast.Grant(src) + ground_slam.Grant(src) + alternating_circle.Grant(src) + spiral.Grant(src) + wave.Grant(src) /mob/living/simple_animal/hostile/megafauna/wendigo/Initialize(mapload) . = ..() @@ -108,13 +100,6 @@ Difficulty: Hard move_to_delay = initial(move_to_delay) if(client) - switch(chosen_attack) - if(1) - heavy_stomp() - if(2) - try_teleport() - if(3) - shockwave_scream() return var/mob/living/living_target = target @@ -127,28 +112,54 @@ Difficulty: Hard chosen_attack = rand(1, 2) switch(chosen_attack) if(1) - heavy_stomp() + ground_slam.Activate(target) if(2) - try_teleport() + teleport.Activate(target) + if(WENDIGO_ENRAGED) + shotgun_blast.Activate(target) if(3) do_teleport(src, starting, 0, channel=TELEPORT_CHANNEL_BLUESPACE, forced = TRUE) - shockwave_scream() + var/shockwave_attack + if(WENDIGO_ENRAGED) + shockwave_attack = rand(1, 3) + else + shockwave_attack = rand(1, 2) + switch(shockwave_attack) + if(1) + alternating_circle.enraged = WENDIGO_ENRAGED + alternating_circle.Activate(target) + if(2) + spiral.enraged = WENDIGO_ENRAGED + spiral.Activate(target) + if(3) + wave.Activate(target) + update_cooldowns(list(COOLDOWN_UPDATE_SET_MELEE = 3 SECONDS, COOLDOWN_UPDATE_SET_RANGED = 3 SECONDS)) /mob/living/simple_animal/hostile/megafauna/wendigo/Move(atom/newloc, direct) - if(!can_move) - return stored_move_dirs |= direct - return ..() + . = ..() + // Remove after anyways in case the movement was prevented + stored_move_dirs &= ~direct /mob/living/simple_animal/hostile/megafauna/wendigo/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE) . = ..() stored_move_dirs &= ~movement_dir if(!stored_move_dirs) - INVOKE_ASYNC(src, PROC_REF(wendigo_slam), stomp_range, 1, 8) + INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(wendigo_slam), src, stomp_range, 1, 8) -/// Slams the ground around the source throwing back enemies caught nearby, delay is for the radius increase -/mob/living/simple_animal/hostile/megafauna/wendigo/proc/wendigo_slam(range, delay, throw_range) - var/turf/origin = get_turf(src) +/proc/wendigo_scream(mob/owner) + SLEEP_CHECK_DEATH(5, owner) + playsound(owner.loc, 'sound/magic/demon_dies.ogg', 600, FALSE, 10) + var/pixel_shift = rand(5, 15) + animate(owner, pixel_z = pixel_shift, time = 1, loop = 20, flags = ANIMATION_RELATIVE) + animate(pixel_z = -pixel_shift, time = 1, flags = ANIMATION_RELATIVE) + for(var/mob/living/dizzy_target in get_hearers_in_view(7, owner) - owner) + dizzy_target.set_dizzy_if_lower(12 SECONDS) + to_chat(dizzy_target, span_danger("[owner] screams loudly!")) + SLEEP_CHECK_DEATH(1 SECONDS, owner) + +/proc/wendigo_slam(mob/owner, range, delay, throw_range) + var/turf/origin = get_turf(owner) if(!origin) return var/list/all_turfs = RANGE_TURFS(range, origin) @@ -158,117 +169,16 @@ Difficulty: Hard if(get_dist(origin, stomp_turf) > sound_range) continue new /obj/effect/temp_visual/small_smoke/halfsecond(stomp_turf) - for(var/mob/living/target in stomp_turf) - if(target == src || target.throwing) + for(var/mob/living/hit_mob in stomp_turf) + if(hit_mob == owner || hit_mob.throwing) continue - to_chat(target, span_userdanger("[src]'s ground slam shockwave sends you flying!")) - var/turf/thrownat = get_ranged_target_turf_direct(src, target, throw_range, rand(-10, 10)) - target.throw_at(thrownat, 8, 2, null, TRUE, force = MOVE_FORCE_OVERPOWERING, gentle = TRUE) - target.apply_damage(20, BRUTE, wound_bonus=CANT_WOUND) - shake_camera(target, 2, 1) + to_chat(hit_mob, span_userdanger("[owner]'s ground slam shockwave sends you flying!")) + var/turf/thrownat = get_ranged_target_turf_direct(owner, hit_mob, throw_range, rand(-10, 10)) + hit_mob.throw_at(thrownat, 8, 2, null, TRUE, force = MOVE_FORCE_OVERPOWERING, gentle = TRUE) + hit_mob.apply_damage(20, BRUTE, wound_bonus=CANT_WOUND) + shake_camera(hit_mob, 2, 1) all_turfs -= stomp_turf - sleep(delay) - -/// Larger but slower ground stomp -/mob/living/simple_animal/hostile/megafauna/wendigo/proc/heavy_stomp() - can_move = FALSE - wendigo_slam(5, 3 - WENDIGO_ENRAGED, 8) - update_cooldowns(list(COOLDOWN_UPDATE_SET_MELEE = 0 SECONDS, COOLDOWN_UPDATE_SET_RANGED = 0 SECONDS)) - can_move = TRUE - -/// Teleports to a location 4 turfs away from the enemy in view -/mob/living/simple_animal/hostile/megafauna/wendigo/proc/try_teleport() - teleport(6) - if(WENDIGO_ENRAGED) - playsound(loc, 'sound/magic/clockwork/invoke_general.ogg', 100, TRUE) - for(var/shots in 1 to WENDIGO_SHOTGUN_SHOTCOUNT) - var/spread = shots * 10 - 30 - var/turf/startloc = get_step(get_turf(src), get_dir(src, target)) - var/turf/endloc = get_turf(target) - if(!endloc) - break - var/obj/projectile/colossus/wendigo_shockwave/shockwave = new /obj/projectile/colossus/wendigo_shockwave(loc) - shockwave.speed = 8 - shockwave.preparePixelProjectile(endloc, startloc, null, spread) - shockwave.firer = src - if(target) - shockwave.original = target - shockwave.fire() - update_cooldowns(list(COOLDOWN_UPDATE_SET_MELEE = 0 SECONDS, COOLDOWN_UPDATE_SET_RANGED = 0 SECONDS)) - -/mob/living/simple_animal/hostile/megafauna/wendigo/proc/teleport(range = 6) - var/list/possible_ends = view(range, target.loc) - view(range - 1, target.loc) - for(var/turf/closed/cant_teleport_turf in possible_ends) - possible_ends -= cant_teleport_turf - if(!possible_ends.len) - return - var/turf/end = pick(possible_ends) - do_teleport(src, end, 0, channel=TELEPORT_CHANNEL_BLUESPACE, forced = TRUE) - -/// Applies dizziness to all nearby enemies that can hear the scream and animates the wendigo shaking up and down as shockwave projectiles shoot outward -/mob/living/simple_animal/hostile/megafauna/wendigo/proc/shockwave_scream() - can_move = FALSE - COOLDOWN_START(src, scream_cooldown, scream_cooldown_time) - SLEEP_CHECK_DEATH(5, src) - playsound(loc, 'sound/magic/demon_dies.ogg', 600, FALSE, 10) - var/pixel_shift = rand(5, 15) - animate(src, pixel_z = pixel_shift, time = 1, loop = 20, flags = ANIMATION_RELATIVE) - animate(pixel_z = -pixel_shift, time = 1, flags = ANIMATION_RELATIVE) - for(var/mob/living/dizzy_target in get_hearers_in_view(7, src) - src) - dizzy_target.set_dizzy_if_lower(12 SECONDS) - to_chat(dizzy_target, span_danger("The wendigo screams loudly!")) - SLEEP_CHECK_DEATH(1 SECONDS, src) - spiral_attack() - update_cooldowns(list(COOLDOWN_UPDATE_SET_MELEE = 3 SECONDS, COOLDOWN_UPDATE_SET_RANGED = 3 SECONDS)) - SLEEP_CHECK_DEATH(3 SECONDS, src) - can_move = TRUE - -/// Shoots shockwave projectiles in a random preset pattern -/mob/living/simple_animal/hostile/megafauna/wendigo/proc/spiral_attack() - var/list/choices = list("Alternating Circle", "Spiral") - if(WENDIGO_ENRAGED) - choices += "Wave" - var/spiral_type = pick(choices) - switch(spiral_type) - if("Alternating Circle") - var/shots_per = WENDIGO_CIRCLE_SHOTCOUNT - for(var/shoot_times in 1 to WENDIGO_CIRCLE_REPEATCOUNT) - var/offset = shoot_times % 2 - for(var/shot in 1 to shots_per) - var/angle = shot * 360 / shots_per + (offset * 360 / shots_per) * 0.5 - var/obj/projectile/colossus/wendigo_shockwave/shockwave = new /obj/projectile/colossus/wendigo_shockwave(loc) - shockwave.firer = src - shockwave.speed = 3 - WENDIGO_ENRAGED - shockwave.fire(angle) - SLEEP_CHECK_DEATH(6 - WENDIGO_ENRAGED * 2, src) - if("Spiral") - var/shots_spiral = WENDIGO_SPIRAL_SHOTCOUNT - var/angle_to_target = get_angle(src, target) - var/spiral_direction = pick(-1, 1) - for(var/shot in 1 to shots_spiral) - var/shots_per_tick = 5 - WENDIGO_ENRAGED * 3 - var/angle_change = (5 + WENDIGO_ENRAGED * shot / 6) * spiral_direction - for(var/count in 1 to shots_per_tick) - var/angle = angle_to_target + shot * angle_change + count * 360 / shots_per_tick - var/obj/projectile/colossus/wendigo_shockwave/shockwave = new /obj/projectile/colossus/wendigo_shockwave(loc) - shockwave.firer = src - shockwave.damage = 15 - shockwave.fire(angle) - SLEEP_CHECK_DEATH(1, src) - if("Wave") - var/shots_per = WENDIGO_WAVE_SHOTCOUNT - var/difference = 360 / shots_per - var/wave_direction = pick(-1, 1) - for(var/shoot_times in 1 to WENDIGO_WAVE_REPEATCOUNT) - for(var/shot in 1 to shots_per) - var/angle = shot * difference + shoot_times * 5 * wave_direction * -1 - var/obj/projectile/colossus/wendigo_shockwave/shockwave = new /obj/projectile/colossus/wendigo_shockwave(loc) - shockwave.firer = src - shockwave.wave_movement = TRUE - shockwave.speed = 8 - shockwave.wave_speed = 10 * wave_direction - shockwave.fire(angle) - SLEEP_CHECK_DEATH(2, src) + SLEEP_CHECK_DEATH(delay, owner) /mob/living/simple_animal/hostile/megafauna/wendigo/death(gibbed, list/force_grant) if(health > 0) @@ -285,6 +195,7 @@ Difficulty: Hard /obj/projectile/colossus/wendigo_shockwave name = "wendigo shockwave" + speed = 2 /// If wave movement is enabled var/wave_movement = FALSE /// Amount the angle changes every pixel move @@ -292,6 +203,17 @@ Difficulty: Hard /// Amount of movements this projectile has made var/pixel_moves = 0 +/obj/projectile/colossus/wendigo_shockwave/spiral + damage = 15 + +/obj/projectile/colossus/wendigo_shockwave/wave + speed = 8 + wave_movement = TRUE + wave_speed = 10 + +/obj/projectile/colossus/wendigo_shockwave/wave/alternate + wave_speed = -10 + /obj/projectile/colossus/wendigo_shockwave/pixel_move(trajectory_multiplier, hitscanning = FALSE) . = ..() if(wave_movement) @@ -344,9 +266,3 @@ Difficulty: Hard throwforce = 0 #undef WENDIGO_ENRAGED -#undef WENDIGO_CIRCLE_SHOTCOUNT -#undef WENDIGO_CIRCLE_REPEATCOUNT -#undef WENDIGO_SPIRAL_SHOTCOUNT -#undef WENDIGO_WAVE_SHOTCOUNT -#undef WENDIGO_WAVE_REPEATCOUNT -#undef WENDIGO_SHOTGUN_SHOTCOUNT diff --git a/code/modules/mod/mod_paint.dm b/code/modules/mod/mod_paint.dm index 1402a4aebc6bc..77af1f7290c83 100644 --- a/code/modules/mod/mod_paint.dm +++ b/code/modules/mod/mod_paint.dm @@ -151,7 +151,7 @@ if(!pick) balloon_alert(user, "no skin picked!") return - mod.theme.set_skin(pick) + mod.theme.set_skin(mod, pick) /obj/item/mod/paint/proc/check_menu(obj/item/mod/control/mod, mob/user) if(user.incapacitated() || !user.is_holding(src) || !mod || mod.active || mod.activating) @@ -186,7 +186,7 @@ if(!(skin in mod.theme.variants)) balloon_alert(user, "incompatible theme!") return TRUE - mod.theme.set_skin(skin) + mod.theme.set_skin(mod, skin) balloon_alert(user, "skin applied") qdel(src) return TRUE diff --git a/code/modules/mod/mod_theme.dm b/code/modules/mod/mod_theme.dm index ecfa570dde160..971ccaf5c72bf 100644 --- a/code/modules/mod/mod_theme.dm +++ b/code/modules/mod/mod_theme.dm @@ -143,6 +143,8 @@ control_part_datum.part_item = mod mod.mod_parts["[mod.slot_flags]"] = control_part_datum for(var/path in variants[default_skin]) + if(!ispath(path)) + continue var/obj/item/mod_part = new path(mod) if(mod_part.slot_flags == ITEM_SLOT_OCLOTHING && isclothing(mod_part)) var/obj/item/clothing/chestplate = mod_part @@ -576,10 +578,14 @@ /obj/item/clothing/gloves/mod = list( SEALED_CLOTHING = THICKMATERIAL, CAN_OVERSLOT = TRUE, + UNSEALED_MESSAGE = GAUNTLET_UNSEAL_MESSAGE, + SEALED_MESSAGE = GAUNTLET_SEAL_MESSAGE, ), /obj/item/clothing/shoes/mod = list( SEALED_CLOTHING = THICKMATERIAL, CAN_OVERSLOT = TRUE, + UNSEALED_MESSAGE = BOOT_UNSEAL_MESSAGE, + SEALED_MESSAGE = BOOT_SEAL_MESSAGE, ), ), ) @@ -1361,10 +1367,14 @@ /obj/item/clothing/gloves/mod = list( SEALED_CLOTHING = THICKMATERIAL, CAN_OVERSLOT = TRUE, + UNSEALED_MESSAGE = GAUNTLET_UNSEAL_MESSAGE, + SEALED_MESSAGE = GAUNTLET_SEAL_MESSAGE, ), /obj/item/clothing/shoes/mod = list( SEALED_CLOTHING = THICKMATERIAL, CAN_OVERSLOT = TRUE, + UNSEALED_MESSAGE = BOOT_UNSEAL_MESSAGE, + SEALED_MESSAGE = BOOT_SEAL_MESSAGE, ), ), ) @@ -1506,6 +1516,8 @@ UNSEALED_CLOTHING = THICKMATERIAL|CASTING_CLOTHES, SEALED_CLOTHING = STOPSPRESSUREDAMAGE, SEALED_INVISIBILITY = HIDEJUMPSUIT, + UNSEALED_MESSAGE = CHESTPLATE_UNSEAL_MESSAGE, + SEALED_MESSAGE = CHESTPLATE_SEAL_MESSAGE, ), /obj/item/clothing/gloves/mod = list( UNSEALED_CLOTHING = THICKMATERIAL, @@ -2155,14 +2167,20 @@ /obj/item/clothing/suit/mod = list( UNSEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, SEALED_INVISIBILITY = HIDEJUMPSUIT, + UNSEALED_MESSAGE = CHESTPLATE_UNSEAL_MESSAGE, + SEALED_MESSAGE = CHESTPLATE_SEAL_MESSAGE, ), /obj/item/clothing/gloves/mod = list( UNSEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, CAN_OVERSLOT = TRUE, + UNSEALED_MESSAGE = GAUNTLET_UNSEAL_MESSAGE, + SEALED_MESSAGE = GAUNTLET_SEAL_MESSAGE, ), /obj/item/clothing/shoes/mod = list( UNSEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE, CAN_OVERSLOT = TRUE, + UNSEALED_MESSAGE = BOOT_UNSEAL_MESSAGE, + SEALED_MESSAGE = BOOT_SEAL_MESSAGE, ), ), ) diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index e2a197a33900c..a17a9bb8ed054 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -484,7 +484,10 @@ playsound(src, 'sound/machines/card_slide.ogg', 50) /obj/item/modular_computer/proc/turn_on(mob/user, open_ui = TRUE) - var/issynth = HAS_SILICON_ACCESS(user) // Robots and AIs get different activation messages. + var/issynth = FALSE // Robots and AIs get different activation messages. + if(user) + issynth = HAS_SILICON_ACCESS(user) + if(atom_integrity <= integrity_failure * max_integrity) if(user) if(issynth) diff --git a/code/modules/modular_computers/computers/item/computer_circuit.dm b/code/modules/modular_computers/computers/item/computer_circuit.dm index 2a6a0d70be971..35caaf3c85107 100644 --- a/code/modules/modular_computers/computers/item/computer_circuit.dm +++ b/code/modules/modular_computers/computers/item/computer_circuit.dm @@ -5,7 +5,9 @@ var/obj/item/modular_computer/computer ///Turns the PC on/off var/datum/port/input/on_off - ///When set, will print a piece of paper with the value as text. + ///Determines the text to be printed + var/datum/port/input/print_text + /// Print when triggered var/datum/port/input/print ///Sent when turned on @@ -18,6 +20,7 @@ var/datum/port/input/red var/datum/port/input/green var/datum/port/input/blue + var/datum/port/input/set_color /obj/item/circuit_component/modpc/register_shell(atom/movable/shell) . = ..() @@ -39,10 +42,11 @@ * I hope you're cool with me doing it here. */ if(computer.has_light && isnull(lights)) - lights = add_input_port("Toggle Lights", PORT_TYPE_SIGNAL) + lights = add_input_port("Toggle Lights", PORT_TYPE_SIGNAL, trigger = PROC_REF(toggle_flashlight)) red = add_input_port("Red", PORT_TYPE_NUMBER) green = add_input_port("Green", PORT_TYPE_NUMBER) blue = add_input_port("Blue", PORT_TYPE_NUMBER) + set_color = add_input_port("Set Color", PORT_TYPE_SIGNAL, trigger = PROC_REF(set_flashlight_color)) /obj/item/circuit_component/modpc/unregister_shell(atom/movable/shell) if(computer) @@ -51,45 +55,37 @@ return ..() /obj/item/circuit_component/modpc/populate_ports() - on_off = add_input_port("Turn On/Off", PORT_TYPE_SIGNAL) - print = add_input_port("Print Text", PORT_TYPE_STRING) + on_off = add_input_port("Turn On/Off", PORT_TYPE_SIGNAL, trigger = PROC_REF(toggle_power)) + print_text = add_input_port("Print Text", PORT_TYPE_STRING) + print = add_input_port("Print", PORT_TYPE_SIGNAL, trigger = PROC_REF(print_text)) is_on = add_output_port("Turned On", PORT_TYPE_SIGNAL) - is_on = add_output_port("Shut Down", PORT_TYPE_SIGNAL) + is_off = add_output_port("Shut Down", PORT_TYPE_SIGNAL) /obj/item/circuit_component/modpc/pre_input_received(datum/port/input/port) if(isnull(computer)) return - if(COMPONENT_TRIGGERED_BY(print, port)) + if(COMPONENT_TRIGGERED_BY(print_text, port)) print.set_value(html_encode(trim(print.value, MAX_PAPER_LENGTH))) - else if(COMPONENT_TRIGGERED_BY(red, port)) - red.set_value(clamp(red.value, 0, 255)) - else if(COMPONENT_TRIGGERED_BY(blue, port)) - blue.set_value(clamp(blue.value, 0, 255)) - else if(COMPONENT_TRIGGERED_BY(green, port)) - green.set_value(clamp(green.value, 0, 255)) - -/obj/item/circuit_component/modpc/input_received(datum/port/input/port) - if(isnull(computer)) - return - if(COMPONENT_TRIGGERED_BY(on_off, port)) - if(computer.enabled) - INVOKE_ASYNC(computer, TYPE_PROC_REF(/obj/item/modular_computer, shutdown_computer)) - else - INVOKE_ASYNC(computer, TYPE_PROC_REF(/obj/item/modular_computer, turn_on)) - return - if(!computer.enabled) - return +/obj/item/circuit_component/modpc/proc/print_text(datum/source) + if(computer.enabled) + computer.print_text(print_text.value) + +/obj/item/circuit_component/modpc/proc/toggle_power(datum/source) + if(computer.enabled) + INVOKE_ASYNC(computer, TYPE_PROC_REF(/obj/item/modular_computer, shutdown_computer)) + else + INVOKE_ASYNC(computer, TYPE_PROC_REF(/obj/item/modular_computer, turn_on)) - if(COMPONENT_TRIGGERED_BY(print, port)) - computer.print_text(print.value) +/obj/item/circuit_component/modpc/proc/toggle_flashlight(datum/source) + computer.toggle_flashlight() - if(lights) - if(COMPONENT_TRIGGERED_BY(lights, port)) - computer.toggle_flashlight() - if(COMPONENT_TRIGGERED_BY(red, port) || COMPONENT_TRIGGERED_BY(green, port) || COMPONENT_TRIGGERED_BY(blue, port)) - computer.set_flashlight_color(rgb(red.value || 0, green.value || 0, blue.value || 0)) +/obj/item/circuit_component/modpc/proc/set_flashlight_color(datum/source) + red.set_value(clamp(red.value, 0, 255)) + blue.set_value(clamp(blue.value, 0, 255)) + green.set_value(clamp(green.value, 0, 255)) + computer.set_flashlight_color(rgb(red.value || 0, green.value || 0, blue.value || 0)) /obj/item/circuit_component/modpc/proc/computer_on(datum/source, mob/user) SIGNAL_HANDLER diff --git a/code/modules/projectiles/guns/energy/beam_rifle.dm b/code/modules/projectiles/guns/energy/beam_rifle.dm index 1c5b025baea80..11399e9c24dad 100644 --- a/code/modules/projectiles/guns/energy/beam_rifle.dm +++ b/code/modules/projectiles/guns/energy/beam_rifle.dm @@ -71,6 +71,8 @@ var/current_zoom_x = 0 var/current_zoom_y = 0 + var/obj/projectile/beam/beam_rifle/hitscan/aiming_beam/trace = null + /obj/item/gun/energy/beam_rifle/apply_fantasy_bonuses(bonus) . = ..() delay = modify_fantasy_variable("delay", delay, -bonus * 2) @@ -192,16 +194,19 @@ if(diff < AIMING_BEAM_ANGLE_CHANGE_THRESHOLD && !force_update) return aiming_lastangle = lastangle - var/obj/projectile/beam/beam_rifle/hitscan/aiming_beam/P = new - P.gun = src - P.wall_pierce_amount = wall_pierce_amount - P.structure_pierce_amount = structure_piercing - P.do_pierce = projectile_setting_pierce + // ONLY ONE at once (since fire can sleep) + if(trace) + QDEL_NULL(trace) + trace = new + trace.gun = src + trace.wall_pierce_amount = wall_pierce_amount + trace.structure_pierce_amount = structure_piercing + trace.do_pierce = projectile_setting_pierce if(aiming_time) var/percent = ((100/aiming_time)*aiming_time_left) - P.color = rgb(255 * percent,255 * ((100 - percent) / 100),0) + trace.color = rgb(255 * percent,255 * ((100 - percent) / 100),0) else - P.color = rgb(0, 255, 0) + trace.color = rgb(0, 255, 0) var/turf/curloc = get_turf(src) var/atom/target_atom = current_user.client.mouse_object_ref?.resolve() @@ -211,8 +216,9 @@ return targloc = get_turf_in_angle(lastangle, curloc, 10) var/mouse_modifiers = params2list(current_user.client.mouseParams) - P.preparePixelProjectile(targloc, current_user, mouse_modifiers, 0) - P.fire(lastangle) + trace.preparePixelProjectile(targloc, current_user, mouse_modifiers, 0) + trace.fire(lastangle) + trace = null /obj/item/gun/energy/beam_rifle/process() if(!aiming) @@ -259,6 +265,7 @@ aiming_time_left = aiming_time aiming = FALSE QDEL_LIST(current_tracers) + QDEL_NULL(trace) stop_zooming(user) /obj/item/gun/energy/beam_rifle/proc/set_user(mob/user) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 872bf0cdd5e48..43e4e160d06a1 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -817,6 +817,8 @@ RegisterSignal(src, COMSIG_ATOM_ATTACK_HAND, PROC_REF(attempt_parry)) if(hitscan) process_hitscan() + if(QDELETED(src)) + return if(!(datum_flags & DF_ISPROCESSING)) START_PROCESSING(SSprojectiles, src) pixel_move(pixel_speed_multiplier, FALSE) //move it now! @@ -911,6 +913,9 @@ qdel(src) return //Kill! pixel_move(1, TRUE) + // No kevinz I do not care that this is a hitscan weapon, it is not allowed to travel 100 turfs in a tick + if(CHECK_TICK && QDELETED(src)) + return /obj/projectile/proc/pixel_move(trajectory_multiplier, hitscanning = FALSE) if(!loc || !trajectory) diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm index 4acb1aa0a33c6..2771bc1adb25d 100644 --- a/code/modules/recycling/disposal/bin.dm +++ b/code/modules/recycling/disposal/bin.dm @@ -241,7 +241,7 @@ flushing = TRUE flushAnimation() sleep(1 SECONDS) - if(last_sound < world.time + 1) + if(last_sound < world.time - 1) //Prevents piles of items from playing a dozen sounds at once playsound(src, 'sound/machines/disposalflush.ogg', 50, FALSE, FALSE) last_sound = world.time sleep(0.5 SECONDS) diff --git a/code/modules/research/machinery/_production.dm b/code/modules/research/machinery/_production.dm index bdd31f4e9a04c..cc6a45a5f1f13 100644 --- a/code/modules/research/machinery/_production.dm +++ b/code/modules/research/machinery/_production.dm @@ -414,6 +414,7 @@ created.pixel_x = created.base_pixel_x + rand(-6, 6) created.pixel_y = created.base_pixel_y + rand(-6, 6) + SSblackbox.record_feedback("nested tally", "lathe_printed_items", 1, list("[type]", "[created.type]")) if(is_stack) items_remaining = 0 diff --git a/code/modules/vehicles/mecha/equipment/weapons/weapons.dm b/code/modules/vehicles/mecha/equipment/weapons/weapons.dm index bd9bbfca91f27..d13b90e5659f7 100644 --- a/code/modules/vehicles/mecha/equipment/weapons/weapons.dm +++ b/code/modules/vehicles/mecha/equipment/weapons/weapons.dm @@ -580,10 +580,10 @@ . = ..() var/mob/living/mobtarget = target if(mobtarget.move_resist == MOVE_FORCE_OVERPOWERING) //No megafauna or bolted AIs, please. - to_chat(source, "[span_warning("[src] is unable to lift [mobtarget].")]") + balloon_alert(source, "too strong!") return if(secmech.cargo_hold.contents.len >= secmech.cargo_hold.cargo_capacity) - to_chat(source, "[icon2html(src, source)][span_warning("Not enough room in cargo compartment!")]") + balloon_alert(source, "no room!") return playsound(chassis, clampsound, 50, FALSE, -6) diff --git a/code/modules/vehicles/mecha/mech_fabricator.dm b/code/modules/vehicles/mecha/mech_fabricator.dm index 2dce26624ad25..47c116cbc6029 100644 --- a/code/modules/vehicles/mecha/mech_fabricator.dm +++ b/code/modules/vehicles/mecha/mech_fabricator.dm @@ -260,22 +260,23 @@ * * Returns FALSE is the machine cannot dispense the part on the appropriate turf. * Return TRUE if the part was successfully dispensed. - * * D - Design datum to attempt to dispense. + * * dispensed_design - Design datum to attempt to dispense. */ -/obj/machinery/mecha_part_fabricator/proc/dispense_built_part(datum/design/D) - var/obj/item/I = new D.build_path(src) +/obj/machinery/mecha_part_fabricator/proc/dispense_built_part(datum/design/dispensed_design) + var/obj/item/built_part = new dispensed_design.build_path(src) + SSblackbox.record_feedback("nested tally", "lathe_printed_items", 1, list("[type]", "[built_part.type]")) being_built = null var/turf/exit = get_step(src,(dir)) if(exit.density) say("Error! The part outlet is obstructed.") - desc = "It's trying to dispense the fabricated [D.name], but the part outlet is obstructed." - stored_part = I + desc = "It's trying to dispense the fabricated [dispensed_design.name], but the part outlet is obstructed." + stored_part = built_part return FALSE - say("The fabrication of [I] is now complete.") - I.forceMove(exit) + say("The fabrication of [built_part] is now complete.") + built_part.forceMove(exit) top_job_id += 1 diff --git a/code/modules/vehicles/mecha/working/ripley.dm b/code/modules/vehicles/mecha/working/ripley.dm index 1bed2350f08c8..be9dc0d69c337 100644 --- a/code/modules/vehicles/mecha/working/ripley.dm +++ b/code/modules/vehicles/mecha/working/ripley.dm @@ -396,8 +396,13 @@ GLOBAL_DATUM(cargo_ripley, /obj/vehicle/sealed/mecha/ripley/cargo) return ..() /obj/item/mecha_parts/mecha_equipment/ejector/seccage/container_resist_act(mob/living/user) - to_chat(user, span_notice("You begin attempting a breakout. (This will take around 45 seconds and [chassis] need to remain stationary.)")) - if(!do_after(user, 1 MINUTES, target = chassis)) + var/breakout_time = 1 MINUTES + + if (user.mob_size > MOB_SIZE_HUMAN) + breakout_time = 6 SECONDS + + to_chat(user, span_notice("You begin attempting a breakout. (This will take around [DisplayTimeText(breakout_time)] and [chassis] needs to remain stationary.)")) + if(!do_after(user, breakout_time, target = chassis)) return to_chat(user, span_notice("You break out of the [src].")) playsound(chassis, 'sound/items/crowbar.ogg', 100, TRUE) diff --git a/code/modules/wiremod/shell/module.dm b/code/modules/wiremod/shell/module.dm index 9061bac3e300e..14092f5d2c83c 100644 --- a/code/modules/wiremod/shell/module.dm +++ b/code/modules/wiremod/shell/module.dm @@ -271,7 +271,7 @@ SIGNAL_HANDLER var/string_list = list() var/is_deployed = TRUE - for(var/obj/item/part as anything in attached_module.mod.mod_parts) + for(var/obj/item/part as anything in attached_module.mod.get_parts()) if(part.loc == attached_module.mod) is_deployed = FALSE else diff --git a/config/dynamic.json b/config/dynamic.json index a4a1eb7ebdbfb..5761dbabc324e 100644 --- a/config/dynamic.json +++ b/config/dynamic.json @@ -117,10 +117,6 @@ "weight": 0 }, - "Sentient Disease": { - "weight": 0 - }, - "Space Pirates": { "weight": 0 }, diff --git a/html/changelogs/AutoChangeLog-pr-83399.yml b/html/changelogs/AutoChangeLog-pr-83399.yml new file mode 100644 index 0000000000000..750fedb54e781 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83399.yml @@ -0,0 +1,4 @@ +author: "jlsnow301" +delete-after: True +changes: + - bugfix: "Lootpanel no longer opens up when alt clicking objects on your person" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83420.yml b/html/changelogs/AutoChangeLog-pr-83420.yml deleted file mode 100644 index 1d1cb39750c2a..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83420.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "YesterdaysPromise" -delete-after: True -changes: - - image: "Cleaned a single stray pixel in a single frame of a bite telegraphing accidentaly found while re-organizing the files." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83421.yml b/html/changelogs/AutoChangeLog-pr-83421.yml deleted file mode 100644 index 9a03244707dcd..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83421.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Melbert" -delete-after: True -changes: - - refactor: "Refactored the way high toxins cause you to vomit." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83425.yml b/html/changelogs/AutoChangeLog-pr-83425.yml new file mode 100644 index 0000000000000..4bb476e3ce13b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83425.yml @@ -0,0 +1,6 @@ +author: "FlufflesTheDog" +delete-after: True +changes: + - bugfix: "some missing modsuit (un)sealing messages should no longer be missing" + - bugfix: "MOD circuit adapter core deployed parts output should work again" + - bugfix: "Modsuit painter works again" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83431.yml b/html/changelogs/AutoChangeLog-pr-83431.yml new file mode 100644 index 0000000000000..0aa1c01e555ec --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83431.yml @@ -0,0 +1,5 @@ +author: "jlsnow301" +delete-after: True +changes: + - rscadd: "Added a screentip for hilbert's hotel door" + - bugfix: "Fixed alt-click interaction with hilbert's hotel door" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83432.yml b/html/changelogs/AutoChangeLog-pr-83432.yml deleted file mode 100644 index 53ebc36723874..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83432.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "by INFRARED_BARON" -delete-after: True -changes: - - image: "Changes the sprites of bone and ash drake armor (suit + helmet mob/objs)" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83453.yml b/html/changelogs/AutoChangeLog-pr-83453.yml deleted file mode 100644 index cc036ce9d1498..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83453.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Time-Green" -delete-after: True -changes: - - rscdel: "Removes sentient disease from the game" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83455.yml b/html/changelogs/AutoChangeLog-pr-83455.yml deleted file mode 100644 index d7f9b7d0dd1b6..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83455.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Time-Green" -delete-after: True -changes: - - rscdel: "Miasma and gibs no longer generates random diseases" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83460.yml b/html/changelogs/AutoChangeLog-pr-83460.yml new file mode 100644 index 0000000000000..859ba4611eeab --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83460.yml @@ -0,0 +1,4 @@ +author: "Mey-Ha-Zah" +delete-after: True +changes: + - image: "Revamped Contractor Gear. You'll stand out more now, but hey, that's why the syndicate contracts out work in the first place." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83470.yml b/html/changelogs/AutoChangeLog-pr-83470.yml new file mode 100644 index 0000000000000..753c455022860 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83470.yml @@ -0,0 +1,4 @@ +author: "Capsandi" +delete-after: True +changes: + - sound: "Disposal chutes will no longer play a sound for each item when many items enter it at once" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83472.yml b/html/changelogs/AutoChangeLog-pr-83472.yml new file mode 100644 index 0000000000000..6eb62ab86bce6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83472.yml @@ -0,0 +1,4 @@ +author: "Melbert" +delete-after: True +changes: + - bugfix: "The Bar on Icebox should receive less trash" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83486.yml b/html/changelogs/AutoChangeLog-pr-83486.yml deleted file mode 100644 index 1ae1044efe103..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83486.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "necromanceranne" -delete-after: True -changes: - - bugfix: "Material floor tiles once again have their improved sprite." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83498.yml b/html/changelogs/AutoChangeLog-pr-83498.yml new file mode 100644 index 0000000000000..98532aea8dc63 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83498.yml @@ -0,0 +1,4 @@ +author: "Absolucy" +delete-after: True +changes: + - bugfix: "Fix a rare issue where a turf would remain permanently \"elevated\" if an elevated object was initialized inside of a non-turf object." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83506.yml b/html/changelogs/AutoChangeLog-pr-83506.yml new file mode 100644 index 0000000000000..d9db6982d0ef9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83506.yml @@ -0,0 +1,4 @@ +author: "NewyearnewmeUwu" +delete-after: True +changes: + - bugfix: "Fixed a typo preventing creation of paystands using an ID." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83518.yml b/html/changelogs/AutoChangeLog-pr-83518.yml new file mode 100644 index 0000000000000..54333ae06168e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83518.yml @@ -0,0 +1,4 @@ +author: "Time-Green" +delete-after: True +changes: + - rscdel: "Wipes the last echo of sentient disease from existence" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83523.yml b/html/changelogs/AutoChangeLog-pr-83523.yml new file mode 100644 index 0000000000000..2db25d83372e9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83523.yml @@ -0,0 +1,4 @@ +author: "FearfulFurnishing" +delete-after: True +changes: + - bugfix: "fixed watcher wreath bounties being incompletable" \ No newline at end of file diff --git a/html/changelogs/archive/2024-05.yml b/html/changelogs/archive/2024-05.yml index 0bc768070518f..aaa901966a304 100644 --- a/html/changelogs/archive/2024-05.yml +++ b/html/changelogs/archive/2024-05.yml @@ -700,3 +700,56 @@ - qol: Made borg inventory not shift around depending on equipped items tmyqlfpir: - bugfix: '[Ice Box Station] Dorm 1''s door no longer shares ID with dorm 2''s door' +2024-05-27: + Melbert: + - refactor: Refactored the way high toxins cause you to vomit. + Time-Green: + - rscdel: Removes sentient disease from the game + - rscdel: Miasma and gibs no longer generates random diseases + YesterdaysPromise: + - image: Cleaned a single stray pixel in a single frame of a bite telegraphing accidentaly + found while re-organizing the files. + by INFRARED_BARON: + - image: Changes the sprites of bone and ash drake armor (suit + helmet mob/objs) + necromanceranne: + - bugfix: Material floor tiles once again have their improved sprite. +2024-05-28: + Echriser: + - bugfix: computers with no lights can now turn on using the on/off signal + - bugfix: RGB lights on PDA circuits now use a signal + - bugfix: the is_off signal now works on consoles + - bugfix: printing text on a console component now uses a signal + - refactor: each input signal in console circuits now have their own proc + EnterTheJake: + - bugfix: Rust debuffs now gets properly removed if you derust a tile you are standing + on. + Fikou: + - image: makes food hud burger icon have a sharp outline + Fluffles: + - bugfix: echolocation is less laggy. and works. + Higgin: + - balance: Viruses now self-heal much more effectively with good mood, sleep, food, + and spaceacillin. + - balance: Viruses now punish being hungry more. Stay fed! + - balance: Spaceacillin now gives 200 ticks of symptom resistance, declining over + time, rather than 100. + - balance: Viruses now progress slightly slower. + - balance: Viruses now only hide if their stealth stat is greater than their total + computed severity. + Jacquerel: + - balance: Mobs significantly larger than humans, such as Space Dragons and Xenomorph + Queens, breakout of being arrested by a mech significantly faster. + - bugfix: Venus Man Traps cannot use vines to drag around machines or objects that + are bolted, welded, rooted to, or otherwise are part of the ground + - bugfix: Standing on a table will not prevent you from being grappled by a Venus + Man Trap + LemonInTheDark: + - refactor: I have reworked how parallax and its animations (space travel) work. + Please report any bugs lads! + Pickle-Coding: + - spellcheck: Fixes labour camp shuttle retrieval message starting with "/p". + Whoneedspacee: + - refactor: Wendigos abilities have been changed into actions that can be added + to any mob. + zxaber: + - qol: Traitor-created Infected AIs no longer hear the Malf AI antag sound alert. diff --git a/icons/mob/clothing/head/spacehelm.dmi b/icons/mob/clothing/head/spacehelm.dmi index 181e5eb2e6865..0b9f3d4a36eb4 100644 Binary files a/icons/mob/clothing/head/spacehelm.dmi and b/icons/mob/clothing/head/spacehelm.dmi differ diff --git a/icons/mob/clothing/suits/spacesuit.dmi b/icons/mob/clothing/suits/spacesuit.dmi index 3c381ecd56f94..0067c4bf36a8c 100644 Binary files a/icons/mob/clothing/suits/spacesuit.dmi and b/icons/mob/clothing/suits/spacesuit.dmi differ diff --git a/icons/mob/inhands/weapons/melee_lefthand.dmi b/icons/mob/inhands/weapons/melee_lefthand.dmi index 79a362a009007..d1ac470b093ff 100644 Binary files a/icons/mob/inhands/weapons/melee_lefthand.dmi and b/icons/mob/inhands/weapons/melee_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/melee_righthand.dmi b/icons/mob/inhands/weapons/melee_righthand.dmi index 222f8955396c6..8c18a06de3a24 100644 Binary files a/icons/mob/inhands/weapons/melee_righthand.dmi and b/icons/mob/inhands/weapons/melee_righthand.dmi differ diff --git a/icons/obj/clothing/head/spacehelm.dmi b/icons/obj/clothing/head/spacehelm.dmi index ee8127e4964bb..c2830a9d9335f 100644 Binary files a/icons/obj/clothing/head/spacehelm.dmi and b/icons/obj/clothing/head/spacehelm.dmi differ diff --git a/icons/obj/clothing/suits/spacesuit.dmi b/icons/obj/clothing/suits/spacesuit.dmi index 84f84ac978e85..922ad05c35e7a 100644 Binary files a/icons/obj/clothing/suits/spacesuit.dmi and b/icons/obj/clothing/suits/spacesuit.dmi differ diff --git a/icons/obj/weapons/baton.dmi b/icons/obj/weapons/baton.dmi index e97547d851745..2d5100ec4d414 100644 Binary files a/icons/obj/weapons/baton.dmi and b/icons/obj/weapons/baton.dmi differ diff --git a/sound/machines/hiss.ogg b/sound/machines/hiss.ogg index a1b725eab931e..73ace2de31fcf 100644 Binary files a/sound/machines/hiss.ogg and b/sound/machines/hiss.ogg differ diff --git a/tgstation.dme b/tgstation.dme index d35ffe575fabd..165b2419ccc35 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -852,6 +852,7 @@ #include "code\datums\actions\mobs\dash.dm" #include "code\datums\actions\mobs\defensive_mode.dm" #include "code\datums\actions\mobs\fire_breath.dm" +#include "code\datums\actions\mobs\ground_slam.dm" #include "code\datums\actions\mobs\lava_swoop.dm" #include "code\datums\actions\mobs\meteors.dm" #include "code\datums\actions\mobs\mobcooldown.dm" @@ -860,6 +861,7 @@ #include "code\datums\actions\mobs\projectileattack.dm" #include "code\datums\actions\mobs\sign_language.dm" #include "code\datums\actions\mobs\sneak.dm" +#include "code\datums\actions\mobs\teleport.dm" #include "code\datums\actions\mobs\transform_weapon.dm" #include "code\datums\actions\mobs\sequences\dash_attack.dm" #include "code\datums\actions\mobs\sequences\projectile.dm" diff --git a/tgui/packages/tgui/interfaces/Pandemic/Symptom.tsx b/tgui/packages/tgui/interfaces/Pandemic/Symptom.tsx index cdbb49f715fca..5fa92583f2e51 100644 --- a/tgui/packages/tgui/interfaces/Pandemic/Symptom.tsx +++ b/tgui/packages/tgui/interfaces/Pandemic/Symptom.tsx @@ -70,7 +70,7 @@ const Thresholds = (props) => { /** Displays the numerical trait modifiers for a virus symptom */ const Traits = (props) => { const { - symptom: { level, resistance, stage_speed, stealth, transmission }, + symptom: { level, weight, resistance, stage_speed, stealth, transmission }, } = props; return ( @@ -81,6 +81,11 @@ const Traits = (props) => { {level} + + + {weight} + + {resistance} diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/sentientdisease.ts b/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/sentientdisease.ts deleted file mode 100644 index a9c11eda72910..0000000000000 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/antagonists/antagonists/sentientdisease.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Antagonist, Category } from '../base'; - -const SentientDisease: Antagonist = { - key: 'sentientdisease', - name: 'Sentient Disease', - description: [ - ` - Mutate and spread yourself and infect as much of the crew as possible - with a deadly plague of your own creation. - `, - ], - category: Category.Midround, -}; - -export default SentientDisease;