Merge branch 'master' into revenant_TK

This commit is contained in:
Artur
2021-01-20 18:27:11 +02:00
414 changed files with 6097 additions and 2811 deletions
+1 -1
View File
@@ -92,7 +92,7 @@
trauma = _trauma
owner = trauma.owner
setup_friend()
INVOKE_ASYNC(src, .proc/setup_friend)
join = new
join.Grant(src)
+20 -6
View File
@@ -30,7 +30,7 @@
/datum/cinematic
var/id = CINEMATIC_DEFAULT
var/list/watching = list() //List of clients watching this
var/list/locked = list() //Who had mob_transforming set during the cinematic
var/list/locked = list() //Who had mob_transforming set during the cinematic
var/is_global = FALSE //Global cinematics will override mob-specific ones
var/obj/screen/cinematic/screen
var/datum/callback/special_callback //For special effects synced with animation (explosions after the countdown etc)
@@ -45,7 +45,7 @@
if(!CC)
continue
var/client/C = CC
//C.mob.clear_fullscreen("cinematic")
C.mob.clear_fullscreen("cinematic")
C.screen -= screen
watching = null
QDEL_NULL(screen)
@@ -54,7 +54,7 @@
if(!MM)
continue
var/mob/M = MM
M.mob_transforming = FALSE
M.mob_transforming = FALSE
locked = null
return ..()
@@ -93,7 +93,7 @@
toggle_ooc(TRUE)
/datum/cinematic/proc/show_to(mob/M, client/C)
//SIGNAL_HANDLER //must not wait.
SIGNAL_HANDLER
if(!M.mob_transforming)
locked += M
@@ -101,7 +101,7 @@
if(!C)
return
watching += C
//M.overlay_fullscreen("cinematic",/obj/screen/fullscreen/cinematic_backdrop)
M.overlay_fullscreen("cinematic",/obj/screen/fullscreen/cinematic_backdrop)
C.screen += screen
//Sound helper
@@ -122,7 +122,7 @@
sleep(50)
/datum/cinematic/proc/replacement_cinematic(datum/source, datum/cinematic/other)
//SIGNAL_HANDLER
SIGNAL_HANDLER
if(!is_global && other.is_global) //Allow it to play if we're local and it's global
return NONE
@@ -210,6 +210,20 @@
special()
screen.icon_state = "summary_cult"
// /datum/cinematic/cult_fail
// id = CINEMATIC_CULT_FAIL
// /datum/cinematic/cult_fail/content()
// screen.icon_state = "station_intact"
// sleep(20)
// cinematic_sound(sound('sound/creatures/narsie_rises.ogg'))
// sleep(60)
// cinematic_sound(sound('sound/effects/explosion_distant.ogg'))
// sleep(10)
// cinematic_sound(sound('sound/magic/demon_dies.ogg'))
// sleep(30)
// special()
/datum/cinematic/nuke_annihilation
id = CINEMATIC_ANNIHILATION
+1 -1
View File
@@ -125,7 +125,7 @@
///Changes the user direction to (try) keep match the pointer.
/datum/component/combat_mode/proc/on_move(atom/movable/source, dir, atom/oldloc, forced)
var/mob/living/L = source
if(mode_flags & COMBAT_MODE_ACTIVE && L.client && lastmousedir && lastmousedir != dir)
if((mode_flags & COMBAT_MODE_ACTIVE) && L.client)
L.setDir(lastmousedir, ismousemovement = TRUE)
/// Added movement delay if moving backward.
+6 -38
View File
@@ -2,6 +2,12 @@
/obj/item/weaponcrafting
icon = 'icons/obj/improvised.dmi'
/obj/item/weaponcrafting/receiver
name = "modular receiver"
desc = "A prototype modular receiver and trigger assembly for a firearm."
icon = 'icons/obj/improvised.dmi'
icon_state = "receiver"
/obj/item/weaponcrafting/stock
name = "rifle stock"
desc = "A classic rifle stock that doubles as a grip, roughly carved out of wood."
@@ -12,41 +18,3 @@
name = "wound thread"
desc = "A long piece of thread with some resemblance to cable coil."
icon_state = "durastring"
////////////////////////////////
// IMPROVISED WEAPON PARTS//
////////////////////////////////
/obj/item/weaponcrafting/improvised_parts
name = "Debug Improvised Gun Part"
desc = "A badly coded gun part. You should report coders if you see this."
icon = 'icons/obj/guns/gun_parts.dmi'
icon_state = "palette"
// RECEIVERS
/obj/item/weaponcrafting/improvised_parts/rifle_receiver
name = "rifle receiver"
desc = "A crudely constructed receiver to create an improvised bolt-action breechloaded rifle." // removed some text implying that the item had more uses than it does
icon_state = "receiver_rifle"
w_class = WEIGHT_CLASS_SMALL
/obj/item/weaponcrafting/improvised_parts/shotgun_receiver
name = "shotgun reciever"
desc = "An improvised receiver to create a break-action breechloaded shotgun." // removed some text implying that the item had more uses than it does
icon_state = "receiver_shotgun"
w_class = WEIGHT_CLASS_SMALL
// MISC
/obj/item/weaponcrafting/improvised_parts/trigger_assembly
name = "firearm trigger assembly"
desc = "A modular trigger assembly with a firing pin, this can be used to make a whole bunch of improvised firearss."
icon_state = "trigger_assembly"
w_class = WEIGHT_CLASS_SMALL
/obj/item/weaponcrafting/improvised_parts/wooden_body
name = "wooden firearm body"
desc = "A crudely fashioned wooden body to help keep higher calibre improvised weapons from blowing themselves apart."
icon_state = "wooden_body"
@@ -172,11 +172,11 @@
///////////////////
/datum/crafting_recipe/upgraded_gauze
name = "Improved Gauze"
name = "Sterilized Gauze"
result = /obj/item/stack/medical/gauze/adv/one
time = 1
reqs = list(/obj/item/stack/medical/gauze = 1,
/datum/reagent/space_cleaner/sterilizine = 10)
/datum/reagent/space_cleaner/sterilizine = 5)
category = CAT_MISC
subcategory = CAT_TOOL
@@ -184,7 +184,7 @@
name = "Suture Pack"
result = /obj/item/stack/medical/suture/five
time = 1
reqs = list(/obj/item/stack/medical/gauze = 1,
reqs = list(/obj/item/stack/medical/gauze/adv = 1,
/datum/reagent/medicine/styptic_powder = 10)
category = CAT_MISC
subcategory = CAT_TOOL
@@ -193,7 +193,7 @@
name = "Regenerative Mesh"
result = /obj/item/stack/medical/mesh/five
time = 1
reqs = list(/obj/item/stack/medical/gauze = 1,
reqs = list(/obj/item/stack/medical/gauze/adv = 1,
/datum/reagent/medicine/silver_sulfadiazine = 10)
category = CAT_MISC
subcategory = CAT_TOOL
@@ -297,30 +297,15 @@
/datum/crafting_recipe/ishotgun
name = "Improvised Shotgun"
result = /obj/item/gun/ballistic/revolver/doublebarrel/improvised
reqs = list(/obj/item/pipe = 2, // putting a large amount of meaningless timegates by forcing people to turn base resources into upgraded resources kinda sucks
/obj/item/weaponcrafting/improvised_parts/shotgun_receiver = 1,
/obj/item/weaponcrafting/improvised_parts/trigger_assembly = 1,
/obj/item/weaponcrafting/improvised_parts/wooden_body = 1,
/obj/item/weaponcrafting/stock = 1,
/obj/item/stack/packageWrap = 5)
tools = list(TOOL_SCREWDRIVER)
time = 100
category = CAT_WEAPONRY
subcategory = CAT_WEAPON
/datum/crafting_recipe/irifle // larger and less versatile gun, but a bit easier to make
name = "Improvised Rifle (7.62mm)"
result = /obj/item/gun/ballistic/shotgun/boltaction/improvised
reqs = list(/obj/item/pipe = 2, // above
/obj/item/weaponcrafting/improvised_parts/rifle_receiver = 1,
/obj/item/weaponcrafting/improvised_parts/trigger_assembly = 1,
/obj/item/weaponcrafting/improvised_parts/wooden_body = 1,
reqs = list(/obj/item/pipe = 1,
/obj/item/weaponcrafting/receiver = 1,
/obj/item/weaponcrafting/stock = 1,
/obj/item/stack/packageWrap = 5)
tools = list(TOOL_SCREWDRIVER)
time = 100
category = CAT_WEAPONRY
subcategory = CAT_WEAPON
//the Improvised Rifle will not be missed. Rest in Pieces 2019-2021
//////////////////
///AMMO CRAFTING//
@@ -449,38 +434,6 @@
// PARTS CRAFTING //
////////////////////
// RECEIVERS
/datum/crafting_recipe/rifle_receiver
name = "Improvised Rifle Receiver"
result = /obj/item/weaponcrafting/improvised_parts/rifle_receiver
reqs = list(/obj/item/stack/sheet/metal = 15)
tools = list(TOOL_SCREWDRIVER, TOOL_WELDER)
time = 25
category = CAT_WEAPONRY
subcategory = CAT_PARTS
/datum/crafting_recipe/shotgun_receiver
name = "Improvised Shotgun Receiver"
result = /obj/item/weaponcrafting/improvised_parts/shotgun_receiver
reqs = list(/obj/item/stack/sheet/metal = 10) // shotgun does less damage than the rifle and can't 1shot but is more portable
tools = list(TOOL_SCREWDRIVER, TOOL_WELDER)
time = 20
category = CAT_WEAPONRY
subcategory = CAT_PARTS
// MISC
/datum/crafting_recipe/trigger_assembly
name = "Trigger Assembly"
result = /obj/item/weaponcrafting/improvised_parts/trigger_assembly
reqs = list(/obj/item/stack/sheet/metal = 3,
/obj/item/assembly/igniter = 1)
tools = list(TOOL_SCREWDRIVER, TOOL_WELDER)
time = 20
category = CAT_WEAPONRY
subcategory = CAT_PARTS
// BOKKEN CRAFTING
/datum/crafting_recipe/bokken_blade
+8 -8
View File
@@ -46,7 +46,7 @@
var/mob/living/LM = parent
if(!T.footstep || LM.buckled || !CHECK_MOBILITY(LM, MOBILITY_STAND) || LM.buckled || LM.throwing || (LM.movement_type & (VENTCRAWLING | FLYING)))
if (LM.lying && !LM.buckled && !(!T.footstep || LM.movement_type & (VENTCRAWLING | FLYING))) //play crawling sound if we're lying
playsound(T, 'sound/effects/footstep/crawl1.ogg', 15 * volume)
playsound(T, 'sound/effects/footstep/crawl1.ogg', 15 * volume, falloff_distance = 1)
return
if(HAS_TRAIT(LM, TRAIT_SILENT_STEP))
@@ -75,7 +75,7 @@
if(!T)
return
if(isfile(footstep_sounds) || istext(footstep_sounds))
playsound(T, footstep_sounds, volume)
playsound(T, footstep_sounds, volume, falloff_distance = 1)
return
var/turf_footstep
switch(footstep_type)
@@ -89,7 +89,7 @@
turf_footstep = T.footstep
if(!turf_footstep)
return
playsound(T, pick(footstep_sounds[turf_footstep][1]), footstep_sounds[turf_footstep][2] * volume, TRUE, footstep_sounds[turf_footstep][3] + e_range)
playsound(T, pick(footstep_sounds[turf_footstep][1]), footstep_sounds[turf_footstep][2] * volume, TRUE, footstep_sounds[turf_footstep][3] + e_range, falloff_distance = 1)
/datum/component/footstep/proc/play_humanstep()
var/turf/open/T = prepare_step()
@@ -114,10 +114,10 @@
turf_footstep = T.footstep
L = GLOB.footstep
if(FOOTSTEP_MOB_SLIME)
playsound(T, 'sound/effects/footstep/slime1.ogg', 50 * volume)
playsound(T, 'sound/effects/footstep/slime1.ogg', 50 * volume, falloff_distance = 1)
return
if(FOOTSTEP_MOB_CRAWL)
playsound(T, 'sound/effects/footstep/crawl1.ogg', 50 * volume)
playsound(T, 'sound/effects/footstep/crawl1.ogg', 50 * volume, falloff_distance = 1)
return
special = TRUE
else
@@ -126,13 +126,13 @@
playsound(T, pick(GLOB.footstep[T.footstep][1]),
GLOB.footstep[T.footstep][2] * volume,
TRUE,
GLOB.footstep[T.footstep][3] + e_range)
GLOB.footstep[T.footstep][3] + e_range, falloff_distance = 1)
return
if(!special && H.dna.species.special_step_sounds)
playsound(T, pick(H.dna.species.special_step_sounds), 50, TRUE)
playsound(T, pick(H.dna.species.special_step_sounds), 50, TRUE, falloff_distance = 1)
else
playsound(T, pick(L[turf_footstep][1]),
L[turf_footstep][2] * volume,
TRUE,
L[turf_footstep][3] + e_range)
L[turf_footstep][3] + e_range, falloff_distance = 1)
+17 -12
View File
@@ -36,15 +36,15 @@
if(del_on_unbuckle_all && !AM.has_buckled_mobs())
qdel(src)
/datum/component/riding/proc/vehicle_mob_buckle(datum/source, mob/living/M, force = FALSE)
/datum/component/riding/proc/vehicle_mob_buckle(datum/source, mob/living/M, force)
handle_vehicle_offsets()
/datum/component/riding/proc/handle_vehicle_layer()
/datum/component/riding/proc/handle_vehicle_layer(dir)
var/atom/movable/AM = parent
var/static/list/defaults = list(TEXT_NORTH = OBJ_LAYER, TEXT_SOUTH = ABOVE_MOB_LAYER, TEXT_EAST = ABOVE_MOB_LAYER, TEXT_WEST = ABOVE_MOB_LAYER)
. = defaults["[AM.dir]"]
if(directional_vehicle_layers["[AM.dir]"])
. = directional_vehicle_layers["[AM.dir]"]
. = defaults["[dir]"]
if(directional_vehicle_layers["[dir]"])
. = directional_vehicle_layers["[dir]"]
if(isnull(.)) //you can set it to null to not change it.
. = AM.layer
AM.layer = .
@@ -52,12 +52,17 @@
/datum/component/riding/proc/set_vehicle_dir_layer(dir, layer)
directional_vehicle_layers["[dir]"] = layer
/datum/component/riding/proc/vehicle_moved(datum/source)
/datum/component/riding/proc/vehicle_moved(datum/source, oldLoc, dir)
SIGNAL_HANDLER
var/atom/movable/AM = parent
if (isnull(dir))
dir = AM.dir
AM.set_glide_size(DELAY_TO_GLIDE_SIZE(vehicle_move_delay), FALSE)
for(var/i in AM.buckled_mobs)
ride_check(i)
handle_vehicle_offsets()
handle_vehicle_layer()
handle_vehicle_offsets(dir)
handle_vehicle_layer(dir)
/datum/component/riding/proc/ride_check(mob/living/M)
var/atom/movable/AM = parent
@@ -74,9 +79,9 @@
/datum/component/riding/proc/additional_offset_checks()
return TRUE
/datum/component/riding/proc/handle_vehicle_offsets()
/datum/component/riding/proc/handle_vehicle_offsets(dir)
var/atom/movable/AM = parent
var/AM_dir = "[AM.dir]"
var/AM_dir = "[dir]"
var/passindex = 0
if(AM.has_buckled_mobs())
for(var/m in AM.buckled_mobs)
@@ -177,8 +182,8 @@
else
last_move_diagonal = FALSE
handle_vehicle_offsets()
handle_vehicle_layer()
handle_vehicle_offsets(direction)
handle_vehicle_layer(direction)
else
to_chat(user, "<span class='notice'>You'll need the keys in one of your hands to [drive_verb] [AM].</span>")
+27 -7
View File
@@ -19,7 +19,14 @@
/// chance we'll be stopped from squeaking by cooldown when something crossing us squeaks
var/cross_squeak_delay_chance = 33 // about 3 things can squeak at a time
/datum/component/squeak/Initialize(custom_sounds, volume_override, chance_override, step_delay_override, use_delay_override)
///extra-range for this component's sound
var/sound_extra_range = -1
///when sounds start falling off for the squeak
var/sound_falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE
///sound exponent for squeak. Defaults to 10 as squeaking is loud and annoying enough.
var/sound_falloff_exponent = 10
/datum/component/squeak/Initialize(custom_sounds, volume_override, chance_override, step_delay_override, use_delay_override, extrarange, falloff_exponent, fallof_distance)
if(!isatom(parent))
return COMPONENT_INCOMPATIBLE
RegisterSignal(parent, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_BLOB_ACT, COMSIG_ATOM_HULK_ATTACK, COMSIG_PARENT_ATTACKBY), .proc/play_squeak)
@@ -45,6 +52,12 @@
step_delay = step_delay_override
if(isnum(use_delay_override))
use_delay = use_delay_override
if(isnum(extrarange))
sound_extra_range = extrarange
if(isnum(falloff_exponent))
sound_falloff_exponent = falloff_exponent
if(isnum(fallof_distance))
sound_falloff_distance = fallof_distance
/datum/component/squeak/UnregisterFromParent()
if(!isatom(parent))
@@ -62,6 +75,7 @@
return ..()
/datum/component/squeak/proc/play_squeak()
SIGNAL_HANDLER
do_play_squeak()
/datum/component/squeak/proc/do_play_squeak(bypass_cooldown = FALSE)
@@ -69,14 +83,16 @@
return FALSE
if(prob(squeak_chance))
if(!override_squeak_sounds)
playsound(parent, pickweight(default_squeak_sounds), volume, 1, -1)
playsound(parent, pickweight(default_squeak_sounds), volume, TRUE, sound_extra_range, sound_falloff_exponent, falloff_distance = sound_falloff_distance)
else
playsound(parent, pickweight(override_squeak_sounds), volume, 1, -1)
playsound(parent, pickweight(override_squeak_sounds), volume, TRUE, sound_extra_range, sound_falloff_exponent, falloff_distance = sound_falloff_distance)
last_squeak = world.time
return TRUE
return FALSE
/datum/component/squeak/proc/step_squeak()
SIGNAL_HANDLER
if(steps > step_delay)
do_play_squeak(TRUE)
steps = 0
@@ -84,20 +100,22 @@
steps++
/datum/component/squeak/proc/play_squeak_crossed(datum/source, atom/movable/AM)
SIGNAL_HANDLER
if(isitem(AM))
var/obj/item/I = AM
if(I.item_flags & ABSTRACT)
return
else if(istype(AM, /obj/item/projectile))
var/obj/item/projectile/P = AM
if(P.original != parent)
return
if(AM.movement_type & (FLYING|FLOATING) || !AM.has_gravity())
return
var/atom/current_parent = parent
if(isturf(current_parent.loc))
if(do_play_squeak())
SEND_SIGNAL(AM, COMSIG_CROSS_SQUEAKED)
/datum/component/squeak/proc/use_squeak()
SIGNAL_HANDLER
if(last_use + use_delay < world.time)
last_use = world.time
play_squeak()
@@ -118,6 +136,8 @@
RegisterSignal(holder, COMSIG_ATOM_DIR_CHANGE, .proc/holder_dir_change)
/datum/component/squeak/proc/holder_dir_change(datum/source, old_dir, new_dir)
SIGNAL_HANDLER
//If the dir changes it means we're going through a bend in the pipes, let's pretend we bumped the wall
if(old_dir != new_dir)
play_squeak()
+15 -17
View File
@@ -77,21 +77,21 @@
/**
* Default implementation of clean-up code.
*
* This should be overridden to remove all references pointing to the object being destroyed, if
* you do override it, make sure to call the parent and return it's return value by default
*
* Return an appropriate [QDEL_HINT][QDEL_HINT_QUEUE] to modify handling of your deletion;
* in most cases this is [QDEL_HINT_QUEUE].
*
* The base case is responsible for doing the following
* * Erasing timers pointing to this datum
* * Erasing compenents on this datum
* * Notifying datums listening to signals from this datum that we are going away
*
* Returns [QDEL_HINT_QUEUE]
*/
* Default implementation of clean-up code.
*
* This should be overridden to remove all references pointing to the object being destroyed, if
* you do override it, make sure to call the parent and return it's return value by default
*
* Return an appropriate [QDEL_HINT][QDEL_HINT_QUEUE] to modify handling of your deletion;
* in most cases this is [QDEL_HINT_QUEUE].
*
* The base case is responsible for doing the following
* * Erasing timers pointing to this datum
* * Erasing compenents on this datum
* * Notifying datums listening to signals from this datum that we are going away
*
* Returns [QDEL_HINT_QUEUE]
*/
/datum/proc/Destroy(force=FALSE, ...)
SHOULD_CALL_PARENT(TRUE)
tag = null
@@ -138,8 +138,6 @@
UnregisterSignal(target, signal_procs[target])
//END: ECS SHIT
SSsounds.free_datum_channels(src) //?? (not on tg)
return QDEL_HINT_QUEUE
#ifdef DATUMVAR_DEBUGGING_MODE
+1 -1
View File
@@ -4,7 +4,7 @@
/datum/proc/can_vv_get(var_name)
return TRUE
/datum/proc/vv_edit_var(var_name, var_value) //called whenever a var is edited
/datum/proc/vv_edit_var(var_name, var_value, massedit) //called whenever a var is edited
if(var_name == NAMEOF(src, vars))
return FALSE
vars[var_name] = var_value
+2 -2
View File
@@ -37,7 +37,7 @@
to_chat(H, "<span class='warning'>You feel [pick("full", "nauseated", "sweaty", "weak", "tired", "short on breath", "uneasy")].</span>")
if(3 to 4)
if(!sound)
H.playsound_local(H, 'sound/health/slowbeat.ogg',40,0, channel = CHANNEL_HEARTBEAT)
H.playsound_local(H, 'sound/health/slowbeat.ogg', 40, FALSE, channel = CHANNEL_HEARTBEAT)
sound = TRUE
if(prob(3))
to_chat(H, "<span class='danger'>You feel a sharp pain in your chest!</span>")
@@ -53,7 +53,7 @@
H.emote("cough")
if(5)
H.stop_sound_channel(CHANNEL_HEARTBEAT)
H.playsound_local(H, 'sound/effects/singlebeat.ogg', 100, 0)
H.playsound_local(H, 'sound/effects/singlebeat.ogg', 100, FALSE)
if(H.stat == CONSCIOUS)
H.visible_message("<span class='userdanger'>[H] clutches at [H.p_their()] chest as if [H.p_their()] heart is stopping!</span>")
H.adjustStaminaLoss(60)
+1 -1
View File
@@ -57,4 +57,4 @@
tucked.transform = turn(tucked.transform, -rotation_degree)
UnregisterSignal(tucked, COMSIG_ITEM_PICKUP)
UnregisterSignal(tucked, COMSIG_ITEM_PICKUP)
+28 -11
View File
@@ -33,6 +33,14 @@ GLOBAL_LIST_EMPTY(explosions)
EX_PREPROCESS_EXIT_CHECK\
}
#define CREAK_DELAY 5 SECONDS //Time taken for the creak to play after explosion, if applicable.
#define FAR_UPPER 60 //Upper limit for the far_volume, distance, clamped.
#define FAR_LOWER 40 //lower limit for the far_volume, distance, clamped.
#define PROB_SOUND 75 //The probability modifier for a sound to be an echo, or a far sound. (0-100)
#define SHAKE_CLAMP 2.5 //The limit for how much the camera can shake for out of view booms.
#define FREQ_UPPER 40 //The upper limit for the randomly selected frequency.
#define FREQ_LOWER 25 //The lower of the above.
/datum/explosion/New(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog, ignorecap, flame_range, silent, smoke)
set waitfor = FALSE
@@ -89,7 +97,7 @@ GLOBAL_LIST_EMPTY(explosions)
if(adminlog)
message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in [ADMIN_VERBOSEJMP(epicenter)]")
log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in [loc_name(epicenter)]")
deadchat_broadcast("<span class='deadsay bold'>An explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) has occured at ([get_area(epicenter)])</span>", turf_target = get_turf(epicenter))
var/x0 = epicenter.x
@@ -115,13 +123,14 @@ GLOBAL_LIST_EMPTY(explosions)
var/sound/creaking_explosion_sound = sound(get_sfx("explosion_creaking"))
var/sound/hull_creaking_sound = sound(get_sfx("hull_creaking"))
var/sound/explosion_echo_sound = sound('sound/effects/explosion_distant.ogg')
var/on_station = SSmapping.level_trait(epicenter.z, ZTRAIT_STATION)
var/on_station = SSmapping.level_trait(epicenter.z, ZTRAIT_STATION)
var/creaking_explosion = FALSE
if(prob(devastation_range*30+heavy_impact_range*5) && on_station) // Huge explosions are near guaranteed to make the station creak and whine, smaller ones might.
creaking_explosion = TRUE // prob over 100 always returns true
for(var/mob/M in GLOB.player_list)
for(var/MN in GLOB.player_list)
var/mob/M = MN
// Double check for client
var/turf/M_turf = get_turf(M)
if(M_turf && M_turf.z == z0)
@@ -131,15 +140,15 @@ GLOBAL_LIST_EMPTY(explosions)
baseshakeamount = sqrt((orig_max_distance - dist)*0.1)
// If inside the blast radius + world.view - 2
if(dist <= round(max_range + world.view - 2, 1))
M.playsound_local(epicenter, null, 100, 1, frequency, falloff = 5, S = explosion_sound)
M.playsound_local(epicenter, null, 100, 1, frequency, S = explosion_sound)
if(baseshakeamount > 0)
shake_camera(M, 25, clamp(baseshakeamount, 0, 10))
// You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station.
else if(dist <= far_dist)
var/far_volume = clamp(far_dist/2, 40, 60) // Volume is based on explosion size and dist
var/far_volume = clamp(far_dist/2, FAR_LOWER, FAR_UPPER) // Volume is based on explosion size and dist
if(creaking_explosion)
M.playsound_local(epicenter, null, far_volume, 1, frequency, S = creaking_explosion_sound, distance_multiplier = 0)
else if(prob(75))
else if(prob(PROB_SOUND)) // Sound variety during meteor storm/tesloose/other bad event
M.playsound_local(epicenter, null, far_volume, 1, frequency, S = far_explosion_sound, distance_multiplier = 0) // Far sound
else
M.playsound_local(epicenter, null, far_volume, 1, frequency, S = explosion_echo_sound, distance_multiplier = 0) // Echo sound
@@ -147,18 +156,18 @@ GLOBAL_LIST_EMPTY(explosions)
if(baseshakeamount > 0 || devastation_range)
if(!baseshakeamount) // Devastating explosions rock the station and ground
baseshakeamount = devastation_range*3
shake_camera(M, 10, clamp(baseshakeamount*0.25, 0, 2.5))
else if(M.can_hear() && !isspaceturf(get_turf(M)) && heavy_impact_range) // Big enough explosions echo throughout the hull
shake_camera(M, 10, clamp(baseshakeamount*0.25, 0, SHAKE_CLAMP))
else if(!isspaceturf(get_turf(M)) && heavy_impact_range) // Big enough explosions echo throughout the hull
var/echo_volume = 40
if(devastation_range)
baseshakeamount = devastation_range
shake_camera(M, 10, clamp(baseshakeamount*0.25, 0, 2.5))
shake_camera(M, 10, clamp(baseshakeamount*0.25, 0, SHAKE_CLAMP))
echo_volume = 60
M.playsound_local(epicenter, null, echo_volume, 1, frequency, S = explosion_echo_sound, distance_multiplier = 0)
if(creaking_explosion) // 5 seconds after the bang, the station begins to creak
addtimer(CALLBACK(M, /mob/proc/playsound_local, epicenter, null, rand(25, 40), 1, frequency, null, null, FALSE, hull_creaking_sound, null, null, null, null, 0), 5 SECONDS)
addtimer(CALLBACK(M, /mob/proc/playsound_local, epicenter, null, rand(FREQ_LOWER, FREQ_UPPER), 1, frequency, null, null, FALSE, hull_creaking_sound, 0), CREAK_DELAY)
EX_PREPROCESS_CHECK_TICK
//postpone processing for a bit
@@ -316,6 +325,14 @@ GLOBAL_LIST_EMPTY(explosions)
++stopped
qdel(src)
#undef CREAK_DELAY
#undef FAR_UPPER
#undef FAR_LOWER
#undef PROB_SOUND
#undef SHAKE_CLAMP
#undef FREQ_UPPER
#undef FREQ_LOWER
#undef EX_PREPROCESS_EXIT_CHECK
#undef EX_PREPROCESS_CHECK_TICK
+40 -40
View File
@@ -237,7 +237,7 @@
/obj/item/disk/holodisk/Initialize(mapload)
. = ..()
if(preset_record_text)
build_record()
INVOKE_ASYNC(src, .proc/build_record)
/obj/item/disk/holodisk/Destroy()
QDEL_NULL(record)
@@ -425,42 +425,42 @@
"}
/obj/item/disk/holodisk/ruin/snowengieruin
name = "Blackbox Print-out #EB412"
desc = "A holodisk containing the last moments of EB412. There's a bloody fingerprint on it."
preset_image_type = /datum/preset_holoimage/engineer
preset_record_text = {"
NAME Dave Tundrale
SAY Maria, how's Build?
DELAY 10
NAME Maria Dell
PRESET /datum/preset_holoimage/engineer/atmos
SAY It's fine, don't worry. I've got Plastic on it. And frankly, i'm kinda busy with, the, uhhm, incinerator.
DELAY 30
NAME Dave Tundrale
PRESET /datum/preset_holoimage/engineer
SAY Aight, wonderful. The science mans been kinda shit though. No RCDs-
DELAY 20
NAME Maria Dell
PRESET /datum/preset_holoimage/engineer/atmos
SAY Enough about your RCDs. They're not even that important, just bui-
DELAY 15
SOUND explosion
DELAY 10
SAY Oh, shit!
DELAY 10
PRESET /datum/preset_holoimage/engineer/atmos/rig
LANGUAGE /datum/language/narsie
NAME Unknown
SAY RISE, MY LORD!!
DELAY 10
LANGUAGE /datum/language/common
NAME Plastic
PRESET /datum/preset_holoimage/engineer/rig
SAY Fuck, fuck, fuck!
DELAY 20
SAY It's loose! CALL THE FUCKING SHUTT-
DELAY 10
PRESET /datum/preset_holoimage/corgi
NAME Blackbox Automated Message
SAY Connection lost. Dumping audio logs to disk.
DELAY 50"}
name = "Blackbox Print-out #EB412"
desc = "A holodisk containing the last moments of EB412. There's a bloody fingerprint on it."
preset_image_type = /datum/preset_holoimage/engineer
preset_record_text = {"
NAME Dave Tundrale
SAY Maria, how's Build?
DELAY 10
NAME Maria Dell
PRESET /datum/preset_holoimage/engineer/atmos
SAY It's fine, don't worry. I've got Plastic on it. And frankly, i'm kinda busy with, the, uhhm, incinerator.
DELAY 30
NAME Dave Tundrale
PRESET /datum/preset_holoimage/engineer
SAY Aight, wonderful. The science mans been kinda shit though. No RCDs-
DELAY 20
NAME Maria Dell
PRESET /datum/preset_holoimage/engineer/atmos
SAY Enough about your RCDs. They're not even that important, just bui-
DELAY 15
SOUND explosion
DELAY 10
SAY Oh, shit!
DELAY 10
PRESET /datum/preset_holoimage/engineer/atmos/rig
LANGUAGE /datum/language/narsie
NAME Unknown
SAY RISE, MY LORD!!
DELAY 10
LANGUAGE /datum/language/common
NAME Plastic
PRESET /datum/preset_holoimage/engineer/rig
SAY Fuck, fuck, fuck!
DELAY 20
SAY It's loose! CALL THE FUCKING SHUTT-
DELAY 10
PRESET /datum/preset_holoimage/corgi
NAME Blackbox Automated Message
SAY Connection lost. Dumping audio logs to disk.
DELAY 50"}
+13 -13
View File
@@ -18,8 +18,12 @@
var/list/atom/output_atoms
var/mid_sounds
var/mid_length
///Override for volume of start sound
var/start_volume
var/start_sound
var/start_length
///Override for volume of end sound
var/end_volume
var/end_sound
var/chance
var/volume = 100
@@ -27,10 +31,9 @@
var/max_loops
var/direct
var/extra_range = 0
var/falloff
var/falloff_exponent
var/timerid
var/init_timerid
var/falloff_distance
/datum/looping_sound/New(list/_output_atoms=list(), start_immediately=FALSE, _direct=FALSE)
if(!mid_sounds)
@@ -51,16 +54,13 @@
/datum/looping_sound/proc/start(atom/add_thing)
if(add_thing)
output_atoms |= add_thing
if(timerid || init_timerid)
if(timerid)
return
on_start()
/datum/looping_sound/proc/stop(atom/remove_thing)
if(remove_thing)
output_atoms -= remove_thing
if(init_timerid)
deltimer(init_timerid)
init_timerid = null
if(!timerid)
return
on_stop()
@@ -76,18 +76,18 @@
if(!timerid)
timerid = addtimer(CALLBACK(src, .proc/sound_loop, world.time), mid_length, TIMER_CLIENT_TIME | TIMER_STOPPABLE | TIMER_LOOP)
/datum/looping_sound/proc/play(soundfile)
/datum/looping_sound/proc/play(soundfile, volume_override)
var/list/atoms_cache = output_atoms
var/sound/S = sound(soundfile)
if(direct)
S.channel = SSsounds.random_available_channel()
S.volume = volume
S.volume = volume_override || volume //Use volume as fallback if theres no override
for(var/i in 1 to atoms_cache.len)
var/atom/thing = atoms_cache[i]
if(direct)
SEND_SOUND(thing, S)
else
playsound(thing, S, volume, vary, extra_range, falloff)
playsound(thing, S, volume, vary, extra_range, falloff_exponent = falloff_exponent, falloff_distance = falloff_distance)
/datum/looping_sound/proc/get_sound(starttime, _mid_sounds)
. = _mid_sounds || mid_sounds
@@ -97,10 +97,10 @@
/datum/looping_sound/proc/on_start()
var/start_wait = 0
if(start_sound)
play(start_sound)
play(start_sound, start_volume)
start_wait = start_length
init_timerid = addtimer(CALLBACK(src, .proc/sound_loop), start_wait, TIMER_CLIENT_TIME | TIMER_STOPPABLE)
addtimer(CALLBACK(src, .proc/sound_loop), start_wait, TIMER_CLIENT_TIME)
/datum/looping_sound/proc/on_stop()
if(end_sound)
play(end_sound)
play(end_sound, end_volume)
+74 -7
View File
@@ -4,7 +4,7 @@
mid_sounds = list('sound/machines/shower/shower_mid1.ogg'=1,'sound/machines/shower/shower_mid2.ogg'=1,'sound/machines/shower/shower_mid3.ogg'=1)
mid_length = 10
end_sound = 'sound/machines/shower/shower_end.ogg'
volume = 10
volume = 20
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -12,6 +12,28 @@
mid_sounds = list('sound/machines/sm/supermatter1.ogg'=1,'sound/machines/sm/supermatter2.ogg'=1,'sound/machines/sm/supermatter3.ogg'=1)
mid_length = 10
volume = 1
extra_range = 25
falloff_exponent = 10
falloff_distance = 5
vary = TRUE
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/looping_sound/destabilized_crystal
mid_sounds = list('sound/machines/sm/loops/delamming.ogg' = 1)
mid_length = 60
volume = 55
extra_range = 15
vary = TRUE
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// /datum/looping_sound/hypertorus
// mid_sounds = list('sound/machines/hypertorus/loops/hypertorus_nominal.ogg' = 1)
// mid_length = 60
// volume = 55
// extra_range = 15
// vary = TRUE
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -32,7 +54,22 @@
mid_sounds = list('sound/machines/fryer/deep_fryer_1.ogg' = 1, 'sound/machines/fryer/deep_fryer_2.ogg' = 1)
mid_length = 2
end_sound = 'sound/machines/fryer/deep_fryer_emerge.ogg'
volume = 5
volume = 15
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/looping_sound/grill
mid_sounds = list('sound/machines/grill/grillsizzle.ogg' = 1)
mid_length = 18
volume = 50
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/looping_sound/deep_fryer
mid_length = 2
mid_sounds = list('sound/machines/fryer/deep_fryer_1.ogg' = 1, 'sound/machines/fryer/deep_fryer_2.ogg' = 1)
volume = 30
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -46,9 +83,39 @@
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/looping_sound/grill
mid_length = 2
mid_sounds = list('sound/machines/fryer/deep_fryer_1.ogg' = 1, 'sound/machines/fryer/deep_fryer_2.ogg' = 1)
volume = 10
// /datum/looping_sound/jackpot
// mid_length = 11
// mid_sounds = list('sound/machines/roulettejackpot.ogg')
// volume = 85
// vary = TRUE
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
/datum/looping_sound/server
mid_sounds = list('sound/machines/tcomms/tcomms_mid1.ogg'=1,'sound/machines/tcomms/tcomms_mid2.ogg'=1,'sound/machines/tcomms/tcomms_mid3.ogg'=1,'sound/machines/tcomms/tcomms_mid4.ogg'=1,\
'sound/machines/tcomms/tcomms_mid5.ogg'=1,'sound/machines/tcomms/tcomms_mid6.ogg'=1,'sound/machines/tcomms/tcomms_mid7.ogg'=1)
mid_length = 1.8 SECONDS
extra_range = -11
falloff_distance = 1
falloff_exponent = 5
volume = 50
*/
// /datum/looping_sound/computer
// start_sound = 'sound/machines/computer/computer_start.ogg'
// start_length = 7.2 SECONDS
// start_volume = 10
// mid_sounds = list('sound/machines/computer/computer_mid1.ogg'=1, 'sound/machines/computer/computer_mid2.ogg'=1)
// mid_length = 1.8 SECONDS
// end_sound = 'sound/machines/computer/computer_end.ogg'
// end_volume = 10
// volume = 2
// falloff_exponent = 5 //Ultra quiet very fast
// extra_range = -12
// falloff_distance = 1 //Instant falloff after initial tile
// /datum/looping_sound/gravgen
// mid_sounds = list('sound/machines/gravgen/gravgen_mid1.ogg'=1,'sound/machines/gravgen/gravgen_mid2.ogg'=1,'sound/machines/gravgen/gravgen_mid3.ogg'=1,'sound/machines/gravgen/gravgen_mid4.ogg'=1,)
// mid_length = 1.8 SECONDS
// extra_range = 10
// volume = 70
// falloff_distance = 5
// falloff_exponent = 20
+2 -2
View File
@@ -47,7 +47,7 @@ GLOBAL_LIST_EMPTY(potential_mods_per_skill)
if(!mod_L)
mod_L = GLOB.potential_mods_per_skill[target_skills] = list()
else
BINARY_INSERT(identifier, mod_L, datum/skill_modifier, src, priority, COMPARE_VALUE)
BINARY_INSERT(identifier, mod_L, /datum/skill_modifier, src, priority, COMPARE_VALUE)
mod_L[identifier] = src
GLOB.potential_skills_per_mod[target_skills_key] = list(target_skills)
else //Should be a list.
@@ -66,7 +66,7 @@ GLOBAL_LIST_EMPTY(potential_mods_per_skill)
if(!mod_L)
mod_L = GLOB.potential_mods_per_skill[path] = list()
else
BINARY_INSERT(identifier, mod_L, datum/skill_modifier, src, priority, COMPARE_VALUE)
BINARY_INSERT(identifier, mod_L, /datum/skill_modifier, src, priority, COMPARE_VALUE)
mod_L[identifier] = src
/datum/skill_modifier/Destroy()
+123 -2
View File
@@ -573,13 +573,17 @@
duration = 1 MINUTES
status_type = STATUS_EFFECT_REPLACE
alert_type = /obj/screen/alert/status_effect/regenerative_core
var/heal_amount = 25
/datum/status_effect/regenerative_core/on_apply()
. = ..()
ADD_TRAIT(owner, TRAIT_IGNOREDAMAGESLOWDOWN, "regenerative_core")
owner.adjustBruteLoss(-25)
if(HAS_TRAIT(owner, TRAIT_ROBOTIC_ORGANISM)) //Robots can heal from cores, but only get 1/5th of the healing. They can use this to get past the damage threshhold however, and then regularely heal from there.
heal_amount *= 0.2
owner.adjustBruteLoss(-heal_amount, only_organic = FALSE)
if(!AmBloodsucker(owner)) //use your coffin you lazy bastard
owner.adjustFireLoss(-25)
owner.adjustFireLoss(-heal_amount, only_organic = FALSE)
owner.remove_CC()
owner.bodytemperature = BODYTEMP_NORMAL
return TRUE
@@ -647,3 +651,120 @@
if(D.severity == DISEASE_SEVERITY_POSITIVE)
continue
D.cure()
/datum/status_effect/mantra // available to wizards and admins alone, currently
id = "Mantra"
examine_text = "<span class='notice'>Their aura is filled with yellow energy!</span>"
alert_type = null
var/damageboost = 10
var/woundboost = 5
var/prev_hair_color
var/powerup
var/powerdown
/datum/status_effect/mantra/on_apply()
. = ..()
if(iscarbon(owner))
var/mob/living/carbon/human/H = owner
playsound(H, 'sound/magic/powerup.ogg', 50, 1)
H.add_filter("mantra_glow", 2, list("type" = "outline", "color" = "#edfa347a", "size" = 2))
prev_hair_color = H.hair_color
H.hair_color = "ffe11e"
H.update_hair()
ADD_TRAIT(H, TRAIT_PUGILIST, "Mantra")
ADD_TRAIT(H, TRAIT_NOSOFTCRIT, "Mantra")
ADD_TRAIT(H, TRAIT_STUNIMMUNE, "Mantra")
ADD_TRAIT(H, TRAIT_PUSHIMMUNE, "Mantra")
ADD_TRAIT(H, TRAIT_NOGUNS, "Mantra")
H.dna.species.punchdamagehigh += damageboost
H.dna.species.punchdamagelow += damageboost
H.dna.species.punchwoundbonus += woundboost
H.physiology.brute_mod *= 0.9 // slightly resilient against lethal damage, but...
H.physiology.burn_mod *= 0.9
H.physiology.stamina_mod *= 0.5 // very resistant to non-lethal damage, because they're already draining stamina every second
to_chat(H, "<span class='notice'>Your inner mantra coalesces around you, granting you incredible strength and durability - but at what cost?</span>")
/datum/status_effect/mantra/tick()
. = ..()
if(owner.health < HEALTH_THRESHOLD_FULLCRIT)
owner.remove_status_effect(STATUS_EFFECT_MANTRA)
return
if(owner.combat_flags & COMBAT_FLAG_HARD_STAMCRIT)
owner.remove_status_effect(STATUS_EFFECT_MANTRA)
return
if(iscarbon(owner))
var/mob/living/carbon/human/C = owner
C.adjustBruteLoss(-1) // slightly resilient against lethal damage
C.adjustFireLoss(-1)
C.adjustStaminaLoss(3) // in testing i personally found that 2/sec was too minimal and 4/sec was too much
/*if(SEND_SIGNAL(owner, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE)) // turning on combat mode flares up your aura
else*/
/datum/status_effect/mantra/on_remove()
. = ..()
if(iscarbon(owner))
var/mob/living/carbon/human/M = owner
playsound(M, 'sound/magic/powerdown.ogg', 50, 1)
M.remove_filter("mantra_glow")
M.hair_color = prev_hair_color
M.update_hair()
REMOVE_TRAIT(M, TRAIT_PUGILIST, "Mantra")
REMOVE_TRAIT(M, TRAIT_NOSOFTCRIT, "Mantra")
REMOVE_TRAIT(M, TRAIT_STUNIMMUNE, "Mantra")
REMOVE_TRAIT(M, TRAIT_PUSHIMMUNE, "Mantra")
REMOVE_TRAIT(M, TRAIT_NOGUNS, "Mantra")
M.dna.species.punchdamagehigh -= damageboost
M.dna.species.punchdamagelow -= damageboost
M.dna.species.punchwoundbonus -= woundboost
M.physiology.brute_mod /= 0.9
M.physiology.burn_mod /= 0.9
M.physiology.stamina_mod /= 0.5
to_chat(M, "<span class='notice'>Your inner mantra collapses, for now.</span>")
/datum/status_effect/asura // mfw miner gear
id = "Asura"
examine_text = "<span class='notice'>Their aura is filled with red-hot rage!</span>"
alert_type = null
var/damageboost = 10
var/woundboost = 5
/datum/status_effect/asura/on_apply()
. = ..()
if(iscarbon(owner))
var/mob/living/carbon/human/H = owner
playsound(H, 'sound/magic/powerup.ogg', 50, 1)
H.add_filter("asura_glow", 2, list("type" = "outline", "color" = "#fc21217a", "size" = 2))
ADD_TRAIT(H, TRAIT_PUGILIST, "Asura")
H.dna.species.punchdamagehigh += damageboost
H.dna.species.punchdamagelow += damageboost
H.dna.species.punchwoundbonus += woundboost
to_chat(H, "<span class='notice'>Your anger unleashes in a crimson blaze around you and corrosive power fills your muscles.</span>")
/datum/status_effect/asura/tick()
. = ..()
if(owner.health < HEALTH_THRESHOLD_CRIT)
owner.remove_status_effect(STATUS_EFFECT_ASURA)
return
if(owner.combat_flags & COMBAT_FLAG_HARD_STAMCRIT)
owner.remove_status_effect(STATUS_EFFECT_ASURA)
return
if(iscarbon(owner))
var/mob/living/carbon/human/C = owner
C.adjustBruteLoss(1) // drains 1 hp per second. You're gonna need some Senzu Cores.
C.adjustStaminaLoss(-2) // angry man punch a lot
/*if(SEND_SIGNAL(owner, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE)) // turning on combat mode flares up your aura
else*/
/datum/status_effect/asura/on_remove()
. = ..()
if(iscarbon(owner))
var/mob/living/carbon/human/M = owner
playsound(M, 'sound/magic/powerdown.ogg', 50, 1)
M.remove_filter("asura_glow")
REMOVE_TRAIT(M, TRAIT_PUGILIST, "Asura")
M.dna.species.punchdamagehigh -= damageboost
M.dna.species.punchdamagelow -= damageboost
M.dna.species.punchwoundbonus -= woundboost
to_chat(M, "<span class='notice'>You calm yourself, and your unnatural strength dissipates.</span>")
+8 -2
View File
@@ -74,13 +74,19 @@
/datum/status_effect/proc/on_remove() //Called whenever the buff expires or is removed; do note that at the point this is called, it is out of the owner's status_effects but owner is not yet null
SHOULD_CALL_PARENT(TRUE)
REMOVE_TRAIT(owner, TRAIT_COMBAT_MODE_LOCKED, src)
REMOVE_TRAIT(owner, TRAIT_SPRINT_LOCKED, src)
if(blocks_combatmode)
REMOVE_TRAIT(owner, TRAIT_COMBAT_MODE_LOCKED, src)
if(blocks_sprint)
REMOVE_TRAIT(owner, TRAIT_SPRINT_LOCKED, src)
return TRUE
/datum/status_effect/proc/be_replaced() //Called instead of on_remove when a status effect is replaced by itself or when a status effect with on_remove_on_mob_delete = FALSE has its mob deleted
owner.clear_alert(id)
LAZYREMOVE(owner.status_effects, src)
if(blocks_combatmode)
REMOVE_TRAIT(owner, TRAIT_COMBAT_MODE_LOCKED, src)
if(blocks_sprint)
REMOVE_TRAIT(owner, TRAIT_SPRINT_LOCKED, src)
owner = null
qdel(src)