diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm index 2fda22cd32d..7b894fa4669 100644 --- a/code/game/machinery/bots/mulebot.dm +++ b/code/game/machinery/bots/mulebot.dm @@ -138,11 +138,9 @@ unload(0) switch(severity) if(2) - BITRESET(wires, rand(0,9)) - BITRESET(wires, rand(0,9)) - BITRESET(wires, rand(0,9)) + wires.RandomCutAll(40)//Fix by nanako because the old code was throwing runtimes if(3) - BITRESET(wires, rand(0,9)) + wires.RandomCutAll(20) ..() return diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 934b4f629be..50dd01c87e3 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -928,9 +928,9 @@ About the new airlock wires panel: //if the door is unpowered then it doesn't make sense to hear the woosh of a pneumatic actuator if(arePowerSystemsOn()) - playsound(src.loc, open_sound_powered, 100, 1) + playsound(src.loc, open_sound_powered, 60, 1) else - playsound(src.loc, open_sound_unpowered, 100, 1) + playsound(src.loc, open_sound_unpowered, 60, 1) if(src.closeOther != null && istype(src.closeOther, /obj/machinery/door/airlock/) && !src.closeOther.density) src.closeOther.close() @@ -992,7 +992,7 @@ About the new airlock wires panel: adjustBruteLoss(round(crush_damage / AIRLOCK_CRUSH_DIVISOR)) SetStunned(5) SetWeakened(5) - + var/turf/T = get_turf(src) var/list/valid_turfs = list() @@ -1004,7 +1004,7 @@ About the new airlock wires panel: while(valid_turfs.len) T = pick(valid_turfs) valid_turfs -= T - + if(src.forceMove(T)) return diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 8e7c952def7..0b508787a51 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -26,6 +26,7 @@ var/destroy_hits = 10 //How many strong hits it takes to destroy the door var/min_force = 10 //minimum amount of force needed to damage the door with a melee weapon var/hitsound = 'sound/weapons/smash.ogg' //sound door makes when hit with a weapon + var/hitsound_light = 'sound/effects/Glasshit.ogg'//Sound door makes when hit very gently var/obj/item/stack/material/steel/repairing var/block_air_zones = 1 //If set, air zones cannot merge across the door even when it is opened. var/close_door_at = 0 //When to automatically close the door, if possible @@ -53,9 +54,11 @@ /obj/machinery/door/attack_generic(var/mob/user, var/damage) if(damage >= 10) visible_message("\The [user] smashes into the [src]!") + playsound(src.loc, hitsound, 60, 1) take_damage(damage) else visible_message("\The [user] bonks \the [src] harmlessly.") + playsound(src.loc, hitsound_light, 8, 1, -1) user.do_attack_animation(src) /obj/machinery/door/New() @@ -226,7 +229,7 @@ if (Proj.damage > 90) destroy_hits-- if (destroy_hits <= 0) - visible_message("\red \The [src.name] disintegrates!") + visible_message(span("danger","\The [src.name] disintegrates!")) switch (Proj.damage_type) if(BRUTE) new /obj/item/stack/material/steel(src.loc, 2) @@ -244,15 +247,20 @@ /obj/machinery/door/hitby(AM as mob|obj, var/speed=5) ..() - visible_message("\red [src.name] was hit by [AM].") + visible_message(span("danger","[src.name] was hit by [AM].")) var/tforce = 0 if(ismob(AM)) tforce = 15 * (speed/5) else tforce = AM:throwforce * (speed/5) - playsound(src.loc, hitsound, 100, 1) - take_damage(tforce) - return + + if (tforce > 0) + var/volume = 100 + if (tforce < 20)//No more stupidly loud banging sound from throwing a piece of paper at a door + volume *= (tforce / 20) + playsound(src.loc, hitsound, volume, 1) + take_damage(tforce) + return /obj/machinery/door/attack_ai(mob/user as mob) return src.attack_hand(user) @@ -330,9 +338,9 @@ if(W.damtype == BRUTE || W.damtype == BURN) user.do_attack_animation(src) if(W.force < min_force) - user.visible_message("\red \The [user] hits \the [src] with \the [W] with no visible effect." ) + user.visible_message(span("danger","\The [user] hits \the [src] with \the [W] with no visible effect." )) else - user.visible_message("\red \The [user] forcefully strikes \the [src] with \the [W]!" ) + user.visible_message(span("danger","\The [user] forcefully strikes \the [src] with \the [W]!" )) playsound(src.loc, hitsound, 100, 1) take_damage(W.force) return diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm index 1b32185ace3..a99b771093a 100644 --- a/code/game/objects/explosion.dm +++ b/code/game/objects/explosion.dm @@ -5,8 +5,8 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa ///// Z-Level Stuff src = null //so we don't abort once src is deleted spawn(0) + var/power = max(0,devastation_range) * 2 + max(0,heavy_impact_range) + max(0,light_impact_range) if(config.use_recursive_explosions) - var/power = devastation_range * 2 + heavy_impact_range + light_impact_range //The ranges add up, ie light 14 includes both heavy 7 and devestation 3. So this calculation means devestation counts for 4, heavy for 2 and light for 1 power, giving us a cap of 27 power. explosion_rec(epicenter, power) return @@ -18,7 +18,7 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa if(z_transfer && (devastation_range > 0 || heavy_impact_range > 0)) //transfer the explosion in both directions explosion_z_transfer(epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range) -///// Z-Level Stuff +///// Z-Level Stuffis var/max_range = max(devastation_range, heavy_impact_range, light_impact_range, flash_range) //playsound(epicenter, 'sound/effects/explosionfar.ogg', 100, 1, round(devastation_range*2,1) ) @@ -31,33 +31,65 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa // Calculate far explosion sound range. Only allow the sound effect for heavy/devastating explosions. // 3/7/14 will calculate to 80 + 35 - var/far_dist = 0 - far_dist += heavy_impact_range * 5 - far_dist += devastation_range * 20 + var/volume = 10 + (power * 20) var/frequency = get_rand_frequency() - for(var/mob/M in player_list) - // Double check for client - if(M && M.client) - var/turf/M_turf = get_turf(M) - if(M_turf && M_turf.z == epicenter.z) - var/dist = get_dist(M_turf, epicenter) - // If inside the blast radius + world.view - 2 - if(dist <= round(max_range + world.view - 2, 1)) - M.playsound_local(epicenter, get_sfx("explosion"), 100, 1, frequency, falloff = 5) // get_sfx() is so that everyone gets the same sound + var/closedist = round(max_range + world.view - 2, 1) - //You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station. + //Whether or not this explosion causes enough vibration to send sound or shockwaves through the station + var/vibration = 1 + if (istype(epicenter,/turf/space)) + vibration = 0 + for (var/turf/T in range(src, max_range)) + if (!istype(T,/turf/space)) + //If there is a nonspace tile within the explosion radius + //Then we can reverberate shockwaves through that, and allow it to be felt in a vacuum + vibration = 1 - else if(dist <= far_dist) - var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist - far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion - M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5) + if (vibration) + for(var/mob/M in player_list) + // Double check for client + var/reception = 2//Whether the person can be shaken or hear sound + //2 = BOTH + //1 = shockwaves only + //0 = no effect + if(M && M.client) + var/turf/M_turf = get_turf(M) + + + + if(M_turf && M_turf.z == epicenter.z) + if (istype(M_turf,/turf/space)) + //If the person is standing in space, they wont hear + //But they may still feel the shaking + reception = 0 + for (var/turf/T in range(M, 1)) + if (!istype(T,/turf/space)) + //If theyre touching the hull or on some extruding part of the station + reception = 1//They will get screenshake + break + + if (!reception) + continue + + var/dist = get_dist(M_turf, epicenter) + if (reception == 2 && (M.ear_deaf <= 0 || !M.ear_deaf))//Dont play sounds to deaf people + // If inside the blast radius + world.view - 2 + if(dist <= closedist) + M.playsound_local(epicenter, get_sfx("explosion"), min(100, volume), 1, frequency, falloff = 5) // get_sfx() is so that everyone gets the same sound + //You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station. + + else + volume = M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', volume, 1, frequency, usepressure = 0, falloff = 1000) + //Playsound local will return the final volume the sound is actually played at + //It will return 0 if the sound volume falls to 0 due to falloff or pressure + //Also return zero if sound playing failed for some other reason + + //Deaf people will feel vibrations though + if (volume > 0)//Only shake camera if someone was close enough to hear it + shake_camera(M, min(60,max(2,(power*28) / dist)), min(3.5,((power*6) / dist)),0.05) + //Maximum duration is 6 seconds, and max strength is 3.5 + //Becuse values higher than those just get really silly - var/close = range(world.view+round(devastation_range,1), epicenter) - // to all distanced mobs play a different sound - for(var/mob/M in world) if(M.z == epicenter.z) if(!(M in close)) - // check if the mob can hear - if(M.ear_deaf <= 0 || !M.ear_deaf) if(!istype(M.loc,/turf/space)) - M << 'sound/effects/explosionfar.ogg' if(adminlog) message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z]) (JMP)") log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range]) in area [epicenter.loc.name] ") @@ -115,7 +147,6 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa return 1 - proc/secondaryexplosion(turf/epicenter, range) for(var/turf/tile in range(range, epicenter)) tile.ex_act(2) diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index e44f7595470..7b7d7deab8d 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -69,7 +69,7 @@ /obj/item/device/transfer_valve/attack_self(mob/user as mob) ui_interact(user) - + /obj/item/device/transfer_valve/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) // this is the data which will be sent to the ui @@ -80,7 +80,7 @@ data["valveOpen"] = valve_open ? 1 : 0 // update the ui if it exists, returns null if no ui is passed/found - ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) // the ui does not exist, so we'll create a new() one // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm @@ -149,7 +149,7 @@ tank_two = null else return - + T.loc = get_turf(src) update_icon() @@ -165,18 +165,18 @@ /obj/item/device/transfer_valve/proc/split_gases() if(!valve_open) return - + valve_open = 0 - - if(deleted(tank_one) || deleted(tank_two)) + + if(deleted(tank_one) || deleted(tank_two) || !tank_one.air_contents || !tank_two.air_contents) return - + var/ratio1 = tank_one.air_contents.volume/tank_two.air_contents.volume var/datum/gas_mixture/temp temp = tank_two.air_contents.remove_ratio(ratio1) tank_one.air_contents.merge(temp) tank_two.air_contents.volume -= tank_one.air_contents.volume - + /* Exadv1: I know this isn't how it's going to work, but this was just to check diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 70e599c5b06..7b7be9288ee 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -174,7 +174,7 @@ /obj/structure/window/attack_tk(mob/user as mob) user.visible_message("Something knocks on [src].") - playsound(loc, 'sound/effects/Glasshit.ogg', 50, 1) + playsound(loc, 'sound/effects/Glasshit.ogg', 60, 1) /obj/structure/window/attack_hand(mob/user as mob) if(HULK in user.mutations) @@ -191,26 +191,25 @@ attack_generic(H,25) return - playsound(src.loc, 'sound/effects/glassknock.ogg', 80, 1) + playsound(src.loc, 'sound/effects/glassknock.ogg', 90, 1) user.do_attack_animation(src) usr.visible_message("\red [usr.name] bangs against the [src.name]!", "\red You bang against the [src.name]!", "You hear a banging sound.") else - playsound(src.loc, 'sound/effects/glassknock.ogg', 80, 1) + playsound(src.loc, 'sound/effects/glassknock.ogg', 60, 1) usr.visible_message("[usr.name] knocks on the [src.name].", "You knock on the [src.name].", "You hear a knocking sound.") return /obj/structure/window/attack_generic(var/mob/user, var/damage) - if(!damage) - return if(damage >= 10) visible_message("[user] smashes into [src]!") take_damage(damage) else visible_message("\The [user] bonks \the [src] harmlessly.") + playsound(src.loc, 'sound/effects/Glasshit.ogg', 7, 1, -1) user.do_attack_animation(src) return 1 diff --git a/code/game/sound.dm b/code/game/sound.dm index bb46b510585..2a98112276b 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -48,11 +48,11 @@ var/list/footstepfx = list("defaultstep","concretestep","grassstep","dirtstep"," var/const/FALLOFF_SOUNDS = 0.5 /mob/proc/playsound_local(var/turf/turf_source, soundin, vol as num, vary, frequency, falloff, is_global, var/usepressure = 1, var/environment = -1) - if(!src.client || ear_deaf > 0) return + if(!src.client || ear_deaf > 0) return 0 if(soundin in footstepfx) if(!(src.client.prefs.asfx_togs & ASFX_FOOTSTEPS)) - return + return 0 soundin = get_sfx(soundin) @@ -79,7 +79,6 @@ var/const/FALLOFF_SOUNDS = 0.5 //This extra falloff should probably be rewritten or removed, but for now ive implemented a quick fix by only setting S.volume to vol after calculations are done //This fix allows feeding in high volume values (>100) to make longrange sounds audible // -Nanako - if (usepressure) //sound volume falloff with pressure. Pass usepressure = 0 to disable these calculations var/pressure_factor = 1.0 @@ -101,7 +100,7 @@ var/const/FALLOFF_SOUNDS = 0.5 vol *= pressure_factor if (vol <= 0) - return //no volume means no sound + return 0//no volume means no sound S.volume = vol var/dx = turf_source.x - T.x // Hearing from the right/left @@ -117,6 +116,7 @@ var/const/FALLOFF_SOUNDS = 0.5 S.environment = A.sound_env src << S + return S.volume diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 01e03aa3501..9a5eac6e374 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -456,14 +456,14 @@ It's fairly easy to fix if dealing with single letters but not so much with comp return sanitize(t) -/proc/shake_camera(mob/M, duration, strength=1) +/proc/shake_camera(mob/M, duration, strength=1, var/taper = 0) if(!M || !M.client || M.shakecamera) return + M.shakecamera = 1 - spawn(1) + spawn(2) if(!M.client) return - var/atom/oldeye=M.client.eye var/aiEyeFlag = 0 if(istype(oldeye, /mob/eye/aiEye)) @@ -476,6 +476,20 @@ It's fairly easy to fix if dealing with single letters but not so much with comp else M.client.eye = locate(dd_range(1,M.loc.x+rand(-strength,strength),world.maxx),dd_range(1,M.loc.y+rand(-strength,strength),world.maxy),M.loc.z) sleep(1) + + //Taper code added by nanako. + //Will make the strength falloff after the duration. + //This helps to reduce jarring effects of major screenshaking suddenly returning to stability + //Recommended taper values are 0.05-0.1 + if (taper > 0) + while (strength > 0) + strength -= taper + if(aiEyeFlag) + M.client.eye = locate(dd_range(1,oldeye.loc.x+rand(-strength,strength),world.maxx),dd_range(1,oldeye.loc.y+rand(-strength,strength),world.maxy),oldeye.loc.z) + else + M.client.eye = locate(dd_range(1,M.loc.x+rand(-strength,strength),world.maxx),dd_range(1,M.loc.y+rand(-strength,strength),world.maxy),M.loc.z) + sleep(1) + M.client.eye=oldeye M.shakecamera = 0 diff --git a/html/changelogs/Nanako-AudioBomb.yml b/html/changelogs/Nanako-AudioBomb.yml new file mode 100644 index 00000000000..2fde0e08f95 --- /dev/null +++ b/html/changelogs/Nanako-AudioBomb.yml @@ -0,0 +1,38 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Nanako + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Explosions now have proper directional sounds, so you can tell the direction that something exploded in." + - rscadd: "Distant explosions now cause mild screen shaking proportional to power and distance." + - tweak: "Adjusted sound volumes for several actions related to windows and airlocks."