mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-14 00:23:29 +01:00
fixes merge conflict
This commit is contained in:
@@ -58,7 +58,7 @@
|
||||
icon_state = "eggs"
|
||||
var/amount_grown = 0
|
||||
var/player_spiders = 0
|
||||
var/list/faction = list()
|
||||
var/list/faction = list("spiders")
|
||||
|
||||
/obj/structure/spider/eggcluster/New()
|
||||
..()
|
||||
@@ -90,7 +90,7 @@
|
||||
var/obj/machinery/atmospherics/unary/vent_pump/entry_vent
|
||||
var/travelling_in_vent = 0
|
||||
var/player_spiders = 0
|
||||
var/list/faction = list()
|
||||
var/list/faction = list("spiders")
|
||||
var/selecting_player = 0
|
||||
|
||||
/obj/structure/spider/spiderling/New()
|
||||
@@ -180,7 +180,7 @@
|
||||
if(player_spiders && !selecting_player)
|
||||
selecting_player = 1
|
||||
spawn()
|
||||
var/list/candidates = pollCandidates("Do you want to play as a spider?", ROLE_GSPIDER, 1)
|
||||
var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a giant spider?", ROLE_GSPIDER, TRUE, source = S)
|
||||
|
||||
if(candidates.len)
|
||||
var/mob/C = pick(candidates)
|
||||
|
||||
@@ -2,6 +2,8 @@ GLOBAL_DATUM_INIT(fire_overlay, /image, image("icon" = 'icons/goonstation/effect
|
||||
/obj/item
|
||||
name = "item"
|
||||
icon = 'icons/obj/items.dmi'
|
||||
|
||||
move_resist = null // Set in the Initialise depending on the item size. Unless it's overriden by a specific item
|
||||
var/discrete = 0 // used in item_attack.dm to make an item not show an attack message to viewers
|
||||
var/image/blood_overlay = null //this saves our blood splatter overlay, which will be processed not to go over the edges of the sprite
|
||||
var/blood_overlay_color = null
|
||||
@@ -113,6 +115,23 @@ GLOBAL_DATUM_INIT(fire_overlay, /image, image("icon" = 'icons/goonstation/effect
|
||||
hitsound = 'sound/items/welder.ogg'
|
||||
if(damtype == "brute")
|
||||
hitsound = "swing_hit"
|
||||
if(!move_resist)
|
||||
determine_move_resist()
|
||||
|
||||
/obj/item/proc/determine_move_resist()
|
||||
switch(w_class)
|
||||
if(WEIGHT_CLASS_TINY)
|
||||
move_resist = MOVE_FORCE_EXTREMELY_WEAK
|
||||
if(WEIGHT_CLASS_SMALL)
|
||||
move_resist = MOVE_FORCE_VERY_WEAK
|
||||
if(WEIGHT_CLASS_NORMAL)
|
||||
move_resist = MOVE_FORCE_WEAK
|
||||
if(WEIGHT_CLASS_BULKY)
|
||||
move_resist = MOVE_FORCE_NORMAL
|
||||
if(WEIGHT_CLASS_HUGE)
|
||||
move_resist = MOVE_FORCE_NORMAL
|
||||
if(WEIGHT_CLASS_GIGANTIC)
|
||||
move_resist = MOVE_FORCE_NORMAL
|
||||
|
||||
/obj/item/Destroy()
|
||||
flags &= ~DROPDEL //prevent reqdels
|
||||
|
||||
@@ -221,6 +221,12 @@
|
||||
A.contents += thing
|
||||
thing.change_area(old_area, A)
|
||||
|
||||
var/area/oldA = get_area(get_turf(usr))
|
||||
var/list/firedoors = oldA.firedoors
|
||||
for(var/door in firedoors)
|
||||
var/obj/machinery/door/firedoor/FD = door
|
||||
FD.CalculateAffectingAreas()
|
||||
|
||||
interact()
|
||||
area_created = TRUE
|
||||
return area_created
|
||||
@@ -236,6 +242,10 @@
|
||||
return
|
||||
set_area_machinery_title(A,str,prevname)
|
||||
A.name = str
|
||||
if(A.firedoors)
|
||||
for(var/D in A.firedoors)
|
||||
var/obj/machinery/door/firedoor/FD = D
|
||||
FD.CalculateAffectingAreas()
|
||||
to_chat(usr, "<span class='notice'>You rename the '[prevname]' to '[str]'.</span>")
|
||||
interact()
|
||||
return 1
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
slot_flags = SLOT_BELT | SLOT_EARS
|
||||
attack_verb = list("attacked", "coloured")
|
||||
toolspeed = 1
|
||||
var/colour = "#FF0000" //RGB
|
||||
var/colour = COLOR_RED
|
||||
var/drawtype = "rune"
|
||||
var/list/graffiti = list("body","amyjon","face","matt","revolution","engie","guy","end","dwarf","uboa","up","down","left","right","heart","borgsrogue","voxpox","shitcurity","catbeast","hieroglyphs1","hieroglyphs2","hieroglyphs3","security","syndicate1","syndicate2","nanotrasen","lie","valid","arrowleft","arrowright","arrowup","arrowdown","chicken","hailcrab","brokenheart","peace","scribble","scribble2","scribble3","skrek","squish","tunnelsnake","yip","youaredead")
|
||||
var/list/letters = list("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z")
|
||||
@@ -123,54 +123,54 @@
|
||||
|
||||
/obj/item/toy/crayon/red
|
||||
icon_state = "crayonred"
|
||||
colour = "#DA0000"
|
||||
colour = COLOR_RED
|
||||
colourName = "red"
|
||||
|
||||
/obj/item/toy/crayon/orange
|
||||
icon_state = "crayonorange"
|
||||
colour = "#FF9300"
|
||||
colour = COLOR_ORANGE
|
||||
colourName = "orange"
|
||||
|
||||
/obj/item/toy/crayon/yellow
|
||||
icon_state = "crayonyellow"
|
||||
colour = "#FFF200"
|
||||
colour = COLOR_YELLOW
|
||||
colourName = "yellow"
|
||||
|
||||
/obj/item/toy/crayon/green
|
||||
icon_state = "crayongreen"
|
||||
colour = "#A8E61D"
|
||||
colour = COLOR_GREEN
|
||||
colourName = "green"
|
||||
|
||||
/obj/item/toy/crayon/blue
|
||||
icon_state = "crayonblue"
|
||||
colour = "#00B7EF"
|
||||
colour = COLOR_BLUE
|
||||
colourName = "blue"
|
||||
|
||||
/obj/item/toy/crayon/purple
|
||||
icon_state = "crayonpurple"
|
||||
colour = "#DA00FF"
|
||||
colour = COLOR_PURPLE
|
||||
colourName = "purple"
|
||||
|
||||
/obj/item/toy/crayon/random/New()
|
||||
icon_state = pick(list("crayonred", "crayonorange", "crayonyellow", "crayongreen", "crayonblue", "crayonpurple"))
|
||||
switch(icon_state)
|
||||
if("crayonred")
|
||||
colour = "#DA0000"
|
||||
colour = COLOR_RED
|
||||
colourName = "red"
|
||||
if("crayonorange")
|
||||
colour = "#FF9300"
|
||||
colour = COLOR_ORANGE
|
||||
colourName = "orange"
|
||||
if("crayonyellow")
|
||||
colour = "#FFF200"
|
||||
colour = COLOR_YELLOW
|
||||
colourName = "yellow"
|
||||
if("crayongreen")
|
||||
colour = "#A8E61D"
|
||||
colour =COLOR_GREEN
|
||||
colourName = "green"
|
||||
if("crayonblue")
|
||||
colour = "#00B7EF"
|
||||
colour = COLOR_BLUE
|
||||
colourName = "blue"
|
||||
if("crayonpurple")
|
||||
colour = "#DA00FF"
|
||||
colour = COLOR_PURPLE
|
||||
colourName = "purple"
|
||||
..()
|
||||
|
||||
@@ -197,10 +197,10 @@
|
||||
if(!Adjacent(usr) || usr.incapacitated())
|
||||
return
|
||||
if(href_list["color"])
|
||||
if(colour != "#FFFFFF")
|
||||
colour = "#FFFFFF"
|
||||
if(colour != COLOR_WHITE)
|
||||
colour = COLOR_WHITE
|
||||
else
|
||||
colour = "#000000"
|
||||
colour = COLOR_BLACK
|
||||
update_window(usr)
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -1,192 +0,0 @@
|
||||
//copy pasta of the space piano, don't hurt me -Pete
|
||||
/obj/item/instrument
|
||||
name = "generic instrument"
|
||||
icon = 'icons/obj/musician.dmi'
|
||||
lefthand_file = 'icons/mob/inhands/equipment/instruments_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/instruments_righthand.dmi'
|
||||
resistance_flags = FLAMMABLE
|
||||
max_integrity = 100
|
||||
var/datum/song/handheld/song
|
||||
var/instrumentId = "generic"
|
||||
var/instrumentExt = "mid"
|
||||
|
||||
/obj/item/instrument/New()
|
||||
song = new(instrumentId, src, instrumentExt)
|
||||
..()
|
||||
|
||||
/obj/item/instrument/Destroy()
|
||||
QDEL_NULL(song)
|
||||
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)
|
||||
song.tempo = song.sanitize_tempo(song.tempo) // tick_lag isn't set when the map is loaded
|
||||
..()
|
||||
|
||||
/obj/item/instrument/attack_self(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/item/instrument/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1)
|
||||
if(!isliving(user) || user.incapacitated())
|
||||
return
|
||||
|
||||
song.ui_interact(user, ui_key, ui, force_open)
|
||||
|
||||
/obj/item/instrument/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state)
|
||||
return song.ui_data(user, ui_key, state)
|
||||
|
||||
/obj/item/instrument/Topic(href, href_list)
|
||||
song.Topic(href, href_list)
|
||||
|
||||
/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"
|
||||
instrumentExt = "ogg"
|
||||
force = 10
|
||||
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", "glockenspiel" = "mid", "guitar" = "ogg", "eguitar" = "ogg", "harmonica" = "mid", "piano" = "ogg", "recorder" = "mid", "saxophone" = "mid", "trombone" = "mid", "violin" = "ogg", "xylophone" = "mid")
|
||||
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/guitar
|
||||
name = "guitar"
|
||||
desc = "It's made of wood and has bronze strings."
|
||||
icon_state = "guitar"
|
||||
item_state = "guitar"
|
||||
instrumentExt = "ogg"
|
||||
force = 10
|
||||
attack_verb = list("played metal on", "serenaded", "crashed", "smashed")
|
||||
hitsound = 'sound/effects/guitarsmash.ogg'
|
||||
instrumentId = "guitar"
|
||||
|
||||
/obj/item/instrument/eguitar
|
||||
name = "electric guitar"
|
||||
desc = "Makes all your shredding needs possible."
|
||||
icon_state = "eguitar"
|
||||
item_state = "eguitar"
|
||||
instrumentExt = "ogg"
|
||||
force = 12
|
||||
attack_verb = list("played metal on", "shredded", "crashed", "smashed")
|
||||
hitsound = 'sound/weapons/stringsmash.ogg'
|
||||
instrumentId = "eguitar"
|
||||
|
||||
/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/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/trombone
|
||||
name = "trombone"
|
||||
desc = "How can any pool table ever hope to compete?"
|
||||
icon_state = "trombone"
|
||||
item_state = "trombone"
|
||||
instrumentId = "trombone"
|
||||
|
||||
/obj/item/instrument/recorder
|
||||
name = "recorder"
|
||||
desc = "Just like in school, playing ability and all."
|
||||
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"
|
||||
force = 5
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/instrument/xylophone
|
||||
name = "xylophone"
|
||||
desc = "a percussion instrument with a bright tone."
|
||||
icon_state = "xylophone"
|
||||
item_state = "xylophone"
|
||||
instrumentId = "xylophone"
|
||||
|
||||
/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/items_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
|
||||
attack_verb = list("beautifully honks")
|
||||
instrumentId = "bikehorn"
|
||||
instrumentExt = "ogg"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
force = 0
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
hitsound = 'sound/items/bikehorn.ogg'
|
||||
|
||||
/datum/crafting_recipe/violin
|
||||
name = "Violin"
|
||||
result = /obj/item/instrument/violin
|
||||
reqs = list(/obj/item/stack/sheet/wood = 5,
|
||||
/obj/item/stack/cable_coil = 6,
|
||||
/obj/item/stack/tape_roll = 5)
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
|
||||
time = 80
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/guitar
|
||||
name = "Guitar"
|
||||
result = /obj/item/instrument/guitar
|
||||
reqs = list(/obj/item/stack/sheet/wood = 5,
|
||||
/obj/item/stack/cable_coil = 6,
|
||||
/obj/item/stack/tape_roll = 5)
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
|
||||
time = 80
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/eguitar
|
||||
name = "Electric Guitar"
|
||||
result = /obj/item/instrument/eguitar
|
||||
reqs = list(/obj/item/stack/sheet/metal = 5,
|
||||
/obj/item/stack/cable_coil = 6,
|
||||
/obj/item/stack/tape_roll = 5)
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
|
||||
time = 80
|
||||
category = CAT_MISC
|
||||
@@ -191,7 +191,7 @@
|
||||
if(CanUse(U))
|
||||
if(!Use(U))
|
||||
return
|
||||
to_chat(U, "<span class='notice'>You replace [target.fitting] with [src].</span>")
|
||||
to_chat(U, "<span class='notice'>You replace the light [target.fitting] with [src].</span>")
|
||||
|
||||
if(target.status != LIGHT_EMPTY)
|
||||
AddShards(1, U)
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
materials = list(MAT_METAL=10000, MAT_GLASS=2500)
|
||||
var/code = 2
|
||||
|
||||
is_special = 1
|
||||
|
||||
/obj/item/radio/electropack/attack_hand(mob/user as mob)
|
||||
if(src == user.back)
|
||||
to_chat(user, "<span class='notice'>You need help taking this off!</span>")
|
||||
@@ -54,23 +52,6 @@
|
||||
if(src.flags & NODROP)
|
||||
A.flags |= NODROP
|
||||
|
||||
/obj/item/radio/electropack/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["freq"])
|
||||
var/new_frequency = sanitize_frequency(frequency + text2num(href_list["freq"]))
|
||||
set_frequency(new_frequency)
|
||||
|
||||
else if(href_list["code"])
|
||||
code += text2num(href_list["code"])
|
||||
code = round(code)
|
||||
code = clamp(code, 1, 100)
|
||||
|
||||
else if(href_list["power"])
|
||||
on = !on
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
/obj/item/radio/electropack/receive_signal(datum/signal/signal)
|
||||
if(!signal || signal.encryption != code)
|
||||
@@ -96,18 +77,48 @@
|
||||
return
|
||||
|
||||
|
||||
/obj/item/radio/electropack/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/item/radio/electropack/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_inventory_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "radio_electro.tmpl", "[name]", 400, 500)
|
||||
ui = new(user, src, ui_key, "Electropack", name, 360, 150, master_ui, state)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/item/radio/electropack/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state)
|
||||
var/data[0]
|
||||
|
||||
/obj/item/radio/electropack/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["power"] = on
|
||||
data["freq"] = format_frequency(frequency)
|
||||
data["frequency"] = frequency
|
||||
data["code"] = code
|
||||
|
||||
data["minFrequency"] = PUBLIC_LOW_FREQ
|
||||
data["maxFrequency"] = PUBLIC_HIGH_FREQ
|
||||
return data
|
||||
|
||||
/obj/item/radio/electropack/tgui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
. = TRUE
|
||||
switch(action)
|
||||
if("power")
|
||||
on = !on
|
||||
if("freq")
|
||||
var/value = params["freq"]
|
||||
if(value)
|
||||
frequency = sanitize_frequency(value)
|
||||
set_frequency(frequency)
|
||||
else
|
||||
. = FALSE
|
||||
if("code")
|
||||
var/value = text2num(params["code"])
|
||||
if(value)
|
||||
value = round(value)
|
||||
code = clamp(value, 1, 100)
|
||||
else
|
||||
. = FALSE
|
||||
if("reset")
|
||||
if(params["reset"] == "freq")
|
||||
frequency = initial(frequency)
|
||||
else if(params["reset"] == "code")
|
||||
code = initial(code)
|
||||
else
|
||||
. = FALSE
|
||||
if(.)
|
||||
add_fingerprint(usr)
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
"Vox Armalis" = 'icons/mob/species/armalis/ears.dmi'
|
||||
) //We read you loud and skree-er.
|
||||
materials = list(MAT_METAL=75)
|
||||
subspace_transmission = TRUE
|
||||
canhear_range = 0 // can't hear headsets from very far away
|
||||
|
||||
slot_flags = SLOT_EARS
|
||||
@@ -91,6 +90,7 @@
|
||||
ks1type = /obj/item/encryptionkey/syndicate/nukeops
|
||||
requires_tcomms = FALSE
|
||||
instant = TRUE // Work instantly if there are no comms
|
||||
freqlock = TRUE
|
||||
|
||||
/obj/item/radio/headset/syndicate/alt //undisguised bowman with flash protection
|
||||
name = "syndicate headset"
|
||||
@@ -289,6 +289,7 @@
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/ert
|
||||
freqlock = TRUE
|
||||
|
||||
/obj/item/radio/headset/ert/alt
|
||||
name = "\proper emergency response team's bowman headset"
|
||||
@@ -367,7 +368,7 @@
|
||||
else
|
||||
to_chat(user, "This headset doesn't have any encryption keys! How useless...")
|
||||
|
||||
/obj/item/radio/headset/proc/recalculateChannels(var/setDescription = FALSE)
|
||||
/obj/item/radio/headset/recalculateChannels(setDescription = FALSE)
|
||||
channels = list()
|
||||
translate_binary = FALSE
|
||||
translate_hive = FALSE
|
||||
|
||||
@@ -75,7 +75,6 @@
|
||||
name = "illicit intercom"
|
||||
desc = "Talk through this. Evilly"
|
||||
frequency = SYND_FREQ
|
||||
subspace_transmission = TRUE
|
||||
syndiekey = new /obj/item/encryptionkey/syndicate/nukeops
|
||||
|
||||
/obj/item/radio/intercom/syndicate/New()
|
||||
@@ -85,7 +84,6 @@
|
||||
/obj/item/radio/intercom/pirate
|
||||
name = "pirate radio intercom"
|
||||
desc = "You wouldn't steal a space shuttle. Piracy. It's a crime!"
|
||||
subspace_transmission = 1
|
||||
|
||||
/obj/item/radio/intercom/pirate/New()
|
||||
..()
|
||||
@@ -109,13 +107,13 @@
|
||||
GLOB.global_intercoms.Remove(src)
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/intercom/attack_ai(mob/user as mob)
|
||||
/obj/item/radio/intercom/attack_ai(mob/user)
|
||||
add_hiddenprint(user)
|
||||
add_fingerprint(user)
|
||||
spawn(0)
|
||||
attack_self(user)
|
||||
|
||||
/obj/item/radio/intercom/attack_hand(mob/user as mob)
|
||||
/obj/item/radio/intercom/attack_hand(mob/user)
|
||||
add_fingerprint(user)
|
||||
spawn(0)
|
||||
attack_self(user)
|
||||
@@ -186,10 +184,10 @@
|
||||
update_icon()
|
||||
START_PROCESSING(SSobj, src)
|
||||
for(var/i, i<= 5, i++)
|
||||
wires.UpdateCut(i,1)
|
||||
wires.on_cut(i, 1)
|
||||
|
||||
/obj/item/radio/intercom/wirecutter_act(mob/user, obj/item/I)
|
||||
if(!(buildstage == 3 && b_stat && wires.IsAllCut()))
|
||||
if(!(buildstage == 3 && b_stat && wires.is_all_cut()))
|
||||
return
|
||||
. = TRUE
|
||||
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
|
||||
@@ -270,4 +268,4 @@
|
||||
|
||||
/obj/item/radio/intercom/locked/prison/New()
|
||||
..()
|
||||
wires.CutWireIndex(RADIO_WIRE_TRANSMIT)
|
||||
wires.cut(WIRE_RADIO_TRANSMIT)
|
||||
|
||||
@@ -26,21 +26,37 @@ GLOBAL_LIST_INIT(default_medbay_channels, list(
|
||||
suffix = "\[3\]"
|
||||
icon_state = "walkietalkie"
|
||||
item_state = "walkietalkie"
|
||||
var/on = 1 // 0 for off
|
||||
/// boolean for radio enabled or not
|
||||
var/on = TRUE
|
||||
var/last_transmission
|
||||
var/frequency = PUB_FREQ //common chat
|
||||
var/traitor_frequency = 0 //tune to frequency to unlock traitor supplies
|
||||
var/canhear_range = 3 // the range which mobs can hear this radio from
|
||||
var/frequency = PUB_FREQ
|
||||
/// tune to frequency to unlock traitor supplies
|
||||
var/traitor_frequency = 0
|
||||
/// the range which mobs can hear this radio from
|
||||
var/canhear_range = 3
|
||||
var/datum/wires/radio/wires = null
|
||||
var/b_stat = 0
|
||||
var/broadcasting = 0
|
||||
var/listening = 1
|
||||
var/list/channels = list() //see communications.dm for full list. First channes is a "default" for :h
|
||||
var/subspace_transmission = 0
|
||||
var/obj/item/encryptionkey/syndicate/syndiekey = null //Holder for the syndicate encryption key if present
|
||||
var/disable_timer = 0 //How many times this is disabled by EMPs
|
||||
|
||||
var/is_special = 0 //For electropacks mostly, skips Topic() checks
|
||||
/// Whether the radio will broadcast stuff it hears, out over the radio
|
||||
var/broadcasting = FALSE
|
||||
/// Whether the radio is currently receiving
|
||||
var/listening = TRUE
|
||||
/// Whether the radio can be re-tuned to restricted channels it has no key for
|
||||
var/freerange = FALSE
|
||||
/// Whether the radio is able to have its primary frequency changed. Used for radios with weird primary frequencies, like DS, syndi, etc
|
||||
var/freqlock = FALSE
|
||||
|
||||
/// Whether the radio broadcasts to everyone within a few tiles, or not
|
||||
var/loudspeaker = FALSE
|
||||
/// Whether loudspeaker can be toggled by the user
|
||||
var/has_loudspeaker = FALSE
|
||||
|
||||
/// see communications.dm for full list. First channes is a "default" for :h
|
||||
var/list/channels = list()
|
||||
/// Holder for the syndicate encryption key if present
|
||||
var/obj/item/encryptionkey/syndicate/syndiekey = null
|
||||
/// How many times this is disabled by EMPs
|
||||
var/disable_timer = 0
|
||||
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
@@ -76,6 +92,7 @@ GLOBAL_LIST_INIT(default_medbay_channels, list(
|
||||
GLOB.global_radios |= src
|
||||
|
||||
/obj/item/radio/Destroy()
|
||||
SStgui.close_uis(wires)
|
||||
QDEL_NULL(wires)
|
||||
if(SSradio)
|
||||
SSradio.remove_object(src, frequency)
|
||||
@@ -99,47 +116,87 @@ GLOBAL_LIST_INIT(default_medbay_channels, list(
|
||||
/obj/item/radio/attack_ghost(mob/user)
|
||||
return interact(user)
|
||||
|
||||
/obj/item/radio/attack_self(mob/user as mob)
|
||||
user.set_machine(src)
|
||||
interact(user)
|
||||
/obj/item/radio/attack_self(mob/user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/item/radio/interact(mob/user)
|
||||
if(!user)
|
||||
return 0
|
||||
|
||||
if(b_stat)
|
||||
wires.Interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
return ui_interact(user)
|
||||
|
||||
/obj/item/radio/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/item/radio/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "radio_basic.tmpl", "[name]", 400, 550)
|
||||
ui = new(user, src, ui_key, "Radio", name, 360, 150 + (length(channels) * 20), master_ui, state)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/item/radio/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state)
|
||||
var/data[0]
|
||||
/obj/item/radio/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["mic_status"] = broadcasting
|
||||
data["speaker"] = listening
|
||||
data["freq"] = format_frequency(frequency)
|
||||
data["rawfreq"] = num2text(frequency)
|
||||
|
||||
data["mic_cut"] = (wires.IsIndexCut(RADIO_WIRE_TRANSMIT) || wires.IsIndexCut(RADIO_WIRE_SIGNAL))
|
||||
data["spk_cut"] = (wires.IsIndexCut(RADIO_WIRE_RECEIVE) || wires.IsIndexCut(RADIO_WIRE_SIGNAL))
|
||||
|
||||
var/list/chanlist = list_channels(user)
|
||||
if(islist(chanlist) && chanlist.len)
|
||||
data["chan_list"] = chanlist
|
||||
data["chan_list_len"] = chanlist.len
|
||||
|
||||
if(syndiekey)
|
||||
data["useSyndMode"] = 1
|
||||
data["broadcasting"] = broadcasting
|
||||
data["listening"] = listening
|
||||
data["frequency"] = frequency
|
||||
data["minFrequency"] = freerange ? RADIO_LOW_FREQ : PUBLIC_LOW_FREQ
|
||||
data["maxFrequency"] = freerange ? RADIO_HIGH_FREQ : PUBLIC_HIGH_FREQ
|
||||
data["canReset"] = frequency == initial(frequency) ? FALSE : TRUE
|
||||
data["freqlock"] = freqlock
|
||||
data["channels"] = list()
|
||||
for(var/channel in channels)
|
||||
data["channels"][channel] = channels[channel] & FREQ_LISTENING
|
||||
|
||||
data["has_loudspeaker"] = has_loudspeaker
|
||||
data["loudspeaker"] = loudspeaker
|
||||
return data
|
||||
|
||||
/obj/item/radio/tgui_act(action, params, datum/tgui/ui)
|
||||
if(..())
|
||||
return
|
||||
. = TRUE
|
||||
switch(action)
|
||||
if("frequency")
|
||||
if(freqlock)
|
||||
return
|
||||
var/tune = params["tune"]
|
||||
var/adjust = text2num(params["adjust"])
|
||||
if(tune == "reset")
|
||||
tune = initial(frequency)
|
||||
else if(adjust)
|
||||
tune = frequency + adjust * 10
|
||||
else if(text2num(tune) != null)
|
||||
tune = tune * 10
|
||||
else
|
||||
. = FALSE
|
||||
if(hidden_uplink)
|
||||
if(hidden_uplink.check_trigger(usr, frequency, traitor_frequency))
|
||||
usr << browse(null, "window=radio")
|
||||
if(.)
|
||||
set_frequency(sanitize_frequency(tune, freerange))
|
||||
if("listen")
|
||||
listening = !listening
|
||||
if("broadcast")
|
||||
broadcasting = !broadcasting
|
||||
if("channel")
|
||||
var/channel = params["channel"]
|
||||
if(!(channel in channels))
|
||||
return
|
||||
if(channels[channel] & FREQ_LISTENING)
|
||||
channels[channel] &= ~FREQ_LISTENING
|
||||
else
|
||||
channels[channel] |= FREQ_LISTENING
|
||||
if("loudspeaker")
|
||||
// Toggle loudspeaker mode, AKA everyone around you hearing your radio.
|
||||
if(has_loudspeaker)
|
||||
loudspeaker = !loudspeaker
|
||||
if(loudspeaker)
|
||||
canhear_range = 3
|
||||
else
|
||||
canhear_range = 0
|
||||
else
|
||||
. = FALSE
|
||||
if(.)
|
||||
add_fingerprint(usr)
|
||||
|
||||
/obj/item/radio/proc/list_channels(var/mob/user)
|
||||
return list_internal_channels(user)
|
||||
@@ -184,57 +241,10 @@ GLOBAL_LIST_INIT(default_medbay_channels, list(
|
||||
return can_admin_interact()
|
||||
|
||||
/obj/item/radio/proc/ToggleBroadcast()
|
||||
broadcasting = !broadcasting && !(wires.IsIndexCut(RADIO_WIRE_TRANSMIT) || wires.IsIndexCut(RADIO_WIRE_SIGNAL))
|
||||
broadcasting = !broadcasting && !(wires.is_cut(WIRE_RADIO_TRANSMIT) || wires.is_cut(WIRE_RADIO_SIGNAL))
|
||||
|
||||
/obj/item/radio/proc/ToggleReception()
|
||||
listening = !listening && !(wires.IsIndexCut(RADIO_WIRE_RECEIVE) || wires.IsIndexCut(RADIO_WIRE_SIGNAL))
|
||||
|
||||
/obj/item/radio/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(is_special)
|
||||
return 0
|
||||
|
||||
if(href_list["track"])
|
||||
var/mob/target = locate(href_list["track"])
|
||||
var/mob/living/silicon/ai/A = locate(href_list["track2"])
|
||||
if(A && target)
|
||||
A.ai_actual_track(target)
|
||||
. = 1
|
||||
|
||||
else if(href_list["freq"])
|
||||
var/new_frequency = (frequency + text2num(href_list["freq"]))
|
||||
if((new_frequency < PUBLIC_LOW_FREQ || new_frequency > PUBLIC_HIGH_FREQ))
|
||||
new_frequency = sanitize_frequency(new_frequency)
|
||||
set_frequency(new_frequency)
|
||||
if(hidden_uplink)
|
||||
if(hidden_uplink.check_trigger(usr, frequency, traitor_frequency))
|
||||
usr << browse(null, "window=radio")
|
||||
. = 1
|
||||
else if(href_list["talk"])
|
||||
ToggleBroadcast()
|
||||
. = 1
|
||||
else if(href_list["listen"])
|
||||
var/chan_name = href_list["ch_name"]
|
||||
if(!chan_name)
|
||||
ToggleReception()
|
||||
else
|
||||
if(channels[chan_name] & FREQ_LISTENING)
|
||||
channels[chan_name] &= ~FREQ_LISTENING
|
||||
else
|
||||
channels[chan_name] |= FREQ_LISTENING
|
||||
. = 1
|
||||
else if(href_list["spec_freq"])
|
||||
var/freq = href_list["spec_freq"]
|
||||
if(has_channel_access(usr, freq))
|
||||
set_frequency(text2num(freq))
|
||||
. = 1
|
||||
|
||||
if(href_list["nowindow"]) // here for pAIs, maybe others will want it, idk
|
||||
return 1
|
||||
|
||||
add_fingerprint(usr)
|
||||
listening = !listening && !(wires.is_cut(WIRE_RADIO_RECEIVER) || wires.is_cut(WIRE_RADIO_SIGNAL))
|
||||
|
||||
/obj/item/radio/proc/autosay(message, from, channel, role = "Unknown") //BS12 EDIT
|
||||
var/datum/radio_frequency/connection = null
|
||||
@@ -325,7 +335,7 @@ GLOBAL_LIST_INIT(default_medbay_channels, list(
|
||||
// If we were to send to a channel we don't have, drop it.
|
||||
return RADIO_CONNECTION_FAIL
|
||||
|
||||
/obj/item/radio/talk_into(mob/living/M as mob, list/message_pieces, channel, var/verb = "says")
|
||||
/obj/item/radio/talk_into(mob/living/M as mob, list/message_pieces, channel, verbage = "says")
|
||||
if(!on)
|
||||
return 0 // the device has to be on
|
||||
// Fix for permacell radios, but kinda eh about actually fixing them.
|
||||
@@ -334,7 +344,7 @@ GLOBAL_LIST_INIT(default_medbay_channels, list(
|
||||
|
||||
// Uncommenting this. To the above comment:
|
||||
// The permacell radios aren't suppose to be able to transmit, this isn't a bug and this "fix" is just making radio wires useless. -Giacom
|
||||
if(wires.IsIndexCut(RADIO_WIRE_TRANSMIT)) // The device has to have all its wires and shit intact
|
||||
if(wires.is_cut(WIRE_RADIO_TRANSMIT)) // The device has to have all its wires and shit intact
|
||||
return 0
|
||||
|
||||
if(!M.IsVocal())
|
||||
@@ -428,6 +438,7 @@ GLOBAL_LIST_INIT(default_medbay_channels, list(
|
||||
tcm.connection = connection
|
||||
tcm.vname = M.voice_name
|
||||
tcm.sender = M
|
||||
tcm.verbage = verbage
|
||||
// Now put that through the stuff
|
||||
var/handled = FALSE
|
||||
if(connection)
|
||||
@@ -514,7 +525,7 @@ GLOBAL_LIST_INIT(default_medbay_channels, list(
|
||||
var/is_listening = TRUE
|
||||
if(!on)
|
||||
is_listening = FALSE
|
||||
if(!wires || wires.IsIndexCut(RADIO_WIRE_RECEIVE))
|
||||
if(!wires || wires.is_cut(WIRE_RADIO_RECEIVER))
|
||||
is_listening = FALSE
|
||||
if(!listening)
|
||||
is_listening = FALSE
|
||||
@@ -580,19 +591,24 @@ GLOBAL_LIST_INIT(default_medbay_channels, list(
|
||||
if(!disable_timer)
|
||||
on = 1
|
||||
|
||||
/obj/item/radio/proc/recalculateChannels()
|
||||
/// Exists so that borg radios and headsets can override it.
|
||||
stack_trace("recalculateChannels() called on a radio which does not implement the proc.")
|
||||
|
||||
///////////////////////////////
|
||||
//////////Borg Radios//////////
|
||||
///////////////////////////////
|
||||
//Giving borgs their own radio to have some more room to work with -Sieve
|
||||
|
||||
/obj/item/radio/borg
|
||||
name = "Cyborg Radio"
|
||||
var/mob/living/silicon/robot/myborg = null // Cyborg which owns this radio. Used for power checks
|
||||
var/obj/item/encryptionkey/keyslot = null//Borg radios can handle a single encryption key
|
||||
var/shut_up = 1
|
||||
icon = 'icons/obj/robot_component.dmi' // Cyborgs radio icons should look like the component.
|
||||
icon_state = "radio"
|
||||
has_loudspeaker = TRUE
|
||||
loudspeaker = FALSE
|
||||
canhear_range = 0
|
||||
subspace_transmission = 1
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/radio/borg/syndicate
|
||||
@@ -614,12 +630,14 @@ GLOBAL_LIST_INIT(default_medbay_channels, list(
|
||||
..()
|
||||
syndiekey = keyslot
|
||||
set_frequency(SYND_FREQ)
|
||||
freqlock = TRUE
|
||||
|
||||
/obj/item/radio/borg/deathsquad
|
||||
|
||||
/obj/item/radio/borg/deathsquad/New()
|
||||
..()
|
||||
set_frequency(DTH_FREQ)
|
||||
freqlock = TRUE
|
||||
|
||||
/obj/item/radio/borg/ert
|
||||
keyslot = new /obj/item/encryptionkey/ert
|
||||
@@ -627,6 +645,7 @@ GLOBAL_LIST_INIT(default_medbay_channels, list(
|
||||
/obj/item/radio/borg/ert/New()
|
||||
..()
|
||||
set_frequency(ERT_FREQ)
|
||||
freqlock = TRUE
|
||||
|
||||
/obj/item/radio/borg/ert/specops
|
||||
keyslot = new /obj/item/encryptionkey/centcom
|
||||
@@ -671,7 +690,7 @@ GLOBAL_LIST_INIT(default_medbay_channels, list(
|
||||
else
|
||||
to_chat(user, "This radio doesn't have any encryption keys!")
|
||||
|
||||
/obj/item/radio/borg/proc/recalculateChannels()
|
||||
/obj/item/radio/borg/recalculateChannels()
|
||||
channels = list()
|
||||
syndiekey = null
|
||||
|
||||
@@ -704,72 +723,12 @@ GLOBAL_LIST_INIT(default_medbay_channels, list(
|
||||
|
||||
return
|
||||
|
||||
/obj/item/radio/borg/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if(href_list["mode"])
|
||||
var/enable_subspace_transmission = text2num(href_list["mode"])
|
||||
if(enable_subspace_transmission != subspace_transmission)
|
||||
subspace_transmission = !subspace_transmission
|
||||
if(subspace_transmission)
|
||||
to_chat(usr, "<span class='notice'>Subspace Transmission is enabled.</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>Subspace Transmission is disabled.</span>")
|
||||
|
||||
if(subspace_transmission == 0)//Simple as fuck, clears the channel list to prevent talking/listening over them if subspace transmission is disabled
|
||||
channels = list()
|
||||
else
|
||||
recalculateChannels()
|
||||
. = 1
|
||||
if(href_list["shutup"]) // Toggle loudspeaker mode, AKA everyone around you hearing your radio.
|
||||
var/do_shut_up = text2num(href_list["shutup"])
|
||||
if(do_shut_up != shut_up)
|
||||
shut_up = !shut_up
|
||||
if(shut_up)
|
||||
canhear_range = 0
|
||||
to_chat(usr, "<span class='notice'>Loudspeaker disabled.</span>")
|
||||
else
|
||||
canhear_range = 3
|
||||
to_chat(usr, "<span class='notice'>Loudspeaker enabled.</span>")
|
||||
. = 1
|
||||
|
||||
|
||||
/obj/item/radio/borg/interact(mob/user as mob)
|
||||
/obj/item/radio/borg/interact(mob/user)
|
||||
if(!on)
|
||||
return
|
||||
|
||||
. = ..()
|
||||
|
||||
/obj/item/radio/borg/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "radio_basic.tmpl", "[name]", 430, 500)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/item/radio/borg/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state)
|
||||
var/data[0]
|
||||
|
||||
data["mic_status"] = broadcasting
|
||||
data["speaker"] = listening
|
||||
data["freq"] = format_frequency(frequency)
|
||||
data["rawfreq"] = num2text(frequency)
|
||||
|
||||
var/list/chanlist = list_channels(user)
|
||||
if(islist(chanlist) && chanlist.len)
|
||||
data["chan_list"] = chanlist
|
||||
data["chan_list_len"] = chanlist.len
|
||||
|
||||
if(syndiekey)
|
||||
data["useSyndMode"] = 1
|
||||
|
||||
data["has_loudspeaker"] = 1
|
||||
data["loudspeaker"] = !shut_up
|
||||
data["has_subspace"] = 1
|
||||
data["subspace"] = subspace_transmission
|
||||
|
||||
return data
|
||||
|
||||
/obj/item/radio/proc/config(op)
|
||||
if(SSradio)
|
||||
for(var/ch_name in channels)
|
||||
|
||||
@@ -72,7 +72,7 @@ REAGENT SCANNER
|
||||
var/turf/U = O.loc
|
||||
if(U && U.intact)
|
||||
O.invisibility = 101
|
||||
O.alpha = 255
|
||||
O.alpha = 255
|
||||
for(var/mob/living/M in T.contents)
|
||||
var/oldalpha = M.alpha
|
||||
if(M.alpha < 255 && istype(M))
|
||||
|
||||
@@ -86,64 +86,64 @@
|
||||
O.hear_message(M, msg)
|
||||
|
||||
/obj/item/transfer_valve/attack_self(mob/user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/item/transfer_valve/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1)
|
||||
// update the ui if it exists, returns null if no ui is passed/found
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/item/transfer_valve/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_inventory_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
// the ui does not exist, so we'll create a new() one
|
||||
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
||||
ui = new(user, src, ui_key, "transfer_valve.tmpl", "Tank Transfer Valve", 460, 280)
|
||||
// open the new ui window
|
||||
ui = new(user, src, ui_key, "TransferValve", name, 460, 320, master_ui, state)
|
||||
ui.open()
|
||||
// auto update every Master Controller tick
|
||||
//ui.set_auto_update(1)
|
||||
|
||||
/obj/item/transfer_valve/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state)
|
||||
var/data[0]
|
||||
|
||||
data["attachmentOne"] = tank_one ? tank_one.name : null
|
||||
data["attachmentTwo"] = tank_two ? tank_two.name : null
|
||||
data["valveAttachment"] = attached_device ? attached_device.name : null
|
||||
data["valveOpen"] = valve_open ? 1 : 0
|
||||
|
||||
/obj/item/transfer_valve/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["tank_one"] = tank_one ? tank_one.name : null
|
||||
data["tank_two"] = tank_two ? tank_two.name : null
|
||||
data["attached_device"] = attached_device ? attached_device.name : null
|
||||
data["valve"] = valve_open
|
||||
return data
|
||||
|
||||
/obj/item/transfer_valve/Topic(href, href_list)
|
||||
..()
|
||||
if(usr.incapacitated())
|
||||
return 0
|
||||
if(loc != usr)
|
||||
return 0
|
||||
if(tank_one && href_list["tankone"])
|
||||
split_gases()
|
||||
valve_open = 0
|
||||
tank_one.forceMove(get_turf(src))
|
||||
tank_one = null
|
||||
|
||||
|
||||
/obj/item/transfer_valve/tgui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
. = TRUE
|
||||
switch(action)
|
||||
if("tankone")
|
||||
if(tank_one)
|
||||
split_gases()
|
||||
valve_open = FALSE
|
||||
tank_one.forceMove(get_turf(src))
|
||||
tank_one = null
|
||||
update_icon()
|
||||
if((!tank_two || tank_two.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL))
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
if("tanktwo")
|
||||
if(tank_two)
|
||||
split_gases()
|
||||
valve_open = FALSE
|
||||
tank_two.forceMove(get_turf(src))
|
||||
tank_two = null
|
||||
update_icon()
|
||||
if((!tank_one || tank_one.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL))
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
if("toggle")
|
||||
toggle_valve()
|
||||
if("device")
|
||||
if(attached_device)
|
||||
attached_device.attack_self(usr)
|
||||
if("remove_device")
|
||||
if(attached_device)
|
||||
attached_device.forceMove(get_turf(src))
|
||||
attached_device.holder = null
|
||||
attached_device = null
|
||||
update_icon()
|
||||
else
|
||||
. = FALSE
|
||||
if(.)
|
||||
update_icon()
|
||||
if((!tank_two || tank_two.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL))
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
else if(tank_two && href_list["tanktwo"])
|
||||
split_gases()
|
||||
valve_open = 0
|
||||
tank_two.forceMove(get_turf(src))
|
||||
tank_two = null
|
||||
update_icon()
|
||||
if((!tank_one || tank_one.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL))
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
else if(href_list["open"])
|
||||
toggle_valve()
|
||||
else if(attached_device)
|
||||
if(href_list["rem_device"])
|
||||
attached_device.forceMove(get_turf(src))
|
||||
attached_device.holder = null
|
||||
attached_device = null
|
||||
update_icon()
|
||||
if(href_list["device"])
|
||||
attached_device.attack_self(usr)
|
||||
add_fingerprint(usr)
|
||||
return 1 // Returning 1 sends an update to attached UIs
|
||||
add_fingerprint(usr)
|
||||
|
||||
|
||||
/obj/item/transfer_valve/proc/process_activation(obj/item/D)
|
||||
if(toggle)
|
||||
|
||||
@@ -251,6 +251,7 @@
|
||||
message_admins("[key_name_admin(user)] has lit the [src] trapped with [boobytrap] by [key_name_admin(trapper)] at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a>.")
|
||||
log_game("[key_name_admin(user)] has lit the [src] trapped with [boobytrap] by [key_name_admin(trapper)] at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).")
|
||||
investigate_log("[key_name_admin(user)] has lit the [src] trapped with [boobytrap] by [key_name_admin(trapper)] at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).", INVESTIGATE_BOMB)
|
||||
burn()
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -267,8 +268,16 @@
|
||||
|
||||
/obj/item/flag/chameleon/burn()
|
||||
if(boobytrap)
|
||||
boobytrap.prime()
|
||||
..()
|
||||
fire_act()
|
||||
addtimer(CALLBACK(src, .proc/prime_boobytrap), boobytrap.det_time)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/flag/chameleon/proc/prime_boobytrap()
|
||||
boobytrap.forceMove(get_turf(loc))
|
||||
boobytrap.prime()
|
||||
boobytrap = null
|
||||
burn()
|
||||
|
||||
/obj/item/flag/chameleon/updateFlagIcon()
|
||||
icon_state = updated_icon_state
|
||||
|
||||
@@ -472,7 +472,8 @@ GLOBAL_LIST_INIT(plastic_recipes, list(
|
||||
new /datum/stack_recipe("cane mould", /obj/item/kitchen/mould/cane, 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("cash mould", /obj/item/kitchen/mould/cash, 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("coin mould", /obj/item/kitchen/mould/coin, 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("sucker mould", /obj/item/kitchen/mould/loli, 1, on_floor = 1)))
|
||||
new /datum/stack_recipe("sucker mould", /obj/item/kitchen/mould/loli, 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("warning cone", /obj/item/clothing/head/cone, 5, on_floor = 1)))
|
||||
|
||||
/obj/item/stack/sheet/plastic
|
||||
name = "plastic"
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
desc = "A translucent balloon. There's nothing in it."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "waterballoon-e"
|
||||
item_state = "balloon-empty"
|
||||
item_state = "waterballoon-e"
|
||||
|
||||
/obj/item/toy/balloon/New()
|
||||
..()
|
||||
@@ -99,10 +99,10 @@
|
||||
/obj/item/toy/balloon/update_icon()
|
||||
if(src.reagents.total_volume >= 1)
|
||||
icon_state = "waterballoon"
|
||||
item_state = "balloon"
|
||||
item_state = "waterballoon"
|
||||
else
|
||||
icon_state = "waterballoon-e"
|
||||
item_state = "balloon-empty"
|
||||
item_state = "waterballoon-e"
|
||||
|
||||
/obj/item/toy/syndicateballoon
|
||||
name = "syndicate balloon"
|
||||
@@ -344,56 +344,56 @@
|
||||
|
||||
/obj/item/toy/prize/ripley
|
||||
name = "toy ripley"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 1/11."
|
||||
desc = "Mini-Mecha action figure! Collect them all! 1/11. This one is a ripley, a mining and engineering mecha."
|
||||
|
||||
/obj/item/toy/prize/fireripley
|
||||
name = "toy firefighting ripley"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 2/11."
|
||||
desc = "Mini-Mecha action figure! Collect them all! 2/11. This one is a firefighter ripley, a fireproof mining and engineering mecha."
|
||||
icon_state = "fireripleytoy"
|
||||
|
||||
/obj/item/toy/prize/deathripley
|
||||
name = "toy deathsquad ripley"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 3/11."
|
||||
desc = "Mini-Mecha action figure! Collect them all! 3/11. This one is the black ripley used by the hero of DeathSquad, that TV drama about loose-cannon ERT officers!"
|
||||
icon_state = "deathripleytoy"
|
||||
|
||||
/obj/item/toy/prize/gygax
|
||||
name = "toy gygax"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 4/11."
|
||||
desc = "Mini-Mecha action figure! Collect them all! 4/11. This one is the speedy gygax combat mecha. Zoom zoom, pew pew!"
|
||||
icon_state = "gygaxtoy"
|
||||
|
||||
/obj/item/toy/prize/durand
|
||||
name = "toy durand"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 5/11."
|
||||
desc = "Mini-Mecha action figure! Collect them all! 5/11. This one is the heavy durand combat mecha. Stomp stomp!"
|
||||
icon_state = "durandprize"
|
||||
|
||||
/obj/item/toy/prize/honk
|
||||
name = "toy H.O.N.K."
|
||||
desc = "Mini-Mecha action figure! Collect them all! 6/11."
|
||||
desc = "Mini-Mecha action figure! Collect them all! 6/11. This one is the infamous H.O.N.K mech!"
|
||||
icon_state = "honkprize"
|
||||
|
||||
/obj/item/toy/prize/marauder
|
||||
name = "toy marauder"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 7/11."
|
||||
desc = "Mini-Mecha action figure! Collect them all! 7/11. This one is the powerful marauder combat mecha! Run for cover!"
|
||||
icon_state = "marauderprize"
|
||||
|
||||
/obj/item/toy/prize/seraph
|
||||
name = "toy seraph"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 8/11."
|
||||
desc = "Mini-Mecha action figure! Collect them all! 8/11. This one is the powerful seraph combat mecha! Someone's in trouble!"
|
||||
icon_state = "seraphprize"
|
||||
|
||||
/obj/item/toy/prize/mauler
|
||||
name = "toy mauler"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 9/11."
|
||||
desc = "Mini-Mecha action figure! Collect them all! 9/11. This one is the deadly mauler combat mecha! Look out!"
|
||||
icon_state = "maulerprize"
|
||||
|
||||
/obj/item/toy/prize/odysseus
|
||||
name = "toy odysseus"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 10/11."
|
||||
desc = "Mini-Mecha action figure! Collect them all! 10/11. This one is the spindly, syringe-firing odysseus medical mecha."
|
||||
icon_state = "odysseusprize"
|
||||
|
||||
/obj/item/toy/prize/phazon
|
||||
name = "toy phazon"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 11/11."
|
||||
desc = "Mini-Mecha action figure! Collect them all! 11/11. This one is the mysterious Phazon combat mecha! Nobody's safe!"
|
||||
icon_state = "phazonprize"
|
||||
|
||||
|
||||
@@ -1591,182 +1591,217 @@ obj/item/toy/cards/deck/syndicate/black
|
||||
|
||||
/obj/item/toy/figure/cmo
|
||||
name = "Chief Medical Officer action figure"
|
||||
desc = "The ever-suffering CMO, from Space Life's SS12 figurine collection."
|
||||
icon_state = "cmo"
|
||||
toysay = "Suit sensors!"
|
||||
|
||||
/obj/item/toy/figure/assistant
|
||||
name = "Assistant action figure"
|
||||
desc = "The faceless, hairless scourge of the station, from Space Life's SS12 figurine collection."
|
||||
icon_state = "assistant"
|
||||
toysay = "Grey tide station wide!"
|
||||
|
||||
/obj/item/toy/figure/atmos
|
||||
name = "Atmospheric Technician action figure"
|
||||
desc = "The faithful atmospheric technician, from Space Life's SS12 figurine collection."
|
||||
icon_state = "atmos"
|
||||
toysay = "Glory to Atmosia!"
|
||||
|
||||
/obj/item/toy/figure/bartender
|
||||
name = "Bartender action figure"
|
||||
desc = "The suave bartender, from Space Life's SS12 figurine collection."
|
||||
icon_state = "bartender"
|
||||
toysay = "Wheres my monkey?"
|
||||
|
||||
/obj/item/toy/figure/borg
|
||||
name = "Cyborg action figure"
|
||||
desc = "The iron-willed cyborg, from Space Life's SS12 figurine collection."
|
||||
icon_state = "borg"
|
||||
toysay = "I. LIVE. AGAIN."
|
||||
|
||||
/obj/item/toy/figure/botanist
|
||||
name = "Botanist action figure"
|
||||
desc = "The drug-addicted botanist, from Space Life's SS12 figurine collection."
|
||||
icon_state = "botanist"
|
||||
toysay = "Dude, I see colors..."
|
||||
|
||||
/obj/item/toy/figure/captain
|
||||
name = "Captain action figure"
|
||||
desc = "The inept captain, from Space Life's SS12 figurine collection."
|
||||
icon_state = "captain"
|
||||
toysay = "Crew, the Nuke Disk is safely up my ass."
|
||||
|
||||
/obj/item/toy/figure/cargotech
|
||||
name = "Cargo Technician action figure"
|
||||
desc = "The hard-working cargo tech, from Space Life's SS12 figurine collection."
|
||||
icon_state = "cargotech"
|
||||
toysay = "For Cargonia!"
|
||||
|
||||
/obj/item/toy/figure/ce
|
||||
name = "Chief Engineer action figure"
|
||||
desc = "The expert Chief Engineer, from Space Life's SS12 figurine collection."
|
||||
icon_state = "ce"
|
||||
toysay = "Wire the solars!"
|
||||
|
||||
/obj/item/toy/figure/chaplain
|
||||
name = "Chaplain action figure"
|
||||
desc = "The obsessed Chaplain, from Space Life's SS12 figurine collection."
|
||||
icon_state = "chaplain"
|
||||
toysay = "Gods make me a killing machine please!"
|
||||
|
||||
/obj/item/toy/figure/chef
|
||||
name = "Chef action figure"
|
||||
desc = "The cannibalistic chef, from Space Life's SS12 figurine collection."
|
||||
icon_state = "chef"
|
||||
toysay = "I swear it's not human meat."
|
||||
|
||||
/obj/item/toy/figure/chemist
|
||||
name = "Chemist action figure"
|
||||
desc = "The legally dubious Chemist, from Space Life's SS12 figurine collection."
|
||||
icon_state = "chemist"
|
||||
toysay = "Get your pills!"
|
||||
|
||||
/obj/item/toy/figure/clown
|
||||
name = "Clown action figure"
|
||||
desc = "The mischevious Clown, from Space Life's SS12 figurine collection."
|
||||
icon_state = "clown"
|
||||
toysay = "Honk!"
|
||||
|
||||
/obj/item/toy/figure/ian
|
||||
name = "Ian action figure"
|
||||
desc = "The adorable corgi, from Space Life's SS12 figurine collection."
|
||||
icon_state = "ian"
|
||||
toysay = "Arf!"
|
||||
|
||||
/obj/item/toy/figure/detective
|
||||
name = "Detective action figure"
|
||||
desc = "The clever detective, from Space Life's SS12 figurine collection."
|
||||
icon_state = "detective"
|
||||
toysay = "This airlock has grey jumpsuit and insulated glove fibers on it."
|
||||
|
||||
/obj/item/toy/figure/dsquad
|
||||
name = "Death Squad Officer action figure"
|
||||
desc = "It's a member of the DeathSquad, a TV drama where loose-cannon ERT officers face up against the threats of the galaxy! It's from Space Life's special edition SS12 figurine collection."
|
||||
icon_state = "dsquad"
|
||||
toysay = "Eliminate all threats!"
|
||||
|
||||
/obj/item/toy/figure/engineer
|
||||
name = "Engineer action figure"
|
||||
desc = "The frantic engineer, from Space Life's SS12 figurine collection."
|
||||
icon_state = "engineer"
|
||||
toysay = "Oh god, the singularity is loose!"
|
||||
|
||||
/obj/item/toy/figure/geneticist
|
||||
name = "Geneticist action figure"
|
||||
desc = "The balding geneticist, from Space Life's SS12 figurine collection."
|
||||
icon_state = "geneticist"
|
||||
toysay = "I'm not qualified for this job."
|
||||
|
||||
/obj/item/toy/figure/hop
|
||||
name = "Head of Personnel action figure"
|
||||
desc = "The officious Head of Personnel, from Space Life's SS12 figurine collection."
|
||||
icon_state = "hop"
|
||||
toysay = "Giving out all access!"
|
||||
toysay = "Papers, please!"
|
||||
|
||||
/obj/item/toy/figure/hos
|
||||
name = "Head of Security action figure"
|
||||
desc = "The bloodlust-filled Head of Security, from Space Life's SS12 figurine collection."
|
||||
icon_state = "hos"
|
||||
toysay = "I'm here to win, anything else is secondary."
|
||||
toysay = "Space law? What?"
|
||||
|
||||
/obj/item/toy/figure/qm
|
||||
name = "Quartermaster action figure"
|
||||
desc = "The nationalistic Quartermaster, from Space Life's SS12 figurine collection."
|
||||
icon_state = "qm"
|
||||
toysay = "Hail Cargonia!"
|
||||
|
||||
/obj/item/toy/figure/janitor
|
||||
name = "Janitor action figure"
|
||||
desc = "The water-using Janitor, from Space Life's SS12 figurine collection."
|
||||
icon_state = "janitor"
|
||||
toysay = "Look at the signs, you idiot."
|
||||
|
||||
/obj/item/toy/figure/lawyer
|
||||
name = "Internal Affairs Agent action figure"
|
||||
desc = "The unappreciated Internal Affairs Agent, from Space Life's SS12 figurine collection."
|
||||
icon_state = "lawyer"
|
||||
toysay = "Standard Operating Procedure says they're guilty! Hacking is proof they're an Enemy of the Corporation!"
|
||||
|
||||
/obj/item/toy/figure/librarian
|
||||
name = "Librarian action figure"
|
||||
desc = "The quiet Librarian, from Space Life's SS12 figurine collection."
|
||||
icon_state = "librarian"
|
||||
toysay = "One day while..."
|
||||
|
||||
/obj/item/toy/figure/md
|
||||
name = "Medical Doctor action figure"
|
||||
desc = "The stressed-out doctor, from Space Life's SS12 figurine collection."
|
||||
icon_state = "md"
|
||||
toysay = "The patient is already dead!"
|
||||
|
||||
/obj/item/toy/figure/mime
|
||||
name = "Mime action figure"
|
||||
desc = "A \"Space Life\" brand Mime action figure."
|
||||
desc = "... from Space Life's SS12 figurine collection."
|
||||
icon_state = "mime"
|
||||
toysay = "..."
|
||||
|
||||
/obj/item/toy/figure/miner
|
||||
name = "Shaft Miner action figure"
|
||||
desc = "The gun-toting Shaft Miner, from Space Life's SS12 figurine collection."
|
||||
icon_state = "miner"
|
||||
toysay = "Oh god it's eating my intestines!"
|
||||
|
||||
/obj/item/toy/figure/ninja
|
||||
name = "Ninja action figure"
|
||||
desc = "It's the mysterious ninja! It's from Space Life's special edition SS12 figurine collection."
|
||||
icon_state = "ninja"
|
||||
toysay = "Oh god! Stop shooting, I'm friendly!"
|
||||
|
||||
/obj/item/toy/figure/wizard
|
||||
name = "Wizard action figure"
|
||||
desc = "It's the deadly, spell-slinging wizard! It's from Space Life's special edition SS12 figurine collection."
|
||||
icon_state = "wizard"
|
||||
toysay = "Ei Nath!"
|
||||
|
||||
/obj/item/toy/figure/rd
|
||||
name = "Research Director action figure"
|
||||
desc = "The ambitious RD, from Space Life's SS12 figurine collection."
|
||||
icon_state = "rd"
|
||||
toysay = "Blowing all of the borgs!"
|
||||
|
||||
/obj/item/toy/figure/roboticist
|
||||
name = "Roboticist action figure"
|
||||
desc = "The skillful Roboticist, from Space Life's SS12 figurine collection."
|
||||
icon_state = "roboticist"
|
||||
toysay = "He asked to be borged!"
|
||||
|
||||
/obj/item/toy/figure/scientist
|
||||
name = "Scientist action figure"
|
||||
desc = "The mad Scientist, from Space Life's SS12 figurine collection."
|
||||
icon_state = "scientist"
|
||||
toysay = "Someone else must have made those bombs!"
|
||||
|
||||
/obj/item/toy/figure/syndie
|
||||
name = "Nuclear Operative action figure"
|
||||
desc = "It's the red-suited Nuclear Operative! It's from Space Life's special edition SS12 figurine collection."
|
||||
icon_state = "syndie"
|
||||
toysay = "Get that fucking disk!"
|
||||
|
||||
/obj/item/toy/figure/secofficer
|
||||
name = "Security Officer action figure"
|
||||
desc = "The power-tripping Security Officer, from Space Life's SS12 figurine collection."
|
||||
icon_state = "secofficer"
|
||||
toysay = "I am the law!"
|
||||
|
||||
/obj/item/toy/figure/virologist
|
||||
name = "Virologist action figure"
|
||||
desc = "The pandemic-starting Virologist, from Space Life's SS12 figurine collection."
|
||||
icon_state = "virologist"
|
||||
toysay = "The cure is potassium!"
|
||||
toysay = "It's not my virus!"
|
||||
|
||||
/obj/item/toy/figure/warden
|
||||
name = "Warden action figure"
|
||||
desc = "The amnesiac Warden, from Space Life's SS12 figurine collection."
|
||||
icon_state = "warden"
|
||||
toysay = "Execute him for breaking in!"
|
||||
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
/// Delay in deci-seconds between two non-lethal attacks
|
||||
#define BATON_STUN_COOLDOWN 4 SECONDS
|
||||
/// Force of the telescopic baton when deployed
|
||||
#define BATON_TELESCOPIC_FORCE_DEPLOYED 10
|
||||
|
||||
/**
|
||||
* # Police Baton
|
||||
*
|
||||
* Knocks down the hit mob when not on harm intent and when [/obj/item/melee/classic_baton/on] is TRUE
|
||||
*
|
||||
* A non-lethal attack has a cooldown to avoid spamming
|
||||
*/
|
||||
/obj/item/melee/classic_baton
|
||||
name = "police baton"
|
||||
desc = "A wooden truncheon for beating criminal scum."
|
||||
icon_state = "baton"
|
||||
item_state = "classic_baton"
|
||||
slot_flags = SLOT_BELT
|
||||
force = 12 //9 hit crit
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
/// Whether the baton is on cooldown
|
||||
var/on_cooldown = FALSE
|
||||
/// Whether the baton is toggled on (to allow attacking)
|
||||
var/on = TRUE
|
||||
|
||||
/obj/item/melee/classic_baton/attack(mob/living/target, mob/living/user)
|
||||
if(!on)
|
||||
return ..()
|
||||
|
||||
add_fingerprint(user)
|
||||
if((CLUMSY in user.mutations) && prob(50))
|
||||
user.visible_message("<span class='danger'>[user] accidentally clubs [user.p_them()]self with [src]!</span>", \
|
||||
"<span class='userdanger'>You accidentally club yourself with [src]!</span>")
|
||||
user.Weaken(force * 3)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.apply_damage(force * 2, BRUTE, "head")
|
||||
else
|
||||
user.take_organ_damage(force * 2)
|
||||
return
|
||||
|
||||
if(user.a_intent == INTENT_HARM || isrobot(target)) // Lethal attack or it's a borg (can't knock them down!)
|
||||
return ..()
|
||||
else if(!on_cooldown) // Non-lethal attack - knock them down
|
||||
// Check for shield/countering
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(H.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK))
|
||||
return
|
||||
if(check_martial_counter(H, user))
|
||||
return
|
||||
// Visuals and sound
|
||||
user.do_attack_animation(target)
|
||||
playsound(target, 'sound/effects/woodhit.ogg', 75, TRUE, -1)
|
||||
add_attack_logs(user, target, "Stunned with [src]")
|
||||
target.visible_message("<span class='danger'>[user] has knocked down [target] with \the [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has knocked down [target] with \the [src]!</span>")
|
||||
// Hit 'em
|
||||
target.LAssailant = iscarbon(user) ? user : null
|
||||
target.Weaken(3)
|
||||
on_cooldown = TRUE
|
||||
addtimer(CALLBACK(src, .proc/cooldown_finished), BATON_STUN_COOLDOWN)
|
||||
|
||||
/**
|
||||
* Called some time after a non-lethal attack
|
||||
*/
|
||||
/obj/item/melee/classic_baton/proc/cooldown_finished()
|
||||
on_cooldown = FALSE
|
||||
|
||||
/**
|
||||
* # Fancy Cane
|
||||
*/
|
||||
/obj/item/melee/classic_baton/ntcane
|
||||
name = "fancy cane"
|
||||
desc = "A cane with special engraving on it. It seems well suited for fending off assailants..."
|
||||
icon_state = "cane_nt"
|
||||
item_state = "cane_nt"
|
||||
needs_permit = FALSE
|
||||
|
||||
/obj/item/melee/classic_baton/ntcane/is_crutch()
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* # Telescopic Baton
|
||||
*/
|
||||
/obj/item/melee/classic_baton/telescopic
|
||||
name = "telescopic baton"
|
||||
desc = "A compact yet robust personal defense weapon. Can be concealed when folded."
|
||||
icon_state = "telebaton_0"
|
||||
item_state = null
|
||||
slot_flags = SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
needs_permit = FALSE
|
||||
force = 0
|
||||
on = FALSE
|
||||
/// Attack verbs when concealed (created on Initialize)
|
||||
var/static/list/attack_verb_off
|
||||
/// Attack verbs when extended (created on Initialize)
|
||||
var/static/list/attack_verb_on
|
||||
|
||||
/obj/item/melee/classic_baton/telescopic/Initialize(mapload)
|
||||
. = ..()
|
||||
if(!attack_verb_off)
|
||||
attack_verb_off = list("hit", "poked")
|
||||
attack_verb_on = list("smacked", "struck", "cracked", "beaten")
|
||||
attack_verb = on ? attack_verb_on : attack_verb_off
|
||||
|
||||
/obj/item/melee/classic_baton/telescopic/attack_self(mob/user)
|
||||
on = !on
|
||||
icon_state = "telebaton_[on]"
|
||||
if(on)
|
||||
to_chat(user, "<span class='warning'>You extend the baton.</span>")
|
||||
item_state = "nullrod"
|
||||
w_class = WEIGHT_CLASS_BULKY //doesnt fit in backpack when its on for balance
|
||||
force = BATON_TELESCOPIC_FORCE_DEPLOYED //stunbaton damage
|
||||
attack_verb = attack_verb_on
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You collapse the baton.</span>")
|
||||
item_state = null //no sprite for concealment even when in hand
|
||||
slot_flags = SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
force = 0 //not so robust now
|
||||
attack_verb = attack_verb_off
|
||||
// Update mob hand visuals
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.update_inv_l_hand()
|
||||
H.update_inv_r_hand()
|
||||
playsound(loc, 'sound/weapons/batonextend.ogg', 50, TRUE)
|
||||
add_fingerprint(user)
|
||||
|
||||
#undef BATON_STUN_COOLDOWN
|
||||
#undef BATON_TELESCOPIC_FORCE_DEPLOYED
|
||||
@@ -212,6 +212,11 @@
|
||||
return M
|
||||
owner_ckey = null
|
||||
|
||||
/obj/item/card/id/proc/getPlayerCkey()
|
||||
var/mob/living/carbon/human/H = getPlayer()
|
||||
if(istype(H))
|
||||
return H.ckey
|
||||
|
||||
/obj/item/card/id/proc/is_untrackable()
|
||||
return untrackable
|
||||
|
||||
|
||||
@@ -55,16 +55,15 @@
|
||||
|
||||
/obj/item/lipstick/random/Initialize(mapload)
|
||||
. = ..()
|
||||
var/lscolor = pick(lipstick_colors) // A random color is picked from the var defined initially in a new var.
|
||||
colour = lipstick_colors[lscolor] // The color of the lipstick is pulled from the new variable (right hand side, HTML & Hex RGB)
|
||||
name = "[lscolor] lipstick" // The new variable is also used to match the name to the color of the lipstick. Kudos to Desolate & Lemon
|
||||
colour = pick(lipstick_colors)
|
||||
name = "[colour] lipstick"
|
||||
|
||||
/obj/item/lipstick/attack_self(mob/user)
|
||||
cut_overlays()
|
||||
to_chat(user, "<span class='notice'>You twist \the [src] [open ? "closed" : "open"].</span>")
|
||||
open = !open
|
||||
if(open)
|
||||
var/image/colored = mutable_appearance('icons/obj/items.dmi', "lipstick_uncap_color")
|
||||
var/mutable_appearance/colored = mutable_appearance('icons/obj/items.dmi', "lipstick_uncap_color")
|
||||
colored.color = lipstick_colors[colour]
|
||||
icon_state = "lipstick_uncap"
|
||||
add_overlay(colored)
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
playsound(src.loc, 'sound/weapons/cablecuff.ogg', 15, 1, -1)
|
||||
|
||||
M.visible_message("<span class='danger'>[U] comes from behind and begins garroting [M] with the [src]!</span>", \
|
||||
"<span class='userdanger'>[U]\ begins garroting you with the [src]![improvised ? "" : " You are unable to speak!"]</span>", \
|
||||
"<span class='userdanger'>[U] begins garroting you with the [src]![improvised ? "" : " You are unable to speak!"]</span>", \
|
||||
"You hear struggling and wire strain against flesh!")
|
||||
|
||||
return
|
||||
|
||||
@@ -5,39 +5,51 @@
|
||||
origin_tech = "materials=2;combat=3"
|
||||
light_power = 10
|
||||
light_color = LIGHT_COLOR_WHITE
|
||||
var/light_time = 2
|
||||
var/range = 7
|
||||
|
||||
var/light_time = 0.2 SECONDS // The duration the area is illuminated
|
||||
var/range = 7 // The range in tiles of the flashbang
|
||||
|
||||
/obj/item/grenade/flashbang/prime()
|
||||
update_mob()
|
||||
var/flashbang_turf = get_turf(src)
|
||||
if(!flashbang_turf)
|
||||
return
|
||||
var/turf/T = get_turf(src)
|
||||
if(T)
|
||||
// VFX and SFX
|
||||
do_sparks(rand(5, 9), FALSE, src)
|
||||
playsound(T, 'sound/effects/bang.ogg', 100, TRUE)
|
||||
new /obj/effect/dummy/lighting_obj(T, light_color, range + 2, light_power, light_time)
|
||||
|
||||
set_light(7)
|
||||
|
||||
do_sparks(rand(5, 9), FALSE, src)
|
||||
playsound(flashbang_turf, 'sound/effects/bang.ogg', 25, 1)
|
||||
bang(flashbang_turf, src, range)
|
||||
|
||||
for(var/obj/structure/blob/B in hear(8, flashbang_turf)) //Blob damage here
|
||||
var/damage = round(30 / (get_dist(B, get_turf(src)) + 1))
|
||||
B.take_damage(damage, BURN, "melee", 0)
|
||||
|
||||
spawn(light_time)
|
||||
qdel(src)
|
||||
// Stunning & damaging mechanic
|
||||
bang(T, src, range)
|
||||
qdel(src)
|
||||
|
||||
/**
|
||||
* Creates a flashing effect that blinds and deafens mobs within range
|
||||
*
|
||||
* Also damages blobs
|
||||
* Arguments:
|
||||
* * T - The turf to flash
|
||||
* * A - The flashing atom
|
||||
* * range - The range in tiles of the flash
|
||||
* * flash - Whether to flash (blind)
|
||||
* * bang - Whether to bang (deafen)
|
||||
*/
|
||||
/proc/bang(turf/T, atom/A, range = 7, flash = TRUE, bang = TRUE)
|
||||
// Blob damage
|
||||
for(var/obj/structure/blob/B in hear(range + 1, T))
|
||||
var/damage = round(30 / (get_dist(B, T) + 1))
|
||||
B.take_damage(damage, BURN, "melee", FALSE)
|
||||
|
||||
// Flashing mechanic
|
||||
var/source_turf = get_turf(A)
|
||||
for(var/mob/living/M in hearers(range, T))
|
||||
if(M.stat == DEAD)
|
||||
continue
|
||||
M.show_message("<span class='warning'>BANG</span>", 2)
|
||||
|
||||
//Checking for protections
|
||||
var/ear_safety = M.check_ear_prot()
|
||||
var/distance = max(1, get_dist(get_turf(A), get_turf(M)))
|
||||
var/distance = max(1, get_dist(source_turf, get_turf(M)))
|
||||
var/stun_amount = max(10 / distance, 3)
|
||||
|
||||
//Flash
|
||||
// Flash
|
||||
if(flash)
|
||||
if(M.weakeyes)
|
||||
M.visible_message("<span class='disarm'><b>[M]</b> screams and collapses!</span>")
|
||||
@@ -49,21 +61,20 @@
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/obj/item/organ/internal/eyes/E = H.get_int_organ(/obj/item/organ/internal/eyes)
|
||||
if(E)
|
||||
E.receive_damage(8, 1)
|
||||
|
||||
E.receive_damage(8, TRUE)
|
||||
if(M.flash_eyes(affect_silicon = TRUE))
|
||||
M.Stun(max(10 / distance, 3))
|
||||
M.Weaken(max(10 / distance, 3))
|
||||
M.Stun(stun_amount)
|
||||
M.Weaken(stun_amount)
|
||||
|
||||
|
||||
//Bang
|
||||
// Bang
|
||||
var/ear_safety = M.check_ear_prot()
|
||||
if(bang)
|
||||
if(!distance || A.loc == M || A.loc == M.loc) //Holding on person or being exactly where lies is significantly more dangerous and voids protection
|
||||
if(!distance || A.loc == M || A.loc == M.loc) // Holding on person or being exactly where lies is significantly more dangerous and voids protection
|
||||
M.Stun(10)
|
||||
M.Weaken(10)
|
||||
if(!ear_safety)
|
||||
M.Stun(max(10 / distance, 3))
|
||||
M.Weaken(max(10 / distance, 3))
|
||||
M.Stun(stun_amount)
|
||||
M.Weaken(stun_amount)
|
||||
M.AdjustEarDamage(rand(0, 5), 15)
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
@@ -74,6 +85,5 @@
|
||||
if(prob(ears.ear_damage - 5))
|
||||
to_chat(M, "<span class='warning'>You can't hear anything!</span>")
|
||||
M.BecomeDeaf()
|
||||
else
|
||||
if(ears.ear_damage >= 5)
|
||||
to_chat(M, "<span class='warning'>Your ears start to ring!</span>")
|
||||
else if(ears.ear_damage >= 5)
|
||||
to_chat(M, "<span class='warning'>Your ears start to ring!</span>")
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
/obj/item/grenade/smokebomb/prime()
|
||||
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
src.smoke.set_up(10, 0, usr.loc)
|
||||
smoke.set_up(10, 0)
|
||||
spawn(0)
|
||||
src.smoke.start()
|
||||
sleep(10)
|
||||
|
||||
@@ -126,13 +126,15 @@
|
||||
color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN)
|
||||
..()
|
||||
|
||||
/obj/item/restraints/handcuffs/cable/proc/cable_color(var/colorC)
|
||||
if(colorC)
|
||||
if(colorC == "rainbow")
|
||||
colorC = color_rainbow()
|
||||
color = colorC
|
||||
else
|
||||
/obj/item/restraints/handcuffs/cable/proc/cable_color(colorC)
|
||||
if(!colorC)
|
||||
color = COLOR_RED
|
||||
else if(colorC == "rainbow")
|
||||
color = color_rainbow()
|
||||
else if(colorC == "orange") //byond only knows 16 colors by name, and orange isn't one of them
|
||||
color = COLOR_ORANGE
|
||||
else
|
||||
color = colorC
|
||||
|
||||
/obj/item/restraints/handcuffs/cable/proc/color_rainbow()
|
||||
color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN)
|
||||
|
||||
@@ -255,7 +255,7 @@
|
||||
|
||||
possessed = TRUE
|
||||
|
||||
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as the spirit of [user.real_name]'s blade?", ROLE_PAI, 0, 100)
|
||||
var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Do you want to play as the spirit of [user.real_name]'s blade?", ROLE_PAI, FALSE, 10 SECONDS, source = src)
|
||||
var/mob/dead/observer/theghost = null
|
||||
|
||||
if(candidates.len)
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
|
||||
/obj/item/shard/Crossed(mob/living/L, oldloc)
|
||||
if(istype(L) && has_gravity(loc))
|
||||
if(L.incorporeal_move || L.flying)
|
||||
if(L.incorporeal_move || L.flying || L.floating)
|
||||
return
|
||||
playsound(loc, 'sound/effects/glass_step.ogg', 50, TRUE)
|
||||
return ..()
|
||||
|
||||
@@ -372,6 +372,15 @@
|
||||
new /obj/item/ammo_box/magazine/m12g/buckshot(src)
|
||||
new /obj/item/ammo_box/magazine/m12g/dragon(src)
|
||||
|
||||
/obj/item/storage/backpack/duffel/syndie/ammo/shotgunXLmags
|
||||
desc = "A large duffelbag, containing three types of extended drum magazines."
|
||||
|
||||
/obj/item/storage/backpack/duffel/syndie/ammo/shotgunXLmags/New()
|
||||
..()
|
||||
new /obj/item/ammo_box/magazine/m12g/XtrLrg(src)
|
||||
new /obj/item/ammo_box/magazine/m12g/XtrLrg/buckshot(src)
|
||||
new /obj/item/ammo_box/magazine/m12g/XtrLrg/dragon(src)
|
||||
|
||||
/obj/item/storage/backpack/duffel/mining_conscript/
|
||||
name = "mining conscription kit"
|
||||
desc = "A kit containing everything a crewmember needs to support a shaft miner in the field."
|
||||
|
||||
@@ -380,12 +380,13 @@
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
flags = CONDUCT
|
||||
materials = list(MAT_METAL=3000)
|
||||
cant_hold = list(/obj/item/disk/nuclear) // Prevents some cheesing
|
||||
|
||||
/obj/item/storage/bag/tray/attack(mob/living/M as mob, mob/living/user as mob)
|
||||
/obj/item/storage/bag/tray/attack(mob/living/M, mob/living/user)
|
||||
..()
|
||||
// Drop all the things. All of them.
|
||||
var/list/obj/item/oldContents = contents.Copy()
|
||||
quick_empty()
|
||||
drop_inventory(user)
|
||||
|
||||
// Make each item scatter a bit
|
||||
for(var/obj/item/I in oldContents)
|
||||
|
||||
@@ -204,8 +204,10 @@
|
||||
/obj/item/flashlight/pen,
|
||||
/obj/item/seeds,
|
||||
/obj/item/wirecutters,
|
||||
/obj/item/wrench,
|
||||
)
|
||||
/obj/item/wrench,
|
||||
/obj/item/reagent_containers/spray/weedspray,
|
||||
/obj/item/reagent_containers/spray/pestspray
|
||||
)
|
||||
|
||||
/obj/item/storage/belt/security
|
||||
name = "security belt"
|
||||
|
||||
@@ -846,7 +846,7 @@
|
||||
desc = "A small box of Almost But Not Quite Plasma Premium Matches."
|
||||
icon = 'icons/obj/cigarettes.dmi'
|
||||
icon_state = "matchbox"
|
||||
item_state = "zippo"
|
||||
item_state = "matchbox"
|
||||
storage_slots = 10
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
max_w_class = WEIGHT_CLASS_TINY
|
||||
|
||||
@@ -226,14 +226,14 @@
|
||||
name = "\improper DromedaryCo packet"
|
||||
desc = "A packet of six imported DromedaryCo cancer sticks. A label on the packaging reads, \"Wouldn't a slow death make a change?\""
|
||||
icon_state = "Dpacket"
|
||||
item_state = "cigpacket"
|
||||
item_state = "Dpacket"
|
||||
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/syndicate
|
||||
name = "\improper Syndicate Cigarettes"
|
||||
desc = "A packet of six evil-looking cigarettes, A label on the packaging reads, \"Donk Co\""
|
||||
icon_state = "robustpacket"
|
||||
item_state = "cigpacket"
|
||||
item_state = "robustpacket"
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/syndicate/New()
|
||||
..()
|
||||
@@ -244,14 +244,14 @@
|
||||
name = "cigarette packet"
|
||||
desc = "An obscure brand of cigarettes."
|
||||
icon_state = "syndiepacket"
|
||||
item_state = "cigpacket"
|
||||
item_state = "syndiepacket"
|
||||
cigarette_type = /obj/item/clothing/mask/cigarette/syndicate
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/cigpack_med
|
||||
name = "Medical Marijuana Packet"
|
||||
desc = "A prescription packet containing six marijuana cigarettes."
|
||||
icon_state = "medpacket"
|
||||
item_state = "cigpacket"
|
||||
item_state = "medpacket"
|
||||
cigarette_type = /obj/item/clothing/mask/cigarette/medical_marijuana
|
||||
|
||||
|
||||
@@ -259,46 +259,46 @@
|
||||
name = "\improper Uplift Smooth packet"
|
||||
desc = "Your favorite brand, now menthol flavored."
|
||||
icon_state = "upliftpacket"
|
||||
item_state = "cigpacket"
|
||||
item_state = "upliftpacket"
|
||||
cigarette_type = /obj/item/clothing/mask/cigarette/menthol
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/cigpack_robust
|
||||
name = "\improper Robust packet"
|
||||
desc = "Smoked by the robust."
|
||||
icon_state = "robustpacket"
|
||||
item_state = "cigpacket"
|
||||
item_state = "robustpacket"
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/cigpack_robustgold
|
||||
name = "\improper Robust Gold packet"
|
||||
desc = "Smoked by the truly robust."
|
||||
icon_state = "robustgpacket"
|
||||
item_state = "cigpacket"
|
||||
item_state = "robustgpacket"
|
||||
cigarette_type = /obj/item/clothing/mask/cigarette/robustgold
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/cigpack_carp
|
||||
name = "\improper Carp Classic packet"
|
||||
desc = "Since 2313."
|
||||
icon_state = "carppacket"
|
||||
item_state = "cigpacket"
|
||||
item_state = "carppacket"
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/cigpack_midori
|
||||
name = "\improper Midori Tabako packet"
|
||||
desc = "You can't understand the runes, but the packet smells funny."
|
||||
icon_state = "midoripacket"
|
||||
item_state = "cigpacket"
|
||||
item_state = "midoripacket"
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/cigpack_shadyjims
|
||||
name ="\improper Shady Jim's Super Slims"
|
||||
desc = "Is your weight slowing you down? Having trouble running away from gravitational singularities? Can't stop stuffing your mouth? Smoke Shady Jim's Super Slims and watch all that fat burn away. Guaranteed results!"
|
||||
icon_state = "shadyjimpacket"
|
||||
item_state = "cigpacket"
|
||||
item_state = "shadyjimpacket"
|
||||
cigarette_type = /obj/item/clothing/mask/cigarette/shadyjims
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/cigpack_random
|
||||
name ="\improper Embellished Enigma packet"
|
||||
desc = "For the true connoisseur of exotic flavors."
|
||||
icon_state = "shadyjimpacket"
|
||||
item_state = "cigpacket"
|
||||
item_state = "shadyjimpacket"
|
||||
cigarette_type = /obj/item/clothing/mask/cigarette/random
|
||||
|
||||
/obj/item/storage/fancy/rollingpapers
|
||||
@@ -307,6 +307,7 @@
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
icon = 'icons/obj/cigarettes.dmi'
|
||||
icon_state = "cig_paper_pack"
|
||||
item_state = "cig_paper_pack"
|
||||
storage_slots = 10
|
||||
icon_type = "rolling paper"
|
||||
can_hold = list(/obj/item/rollingpaper)
|
||||
|
||||
@@ -438,8 +438,11 @@
|
||||
if((!ishuman(usr) && (src.loc != usr)) || usr.stat || usr.restrained())
|
||||
return
|
||||
|
||||
drop_inventory(usr)
|
||||
|
||||
/obj/item/storage/proc/drop_inventory(user)
|
||||
var/turf/T = get_turf(src)
|
||||
hide_from(usr)
|
||||
hide_from(user)
|
||||
for(var/obj/item/I in contents)
|
||||
remove_from_storage(I, T)
|
||||
CHECK_TICK
|
||||
@@ -499,10 +502,9 @@
|
||||
|
||||
/obj/item/storage/attack_self(mob/user)
|
||||
|
||||
//Clicking on itself will empty it, if it has the verb to do that.
|
||||
if(user.is_in_active_hand(src))
|
||||
if(verbs.Find(/obj/item/storage/verb/quick_empty))
|
||||
quick_empty()
|
||||
//Clicking on itself will empty it, if allow_quick_empty is TRUE
|
||||
if(allow_quick_empty && user.is_in_active_hand(src))
|
||||
drop_inventory(user)
|
||||
|
||||
//Returns the storage depth of an atom. This is the number of storage items the atom is contained in before reaching toplevel (the area).
|
||||
//Returns -1 if the atom was not found on container.
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
/* Weapons
|
||||
* Contains:
|
||||
* Banhammer
|
||||
* Classic Baton
|
||||
*/
|
||||
|
||||
/*
|
||||
* Banhammer
|
||||
*/
|
||||
/obj/item/banhammer/attack(mob/M, mob/user)
|
||||
to_chat(M, "<font color='red'><b> You have been banned FOR NO REISIN by [user]<b></font>")
|
||||
to_chat(user, "<font color='red'> You have <b>BANNED</b> [M]</font>")
|
||||
playsound(loc, 'sound/effects/adminhelp.ogg', 15) //keep it at 15% volume so people don't jump out of their skin too much
|
||||
|
||||
/*
|
||||
* Classic Baton
|
||||
*/
|
||||
|
||||
/obj/item/melee/classic_baton
|
||||
name = "police baton"
|
||||
desc = "A wooden truncheon for beating criminal scum."
|
||||
icon_state = "baton"
|
||||
item_state = "classic_baton"
|
||||
slot_flags = SLOT_BELT
|
||||
force = 12 //9 hit crit
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
var/cooldown = 0
|
||||
var/on = 1
|
||||
|
||||
/obj/item/melee/classic_baton/attack(mob/target as mob, mob/living/user as mob)
|
||||
if(on)
|
||||
add_fingerprint(user)
|
||||
if((CLUMSY in user.mutations) && prob(50))
|
||||
to_chat(user, "<span class ='danger'>You club yourself over the head.</span>")
|
||||
user.Weaken(3 * force)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.apply_damage(2*force, BRUTE, "head")
|
||||
else
|
||||
user.take_organ_damage(2*force)
|
||||
return
|
||||
if(isrobot(target))
|
||||
..()
|
||||
return
|
||||
if(!isliving(target))
|
||||
return
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
if(!..()) return
|
||||
if(!isrobot(target)) return
|
||||
else
|
||||
if(cooldown <= 0)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(H.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK))
|
||||
return
|
||||
if(check_martial_counter(H, user))
|
||||
return
|
||||
playsound(get_turf(src), 'sound/effects/woodhit.ogg', 75, 1, -1)
|
||||
target.Weaken(3)
|
||||
add_attack_logs(user, target, "Stunned with [src]")
|
||||
add_fingerprint(user)
|
||||
target.visible_message("<span class ='danger'>[user] has knocked down [target] with \the [src]!</span>", \
|
||||
"<span class ='userdanger'>[user] has knocked down [target] with \the [src]!</span>")
|
||||
if(!iscarbon(user))
|
||||
target.LAssailant = null
|
||||
else
|
||||
target.LAssailant = user
|
||||
cooldown = 1
|
||||
spawn(40)
|
||||
cooldown = 0
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/melee/classic_baton/ntcane
|
||||
name = "fancy cane"
|
||||
desc = "A cane with special engraving on it. It seems well suited for fending off assailants..."
|
||||
icon_state = "cane_nt"
|
||||
item_state = "cane_nt"
|
||||
needs_permit = 0
|
||||
|
||||
/obj/item/melee/classic_baton/ntcane/is_crutch()
|
||||
return 1
|
||||
|
||||
//Telescopic baton
|
||||
/obj/item/melee/classic_baton/telescopic
|
||||
name = "telescopic baton"
|
||||
desc = "A compact yet robust personal defense weapon. Can be concealed when folded."
|
||||
icon_state = "telebaton_0"
|
||||
item_state = null
|
||||
slot_flags = SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
needs_permit = 0
|
||||
force = 0
|
||||
on = 0
|
||||
|
||||
/obj/item/melee/classic_baton/telescopic/attack_self(mob/user as mob)
|
||||
on = !on
|
||||
if(on)
|
||||
to_chat(user, "<span class ='warning'>You extend the baton.</span>")
|
||||
icon_state = "telebaton_1"
|
||||
item_state = "nullrod"
|
||||
w_class = WEIGHT_CLASS_BULKY //doesnt fit in backpack when its on for balance
|
||||
force = 10 //stunbaton damage
|
||||
attack_verb = list("smacked", "struck", "cracked", "beaten")
|
||||
else
|
||||
to_chat(user, "<span class ='notice'>You collapse the baton.</span>")
|
||||
icon_state = "telebaton_0"
|
||||
item_state = null //no sprite for concealment even when in hand
|
||||
slot_flags = SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
force = 0 //not so robust now
|
||||
attack_verb = list("hit", "poked")
|
||||
if(istype(user,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.update_inv_l_hand()
|
||||
H.update_inv_r_hand()
|
||||
playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, 1)
|
||||
add_fingerprint(user)
|
||||
@@ -43,35 +43,31 @@
|
||||
/obj/item/tank/proc/toggle_internals(mob/user, silent = FALSE)
|
||||
var/mob/living/carbon/C = user
|
||||
if(!istype(C))
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(C.internal == src)
|
||||
to_chat(C, "<span class='notice'>You close \the [src] valve.</span>")
|
||||
C.internal = null
|
||||
else
|
||||
var/can_open_valve = 0
|
||||
if(C.get_organ_slot("breathing_tube"))
|
||||
can_open_valve = 1
|
||||
else if(C.wear_mask && C.wear_mask.flags & AIRTIGHT)
|
||||
can_open_valve = 1
|
||||
else if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
if(H.head && H.head.flags & AIRTIGHT)
|
||||
can_open_valve = 1
|
||||
if(!C.get_organ_slot("breathing_tube")) // Breathing tubes can always use internals, if they have one, skip ahead and turn internals on/off
|
||||
if(!C.wear_mask) // Do we have a mask equipped?
|
||||
return FALSE
|
||||
|
||||
if(can_open_valve)
|
||||
var/obj/item/clothing/mask/M = C.wear_mask
|
||||
// If the "mask" isn't actually a mask OR That mask isn't internals compatible AND Their headgear isn't internals compatible
|
||||
if(!istype(M) || (!(initial(M.flags) & AIRTIGHT) && !(C.head.flags & AIRTIGHT)))
|
||||
if(!silent)
|
||||
to_chat(C, "<span class='warning'>You are not wearing a suitable mask or helmet.</span>")
|
||||
return FALSE
|
||||
if(M.mask_adjusted) // If the mask is equipped but pushed down
|
||||
M.adjustmask(C) // Adjust it back
|
||||
|
||||
if(!silent)
|
||||
if(C.internal)
|
||||
if(!silent)
|
||||
to_chat(C, "<span class='notice'>You switch your internals to [src].</span>")
|
||||
to_chat(C, "<span class='notice'>You switch your internals to [src].</span>")
|
||||
else
|
||||
if(!silent)
|
||||
to_chat(C, "<span class='notice'>You open \the [src] valve.</span>")
|
||||
C.internal = src
|
||||
else
|
||||
if(!silent)
|
||||
to_chat(C, "<span class='notice'>You are not wearing a suitable mask or helmet.</span>")
|
||||
return 0
|
||||
|
||||
to_chat(C, "<span class='notice'>You open \the [src] valve.</span>")
|
||||
C.internal = src
|
||||
C.update_action_buttons_icon()
|
||||
|
||||
|
||||
@@ -142,70 +138,55 @@
|
||||
if(!(air_contents))
|
||||
return
|
||||
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/item/tank/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
// update the ui if it exists, returns null if no ui is passed/found
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/item/tank/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_inventory_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
// the ui does not exist, so we'll create a new() one
|
||||
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
||||
ui = new(user, src, ui_key, "tanks.tmpl", "Tank", 500, 300)
|
||||
// open the new ui window
|
||||
ui = new(user, src, ui_key, "Tank", name, 300, 150, master_ui, state)
|
||||
ui.open()
|
||||
// auto update every Master Controller tick
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/item/tank/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state)
|
||||
var/using_internal
|
||||
if(iscarbon(loc))
|
||||
var/mob/living/carbon/C = loc
|
||||
if(C.internal == src)
|
||||
using_internal = 1
|
||||
|
||||
var/data[0]
|
||||
/obj/item/tank/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["tankPressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0)
|
||||
data["releasePressure"] = round(distribute_pressure ? distribute_pressure : 0)
|
||||
data["defaultReleasePressure"] = round(TANK_DEFAULT_RELEASE_PRESSURE)
|
||||
data["minReleasePressure"] = round(TANK_DEFAULT_RELEASE_PRESSURE)
|
||||
data["maxReleasePressure"] = round(TANK_MAX_RELEASE_PRESSURE)
|
||||
data["valveOpen"] = using_internal ? 1 : 0
|
||||
|
||||
data["maskConnected"] = 0
|
||||
|
||||
if(iscarbon(loc))
|
||||
var/mob/living/carbon/C = loc
|
||||
if(C.internal == src)
|
||||
data["maskConnected"] = 1
|
||||
else
|
||||
if(C.wear_mask && (C.wear_mask.flags & AIRTIGHT))
|
||||
data["maskConnected"] = 1
|
||||
else if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
if(H.head && (H.head.flags & AIRTIGHT))
|
||||
data["maskConnected"] = 1
|
||||
|
||||
var/mob/living/carbon/C = user
|
||||
if(!istype(C))
|
||||
C = loc.loc
|
||||
if(!istype(C))
|
||||
return data
|
||||
data["has_mask"] = C.wear_mask ? TRUE : FALSE
|
||||
data["connected"] = (C.internal && C.internal == src) ? TRUE : FALSE
|
||||
return data
|
||||
|
||||
/obj/item/tank/Topic(href, href_list)
|
||||
/obj/item/tank/tgui_act(action, params)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["dist_p"])
|
||||
if(href_list["dist_p"] == "reset")
|
||||
distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE
|
||||
else if(href_list["dist_p"] == "max")
|
||||
distribute_pressure = TANK_MAX_RELEASE_PRESSURE
|
||||
return
|
||||
. = TRUE
|
||||
switch(action)
|
||||
if("pressure")
|
||||
var/pressure = params["pressure"]
|
||||
if(pressure == "reset")
|
||||
pressure = initial(distribute_pressure)
|
||||
else if(pressure == "min")
|
||||
pressure = TANK_DEFAULT_RELEASE_PRESSURE
|
||||
else if(pressure == "max")
|
||||
pressure = TANK_MAX_RELEASE_PRESSURE
|
||||
else if(text2num(pressure) != null)
|
||||
pressure = text2num(pressure)
|
||||
else
|
||||
. = FALSE
|
||||
if(.)
|
||||
distribute_pressure = clamp(round(pressure), TANK_DEFAULT_RELEASE_PRESSURE, TANK_MAX_RELEASE_PRESSURE)
|
||||
if("internals")
|
||||
toggle_internals(usr)
|
||||
else
|
||||
var/cp = text2num(href_list["dist_p"])
|
||||
distribute_pressure += cp
|
||||
distribute_pressure = min(max(round(distribute_pressure), 0), TANK_MAX_RELEASE_PRESSURE)
|
||||
|
||||
if(href_list["stat"])
|
||||
toggle_internals(usr)
|
||||
|
||||
add_fingerprint(usr)
|
||||
return 1
|
||||
|
||||
. = FALSE
|
||||
if(.)
|
||||
add_fingerprint(usr)
|
||||
|
||||
/obj/item/tank/remove_air(amount)
|
||||
return air_contents.remove(amount)
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/**
|
||||
* # Banhammer
|
||||
*/
|
||||
/obj/item/banhammer
|
||||
desc = "A banhammer"
|
||||
name = "banhammer"
|
||||
@@ -13,11 +16,15 @@
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70)
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
|
||||
/obj/item/banhammer/suicide_act(mob/user)
|
||||
to_chat(viewers(user), "<span class='suicide'>[user] is hitting [user.p_them()]self with the [src.name]! It looks like [user.p_theyre()] trying to ban [user.p_them()]self from life.</span>")
|
||||
return BRUTELOSS|FIRELOSS|TOXLOSS|OXYLOSS
|
||||
|
||||
/obj/item/banhammer/attack(mob/M, mob/user)
|
||||
to_chat(M, "<font color='red'><b> You have been banned FOR NO REISIN by [user]<b></font>")
|
||||
to_chat(user, "<font color='red'> You have <b>BANNED</b> [M]</font>")
|
||||
playsound(loc, 'sound/effects/adminhelp.ogg', 15) //keep it at 15% volume so people don't jump out of their skin too much
|
||||
|
||||
/obj/item/sord
|
||||
name = "\improper SORD"
|
||||
desc = "This thing is so unspeakably shitty you are having a hard time even holding it."
|
||||
|
||||
@@ -25,9 +25,13 @@
|
||||
..()
|
||||
spawn(1)
|
||||
if(!opened) // if closed, any item at the crate's loc is put in the contents
|
||||
var/itemcount = 0
|
||||
for(var/obj/item/I in loc)
|
||||
if(I.density || I.anchored || I == src) continue
|
||||
I.forceMove(src)
|
||||
// Ensure the storage cap is respected
|
||||
if(++itemcount >= storage_capacity)
|
||||
break
|
||||
|
||||
// Fix for #383 - C4 deleting fridges with corpses
|
||||
/obj/structure/closet/Destroy()
|
||||
|
||||
@@ -45,8 +45,6 @@
|
||||
new /obj/item/clothing/suit/storage/labcoat(src)
|
||||
new /obj/item/radio/headset/headset_sci(src)
|
||||
new /obj/item/radio/headset/headset_sci(src)
|
||||
new /obj/item/reagent_containers/food/drinks/oilcan(src)
|
||||
new /obj/item/reagent_containers/food/drinks/oilcan(src)
|
||||
|
||||
/obj/structure/closet/secure_closet/RD
|
||||
name = "research director's locker"
|
||||
|
||||
@@ -69,6 +69,11 @@
|
||||
/obj/structure/closet/secure_closet/closed_item_click(mob/user)
|
||||
togglelock(user)
|
||||
|
||||
/obj/structure/closet/secure_closet/AltClick(mob/user)
|
||||
..()
|
||||
if(Adjacent(user))
|
||||
togglelock(user)
|
||||
|
||||
/obj/structure/closet/secure_closet/emag_act(mob/user)
|
||||
if(!broken)
|
||||
broken = TRUE
|
||||
|
||||
@@ -82,9 +82,8 @@
|
||||
content_mob = /mob/living/simple_animal/pet/dog/fox
|
||||
|
||||
/obj/structure/closet/critter/butterfly
|
||||
name = "butterflies crate"
|
||||
name = "butterfly crate"
|
||||
content_mob = /mob/living/simple_animal/butterfly
|
||||
amount = 50
|
||||
|
||||
/obj/structure/closet/critter/deer
|
||||
name = "deer crate"
|
||||
|
||||
@@ -56,27 +56,20 @@
|
||||
|
||||
/obj/structure/dresser/crowbar_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(!I.tool_start_check(src, user, 0))
|
||||
if(!I.use_tool(src, user, 0))
|
||||
return
|
||||
TOOL_ATTEMPT_DISMANTLE_MESSAGE
|
||||
if(I.use_tool(src, user, 50, volume = I.tool_volume))
|
||||
TOOL_DISMANTLE_SUCCESS_MESSAGE
|
||||
|
||||
deconstruct(disassembled = TRUE)
|
||||
|
||||
/obj/structure/dresser/wrench_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
|
||||
return
|
||||
if(anchored)
|
||||
WRENCH_UNANCHOR_MESSAGE
|
||||
anchored = FALSE
|
||||
else
|
||||
if(!isfloorturf(loc))
|
||||
user.visible_message("<span class='warning'>A floor must be present to secure [src]!</span>")
|
||||
return
|
||||
WRENCH_ANCHOR_MESSAGE
|
||||
anchored = TRUE
|
||||
default_unfasten_wrench(user, I, time = 20)
|
||||
|
||||
/obj/structure/dresser/deconstruct(disassembled = TRUE)
|
||||
new /obj/item/stack/sheet/wood(drop_location(), 30)
|
||||
qdel(src)
|
||||
obj/structure/dresser/deconstruct(disassembled = FALSE)
|
||||
var/mat_drop = 15
|
||||
if(disassembled)
|
||||
mat_drop = 30
|
||||
new /obj/item/stack/sheet/wood(drop_location(), mat_drop)
|
||||
..()
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
return
|
||||
if(!in_range(src, user))
|
||||
return
|
||||
if(!iscarbon(usr))
|
||||
if(!iscarbon(usr) && !isrobot(usr))
|
||||
return
|
||||
playsound(loc, 'sound/machines/click.ogg', 15, TRUE, -3)
|
||||
opened = !opened
|
||||
|
||||
@@ -11,12 +11,30 @@
|
||||
anchored = TRUE
|
||||
|
||||
/obj/structure/loom/attackby(obj/item/I, mob/user)
|
||||
if(default_unfasten_wrench(user, I, 5))
|
||||
return
|
||||
if(weave(I, user))
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/structure/loom/crowbar_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(!I.use_tool(src, user, 0))
|
||||
return
|
||||
TOOL_ATTEMPT_DISMANTLE_MESSAGE
|
||||
if(I.use_tool(src, user, 50, volume = I.tool_volume))
|
||||
TOOL_DISMANTLE_SUCCESS_MESSAGE
|
||||
deconstruct(disassembled = TRUE)
|
||||
|
||||
/obj/structure/loom/wrench_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
default_unfasten_wrench(user, I, time = 20)
|
||||
|
||||
/obj/structure/loom/deconstruct(disassembled = FALSE)
|
||||
var/mat_drop = 5
|
||||
if(disassembled)
|
||||
mat_drop = 10
|
||||
new /obj/item/stack/sheet/wood(drop_location(), mat_drop)
|
||||
..()
|
||||
|
||||
///Handles the weaving.
|
||||
/obj/structure/loom/proc/weave(obj/item/stack/sheet/cotton/W, mob/user)
|
||||
if(!istype(W))
|
||||
|
||||
@@ -1,341 +0,0 @@
|
||||
|
||||
|
||||
/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/repeat = 0 // number of times remaining to repeat
|
||||
var/max_repeat = 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
|
||||
|
||||
/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)
|
||||
var/sound/music_played = sound(soundfile)
|
||||
for(var/A in hearers(15, source))
|
||||
var/mob/M = A
|
||||
if(!M.client || !(M.client.prefs.sound & SOUND_INSTRUMENTS))
|
||||
continue
|
||||
M.playsound_local(source, null, 100, falloff = 5, S = music_played)
|
||||
|
||||
/datum/song/proc/shouldStopPlaying(mob/user)
|
||||
if(instrumentObj)
|
||||
//if(!user.canUseTopic(instrumentObj))
|
||||
//return 1
|
||||
return !instrumentObj.anchored // add special cases to stop in subclasses
|
||||
else
|
||||
return 1
|
||||
|
||||
/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 = 0
|
||||
return
|
||||
if(length(note) == 0)
|
||||
continue
|
||||
var/cur_note = text2ascii(note) - 96
|
||||
if(cur_note < 1 || cur_note > 7)
|
||||
continue
|
||||
for(var/i=2 to length(note))
|
||||
var/ni = copytext(note,i,i+1)
|
||||
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)
|
||||
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--
|
||||
playing = 0
|
||||
repeat = 0
|
||||
|
||||
/datum/song/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
if(!instrumentObj)
|
||||
return
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, instrumentObj, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, instrumentObj, ui_key, "song.tmpl", instrumentObj.name, 700, 500)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/datum/song/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state)
|
||||
var/data[0]
|
||||
|
||||
data["lines"] = lines
|
||||
data["tempo"] = tempo
|
||||
|
||||
data["playing"] = playing
|
||||
data["help"] = help
|
||||
data["repeat"] = repeat
|
||||
data["maxRepeat"] = max_repeat
|
||||
data["minTempo"] = world.tick_lag
|
||||
data["maxTempo"] = 600
|
||||
|
||||
return data
|
||||
|
||||
/datum/song/Topic(href, href_list)
|
||||
if(!in_range(instrumentObj, usr) || (issilicon(usr) && instrumentObj.loc != usr) || !isliving(usr) || usr.incapacitated())
|
||||
usr << browse(null, "window=instrument")
|
||||
usr.unset_machine()
|
||||
return 1
|
||||
|
||||
instrumentObj.add_fingerprint(usr)
|
||||
|
||||
if(href_list["newsong"])
|
||||
playing = 0
|
||||
lines = new()
|
||||
tempo = sanitize_tempo(5) // default 120 BPM
|
||||
name = ""
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
else if(href_list["import"])
|
||||
playing = 0
|
||||
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(t) >= 12000)
|
||||
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(t) > 12000)
|
||||
|
||||
//split into lines
|
||||
spawn()
|
||||
lines = splittext(t, "\n")
|
||||
if(lines.len == 0)
|
||||
return 1
|
||||
if(copytext(lines[1],1,6) == "BPM: ")
|
||||
tempo = sanitize_tempo(600 / text2num(copytext(lines[1],6)))
|
||||
lines.Cut(1,2)
|
||||
else
|
||||
tempo = sanitize_tempo(5) // default 120 BPM
|
||||
if(lines.len > 200)
|
||||
to_chat(usr, "Too many lines!")
|
||||
lines.Cut(201)
|
||||
var/linenum = 1
|
||||
for(var/l in lines)
|
||||
if(length(l) > 200)
|
||||
to_chat(usr, "Line [linenum] too long!")
|
||||
lines.Remove(l)
|
||||
else
|
||||
linenum++
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
else if(href_list["help"])
|
||||
help = !help
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
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_repeat)
|
||||
repeat = max_repeat
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
else if(href_list["tempo"])
|
||||
tempo = sanitize_tempo(tempo + text2num(href_list["tempo"]) * world.tick_lag)
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
else if(href_list["play"])
|
||||
if(playing)
|
||||
return
|
||||
playing = 1
|
||||
spawn()
|
||||
playsong(usr)
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
else if(href_list["insertline"])
|
||||
var/num = round(text2num(href_list["insertline"]))
|
||||
if(num < 1 || num > lines.len + 1)
|
||||
return
|
||||
|
||||
var/newline = html_encode(input("Enter your line: ", instrumentObj.name) as text|null)
|
||||
if(!newline || !in_range(instrumentObj, usr))
|
||||
return
|
||||
if(lines.len > 200)
|
||||
return
|
||||
if(length(newline) > 200)
|
||||
newline = copytext(newline, 1, 200)
|
||||
|
||||
lines.Insert(num, newline)
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
else if(href_list["deleteline"])
|
||||
var/num = round(text2num(href_list["deleteline"]))
|
||||
if(num > lines.len || num < 1)
|
||||
return
|
||||
lines.Cut(num, num + 1)
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
else if(href_list["modifyline"])
|
||||
var/num = round(text2num(href_list["modifyline"]))
|
||||
var/content = html_encode(input("Enter your line: ", instrumentObj.name, lines[num]) as text|null)
|
||||
if(!content || !in_range(instrumentObj, usr))
|
||||
return
|
||||
if(length(content) > 200)
|
||||
content = copytext(content, 1, 200)
|
||||
if(num > lines.len || num < 1)
|
||||
return
|
||||
lines[num] = content
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
else if(href_list["stop"])
|
||||
playing = 0
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
/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/shouldStopPlaying()
|
||||
if(instrumentObj)
|
||||
return !isliving(instrumentObj.loc)
|
||||
else
|
||||
return 1
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/obj/structure/piano
|
||||
name = "space minimoog"
|
||||
icon = 'icons/obj/musician.dmi'
|
||||
icon_state = "minimoog"
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/datum/song/song
|
||||
|
||||
|
||||
/obj/structure/piano/New()
|
||||
..()
|
||||
song = new("piano", src)
|
||||
|
||||
if(prob(50))
|
||||
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_NULL(song)
|
||||
return ..()
|
||||
|
||||
/obj/structure/piano/Initialize()
|
||||
if(song)
|
||||
song.tempo = song.sanitize_tempo(song.tempo) // tick_lag isn't set when the map is loaded
|
||||
..()
|
||||
|
||||
/obj/structure/piano/attack_hand(mob/user as mob)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/structure/piano/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
if(!isliving(user) || user.incapacitated() || !anchored)
|
||||
return
|
||||
|
||||
song.ui_interact(user, ui_key, ui, force_open)
|
||||
|
||||
/obj/structure/piano/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state)
|
||||
return song.ui_data(user, ui_key, state)
|
||||
|
||||
/obj/structure/piano/Topic(href, href_list)
|
||||
song.Topic(href, href_list)
|
||||
|
||||
/obj/structure/piano/wrench_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(!I.tool_use_check(user, 0))
|
||||
return
|
||||
if(!anchored && !isinspace())
|
||||
WRENCH_ANCHOR_MESSAGE
|
||||
if(!I.use_tool(src, user, 20, volume = I.tool_volume))
|
||||
return
|
||||
user.visible_message( \
|
||||
"[user] tightens [src]'s casters.", \
|
||||
"<span class='notice'> You have tightened [src]'s casters. Now it can be played again.</span>", \
|
||||
"You hear ratchet.")
|
||||
anchored = TRUE
|
||||
else if(anchored)
|
||||
to_chat(user, "<span class='notice'> You begin to loosen [src]'s casters...</span>")
|
||||
if(!I.use_tool(src, user, 40, volume = I.tool_volume))
|
||||
return
|
||||
user.visible_message( \
|
||||
"[user] loosens [src]'s casters.", \
|
||||
"<span class='notice'> You have loosened [src]. Now it can be pulled somewhere else.</span>", \
|
||||
"You hear ratchet.")
|
||||
anchored = FALSE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] needs to be bolted to the floor!</span>")
|
||||
@@ -292,12 +292,12 @@
|
||||
|
||||
/obj/structure/sign/directions/engineering
|
||||
name = "\improper Engineering Department"
|
||||
desc = "A direction sign, pointing out which way the Engineering department is."
|
||||
desc = "A direction sign, pointing out which way the Engineering Department is."
|
||||
icon_state = "direction_eng"
|
||||
|
||||
/obj/structure/sign/directions/security
|
||||
name = "\improper Security Department"
|
||||
desc = "A direction sign, pointing out which way the Security department is."
|
||||
desc = "A direction sign, pointing out which way the Security Department is."
|
||||
icon_state = "direction_sec"
|
||||
|
||||
/obj/structure/sign/directions/medical
|
||||
@@ -307,12 +307,12 @@
|
||||
|
||||
/obj/structure/sign/directions/evac
|
||||
name = "\improper Escape Arm"
|
||||
desc = "A direction sign, pointing out which way escape shuttle dock is."
|
||||
desc = "A direction sign, pointing out which way Escape Shuttle Dock is."
|
||||
icon_state = "direction_evac"
|
||||
|
||||
/obj/structure/sign/directions/cargo
|
||||
name = "\improper Cargo Department"
|
||||
desc = "A direction sign, pointing out which way the Cargo department is."
|
||||
desc = "A direction sign, pointing out which way the Cargo Department is."
|
||||
icon_state = "direction_supply"
|
||||
|
||||
/obj/structure/sign/explosives
|
||||
|
||||
Reference in New Issue
Block a user