Merge remote-tracking branch 'upstream/master' into timer-subsystem

This commit is contained in:
Fox McCloud
2018-04-29 21:14:11 -04:00
40 changed files with 331 additions and 7656 deletions
+5
View File
@@ -202,6 +202,9 @@
var/randomize_shift_time = FALSE
var/enable_night_shifts = FALSE
// Developer
var/developer_express_start = 0
/datum/configuration/New()
for(var/T in subtypesof(/datum/game_mode))
var/datum/game_mode/M = T
@@ -612,6 +615,8 @@
config.high_pop_mc_mode_amount = text2num(value)
if("disable_high_pop_mc_mode_amount")
config.disable_high_pop_mc_mode_amount = text2num(value)
if("developer_express_start")
config.developer_express_start = 1
else
log_config("Unknown setting in configuration: '[name]'")
+5 -2
View File
@@ -54,7 +54,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
var/static/restart_clear = 0
var/static/restart_timeout = 0
var/static/restart_count = 0
var/static/random_seed
//current tick limit, assigned before running a subsystem.
@@ -71,7 +71,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
if(!random_seed)
random_seed = rand(1, 1e9)
rand_seed(random_seed)
var/list/_subsystems = list()
subsystems = _subsystems
if(Master != src)
@@ -195,6 +195,9 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
to_chat(world, "<span class='boldannounce'>[msg]</span>")
log_world(msg)
if(config.developer_express_start & ticker.current_state == GAME_STATE_PREGAME)
ticker.current_state = GAME_STATE_SETTING_UP
if(!current_runlevel)
SetRunLevel(1)
+100
View File
@@ -0,0 +1,100 @@
/*
output_atoms (list of atoms) The destination(s) for the sounds
mid_sounds (list or soundfile) Since this can be either a list or a single soundfile you can have random sounds. May contain further lists but must contain a soundfile at the end.
mid_length (num) The length to wait between playing mid_sounds
start_sound (soundfile) Played before starting the mid_sounds loop
start_length (num) How long to wait before starting the main loop after playing start_sound
end_sound (soundfile) The sound played after the main loop has concluded
chance (num) Chance per loop to play a mid_sound
volume (num) Sound output volume
muted (bool) Private. Used to stop the sound loop.
max_loops (num) The max amount of loops to run for.
direct (bool) If true plays directly to provided atoms instead of from them
*/
/datum/looping_sound
var/list/atom/output_atoms
var/mid_sounds
var/mid_length
var/start_sound
var/start_length
var/end_sound
var/chance
var/volume = 100
var/muted = TRUE
var/max_loops
var/direct
/datum/looping_sound/New(list/_output_atoms = list(), start_immediately = FALSE, _direct = FALSE)
if(!mid_sounds)
WARNING("A looping sound datum was created without sounds to play.")
return
output_atoms = _output_atoms
direct = _direct
if(start_immediately)
start()
/datum/looping_sound/Destroy()
stop()
output_atoms = null
return ..()
/datum/looping_sound/proc/start(atom/add_thing)
if(add_thing)
output_atoms |= add_thing
if(!muted)
return
muted = FALSE
on_start()
/datum/looping_sound/proc/stop(atom/remove_thing)
if(remove_thing)
output_atoms -= remove_thing
if(muted)
return
muted = TRUE
/datum/looping_sound/proc/sound_loop(looped = 0)
if(muted || (max_loops && looped > max_loops))
on_stop(looped)
return
if(!chance || prob(chance))
play(get_sound(looped))
addtimer(src, "sound_loop", mid_length, FALSE, ++looped)
/datum/looping_sound/proc/play(soundfile)
var/list/atoms_cache = output_atoms
var/sound/S = sound(soundfile)
if(direct)
S.channel = open_sound_channel()
S.volume = volume
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)
/datum/looping_sound/proc/get_sound(looped, _mid_sounds)
if(!_mid_sounds)
. = mid_sounds
else
. = _mid_sounds
while(!isfile(.) && !isnull(.))
. = pickweight(.)
/datum/looping_sound/proc/on_start()
var/start_wait = 0
if(start_sound)
play(start_sound)
start_wait = start_length
addtimer(src, "sound_loop", start_wait)
/datum/looping_sound/proc/on_stop(looped)
if(end_sound)
play(end_sound)
@@ -0,0 +1,7 @@
/datum/looping_sound/showering
start_sound = 'sound/machines/shower/shower_start.ogg'
start_length = 2
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 = 20
+1 -1
View File
@@ -145,6 +145,7 @@
belt = /obj/item/gun/projectile/automatic/pistol/deagle/camo
l_ear = /obj/item/radio/headset/syndicate/alt
l_pocket = /obj/item/pinpointer/advpinpointer
r_pocket = null // stop them getting a radio uplink, they get an implant instead
backpack_contents = list(
/obj/item/storage/box/engineer = 1,
@@ -158,7 +159,6 @@
id_icon = "commander"
id_access = "Syndicate Operative Leader"
uplink_uses = 500
/datum/outfit/admin/syndicate/officer/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
. = ..()
+2 -2
View File
@@ -140,13 +140,13 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
var/obj/effect/proc_holder/spell/noclothes/clothes_spell = locate() in (user.mob_spell_list | (user.mind ? user.mind.spell_list : list()))
if((ishuman(user) && clothes_req) && !istype(clothes_spell))//clothes check
var/mob/living/carbon/human/H = user
if(!istype(H.wear_suit, /obj/item/clothing/suit/wizrobe) && !istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit/wizard))
if(!istype(H.wear_suit, /obj/item/clothing/suit/wizrobe) && !istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit/wizard) && !istype(H.wear_suit, /obj/item/clothing/suit/space/eva/plasmaman/wizard))
to_chat(user, "<span class='notice'>I don't feel strong enough without my robe.</span>")
return 0
if(!istype(H.shoes, /obj/item/clothing/shoes/sandal))
to_chat(user, "<span class='notice'>I don't feel strong enough without my sandals.</span>")
return 0
if(!istype(H.head, /obj/item/clothing/head/wizard) && !istype(H.head, /obj/item/clothing/head/helmet/space/hardsuit/wizard))
if(!istype(H.head, /obj/item/clothing/head/wizard) && !istype(H.head, /obj/item/clothing/head/helmet/space/hardsuit/wizard) && !istype(H.wear_suit, /obj/item/clothing/head/helmet/space/eva/plasmaman/wizard))
to_chat(user, "<span class='notice'>I don't feel strong enough without my hat.</span>")
return 0
else if(!ishuman(user))
+3 -2
View File
@@ -141,8 +141,9 @@
wizard_mob.equip_to_slot_or_del(new /obj/item/radio/headset(wizard_mob), slot_l_ear)
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(wizard_mob), slot_w_uniform)
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(wizard_mob), slot_shoes)
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(wizard_mob), slot_wear_suit)
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(wizard_mob), slot_head)
if(!wizard_mob.get_species() == "Plasmaman")//handled in the species file for plasmen on the afterjob equip proc for now
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(wizard_mob), slot_wear_suit)
wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(wizard_mob), slot_head)
if(wizard_mob.backbag == 2)
wizard_mob.equip_to_slot_or_del(new /obj/item/storage/backpack(wizard_mob), slot_back)
if(wizard_mob.backbag == 3)
+7 -2
View File
@@ -249,9 +249,11 @@
var/ismist = 0 //needs a var so we can make it linger~
var/watertemp = "normal" //freezing, normal, or boiling
var/mobpresent = 0 //true if there is a mob on the shower's loc, this is to ease process()
var/datum/looping_sound/showering/soundloop
/obj/machinery/shower/New(turf/T, newdir = SOUTH, building = FALSE)
..()
soundloop = new(list(src), FALSE)
if(building)
dir = newdir
pixel_x = 0
@@ -264,8 +266,8 @@
layer = FLY_LAYER
/obj/machinery/shower/Destroy()
if(mymist)
QDEL_NULL(mymist)
QDEL_NULL(mymist)
QDEL_NULL(soundloop)
return ..()
//add heat controls? when emagged, you can freeze to death in it?
@@ -282,6 +284,7 @@
on = !on
update_icon()
if(on)
soundloop.start()
if(M.loc == loc)
wash(M)
check_heat(M)
@@ -289,6 +292,8 @@
for(var/atom/movable/G in src.loc)
G.clean_blood()
G.water_act(100, convertHeat(), src)
else
soundloop.stop()
/obj/machinery/shower/attackby(obj/item/I as obj, mob/user as mob, params)
if(I.type == /obj/item/analyzer)
+20 -9
View File
@@ -1,4 +1,4 @@
/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, frequency = null, channel = 0, pressure_affected = TRUE)
/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, frequency = null, channel = 0, pressure_affected = TRUE, ignore_walls = TRUE)
if(isarea(source))
error("[source] is an area and is trying to make the sound: [soundin]")
return
@@ -11,7 +11,10 @@
// Looping through the player list has the added bonus of working for mobs inside containers
var/sound/S = sound(get_sfx(soundin))
var/maxdistance = (world.view + extrarange) * 3
for(var/P in player_list)
var/list/listeners = player_list
if(!ignore_walls) //these sounds don't carry through walls
listeners = listeners & hearers(maxdistance, turf_source)
for(var/P in listeners)
var/mob/M = P
if(!M || !M.client)
continue
@@ -78,13 +81,15 @@
S.y = 1
S.falloff = (falloff ? falloff : FALLOFF_SOUNDS)
src << S
SEND_SOUND(src, S)
/client/proc/playtitlemusic()
if(!ticker || !ticker.login_music || config.disable_lobby_music)
return
if(prefs.sound & SOUND_LOBBY)
src << sound(ticker.login_music, repeat = 0, wait = 0, volume = 85, channel = CHANNEL_LOBBYMUSIC) // MAD JAMS
/proc/sound_to_playing_players(soundin, volume = 100, vary = FALSE, frequency = 0, falloff = FALSE, channel = 0, pressure_affected = FALSE, sound/S)
if(!S)
S = sound(get_sfx(soundin))
for(var/m in player_list)
if(ismob(m) && !isnewplayer(m))
var/mob/M = m
M.playsound_local(M, null, volume, vary, frequency, falloff, channel, pressure_affected, S)
/proc/open_sound_channel()
var/static/next_channel = 1 //loop through the available 1024 - (the ones we reserve) channels and pray that its not still being used
@@ -93,7 +98,13 @@
next_channel = 1
/mob/proc/stop_sound_channel(chan)
src << sound(null, repeat = 0, wait = 0, channel = chan)
SEND_SOUND(src, sound(null, repeat = 0, wait = 0, channel = chan))
/client/proc/playtitlemusic()
if(!ticker || !ticker.login_music || config.disable_lobby_music)
return
if(prefs.sound & SOUND_LOBBY)
SEND_SOUND(src, sound(ticker.login_music, repeat = 0, wait = 0, volume = 85, channel = CHANNEL_LOBBYMUSIC)) // MAD JAMS
/proc/get_rand_frequency()
return rand(32000, 55000) //Frequency stuff only works with 45kbps oggs.
@@ -152,3 +152,7 @@
/datum/gear/hat/flowerpin
display_name = "hair flower"
path = /obj/item/clothing/head/hairflower
/datum/gear/hat/kitty
display_name = "kitty headband"
path = /obj/item/clothing/head/kitty
@@ -398,3 +398,13 @@
icon_state = "plasmaman_Nukeops_helmet0"
base_state = "plasmaman_Nukeops_helmet"
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 50)
//WIZARD
/obj/item/clothing/suit/space/eva/plasmaman/wizard
name = "robed plasmaman suit"
icon_state = "plasmamanWizardBlue_suit"
/obj/item/clothing/head/helmet/space/eva/plasmaman/wizard
name = "wizard hat"
icon_state = "plasmamanWizardBlue_helmet0"
base_state = "plasmamanWizardBlue_helmet"
+6
View File
@@ -696,6 +696,12 @@
user.update_inv_head()
return 1
/obj/item/clothing/head/beret/fluff/elo //V-Force_Bomber: E.L.O.
name = "E.L.O.'s medical beret"
desc = "E.L.O.s personal medical beret, issued by Nanotrassen and awarded along with her medal."
icon = 'icons/obj/custom_items.dmi'
icon_state = "elo-beret"
//////////// Suits ////////////
/obj/item/clothing/suit/fluff
icon = 'icons/obj/custom_items.dmi'
@@ -42,7 +42,7 @@
if(lying && surgeries.len)
if(user.a_intent == INTENT_HELP)
for(var/datum/surgery/S in surgeries)
if(S.next_step(user, user.a_intent))
if(S.next_step(user, src))
return 1
return 0
@@ -148,8 +148,13 @@
if("Mime")
suit=/obj/item/clothing/suit/space/eva/plasmaman/mime
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/mime
H.equip_or_collect(new suit(H), slot_wear_suit)
H.equip_or_collect(new helm(H), slot_head)
if((H.mind.special_role == SPECIAL_ROLE_WIZARD) || (H.mind.special_role == SPECIAL_ROLE_WIZARD_APPRENTICE))
H.equip_to_slot(new /obj/item/clothing/suit/space/eva/plasmaman/wizard(H), slot_wear_suit)
H.equip_to_slot(new /obj/item/clothing/head/helmet/space/eva/plasmaman/wizard(H), slot_head)
else
H.equip_or_collect(new suit(H), slot_wear_suit)
H.equip_or_collect(new helm(H), slot_head)
H.equip_or_collect(new /obj/item/tank/plasma/plasmaman(H), tank_slot) // Bigger plasma tank from Raggy.
H.equip_or_collect(new /obj/item/plasmensuit_cartridge(H), slot_in_backpack)
H.equip_or_collect(new /obj/item/plasmensuit_cartridge(H), slot_in_backpack) //Two refill cartridges for their suit. Can fit in boxes.
@@ -0,0 +1,130 @@
/obj/item/gun/blastcannon
name = "pipe gun"
desc = "A pipe welded onto a gun stock, with a mechanical trigger. The pipe has an opening near the top, and there seems to be a spring loaded wheel in the hole."
icon_state = "empty_blastcannon"
var/icon_state_loaded = "loaded_blastcannon"
item_state = "blastcannon_empty"
w_class = WEIGHT_CLASS_NORMAL
force = 10
fire_sound = 'sound/weapons/blastcannon.ogg'
needs_permit = FALSE
clumsy_check = FALSE
randomspread = FALSE
var/obj/item/transfer_valve/bomb
/obj/item/gun/blastcannon/Destroy()
QDEL_NULL(bomb)
return ..()
/obj/item/gun/blastcannon/attack_self(mob/user)
if(bomb)
bomb.forceMove(user.loc)
user.put_in_hands(bomb)
user.visible_message("<span class='warning'>[user] detaches [bomb] from [src].</span>")
bomb = null
update_icon()
return ..()
/obj/item/gun/blastcannon/update_icon()
if(bomb)
icon_state = icon_state_loaded
name = "blast cannon"
desc = "A makeshift device used to concentrate a bomb's blast energy to a narrow wave."
else
icon_state = initial(icon_state)
name = initial(name)
desc = initial(desc)
/obj/item/gun/blastcannon/attackby(obj/O, mob/user)
if(istype(O, /obj/item/transfer_valve))
var/obj/item/transfer_valve/T = O
if(!T.tank_one || !T.tank_two)
to_chat(user, "<span class='warning'>What good would an incomplete bomb do?</span>")
return FALSE
if(!user.drop_item())
to_chat(user, "<span class='warning'>[T] seems to be stuck to your hand!</span>")
return FALSE
user.visible_message("<span class='warning'>[user] attaches [T] to [src]!</span>")
T.forceMove(src)
bomb = T
update_icon()
return TRUE
return ..()
/obj/item/gun/blastcannon/proc/calculate_bomb()
if(!istype(bomb)||!istype(bomb.tank_one)||!istype(bomb.tank_two))
return 0
var/datum/gas_mixture/temp = new() //directional buff.
temp.volume = 60
temp.merge(bomb.tank_one.air_contents.remove_ratio(1))
temp.merge(bomb.tank_two.air_contents.remove_ratio(2))
for(var/i in 1 to 6)
temp.react()
var/pressure = temp.return_pressure()
qdel(temp)
if(pressure < TANK_FRAGMENT_PRESSURE)
return 0
return (pressure / TANK_FRAGMENT_SCALE)
/obj/item/gun/blastcannon/afterattack(atom/target, mob/user, flag, params)
if((!bomb) || (!target) || (get_dist(get_turf(target), get_turf(user)) <= 2))
return ..()
var/power = calculate_bomb()
QDEL_NULL(bomb)
update_icon()
var/heavy = power * 0.2
var/medium = power * 0.5
var/light = power
user.visible_message("<span class='danger'>[user] opens [bomb] on \his [name] and fires a blast wave at [target]!</span>","<span class='danger'>You open [bomb] on your [name] and fire a blast wave at [target]!</span>")
playsound(user, "explosion", 100, 1)
var/turf/starting = get_turf(user)
var/turf/targturf = get_turf(target)
message_admins("Blast wave fired from [ADMIN_COORDJMP(starting)] ([get_area_name(user, TRUE)]) at [ADMIN_COORDJMP(targturf)] ([target.name]) by [key_name_admin(user)] with power [heavy]/[medium]/[light].")
log_game("Blast wave fired from ([starting.x], [starting.y], [starting.z]) ([get_area_name(user, TRUE)]) at ([target.x], [target.y], [target.z]) ([target]) by [key_name(user)] with power [heavy]/[medium]/[light].")
var/obj/item/projectile/blastwave/BW = new(loc, heavy, medium, light)
BW.preparePixelProjectile(target, get_turf(target), user, params, 0)
BW.fire()
/obj/item/projectile/blastwave
name = "blast wave"
icon_state = "blastwave"
damage = 0
nodamage = FALSE
forcedodge = TRUE
range = 150
var/heavyr = 0
var/mediumr = 0
var/lightr = 0
/obj/item/projectile/blastwave/New(loc, _h, _m, _l)
..()
heavyr = _h
mediumr = _m
lightr = _l
/obj/item/projectile/blastwave/Range()
..()
var/amount_destruction = 0
if(heavyr)
amount_destruction = EXPLODE_DEVASTATE
else if(mediumr)
amount_destruction = EXPLODE_HEAVY
else if(lightr)
amount_destruction = EXPLODE_LIGHT
if(amount_destruction && isturf(loc))
var/turf/T = loc
for(var/thing in T.contents)
var/atom/AM = thing
if(AM && AM.simulated)
AM.ex_act(amount_destruction)
CHECK_TICK
T.ex_act(amount_destruction)
else
qdel(src)
heavyr = max(heavyr - 1, 0)
mediumr = max(mediumr - 1, 0)
lightr = max(lightr - 1, 0)
/obj/item/projectile/blastwave/ex_act()
return
@@ -101,7 +101,7 @@
min_temp = 374
result_amount = 1
/datum/chemical_reaction/plastication/on_reaction(datum/reagents/holder)
/datum/chemical_reaction/plastic_polymers/on_reaction(datum/reagents/holder, created_volume)
var/obj/item/stack/sheet/plastic/P = new /obj/item/stack/sheet/plastic
P.amount = 10
P.forceMove(get_turf(holder.my_atom))
+3
View File
@@ -368,3 +368,6 @@ HIGH_POP_MC_MODE_AMOUNT 65
##Disengage high pop mode if player count drops below this
DISABLE_HIGH_POP_MC_MODE_AMOUNT 60
##Uncomment to enable developer start. Auto starts the server after initialization
##DEVELOPER_EXPRESS_START
-7634
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -6352,3 +6352,6 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
- rscadd: Slimes can steal nutrition from other slimes when attacking them
- rscadd: Slime docility potion no longer makes a simple animal slime, instead makes
the target docile and never hungry
2018-04-28:
MINIMAN10000:
- rscadd: Developer express start
@@ -0,0 +1,3 @@
author: Fox McCloud
changes: []
delete-after: true
@@ -0,0 +1,4 @@
author: "Fox McCloud"
delete-after: True
changes:
- rscadd: "Adds Blast cannon"
@@ -0,0 +1,3 @@
author: Anasari
changes: []
delete-after: true
@@ -0,0 +1,3 @@
author: Fox McCloud
changes: []
delete-after: true
Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

After

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

+3
View File
@@ -311,6 +311,8 @@
#include "code\datums\helper_datums\map_template.dm"
#include "code\datums\helper_datums\teleport.dm"
#include "code\datums\helper_datums\topic_input.dm"
#include "code\datums\looping_sounds\looping_sound.dm"
#include "code\datums\looping_sounds\machinery_sounds.dm"
#include "code\datums\outfits\outfit.dm"
#include "code\datums\outfits\outfit_admin.dm"
#include "code\datums\ruins\space.dm"
@@ -2002,6 +2004,7 @@
#include "code\modules\projectiles\guns\energy\telegun.dm"
#include "code\modules\projectiles\guns\magic\staff.dm"
#include "code\modules\projectiles\guns\magic\wand.dm"
#include "code\modules\projectiles\guns\misc\blastcannon.dm"
#include "code\modules\projectiles\guns\projectile\automatic.dm"
#include "code\modules\projectiles\guns\projectile\bow.dm"
#include "code\modules\projectiles\guns\projectile\launchers.dm"
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.