Merge remote-tracking branch 'citadel/master' into combat_rework

This commit is contained in:
kevinz000
2020-04-08 04:04:45 -07:00
919 changed files with 148968 additions and 10144 deletions
+2 -2
View File
@@ -384,8 +384,8 @@
desc = "The POWER that gamers CRAVE! In partnership with Vlad's Salad."
icon_state = "poster39"
/obj/structure/sign/poster/contraband/sun_kist
name = "Sun-kist"
/obj/structure/sign/poster/contraband/starkist
name = "Star-kist"
desc = "Drink the stars!"
icon_state = "poster40"
@@ -0,0 +1,119 @@
// Full credit goes to VG station for these assets. https://github.com/vgstation-coders/vgstation13
// All items in this .dm and the associated .dmi were made by VG station and all credit should go to them.
// -<| IMPORTANT MAPPER NOTE |>-
// Change the 'color' variable on any white sprite to simply recolour it!
/obj/effect/turf_decal/vg_decals
icon = 'icons/turf/vgstation_decals.dmi'
icon_state = "no"
// NUMBERS START
/obj/effect/turf_decal/vg_decals/numbers
icon_state = "no"
/obj/effect/turf_decal/vg_decals/numbers/one
icon_state = "1"
/obj/effect/turf_decal/vg_decals/numbers/two
icon_state = "2"
/obj/effect/turf_decal/vg_decals/numbers/three
icon_state = "3"
/obj/effect/turf_decal/vg_decals/numbers/four
icon_state = "4"
/obj/effect/turf_decal/vg_decals/numbers/five
icon_state = "5"
/obj/effect/turf_decal/vg_decals/numbers/six
icon_state = "6"
/obj/effect/turf_decal/vg_decals/numbers/seven
icon_state = "7"
/obj/effect/turf_decal/vg_decals/numbers/eight
icon_state = "8"
/obj/effect/turf_decal/vg_decals/numbers/nine
icon_state = "9"
/obj/effect/turf_decal/vg_decals/numbers/zero
icon_state = "0"
// NUMBERS END
// ATMOS START
/obj/effect/turf_decal/vg_decals/atmos
icon_state = "no"
/obj/effect/turf_decal/vg_decals/atmos/oxygen
icon_state = "oxygen"
/obj/effect/turf_decal/vg_decals/atmos/carbon_dioxide
icon_state = "carbon_dioxide"
/obj/effect/turf_decal/vg_decals/atmos/nitrogen
icon_state = "nitrogen"
/obj/effect/turf_decal/vg_decals/atmos/air
icon_state = "air"
/obj/effect/turf_decal/vg_decals/atmos/nitrous_oxide
icon_state = "nitrous_oxide"
/obj/effect/turf_decal/vg_decals/atmos/plasma
icon_state = "plasma"
/obj/effect/turf_decal/vg_decals/atmos/mix
icon_state = "mix"
// ATMOS END
// DEPARTMENT START
/obj/effect/turf_decal/vg_decals/department/hop
icon_state = "hop"
/obj/effect/turf_decal/vg_decals/department/bar
icon_state = "bar"
/obj/effect/turf_decal/vg_decals/department/cargo
icon_state = "cargo"
/obj/effect/turf_decal/vg_decals/department/med
icon_state = "med"
/obj/effect/turf_decal/vg_decals/department/sci
icon_state = "sci"
/obj/effect/turf_decal/vg_decals/department/sec
icon_state = "sec"
/obj/effect/turf_decal/vg_decals/department/mining
icon_state = "mine"
/obj/effect/turf_decal/vg_decals/department/zoo
icon_state = "zoo"
// DEPARTMENT END
// MISC START
/obj/effect/turf_decal/vg_decals/no
icon = 'icons/turf/vgstation_decals.dmi'
icon_state = "no"
/obj/effect/turf_decal/vg_decals/radiation_huge
icon_state = "radiation_huge"
/obj/effect/turf_decal/vg_decals/radiation
icon_state = "radiation"
/obj/effect/turf_decal/vg_decals/radiation_custom
icon_state = "radiation-w"
// MISC END
+2
View File
@@ -7,6 +7,8 @@
move_resist = INFINITY
obj_flags = 0
vis_flags = NONE
/obj/effect/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
return
+138 -3
View File
@@ -45,7 +45,6 @@
/obj/effect/spawner/lootdrop/armory_contraband
name = "armory contraband gun spawner"
lootdoubles = FALSE
loot = list(
/obj/item/gun/ballistic/automatic/pistol = 8,
/obj/item/gun/ballistic/shotgun/automatic/combat = 5,
@@ -129,7 +128,6 @@
loot = typesof(/obj/item/flashlight/glowstick)
. = ..()
/obj/effect/spawner/lootdrop/gloves
name = "random gloves"
desc = "These gloves are supposed to be a random color..."
@@ -150,7 +148,6 @@
/obj/effect/spawner/lootdrop/crate_spawner
name = "lootcrate spawner" //USE PROMO CODE "SELLOUT" FOR 20% OFF!
lootdoubles = FALSE
loot = list(
/obj/structure/closet/crate/secure/loot = 20,
"" = 80
@@ -386,3 +383,141 @@
/obj/structure/reagent_dispensers/keg/aphro = 2,
/obj/structure/reagent_dispensers/keg/aphro/strong = 2,
/obj/structure/reagent_dispensers/keg/gargle = 1)
/obj/effect/spawner/lootdrop/coin
lootcount = 1
loot = list(
/obj/item/coin/silver = 30,
/obj/item/coin/iron = 30,
/obj/item/coin/gold = 10,
/obj/item/coin/diamond = 10,
/obj/item/coin/plasma = 10,
/obj/item/coin/uranium = 10,
)
/obj/effect/spawner/lootdrop/cig_packs
lootcount = 1
loot = list(
/obj/item/storage/fancy/cigarettes = 20,
/obj/item/storage/fancy/cigarettes/dromedaryco = 10,
/obj/item/storage/fancy/cigarettes/cigpack_robust = 5,
/obj/item/storage/fancy/cigarettes/cigpack_robustgold = 5,
/obj/item/storage/fancy/cigarettes/cigpack_carp = 15,
/obj/item/storage/fancy/cigarettes/cigpack_syndicate = 2,
/obj/item/storage/fancy/cigarettes/cigpack_midori = 10,
/obj/item/storage/fancy/cigarettes/cigpack_shadyjims = 5,
/obj/item/storage/fancy/cigarettes/cigpack_xeno = 3,
/obj/item/storage/fancy/cigarettes/cigpack_cannabis = 10,
/obj/item/storage/fancy/cigarettes/cigpack_mindbreaker = 10,
/obj/item/storage/fancy/rollingpapers = 10
)
/obj/effect/spawner/lootdrop/cigars_cases
lootcount = 1
loot = list(
/obj/item/storage/fancy/cigarettes/cigars = 50,
/obj/item/storage/fancy/cigarettes/cigars/cohiba = 25,
/obj/item/storage/fancy/cigarettes/cigars/havana = 25,
)
/obj/effect/spawner/lootdrop/space_cash
lootcount = 1
loot = list(
/obj/item/stack/spacecash/c1 = 1,
/obj/item/stack/spacecash/c10 = 9,
/obj/item/stack/spacecash/c20 = 10,
/obj/item/stack/spacecash/c50 = 15,
/obj/item/stack/spacecash/c100 = 25,
/obj/item/stack/spacecash/c200 = 20,
/obj/item/stack/spacecash/c500 = 19,
/obj/item/stack/spacecash/c1000 = 1,
)
/obj/effect/spawner/lootdrop/druggie_pill
lootcount = 1
loot = list(
/obj/item/reagent_containers/pill/stimulant = 1,
/obj/item/reagent_containers/pill/zoom = 9,
/obj/item/reagent_containers/pill/happy = 10,
/obj/item/reagent_containers/pill/lsd = 15,
/obj/item/reagent_containers/pill/aranesp = 25,
/obj/item/reagent_containers/pill/psicodine = 20,
/obj/item/reagent_containers/pill/mannitol = 19,
/obj/item/reagent_containers/pill/happiness = 1,
)
/obj/effect/spawner/lootdrop/low_loot_toilet
name = "random low toilet spawner"
lootcount = 1
//Note this is out of a 100 - Meaning the number you see is also the percent its going to pick that
//This is ment for "low" loot that anyone could fine in a toilet, for better gear use high loot toilet
loot = list("" = 30,
/obj/item/lighter = 2,
/obj/item/tape/random = 1,
/obj/item/poster/random_contraband = 1,
/obj/item/clothing/glasses/sunglasses/blindfold = 4,
/obj/item/clothing/glasses/sunglasses = 1,
/obj/item/toy/plush/random = 5,
/obj/effect/spawner/lootdrop/gloves = 5,
/obj/effect/spawner/lootdrop/glowstick = 5,
/obj/effect/spawner/lootdrop/coin = 3,
/obj/effect/spawner/lootdrop/cig_packs = 10,
/obj/effect/spawner/lootdrop/cigars_cases = 2,
/obj/effect/spawner/lootdrop/space_cash = 5,
/obj/item/reagent_containers/food/snacks/grown/cannabis = 5,
/obj/item/storage/pill_bottle/dice = 5,
/obj/item/toy/cards/deck = 5,
/obj/effect/spawner/lootdrop/druggie_pill = 5
)
/obj/effect/spawner/lootdrop/prison_loot_toilet
name = "random prison toilet spawner"
lootcount = 1
//Note this is out of a 100 - Meaning the number you see is also the percent its going to pick that
//This is ment for "prison" loot that is rather rare and ment for "prisoners if they get a crowbar to fine, or sec.
loot = list("" = 10,
/obj/item/lighter = 5,
/obj/item/poster/random_contraband = 5,
/obj/item/clothing/glasses/sunglasses = 5,
/obj/effect/spawner/lootdrop/coin = 5,
/obj/effect/spawner/lootdrop/cig_packs = 10,
/obj/effect/spawner/lootdrop/cigars_cases = 5,
/obj/item/reagent_containers/food/snacks/grown/cannabis = 5,
/obj/item/storage/pill_bottle/dice = 5,
/obj/item/toy/cards/deck = 5,
/obj/effect/spawner/lootdrop/druggie_pill = 5,
/obj/item/kitchen/knife = 5,
/obj/item/screwdriver = 5,
/obj/item/crowbar/red = 0.5, //Dont you need a crowbar to open this?
/obj/item/stack/medical/bruise_pack = 3,
/obj/item/reagent_containers/food/drinks/bottle/vodka = 2,
/obj/item/radio = 5,
/obj/item/flashlight = 4.5,
/obj/item/clothing/mask/breath = 2,
/obj/item/tank/internals/emergency_oxygen = 3,
/obj/item/storage/box/mre/menu4/safe = 3,
/obj/item/grenade/smokebomb = 2
)
/obj/effect/spawner/lootdrop/high_loot_toilet
name = "random high toilet spawner"
lootcount = 1
//Note this is out of a 100 - Meaning the number you see is also the percent its going to pick that
//The items inside are always going to be something usefull, illegal and likely traitorous.
loot = list(
/obj/item/clothing/glasses/sunglasses = 5,
/obj/effect/spawner/lootdrop/coin = 5,
/obj/effect/spawner/lootdrop/space_cash = 5,
/obj/effect/spawner/lootdrop/druggie_pill = 5,
/obj/item/storage/fancy/cigarettes/cigpack_syndicate = 5,
/obj/item/suppressor = 5,
/obj/item/toy/cards/deck/syndicate = 5,
/obj/item/clothing/under/syndicate = 5,
/obj/item/clothing/mask/gas/syndicate = 5,
/obj/item/grenade/smokebomb = 10,
/obj/item/gun/ballistic/automatic/toy/pistol = 5,
/obj/item/firing_pin = 5,
/obj/item/grenade/empgrenade = 15,
/obj/item/clothing/gloves/combat = 10,
/obj/item/clothing/shoes/sneakers/noslip = 10
)
+6
View File
@@ -7,6 +7,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
/obj/item
name = "item"
icon = 'icons/obj/items_and_weapons.dmi'
blocks_emissive = EMISSIVE_BLOCK_GENERIC
var/item_state = null
var/lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
var/righthand_file = 'icons/mob/inhands/items_righthand.dmi'
@@ -34,7 +35,12 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
var/usesound = null
var/throwhitsound = null
var/w_class = WEIGHT_CLASS_NORMAL
/// The amount of stamina it takes to swing an item in a normal melee attack do not lie to me and say it's for realism because it ain't. If null it will autocalculate from w_class.
var/total_mass //Total mass in arbitrary pound-like values. If there's no balance reasons for an item to have otherwise, this var should be the item's weight in pounds.
/// How long, in deciseconds, this staggers for, if null it will autocalculate from w_class and force. Unlike total mass this supports 0 and negatives.
var/stagger_force
var/slot_flags = 0 //This is used to determine on which slots an item can fit.
pass_flags = PASSTABLE
pressure_resistance = 4
+2 -1
View File
@@ -13,7 +13,8 @@
/obj/item/areaeditor/attack_self(mob/user)
add_fingerprint(user)
. = "<BODY><HTML><head><title>[src]</title></head> \
. = "<BODY><HTML><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>\
<title>[src]</title></head> \
<h2>[station_name()] [src.name]</h2> \
<small>[fluffnotice]</small><hr>"
switch(get_area_type())
+7 -2
View File
@@ -13,6 +13,7 @@
var/lit = FALSE
var/infinite = FALSE
var/start_lit = FALSE
var/heats_space = TRUE
/obj/item/candle/Initialize()
. = ..()
@@ -35,7 +36,7 @@
return ..()
/obj/item/candle/get_temperature()
return lit * heat
return lit * heat * heats_space
/obj/item/candle/proc/light(show_message)
if(!lit)
@@ -67,7 +68,8 @@
new /obj/item/trash/candle(loc)
qdel(src)
update_icon()
open_flame()
if(heats_space)
open_flame()
/obj/item/candle/attack_self(mob/user)
if(put_out_candle())
@@ -77,4 +79,7 @@
infinite = TRUE
start_lit = TRUE
/obj/item/candle/infinite/hugbox
heats_space = FALSE
#undef CANDLE_LUMINOSITY
@@ -293,10 +293,6 @@
name = "Mining Shuttle (Computer Board)"
build_path = /obj/machinery/computer/shuttle/mining
/obj/item/circuitboard/computer/mining_shuttle/common
name = "Lavaland Shuttle (Computer Board)"
build_path = /obj/machinery/computer/shuttle/mining/common
/obj/item/circuitboard/computer/white_ship
name = "White Ship (Computer Board)"
build_path = /obj/machinery/computer/shuttle/white_ship
+2 -2
View File
@@ -271,7 +271,7 @@ GLOBAL_LIST_EMPTY(PDAs)
user.set_machine(src)
var/dat = "<!DOCTYPE html><html><head><title>Personal Data Assistant</title><link href=\"https://fonts.googleapis.com/css?family=Orbitron|Share+Tech+Mono|VT323\" rel=\"stylesheet\"></head><body bgcolor=\"" + background_color + "\"><style>body{" + font_mode + "}ul,ol{list-style-type: none;}a, a:link, a:visited, a:active, a:hover { color: #000000;text-decoration:none; }img {border-style:none;}a img{padding-right: 9px;}</style>"
var/dat = "<!DOCTYPE html><html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Personal Data Assistant</title><link href=\"https://fonts.googleapis.com/css?family=Orbitron|Share+Tech+Mono|VT323\" rel=\"stylesheet\"></head><body bgcolor=\"" + background_color + "\"><style>body{" + font_mode + "}ul,ol{list-style-type: none;}a, a:link, a:visited, a:active, a:hover { color: #000000;text-decoration:none; }img {border-style:none;}a img{padding-right: 9px;}</style>"
dat += assets.css_tag()
dat += emoji_s.css_tag()
@@ -1192,7 +1192,7 @@ GLOBAL_LIST_EMPTY(PDAs)
if(incapacitated())
return
if(!isnull(aiPDA))
var/HTML = "<html><head><title>AI PDA Message Log</title></head><body>[aiPDA.tnote]</body></html>"
var/HTML = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>AI PDA Message Log</title></head><body>[aiPDA.tnote]</body></html>"
user << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0")
else
to_chat(user, "You do not have a PDA. You should make an issue report about this.")
+10 -13
View File
@@ -170,7 +170,7 @@
flags_1 = CONDUCT_1
brightness_on = 2
light_color = "#FFDDCC"
flashlight_power = 0.3
flashlight_power = 0.5
var/holo_cooldown = 0
/obj/item/flashlight/pen/afterattack(atom/target, mob/user, proximity_flag)
@@ -227,15 +227,12 @@
custom_materials = null
on = TRUE
// green-shaded desk lamp
/obj/item/flashlight/lamp/green
desc = "A classic green-shaded desk lamp."
icon_state = "lampgreen"
item_state = "lampgreen"
/obj/item/flashlight/lamp/verb/toggle_light()
set name = "Toggle light"
set category = "Object"
@@ -258,12 +255,13 @@
desc = "A red Nanotrasen issued flare. There are instructions on the side, it reads 'pull cord, make light'."
w_class = WEIGHT_CLASS_SMALL
brightness_on = 7 // Pretty bright.
total_mass = 0.8
light_color = "#FA421A"
icon_state = "flare"
item_state = "flare"
actions_types = list()
var/fuel = 0
var/on_damage = 7
var/on_damage = 9
var/produce_heat = 1500
heat = 1000
light_color = LIGHT_COLOR_FLARE
@@ -331,14 +329,15 @@
name = "torch"
desc = "A torch fashioned from some leaves and a log."
w_class = WEIGHT_CLASS_BULKY
brightness_on = 4
brightness_on = 6 //When on were like a lantern
light_color = "#FAA44B"
icon_state = "torch"
item_state = "torch"
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
light_color = LIGHT_COLOR_ORANGE
on_damage = 10
total_mass = TOTAL_MASS_NORMAL_ITEM
on_damage = 12 //Its a log thats on fire
slot_flags = null
/obj/item/flashlight/lantern
@@ -348,10 +347,9 @@
lefthand_file = 'icons/mob/inhands/equipment/mining_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/mining_righthand.dmi'
desc = "A mining lantern."
brightness_on = 6 // luminosity when on
brightness_on = 6 // luminosity when on
light_color = "#FFAA44"
flashlight_power = 0.75
flashlight_power = 0.8
/obj/item/flashlight/slime
gender = PLURAL
@@ -372,7 +370,6 @@
var/emp_cur_charges = 4
var/charge_tick = 0
/obj/item/flashlight/emp/New()
..()
START_PROCESSING(SSobj, src)
@@ -435,7 +432,7 @@
var/fuel = 0
/obj/item/flashlight/glowstick/Initialize()
fuel = rand(1600, 2000)
fuel = rand(1000, 1500)
light_color = color
. = ..()
@@ -540,7 +537,7 @@
/obj/item/flashlight/eyelight
name = "eyelight"
desc = "This shouldn't exist outside of someone's head, how are you seeing this?"
brightness_on = 15
brightness_on = 10
flags_1 = CONDUCT_1
item_flags = DROPDEL
actions_types = list()
@@ -1,317 +0,0 @@
//copy pasta of the space piano, don't hurt me -Pete
/obj/item/instrument
name = "generic instrument"
resistance_flags = FLAMMABLE
force = 10
max_integrity = 100
icon = 'icons/obj/musician.dmi'
lefthand_file = 'icons/mob/inhands/equipment/instruments_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/instruments_righthand.dmi'
var/datum/song/handheld/song
var/instrumentId = "generic"
var/instrumentExt = "mid"
var/tune_time = 0
/obj/item/instrument/Initialize()
. = ..()
song = new(instrumentId, src, instrumentExt)
/obj/item/instrument/Destroy()
if (tune_time)
STOP_PROCESSING(SSobj, src)
qdel(song)
song = null
return ..()
/obj/item/instrument/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] begins to play 'Gloomy Sunday'! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (BRUTELOSS)
/obj/item/instrument/Initialize(mapload)
. = ..()
if(mapload)
song.tempo = song.sanitize_tempo(song.tempo) // tick_lag isn't set when the map is loaded
/obj/item/instrument/attack_self(mob/user)
if(!user.IsAdvancedToolUser())
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return 1
interact(user)
/obj/item/instrument/interact(mob/user)
ui_interact(user)
/obj/item/instrument/ui_interact(mob/user)
if(!user)
return
if(!isliving(user) || user.stat || user.restrained() || user.lying)
return
user.set_machine(src)
song.interact(user)
/obj/item/instrument/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/musicaltuner))
var/mob/living/carbon/human/H = user
if (HAS_TRAIT(H, TRAIT_MUSICIAN))
if (!tune_time)
H.visible_message("[H] tunes the [src] to perfection!", "<span class='notice'>You tune the [src] to perfection!</span>")
tune_time = 300
START_PROCESSING(SSobj, src)
else
to_chat(H, "<span class='notice'>[src] is already well tuned!</span>")
else
to_chat(H, "<span class='warning'>You have no idea how to use this.</span>")
/obj/item/instrument/process()
if (tune_time)
if (song.playing)
for (var/mob/living/M in song.hearing_mobs)
M.dizziness = max(0,M.dizziness-2)
M.jitteriness = max(0,M.jitteriness-2)
M.confused = max(M.confused-1)
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "goodmusic", /datum/mood_event/goodmusic)
tune_time--
else
if (!tune_time)
if (song.playing)
loc.visible_message("<span class='warning'>[src] starts sounding a little off...</span>")
STOP_PROCESSING(SSobj, src)
/obj/item/instrument/violin
name = "space violin"
desc = "A wooden musical instrument with four strings and a bow. \"The devil went down to space, he was looking for an assistant to grief.\""
icon_state = "violin"
item_state = "violin"
hitsound = "swing_hit"
instrumentId = "violin"
/obj/item/instrument/violin/golden
name = "golden violin"
desc = "A golden musical instrument with four strings and a bow. \"The devil went down to space, he was looking for an assistant to grief.\""
icon_state = "golden_violin"
item_state = "golden_violin"
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
/obj/item/instrument/piano_synth
name = "synthesizer"
desc = "An advanced electronic synthesizer that can be used as various instruments."
icon_state = "synth"
item_state = "synth"
instrumentId = "piano"
instrumentExt = "ogg"
var/static/list/insTypes = list("accordion" = "mid", "bikehorn" = "ogg", "glockenspiel" = "mid", "banjo" = "ogg", "guitar" = "ogg", "harmonica" = "mid", "piano" = "ogg", "recorder" = "mid", "saxophone" = "mid", "trombone" = "mid", "violin" = "mid", "xylophone" = "mid") //No eguitar you ear-rapey fuckers.
actions_types = list(/datum/action/item_action/synthswitch)
/obj/item/instrument/piano_synth/proc/changeInstrument(name = "piano")
song.instrumentDir = name
song.instrumentExt = insTypes[name]
/obj/item/instrument/piano_synth/proc/selectInstrument() // Moved here so it can be used by the action and PAI software panel without copypasta
var/chosen = input("Choose the type of instrument you want to use", "Instrument Selection", song.instrumentDir) as null|anything in insTypes
if(!insTypes[chosen])
return
return changeInstrument(chosen)
/obj/item/instrument/banjo
name = "banjo"
desc = "A 'Mura' brand banjo. It's pretty much just a drum with a neck and strings."
icon_state = "banjo"
item_state = "banjo"
instrumentExt = "ogg"
attack_verb = list("scruggs-styled", "hum-diggitied", "shin-digged", "clawhammered")
hitsound = 'sound/weapons/banjoslap.ogg'
instrumentId = "banjo"
/obj/item/instrument/guitar
name = "guitar"
desc = "It's made of wood and has bronze strings."
icon_state = "guitar"
item_state = "guitar"
instrumentExt = "ogg"
attack_verb = list("played metal on", "serenaded", "crashed", "smashed")
hitsound = 'sound/weapons/stringsmash.ogg'
instrumentId = "guitar"
/obj/item/instrument/eguitar
name = "electric guitar"
desc = "Makes all your shredding needs possible."
icon_state = "eguitar"
item_state = "eguitar"
force = 12
attack_verb = list("played metal on", "shredded", "crashed", "smashed")
hitsound = 'sound/weapons/stringsmash.ogg'
instrumentId = "eguitar"
instrumentExt = "ogg"
/obj/item/instrument/glockenspiel
name = "glockenspiel"
desc = "Smooth metal bars perfect for any marching band."
icon_state = "glockenspiel"
item_state = "glockenspiel"
instrumentId = "glockenspiel"
/obj/item/instrument/accordion
name = "accordion"
desc = "Pun-Pun not included."
icon_state = "accordion"
item_state = "accordion"
instrumentId = "accordion"
/obj/item/instrument/trumpet
name = "trumpet"
desc = "To announce the arrival of the king!"
icon_state = "trumpet"
item_state = "trombone"
instrumentId = "trombone"
/obj/item/instrument/trumpet/spectral
name = "spectral trumpet"
desc = "Things are about to get spooky!"
icon_state = "trumpet"
item_state = "trombone"
force = 0
instrumentId = "trombone"
attack_verb = list("played","jazzed","trumpeted","mourned","dooted","spooked")
/obj/item/instrument/trumpet/spectral/Initialize()
. = ..()
AddComponent(/datum/component/spooky)
/obj/item/instrument/trumpet/spectral/attack(mob/living/carbon/C, mob/user)
playsound (loc, 'sound/instruments/trombone/En4.mid', 100,1,-1)
..()
/obj/item/instrument/saxophone
name = "saxophone"
desc = "This soothing sound will be sure to leave your audience in tears."
icon_state = "saxophone"
item_state = "saxophone"
instrumentId = "saxophone"
/obj/item/instrument/saxophone/spectral
name = "spectral saxophone"
desc = "This spooky sound will be sure to leave mortals in bones."
icon_state = "saxophone"
item_state = "saxophone"
instrumentId = "saxophone"
force = 0
attack_verb = list("played","jazzed","saxxed","mourned","dooted","spooked")
/obj/item/instrument/saxophone/spectral/Initialize()
. = ..()
AddComponent(/datum/component/spooky)
/obj/item/instrument/saxophone/spectral/attack(mob/living/carbon/C, mob/user)
playsound (loc, 'sound/instruments/saxophone/En4.mid', 100,1,-1)
..()
/obj/item/instrument/trombone
name = "trombone"
desc = "How can any pool table ever hope to compete?"
icon_state = "trombone"
item_state = "trombone"
instrumentId = "trombone"
/obj/item/instrument/trombone/spectral
name = "spectral trombone"
desc = "A skeleton's favorite instrument. Apply directly on the mortals."
instrumentId = "trombone"
icon_state = "trombone"
item_state = "trombone"
force = 0
attack_verb = list("played","jazzed","tromboned","mourned","dooted","spooked")
/obj/item/instrument/trombone/spectral/Initialize()
. = ..()
AddComponent(/datum/component/spooky)
/obj/item/instrument/trombone/spectral/attack(mob/living/carbon/C, mob/user)
playsound (loc, 'sound/instruments/trombone/Cn4.mid', 100,1,-1)
..()
/obj/item/instrument/recorder
name = "recorder"
desc = "Just like in school, playing ability and all."
force = 5
icon_state = "recorder"
item_state = "recorder"
instrumentId = "recorder"
/obj/item/instrument/harmonica
name = "harmonica"
desc = "For when you get a bad case of the space blues."
icon_state = "harmonica"
item_state = "harmonica"
instrumentId = "harmonica"
slot_flags = ITEM_SLOT_MASK
force = 5
w_class = WEIGHT_CLASS_SMALL
actions_types = list(/datum/action/item_action/instrument)
/obj/item/instrument/harmonica/proc/handle_speech(datum/source, list/speech_args)
if(song.playing && ismob(loc))
to_chat(loc, "<span class='warning'>You stop playing the harmonica to talk...</span>")
song.playing = FALSE
/obj/item/instrument/harmonica/equipped(mob/M, slot)
. = ..()
RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech)
/obj/item/instrument/harmonica/dropped(mob/M)
. = ..()
UnregisterSignal(M, COMSIG_MOB_SAY)
/obj/item/instrument/bikehorn
name = "gilded bike horn"
desc = "An exquisitely decorated bike horn, capable of honking in a variety of notes."
icon_state = "bike_horn"
item_state = "bike_horn"
lefthand_file = 'icons/mob/inhands/equipment/horns_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/horns_righthand.dmi'
attack_verb = list("beautifully honks")
instrumentId = "bikehorn"
instrumentExt = "ogg"
w_class = WEIGHT_CLASS_TINY
force = 0
throw_speed = 3
throw_range = 15
hitsound = 'sound/items/bikehorn.ogg'
/obj/item/musicaltuner
name = "musical tuner"
desc = "A device for tuning musical instruments both manual and electronic alike."
icon = 'icons/obj/device.dmi'
icon_state = "musicaltuner"
slot_flags = ITEM_SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
/obj/item/choice_beacon/music
name = "instrument delivery beacon"
desc = "Summon your tool of art."
icon_state = "gangtool-red"
/obj/item/choice_beacon/music/generate_display_names()
var/static/list/instruments
if(!instruments)
instruments = list()
var/list/templist = list(/obj/item/instrument/violin,
/obj/item/instrument/piano_synth,
/obj/item/instrument/guitar,
/obj/item/instrument/eguitar,
/obj/item/instrument/glockenspiel,
/obj/item/instrument/accordion,
/obj/item/instrument/trumpet,
/obj/item/instrument/saxophone,
/obj/item/instrument/trombone,
/obj/item/instrument/recorder,
/obj/item/instrument/harmonica
)
for(var/V in templist)
var/atom/A = V
instruments[initial(A.name)] = A
return instruments
+3 -3
View File
@@ -310,11 +310,11 @@ SLIME SCANNER
//GENERAL HANDLER
if(!damage_message)
if(O.organ_flags & ORGAN_FAILING)
damage_message += " <span class='alert'><b>End Stage [O.name] failure detected.</b></span>"
damage_message += " <span class='alert'><b>Chronic [O.name] failure detected.</b></span>"
else if(O.damage > O.high_threshold)
damage_message += " <span class='alert'>Chronic [O.name] failure detected.</span>"
damage_message += " <span class='alert'>Acute [O.name] failure detected.</span>"
else if(O.damage > O.low_threshold && advanced)
damage_message += " <font color='red'>Acute [O.name] failure detected.</span>"
damage_message += " <font color='red'>Minor [O.name] failure detected.</span>"
if(temp_message || damage_message)
msg += "\t<b><span class='info'>[uppertext(O.name)]:</b></span> [damage_message] [temp_message]\n"
+20 -13
View File
@@ -113,24 +113,24 @@
desc = "Looks like some cables tied together. Could be used to tie something up."
icon_state = "cuff"
item_state = "coil"
item_color = "red"
color = "#ff0000"
color = "red"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
custom_materials = list(/datum/material/iron=150, /datum/material/glass=75)
breakouttime = 300 //Deciseconds = 30s
cuffsound = 'sound/weapons/cablecuff.ogg'
/obj/item/restraints/handcuffs/cable/Initialize(mapload, param_color)
. = ..()
var/list/cable_colors = GLOB.cable_colors
item_color = param_color || item_color || pick(cable_colors)
if(cable_colors[item_color])
item_color = cable_colors[item_color]
color = null
add_atom_colour(item_color, FIXED_COLOUR_PRIORITY)
cuffsound = 'sound/weapons/cablecuff.ogg'
/obj/item/restraints/handcuffs/cable/attack_self(mob/user)
to_chat(user, "<span class='notice'>You start unwinding the cable restraints back into coil</span>")
if(!do_after(user, 25, TRUE, user))
return
qdel(src)
var/obj/item/stack/cable_coil/coil = new(get_turf(user))
coil.amount = 15
user.put_in_hands(coil)
coil.color = color
to_chat(user, "<span class='notice'>You unwind the cable restraints back into coil</span>")
/obj/item/restraints/handcuffs/cable/red
item_color = "red"
color = "#ff0000"
@@ -162,6 +162,13 @@
/obj/item/restraints/handcuffs/cable/white
item_color = "white"
/obj/item/restraints/handcuffs/cable/random
/obj/item/restraints/handcuffs/cable/random/Initialize(mapload)
. = ..()
var/list/cable_colors = GLOB.cable_colors
color = pick(cable_colors)
/obj/item/restraints/handcuffs/cable/attackby(obj/item/I, mob/user, params)
..()
if(istype(I, /obj/item/stack/rods))
+1 -1
View File
@@ -494,7 +494,7 @@
S.ckey = C.ckey
S.status_flags |= GODMODE
S.language_holder = user.language_holder.copy(S)
S.AddElement(/datum/element/ghost_role_eligibility)
S.AddElement(/datum/element/ghost_role_eligibility,penalize_on_ghost = TRUE)
START_PROCESSING(SSprocessing,src)
var/input = stripped_input(S,"What are you named?", ,"", MAX_NAME_LEN)
@@ -21,7 +21,7 @@
if (!spell)
return FALSE
if (autorobeless && spell.clothes_req)
spell.clothes_req = FALSE
spell.clothes_req = NONE
target.AddSpell(spell)
return TRUE
+1
View File
@@ -142,6 +142,7 @@
name = "plastic knife"
desc = "A plastic knife. Rather harmless to anything."
force = 1
throwforce = 1
bayonet = FALSE
/obj/item/kitchen/knife/combat/cyborg
+10
View File
@@ -14,6 +14,7 @@
//book contents below
dat = {"<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<style>
h1 {font-size: 18px; margin: 15px 0px 5px;}
h2 {font-size: 15px; margin: 15px 0px 5px;}
@@ -49,6 +50,7 @@
title = "APLU \"Ripley\" Construction and Operation Manual"
dat = {"<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<style>
h1 {font-size: 18px; margin: 15px 0px 5px;}
h2 {font-size: 15px; margin: 15px 0px 5px;}
@@ -122,6 +124,7 @@
title = "Chef Recipes"
dat = {"<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<style>
h1 {font-size: 18px; margin: 15px 0px 5px;}
h2 {font-size: 15px; margin: 15px 0px 5px;}
@@ -202,6 +205,10 @@
author = "Syndicate"
title = "Fission Mailed: Nuclear Sabotage 101"
dat = {"<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
</head>
<body>
Nuclear Explosives 101:<br>
Hello and thank you for choosing the Syndicate for your nuclear information needs.<br>
Today's crash course will deal with the operation of a Fusion Class Nanotrasen made Nuclear Device.<br>
@@ -229,6 +236,7 @@
<b>Disk, Code, Safety, Timer, Disk, RUN!</b><br>
Intelligence Analysts believe that normal Nanotrasen procedure is for the Captain to secure the nuclear authorisation disk.<br>
Good luck!
</body>
</html>"}
// Wiki books that are linked to the configured wiki link.
@@ -249,6 +257,7 @@
dat = {"
<html><head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<style>
iframe {
display: none;
@@ -284,6 +293,7 @@
dat = {"
<html><head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<style>
iframe {
display: none;
+17 -2
View File
@@ -58,6 +58,21 @@
new /obj/effect/abstract/DPtarget(get_turf(src), pod)
/obj/item/choice_beacon/ingredients
name = "ingredient box delivery beacon"
desc = "Summon a box of ingredients from a wide selection!"
icon_state = "gangtool-red"
/obj/item/choice_beacon/ingredients/generate_display_names()
var/static/list/ingredientboxes
if(!ingredientboxes)
ingredientboxes = list()
var/list/templist = typesof(/obj/item/storage/box/ingredients)
for(var/V in templist)
var/obj/item/storage/box/ingredients/A = V
ingredientboxes[initial(A.theme_name)] = A
return ingredientboxes
/obj/item/choice_beacon/hero
name = "heroic beacon"
desc = "To summon heroes from the past to protect the future."
@@ -72,7 +87,6 @@
hero_item_list[initial(A.name)] = A
return hero_item_list
/obj/item/storage/box/hero
name = "Courageous Tomb Raider - 1940's."
@@ -115,4 +129,5 @@
icon = 'icons/obj/supermatter.dmi'
icon_state = "supermatterspray"
w_class = WEIGHT_CLASS_SMALL
var/usesleft = 2
var/usesleft = 2
+1 -1
View File
@@ -83,7 +83,7 @@
/obj/item/pinpointer/crew/proc/trackable(mob/living/carbon/human/H)
var/turf/here = get_turf(src)
if((H.z == 0 || H.z == here.z) && istype(H.w_uniform, /obj/item/clothing/under))
if(H && (H.z == 0 || H.z == here.z) && istype(H.w_uniform, /obj/item/clothing/under))
var/obj/item/clothing/under/U = H.w_uniform
// Suit sensors must be on maximum.
+1
View File
@@ -143,6 +143,7 @@
/obj/item/shield/energy/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if((attack_type & ATTACK_TYPE_PROJECTILE) && is_energy_reflectable_projectile(object))
block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_DEFLECT
return BLOCK_SUCCESS | BLOCK_REDIRECTED | BLOCK_SHOULD_REDIRECT
return ..()
@@ -137,7 +137,7 @@ GLOBAL_LIST_INIT(pglass_recipes, list ( \
return ..()
/obj/item/stack/sheet/plasmaglass/on_solar_construction(obj/machinery/power/solar/S)
S.obj_integrity *= 1.2
S.max_integrity *= 1.2
S.efficiency *= 1.2
/*
@@ -170,7 +170,7 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \
..()
/obj/item/stack/sheet/rglass/on_solar_construction(obj/machinery/power/solar/S)
S.obj_integrity *= 2
S.max_integrity *= 2
/obj/item/stack/sheet/rglass/cyborg
custom_materials = null
@@ -218,7 +218,7 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \
. += GLOB.prglass_recipes
/obj/item/stack/sheet/plasmarglass/on_solar_construction(obj/machinery/power/solar/S)
S.obj_integrity *= 2.2
S.max_integrity *= 2.2
S.efficiency *= 1.2
GLOBAL_LIST_INIT(titaniumglass_recipes, list(
@@ -242,7 +242,7 @@ GLOBAL_LIST_INIT(titaniumglass_recipes, list(
. += GLOB.titaniumglass_recipes
/obj/item/stack/sheet/titaniumglass/on_solar_construction(obj/machinery/power/solar/S)
S.obj_integrity *= 2.5
S.max_integrity *= 2.5
S.efficiency *= 1.5
GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
@@ -270,7 +270,7 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
. += GLOB.plastitaniumglass_recipes
/obj/item/stack/sheet/titaniumglass/on_solar_construction(obj/machinery/power/solar/S)
S.obj_integrity *= 2
S.max_integrity *= 2
S.efficiency *= 2
/obj/item/shard
@@ -120,6 +120,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
)), \
null, \
new/datum/stack_recipe("iron door", /obj/structure/mineral_door/iron, 20, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("pestle", /obj/item/pestle, 1, time = 50), \
new/datum/stack_recipe("floodlight frame", /obj/structure/floodlight_frame, 5, one_per_turf = TRUE, on_floor = TRUE), \
))
@@ -181,8 +182,8 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \
new/datum/stack_recipe("crate", /obj/structure/closet/crate, 5, time = 90, one_per_turf = TRUE), \
null, \
new /datum/stack_recipe_list("airlock assemblies", list( \
new/datum/stack_recipe("high security airlock assembly", /obj/structure/door_assembly/door_assembly_highsecurity, 6, time = 50, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("vault door assembly", /obj/structure/door_assembly/door_assembly_vault, 8, time = 50, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("high security airlock assembly", /obj/structure/door_assembly/door_assembly_highsecurity, 4, time = 50, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("vault door assembly", /obj/structure/door_assembly/door_assembly_vault, 6, time = 50, one_per_turf = 1, on_floor = 1), \
)), \
))
@@ -255,6 +256,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
new/datum/stack_recipe("apiary", /obj/structure/beebox, 40, time = 50),\
null, \
new/datum/stack_recipe("picture frame", /obj/item/wallframe/picture, 1, time = 10),\
new/datum/stack_recipe("mortar", /obj/item/reagent_containers/glass/mortar, 3), \
new/datum/stack_recipe("honey frame", /obj/item/honey_frame, 5, time = 10),\
))
@@ -366,6 +368,7 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \
new/datum/stack_recipe("towel", /obj/item/reagent_containers/rag/towel, 3), \
new/datum/stack_recipe("bedsheet", /obj/item/bedsheet, 3), \
new/datum/stack_recipe("empty sandbag", /obj/item/emptysandbag, 4), \
new/datum/stack_recipe("padded floor tile", /obj/item/stack/tile/padded, 1, 4, 20), \
null, \
new/datum/stack_recipe("fingerless gloves", /obj/item/clothing/gloves/fingerless, 1),\
new/datum/stack_recipe("white gloves", /obj/item/clothing/gloves/color/white, 1),\
@@ -142,6 +142,14 @@
turf_type = /turf/open/floor/wood
resistance_flags = FLAMMABLE
//Cloth Floors
/obj/item/stack/tile/padded
name = "padded floor tile"
desc = "These are soft and cushy, they'd make good pillows. They look very comfortable, although what they're used for is discomforting."
icon_state = "tile_padded"
turf_type = /turf/open/floor/padded
//Basalt
/obj/item/stack/tile/basalt
name = "basalt tile"
+1 -1
View File
@@ -52,7 +52,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
return
// If H is the Chaplain, we can set the icon_state of the bible (but only once!)
if(!GLOB.bible_icon_state && H.job == "Chaplain")
var/dat = "<html><head><title>Pick Bible Style</title></head><body><center><h2>Pick a bible style</h2></center><table>"
var/dat = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Pick Bible Style</title></head><body><center><h2>Pick a bible style</h2></center><table>"
for(var/i in 1 to GLOB.biblestates.len)
var/icon/bibleicon = icon('icons/obj/storage.dmi', GLOB.biblestates[i])
var/nicename = GLOB.biblenames[i]
+45 -1
View File
@@ -946,12 +946,47 @@
/obj/item/reagent_containers/food/snacks/grown/apple,
/obj/item/reagent_containers/food/snacks/chocolatebar,
/obj/item/reagent_containers/food/snacks/grown/cherries,
/obj/item/reagent_containers/food/snacks/grown/berries,
/obj/item/reagent_containers/food/snacks/grown/banana,
/obj/item/reagent_containers/food/snacks/grown/cabbage,
/obj/item/reagent_containers/food/snacks/grown/soybeans,
/obj/item/reagent_containers/food/snacks/grown/corn,
/obj/item/reagent_containers/food/snacks/grown/mushroom/plumphelmet,
/obj/item/reagent_containers/food/snacks/grown/mushroom/chanterelle)
/obj/item/reagent_containers/food/snacks/grown/mushroom/chanterelle,
/obj/item/reagent_containers/food/snacks/faggot,
/obj/item/reagent_containers/food/snacks/grown/citrus/orange,
/obj/item/reagent_containers/food/snacks/grown/citrus/lemon,
/obj/item/reagent_containers/food/snacks/grown/citrus/lime,
/obj/item/reagent_containers/food/snacks/grown/bluecherries,
/obj/item/reagent_containers/food/snacks/grown/cocoapod,
/obj/item/reagent_containers/food/snacks/grown/vanillapod,
/obj/item/reagent_containers/food/snacks/grown/grapes,
/obj/item/reagent_containers/food/snacks/grown/strawberry,
/obj/item/reagent_containers/food/snacks/grown/whitebeet,
/obj/item/reagent_containers/food/snacks/meat/slab/bear,
/obj/item/reagent_containers/food/snacks/meat/slab/spider,
/obj/item/reagent_containers/food/snacks/spidereggs,
/obj/item/reagent_containers/food/snacks/carpmeat,
/obj/item/reagent_containers/food/snacks/meat/slab/xeno,
/obj/item/reagent_containers/food/snacks/meat/slab/corgi,
/obj/item/reagent_containers/food/snacks/grown/oat,
/obj/item/reagent_containers/food/snacks/grown/wheat,
/obj/item/reagent_containers/honeycomb,
/obj/item/reagent_containers/food/snacks/grown/watermelon,
/obj/item/reagent_containers/food/snacks/grown/onion,
/obj/item/reagent_containers/food/snacks/grown/peach,
/obj/item/reagent_containers/food/snacks/grown/peanut,
/obj/item/reagent_containers/food/snacks/grown/pineapple,
/obj/item/reagent_containers/food/snacks/grown/pumpkin,
/obj/item/reagent_containers/food/snacks/meat/rawcrab,
/obj/item/reagent_containers/food/snacks/meat/slab/goliath,
/obj/item/reagent_containers/food/snacks/meat/slab/chicken,
/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime,
/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/golem,
/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/lizard,
/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton,
/obj/item/reagent_containers/food/snacks/egg,
/obj/item/reagent_containers/food/snacks/grown/eggplant)
new randomFood(src)
/obj/item/storage/box/ingredients/fiesta
@@ -1061,6 +1096,15 @@
new /obj/item/reagent_containers/food/snacks/grown/cabbage(src)
new /obj/item/reagent_containers/food/snacks/grown/chili(src)
/obj/item/storage/box/ingredients/sushi
theme_name = "sushi"
/obj/item/storage/box/ingredients/sushi/PopulateContents()
for(var/i in 1 to 3)
new /obj/item/reagent_containers/food/snacks/sea_weed(src)
new /obj/item/reagent_containers/food/snacks/carpmeat(src)
new /obj/item/reagent_containers/food/snacks/meat/rawcrab(src)
/obj/item/storage/box/emptysandbags
name = "box of empty sandbags"
+1 -1
View File
@@ -15,7 +15,7 @@
attack_verb = list("beaten")
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80)
var/stamforce = 25
var/stamforce = 35
var/status = FALSE
var/knockdown = TRUE
var/obj/item/stock_parts/cell/cell
+1 -1
View File
@@ -1182,7 +1182,7 @@
if(iscyborg(target))
..()
return
if(target.run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user) & BLOCK_SUCCESS) //No message; check_shields() handles that
if(target.run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user) & BLOCK_SUCCESS) //No message; run_block() handles that
playsound(target, 'sound/weapons/genhit.ogg', 50, 1)
return FALSE
if(user.a_intent != INTENT_HARM)
+28 -2
View File
@@ -500,7 +500,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
icon_state = "catwhip"
/obj/item/melee/skateboard
name = "skateboard"
name = "improvised skateboard"
desc = "A skateboard. It can be placed on its wheels and ridden, or used as a strong weapon."
icon_state = "skateboard"
item_state = "skateboard"
@@ -508,11 +508,37 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
throwforce = 4
w_class = WEIGHT_CLASS_NORMAL
attack_verb = list("smacked", "whacked", "slammed", "smashed")
///The vehicle counterpart for the board
var/board_item_type = /obj/vehicle/ridden/scooter/skateboard
/obj/item/melee/skateboard/attack_self(mob/user)
new /obj/vehicle/ridden/scooter/skateboard(get_turf(user))
if(!user.canUseTopic(src, TRUE, FALSE, TRUE))
return
var/obj/vehicle/ridden/scooter/skateboard/S = new board_item_type(get_turf(user))
S.buckle_mob(user)
qdel(src)
/obj/item/melee/skateboard/pro
name = "skateboard"
desc = "A RaDSTORMz brand professional skateboard. It looks sturdy and well made."
icon_state = "skateboard2"
item_state = "skateboard2"
board_item_type = /obj/vehicle/ridden/scooter/skateboard/pro
/obj/item/melee/skateboard/hoverboard
name = "hoverboard"
desc = "A blast from the past, so retro!"
icon_state = "hoverboard_red"
item_state = "hoverboard_red"
board_item_type = /obj/vehicle/ridden/scooter/skateboard/hoverboard
/obj/item/melee/skateboard/hoverboard/admin
name = "\improper Board Of Directors"
desc = "The engineering complexity of a spaceship concentrated inside of a board. Just as expensive, too."
icon_state = "hoverboard_nt"
item_state = "hoverboard_nt"
board_item_type = /obj/vehicle/ridden/scooter/skateboard/hoverboard/admin
/obj/item/melee/baseball_bat
name = "baseball bat"
desc = "There ain't a skull in the league that can withstand a swatter."
+72 -6
View File
@@ -211,14 +211,80 @@
/obj/proc/check_uplink_validity()
return 1
/obj/proc/intercept_user_move(dir, mob, newLoc, oldLoc)
return
/obj/vv_get_dropdown()
. = ..()
.["Delete all of type"] = "?_src_=vars;[HrefToken()];delall=[REF(src)]"
.["Osay"] = "?_src_=vars;[HrefToken()];osay[REF(src)]"
.["Modify armor values"] = "?_src_=vars;[HrefToken()];modarmor=[REF(src)]"
VV_DROPDOWN_OPTION("", "---")
VV_DROPDOWN_OPTION(VV_HK_MASS_DEL_TYPE, "Delete all of type")
VV_DROPDOWN_OPTION(VV_HK_OSAY, "Object Say")
VV_DROPDOWN_OPTION(VV_HK_ARMOR_MOD, "Modify armor values")
/obj/vv_do_topic(list/href_list)
if(!(. = ..()))
return
if(href_list[VV_HK_OSAY])
if(check_rights(R_FUN, FALSE))
usr.client.object_say(src)
if(href_list[VV_HK_ARMOR_MOD])
var/list/pickerlist = list()
var/list/armorlist = armor.getList()
for (var/i in armorlist)
pickerlist += list(list("value" = armorlist[i], "name" = i))
var/list/result = presentpicker(usr, "Modify armor", "Modify armor: [src]", Button1="Save", Button2 = "Cancel", Timeout=FALSE, inputtype = "text", values = pickerlist)
if (islist(result))
if (result["button"] != 2) // If the user pressed the cancel button
// text2num conveniently returns a null on invalid values
armor = armor.setRating(melee = text2num(result["values"]["melee"]),\
bullet = text2num(result["values"]["bullet"]),\
laser = text2num(result["values"]["laser"]),\
energy = text2num(result["values"]["energy"]),\
bomb = text2num(result["values"]["bomb"]),\
bio = text2num(result["values"]["bio"]),\
rad = text2num(result["values"]["rad"]),\
fire = text2num(result["values"]["fire"]),\
acid = text2num(result["values"]["acid"]))
log_admin("[key_name(usr)] modified the armor on [src] ([type]) to melee: [armor.melee], bullet: [armor.bullet], laser: [armor.laser], energy: [armor.energy], bomb: [armor.bomb], bio: [armor.bio], rad: [armor.rad], fire: [armor.fire], acid: [armor.acid]")
message_admins("<span class='notice'>[key_name_admin(usr)] modified the armor on [src] ([type]) to melee: [armor.melee], bullet: [armor.bullet], laser: [armor.laser], energy: [armor.energy], bomb: [armor.bomb], bio: [armor.bio], rad: [armor.rad], fire: [armor.fire], acid: [armor.acid]</span>")
if(href_list[VV_HK_MASS_DEL_TYPE])
if(check_rights(R_DEBUG|R_SERVER))
var/action_type = alert("Strict type ([type]) or type and all subtypes?",,"Strict type","Type and subtypes","Cancel")
if(action_type == "Cancel" || !action_type)
return
if(alert("Are you really sure you want to delete all objects of type [type]?",,"Yes","No") != "Yes")
return
if(alert("Second confirmation required. Delete?",,"Yes","No") != "Yes")
return
var/O_type = type
switch(action_type)
if("Strict type")
var/i = 0
for(var/obj/Obj in world)
if(Obj.type == O_type)
i++
qdel(Obj)
CHECK_TICK
if(!i)
to_chat(usr, "No objects of this type exist")
return
log_admin("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ")
message_admins("<span class='notice'>[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) </span>")
if("Type and subtypes")
var/i = 0
for(var/obj/Obj in world)
if(istype(Obj,O_type))
i++
qdel(Obj)
CHECK_TICK
if(!i)
to_chat(usr, "No objects of this type exist")
return
log_admin("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ")
message_admins("<span class='notice'>[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) </span>")
/obj/examine(mob/user)
. = ..()
@@ -3,6 +3,7 @@
icon_state = "sofamiddle"
icon = 'icons/obj/sofa.dmi'
buildstackamount = 1
item_chair = null
var/mutable_appearance/armrest
/obj/structure/chair/sofa/Initialize()
@@ -121,7 +121,7 @@
return FALSE
var/turf/T = get_turf(src)
for(var/mob/living/L in T)
if(L.anchored || horizontal && L.mob_size > MOB_SIZE_TINY && L.density)
if(L.move_resist >= MOVE_FORCE_VERY_STRONG || (horizontal && L.mob_size > MOB_SIZE_TINY && L.density))
if(user)
to_chat(user, "<span class='danger'>There's something large on top of [src], preventing it from opening.</span>" )
return FALSE
@@ -133,7 +133,7 @@
if(closet != src && !closet.wall_mounted)
return FALSE
for(var/mob/living/L in T)
if(L.anchored || horizontal && L.mob_size > MOB_SIZE_TINY && L.density)
if(L.move_resist >= MOVE_FORCE_VERY_STRONG || horizontal && L.mob_size > MOB_SIZE_TINY && L.density)
if(user)
to_chat(user, "<span class='danger'>There's something too large in [src], preventing it from closing.</span>")
return FALSE
@@ -216,7 +216,7 @@
if(!isliving(AM)) //let's not put ghosts or camera mobs inside closets...
return FALSE
var/mob/living/L = AM
if(L.anchored || L.buckled || L.incorporeal_move || L.has_buckled_mobs())
if(L.move_resist >= MOVE_FORCE_VERY_STRONG || L.buckled || L.incorporeal_move || L.has_buckled_mobs())
return FALSE
if(L.mob_size > MOB_SIZE_TINY) // Tiny mobs are treated as items.
if(horizontal && L.density)
@@ -451,7 +451,7 @@
/obj/structure/closet/relaymove(mob/user)
if(user.stat || !isturf(loc) || !isliving(user))
return
if(locked)
if(locked || welded)
if(message_cooldown <= world.time)
message_cooldown = world.time + 50
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
@@ -243,6 +243,7 @@
//door.req_access = req_access
door.electronics = electronics
door.heat_proof = heat_proof_finished
door.security_level = 0
if(electronics.one_access)
door.req_one_access = electronics.accesses
else
@@ -114,7 +114,7 @@
airlock_type = /obj/machinery/door/airlock/highsecurity
noglass = TRUE
material_type = /obj/item/stack/sheet/plasteel
material_amt = 6
material_amt = 4
/obj/structure/door_assembly/door_assembly_vault
name = "vault door assembly"
@@ -124,7 +124,7 @@
airlock_type = /obj/machinery/door/airlock/vault
noglass = TRUE
material_type = /obj/item/stack/sheet/plasteel
material_amt = 8
material_amt = 6
/obj/structure/door_assembly/door_assembly_shuttle
name = "shuttle airlock assembly"
+1 -1
View File
@@ -73,7 +73,7 @@
H.socks_color = recolor_undergarment(H, "socks", H.socks_color)
add_fingerprint(H)
H.update_body()
H.update_body(TRUE)
/obj/structure/dresser/proc/recolor_undergarment(mob/living/carbon/human/H, garment_type = "underwear", default_color)
var/n_color = input(H, "Choose your [garment_type]'\s color.", "Character Preference", default_color) as color|null
@@ -31,7 +31,7 @@
new_spawn.underwear = "Nude" //You're a plant, partner
new_spawn.undershirt = "Nude" //changing underwear/shirt/socks doesn't seem to function correctly right now because of some bug elsewhere?
new_spawn.socks = "Nude"
new_spawn.update_body()
new_spawn.update_body(TRUE)
//Ash walker eggs: Spawns in ash walker dens in lavaland. Ghosts become unbreathing lizards that worship the Necropolis and are advised to retrieve corpses to create more ash walkers.
@@ -674,17 +674,14 @@
O.equip(new_spawn, FALSE, new_spawn.client)
SSjob.equip_loadout(null, new_spawn, FALSE)
SSquirks.AssignQuirks(new_spawn, new_spawn.client, TRUE, TRUE, null, FALSE, new_spawn)
new_spawn.AddElement(/datum/element/ghost_role_eligibility)
new_spawn.AddElement(/datum/element/ghost_role_eligibility, free_ghosting = TRUE)
new_spawn.AddElement(/datum/element/dusts_on_catatonia)
new_spawn.AddElement(/datum/element/dusts_on_leaving_area,list(A.type,/area/hilbertshotel))
ADD_TRAIT(new_spawn, TRAIT_SIXTHSENSE, GHOSTROLE_TRAIT)
ADD_TRAIT(new_spawn, TRAIT_EXEMPT_HEALTH_EVENTS, GHOSTROLE_TRAIT)
ADD_TRAIT(new_spawn, TRAIT_NO_MIDROUND_ANTAG, GHOSTROLE_TRAIT) //The mob can't be made into a random antag, they are still elegible for ghost roles popups.
ADD_TRAIT(new_spawn, TRAIT_NO_MIDROUND_ANTAG, GHOSTROLE_TRAIT) //The mob can't be made into a random antag, they are still eligible for ghost roles popups.
ADD_TRAIT(new_spawn, TRAIT_PACIFISM, GHOSTROLE_TRAIT)
to_chat(new_spawn,"<span class='boldwarning'>You may be sharing your cafe with some ninja-captured individuals, so make sure to only interact with the ghosts you hear as a ghost!</span>")
to_chat(new_spawn,"<span class='boldwarning'>You can turn yourself into a ghost and freely reenter your body with the ghost action.</span>")
var/datum/action/ghost/G = new(new_spawn)
G.Grant(new_spawn)
to_chat(new_spawn,"<span class='boldwarning'>Ghosting is free!</span>")
var/datum/action/toggle_dead_chat_mob/D = new(new_spawn)
D.Grant(new_spawn)
-383
View File
@@ -1,383 +0,0 @@
#define MUSICIAN_HEARCHECK_MINDELAY 4
#define MUSIC_MAXLINES 600
#define MUSIC_MAXLINECHARS 150
/datum/song
var/name = "Untitled"
var/list/lines = new()
var/tempo = 5 // delay between notes
var/playing = 0 // if we're playing
var/help = 0 // if help is open
var/edit = 1 // if we're in editing mode
var/repeat = 0 // number of times remaining to repeat
var/max_repeats = 10 // maximum times we can repeat
var/instrumentDir = "piano" // the folder with the sounds
var/instrumentExt = "ogg" // the file extension
var/obj/instrumentObj = null // the associated obj playing the sound
var/last_hearcheck = 0
var/list/hearing_mobs
/datum/song/New(dir, obj, ext = "ogg")
tempo = sanitize_tempo(tempo)
instrumentDir = dir
instrumentObj = obj
instrumentExt = ext
/datum/song/Destroy()
instrumentObj = null
return ..()
// note is a number from 1-7 for A-G
// acc is either "b", "n", or "#"
// oct is 1-8 (or 9 for C)
/datum/song/proc/playnote(note, acc as text, oct)
// handle accidental -> B<>C of E<>F
if(acc == "b" && (note == 3 || note == 6)) // C or F
if(note == 3)
oct--
note--
acc = "n"
else if(acc == "#" && (note == 2 || note == 5)) // B or E
if(note == 2)
oct++
note++
acc = "n"
else if(acc == "#" && (note == 7)) //G#
note = 1
acc = "b"
else if(acc == "#") // mass convert all sharps to flats, octave jump already handled
acc = "b"
note++
// check octave, C is allowed to go to 9
if(oct < 1 || (note == 3 ? oct > 9 : oct > 8))
return
// now generate name
var/soundfile = "sound/instruments/[instrumentDir]/[ascii2text(note+64)][acc][oct].[instrumentExt]"
soundfile = file(soundfile)
// make sure the note exists
if(!fexists(soundfile))
return
// and play
var/turf/source = get_turf(instrumentObj)
if((world.time - MUSICIAN_HEARCHECK_MINDELAY) > last_hearcheck)
LAZYCLEARLIST(hearing_mobs)
for(var/mob/M in get_hearers_in_view(15, source))
if(!M.client || !(M.client.prefs.toggles & SOUND_INSTRUMENTS))
continue
LAZYADD(hearing_mobs, M)
last_hearcheck = world.time
var/sound/music_played = sound(soundfile)
for(var/i in hearing_mobs)
var/mob/M = i
M.playsound_local(source, null, 100, falloff = 5, S = music_played)
/datum/song/proc/updateDialog(mob/user)
instrumentObj.updateDialog() // assumes it's an object in world, override if otherwise
/datum/song/proc/shouldStopPlaying(mob/user)
if(instrumentObj)
if(!user.canUseTopic(instrumentObj, TRUE, FALSE, FALSE, FALSE))
return TRUE
return !instrumentObj.anchored // add special cases to stop in subclasses
else
return TRUE
/datum/song/proc/playsong(mob/user)
while(repeat >= 0)
var/cur_oct[7]
var/cur_acc[7]
for(var/i = 1 to 7)
cur_oct[i] = 3
cur_acc[i] = "n"
for(var/line in lines)
for(var/beat in splittext(lowertext(line), ","))
var/list/notes = splittext(beat, "/")
for(var/note in splittext(notes[1], "-"))
if(!playing || shouldStopPlaying(user))//If the instrument is playing, or special case
playing = FALSE
hearing_mobs = null
return
if(!length(note))
continue
var/cur_note = text2ascii(note) - 96
if(cur_note < 1 || cur_note > 7)
continue
var/notelen = length(note)
var/ni = ""
for(var/i = length(note[1]) + 1, i <= notelen, i += length(ni))
ni = note[i]
if(!text2num(ni))
if(ni == "#" || ni == "b" || ni == "n")
cur_acc[cur_note] = ni
else if(ni == "s")
cur_acc[cur_note] = "#" // so shift is never required
else
cur_oct[cur_note] = text2num(ni)
if(user.dizziness > 0 && prob(user.dizziness / 2))
cur_note = CLAMP(cur_note + rand(round(-user.dizziness / 10), round(user.dizziness / 10)), 1, 7)
if(user.dizziness > 0 && prob(user.dizziness / 5))
if(prob(30))
cur_acc[cur_note] = "#"
else if(prob(42))
cur_acc[cur_note] = "b"
else if(prob(75))
cur_acc[cur_note] = "n"
playnote(cur_note, cur_acc[cur_note], cur_oct[cur_note])
if(notes.len >= 2 && text2num(notes[2]))
sleep(sanitize_tempo(tempo / text2num(notes[2])))
else
sleep(tempo)
repeat--
hearing_mobs = null
playing = FALSE
repeat = 0
updateDialog(user)
/datum/song/proc/interact(mob/user)
var/dat = ""
if(lines.len > 0)
dat += "<H3>Playback</H3>"
if(!playing)
dat += "<A href='?src=[REF(src)];play=1'>Play</A> <SPAN CLASS='linkOn'>Stop</SPAN><BR><BR>"
dat += "Repeat Song: "
dat += repeat > 0 ? "<A href='?src=[REF(src)];repeat=-10'>-</A><A href='?src=[REF(src)];repeat=-1'>-</A>" : "<SPAN CLASS='linkOff'>-</SPAN><SPAN CLASS='linkOff'>-</SPAN>"
dat += " [repeat] times "
dat += repeat < max_repeats ? "<A href='?src=[REF(src)];repeat=1'>+</A><A href='?src=[REF(src)];repeat=10'>+</A>" : "<SPAN CLASS='linkOff'>+</SPAN><SPAN CLASS='linkOff'>+</SPAN>"
dat += "<BR>"
else
dat += "<SPAN CLASS='linkOn'>Play</SPAN> <A href='?src=[REF(src)];stop=1'>Stop</A><BR>"
dat += "Repeats left: <B>[repeat]</B><BR>"
if(!edit)
dat += "<BR><B><A href='?src=[REF(src)];edit=2'>Show Editor</A></B><BR>"
else
dat += "<H3>Editing</H3>"
dat += "<B><A href='?src=[REF(src)];edit=1'>Hide Editor</A></B>"
dat += " <A href='?src=[REF(src)];newsong=1'>Start a New Song</A>"
dat += " <A href='?src=[REF(src)];import=1'>Import a Song</A><BR><BR>"
var/bpm = round(600 / tempo)
dat += "Tempo: <A href='?src=[REF(src)];tempo=[world.tick_lag]'>-</A> [bpm] BPM <A href='?src=[REF(src)];tempo=-[world.tick_lag]'>+</A><BR><BR>"
var/linecount = 0
for(var/line in lines)
linecount += 1
dat += "Line [linecount]: <A href='?src=[REF(src)];modifyline=[linecount]'>Edit</A> <A href='?src=[REF(src)];deleteline=[linecount]'>X</A> [line]<BR>"
dat += "<A href='?src=[REF(src)];newline=1'>Add Line</A><BR><BR>"
if(help)
dat += "<B><A href='?src=[REF(src)];help=1'>Hide Help</A></B><BR>"
dat += {"
Lines are a series of chords, separated by commas (,), each with notes separated by hyphens (-).<br>
Every note in a chord will play together, with chord timed by the tempo.<br>
<br>
Notes are played by the names of the note, and optionally, the accidental, and/or the octave number.<br>
By default, every note is natural and in octave 3. Defining otherwise is remembered for each note.<br>
Example: <i>C,D,E,F,G,A,B</i> will play a C major scale.<br>
After a note has an accidental placed, it will be remembered: <i>C,C4,C,C3</i> is <i>C3,C4,C4,C3</i><br>
Chords can be played simply by seperating each note with a hyphon: <i>A-C#,Cn-E,E-G#,Gn-B</i><br>
A pause may be denoted by an empty chord: <i>C,E,,C,G</i><br>
To make a chord be a different time, end it with /x, where the chord length will be length<br>
defined by tempo / x: <i>C,G/2,E/4</i><br>
Combined, an example is: <i>E-E4/4,F#/2,G#/8,B/8,E3-E4/4</i>
<br>
Lines may be up to [MUSIC_MAXLINECHARS] characters.<br>
A song may only contain up to [MUSIC_MAXLINES] lines.<br>
"}
else
dat += "<B><A href='?src=[REF(src)];help=2'>Show Help</A></B><BR>"
var/datum/browser/popup = new(user, "instrument", instrumentObj.name, 700, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(instrumentObj.icon, instrumentObj.icon_state))
popup.open()
/datum/song/proc/ParseSong(text)
set waitfor = FALSE
//split into lines
lines = splittext(text, "\n")
if(lines.len)
var/bpm_string = "BPM: "
if(findtext(lines[1], bpm_string, 1, length(bpm_string) + 1))
var/divisor = text2num(copytext(lines[1], length(bpm_string) + 1)) || 120 // default
tempo = sanitize_tempo(600 / round(divisor, 1))
lines.Cut(1, 2)
else
tempo = sanitize_tempo(5) // default 120 BPM
if(lines.len > MUSIC_MAXLINES)
to_chat(usr, "Too many lines!")
lines.Cut(MUSIC_MAXLINES + 1)
var/linenum = 1
for(var/l in lines)
if(length_char(l) > MUSIC_MAXLINECHARS)
to_chat(usr, "Line [linenum] too long!")
lines.Remove(l)
else
linenum++
updateDialog(usr) // make sure updates when complete
/datum/song/Topic(href, href_list)
if(!usr.canUseTopic(instrumentObj, TRUE, FALSE, FALSE, FALSE))
usr << browse(null, "window=instrument")
usr.unset_machine()
return
instrumentObj.add_fingerprint(usr)
if(href_list["newsong"])
lines = new()
tempo = sanitize_tempo(5) // default 120 BPM
name = ""
else if(href_list["import"])
var/t = ""
do
t = html_encode(input(usr, "Please paste the entire song, formatted:", text("[]", name), t) as message)
if(!in_range(instrumentObj, usr))
return
if(length_char(t) >= MUSIC_MAXLINES * MUSIC_MAXLINECHARS)
var/cont = input(usr, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no")
if(cont == "no")
break
while(length_char(t) > MUSIC_MAXLINES * MUSIC_MAXLINECHARS)
ParseSong(t)
else if(href_list["help"])
help = text2num(href_list["help"]) - 1
else if(href_list["edit"])
edit = text2num(href_list["edit"]) - 1
if(href_list["repeat"]) //Changing this from a toggle to a number of repeats to avoid infinite loops.
if(playing)
return //So that people cant keep adding to repeat. If the do it intentionally, it could result in the server crashing.
repeat += round(text2num(href_list["repeat"]))
if(repeat < 0)
repeat = 0
if(repeat > max_repeats)
repeat = max_repeats
else if(href_list["tempo"])
tempo = sanitize_tempo(tempo + text2num(href_list["tempo"]))
else if(href_list["play"])
playing = TRUE
spawn()
playsong(usr)
else if(href_list["newline"])
var/newline = html_encode(input("Enter your line: ", instrumentObj.name) as text|null)
if(!newline || !in_range(instrumentObj, usr))
return
if(lines.len > MUSIC_MAXLINES)
return
if(length(newline) > MUSIC_MAXLINECHARS)
newline = copytext(newline, 1, MUSIC_MAXLINECHARS)
lines.Add(newline)
else if(href_list["deleteline"])
var/num = round(text2num(href_list["deleteline"]))
if(num > lines.len || num < 1)
return
lines.Cut(num, num+1)
else if(href_list["modifyline"])
var/num = round(text2num(href_list["modifyline"]),1)
var/content = stripped_input(usr, "Enter your line: ", instrumentObj.name, lines[num], MUSIC_MAXLINECHARS)
if(!content || !in_range(instrumentObj, usr))
return
if(num > lines.len || num < 1)
return
lines[num] = content
else if(href_list["stop"])
playing = FALSE
hearing_mobs = null
updateDialog(usr)
return
/datum/song/proc/sanitize_tempo(new_tempo)
new_tempo = abs(new_tempo)
return max(round(new_tempo, world.tick_lag), world.tick_lag)
// subclass for handheld instruments, like violin
/datum/song/handheld
/datum/song/handheld/updateDialog(mob/user)
instrumentObj.interact(user)
/datum/song/handheld/shouldStopPlaying()
if(instrumentObj)
return !isliving(instrumentObj.loc)
else
return TRUE
//////////////////////////////////////////////////////////////////////////
/obj/structure/piano
name = "space minimoog"
icon = 'icons/obj/musician.dmi'
icon_state = "minimoog"
anchored = TRUE
density = TRUE
var/datum/song/song
/obj/structure/piano/unanchored
anchored = FALSE
/obj/structure/piano/New()
..()
song = new("piano", src)
if(prob(50) && icon_state == initial(icon_state))
name = "space minimoog"
desc = "This is a minimoog, like a space piano, but more spacey!"
icon_state = "minimoog"
else
name = "space piano"
desc = "This is a space piano, like a regular piano, but always in tune! Even if the musician isn't."
icon_state = "piano"
/obj/structure/piano/Destroy()
qdel(song)
song = null
return ..()
/obj/structure/piano/Initialize(mapload)
. = ..()
if(mapload)
song.tempo = song.sanitize_tempo(song.tempo) // tick_lag isn't set when the map is loaded
/obj/structure/piano/attack_hand(mob/user)
. = ..()
if(.)
return
interact(user)
/obj/structure/piano/attack_paw(mob/user)
return attack_hand(user)
/obj/structure/piano/interact(mob/user)
ui_interact(user)
/obj/structure/piano/ui_interact(mob/user)
if(!user || !anchored)
return
if(!user.IsAdvancedToolUser())
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return 1
user.set_machine(src)
song.interact(user)
/obj/structure/piano/wrench_act(mob/living/user, obj/item/I)
default_unfasten_wrench(user, I, 40)
return TRUE
+1 -1
View File
@@ -89,7 +89,7 @@ FLOOR SAFES
var/obj/item/P = contents[i]
dat += "<tr><td><a href='?src=[REF(src)];retrieve=[REF(P)]'>[P.name]</a></td></tr>"
dat += "</table></center>"
user << browse("<html><head><title>[name]</title></head><body>[dat]</body></html>", "window=safe;size=350x300")
user << browse("<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>[name]</title></head><body>[dat]</body></html>", "window=safe;size=350x300")
/obj/structure/safe/Topic(href, href_list)
if(!ishuman(usr))
@@ -60,6 +60,11 @@
desc = "A sign labelling a restroom."
icon_state = "restroom"
/obj/structure/sign/departments/showers
name ="\improper SHOWER"
desc = "A sign labelling showers."
icon_state = "showerroom"
/obj/structure/sign/departments/medbay
name = "\improper MEDBAY"
desc = "The Intergalactic symbol of Medical institutions. You'll probably get help here."
@@ -55,3 +55,18 @@
name = "cafe"
desc = "A direction sign, pointing out which way the Cafe is."
icon_state = "direction_cafe"
obj/structure/sign/directions/rooms
name = "room"
desc = "Room numbers, helps others find you!"
icon_state = "roomnum"
obj/structure/sign/directions/dorms
name = "dorm"
desc = "Dorm numbers, help others find you, or you find others."
icon_state = "dormnum"
obj/structure/sign/directions/cells
name = "room"
desc = "So the less fortunate amongst us know where they'll be staying."
icon_state = "cellnum"
+6 -12
View File
@@ -12,13 +12,11 @@
var/w_items = 0 //the combined w_class of all the items in the cistern
var/mob/living/swirlie = null //the mob being given a swirlie
/obj/structure/toilet/Initialize()
. = ..()
open = round(rand(0, 1))
update_icon()
/obj/structure/toilet/attack_hand(mob/living/user)
. = ..()
if(.)
@@ -71,11 +69,9 @@
open = !open
update_icon()
/obj/structure/toilet/update_icon_state()
icon_state = "toilet[open][cistern]"
/obj/structure/toilet/attackby(obj/item/I, mob/living/user, params)
if(istype(I, /obj/item/crowbar))
to_chat(user, "<span class='notice'>You start to [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"]...</span>")
@@ -120,8 +116,14 @@
w_items += secret.w_class
contents += secret
/obj/structure/toilet/secret/prison
secret_type = /obj/effect/spawner/lootdrop/prison_loot_toilet
/obj/structure/toilet/secret/low_loot
secret_type = /obj/effect/spawner/lootdrop/low_loot_toilet
/obj/structure/toilet/secret/high_loot
secret_type = /obj/effect/spawner/lootdrop/high_loot_toilet
/obj/structure/urinal
name = "urinal"
@@ -194,7 +196,6 @@
exposed = !exposed
return TRUE
/obj/item/reagent_containers/food/urinalcake
name = "urinal cake"
desc = "The noble urinal cake, protecting the station's pipes from the station's pee. Do not eat."
@@ -278,7 +279,6 @@
add_hiddenprint(user)
return TRUE
/obj/machinery/shower/update_overlays()
. = ..()
if(on)
@@ -315,7 +315,6 @@
else if(isobj(AM))
wash_obj(AM)
/obj/machinery/shower/proc/wash_obj(obj/O)
. = SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
. = O.clean_blood()
@@ -325,7 +324,6 @@
I.acid_level = 0
I.extinguish()
/obj/machinery/shower/proc/wash_turf()
if(isturf(loc))
var/turf/tile = loc
@@ -336,7 +334,6 @@
if(is_cleanable(E))
qdel(E)
/obj/machinery/shower/proc/wash_mob(mob/living/L)
SEND_SIGNAL(L, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
L.wash_cream()
@@ -667,11 +664,9 @@
/obj/structure/sink/puddle/deconstruct(disassembled = TRUE)
qdel(src)
//Shower Curtains//
//Defines used are pre-existing in layers.dm//
/obj/structure/curtain
name = "curtain"
desc = "Contains less than 1% mercury."
@@ -727,7 +722,6 @@
return TRUE
/obj/structure/curtain/attack_hand(mob/user)
. = ..()
if(.)