mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-19 02:54:41 +01:00
Merge branch 'master' of https://github.com/ZomgPonies/Paradise
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
/obj/item
|
||||
name = "item"
|
||||
icon = 'icons/obj/items.dmi'
|
||||
var/discrete = 0 // used in item_attack.dm to make an item not show an attack message to viewers
|
||||
var/icon/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
|
||||
var/abstract = 0
|
||||
@@ -153,10 +154,12 @@
|
||||
return 0
|
||||
else
|
||||
user.u_equip(src)
|
||||
|
||||
else
|
||||
if(isliving(src.loc))
|
||||
return 0
|
||||
user.next_move = max(user.next_move+2,world.time + 2)
|
||||
|
||||
src.pickup(user)
|
||||
add_fingerprint(user)
|
||||
user.put_in_active_hand(src)
|
||||
@@ -616,10 +619,10 @@
|
||||
var/datum/organ/internal/eyes/eyes = H.internal_organs_by_name["eyes"]
|
||||
if(!eyes)
|
||||
return
|
||||
eyes.damage += rand(3,4)
|
||||
eyes.take_damage(rand(3,4), 1)
|
||||
if(eyes.damage >= eyes.min_bruised_damage)
|
||||
if(M.stat != 2)
|
||||
if(eyes.robotic <= 1) //robot eyes bleeding might be a bit silly
|
||||
if(!(istype(eyes, /datum/organ/internal/eyes/robotic)) || istype(eyes, /datum/organ/internal/eyes/assisted)) //robot eyes bleeding might be a bit silly
|
||||
M << "\red Your eyes start to bleed profusely!"
|
||||
if(prob(50))
|
||||
if(M.stat != 2)
|
||||
|
||||
@@ -121,7 +121,7 @@ move an amendment</a> to the drawing.</p>
|
||||
return
|
||||
var/area/A = new
|
||||
A.name = str
|
||||
A.tag="[A.type]_[md5(str)]" // without this dynamic light system ruin everithing
|
||||
A.tagbase="[A.type]_[md5(str)]" // without this dynamic light system ruins everything
|
||||
//var/ma
|
||||
//ma = A.master ? "[A.master]" : "(null)"
|
||||
//world << "DEBUG: create_area: <br>A.name=[A.name]<br>A.tag=[A.tag]<br>A.master=[ma]"
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/obj/item/device/pipe_freezer
|
||||
name = "Pipe Freezer"
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "pipe_freezer"
|
||||
item_state = "flight"
|
||||
@@ -48,6 +48,18 @@
|
||||
del(src)
|
||||
return
|
||||
|
||||
/obj/item/device/radio/beacon/syndicate/bomb
|
||||
name = "suspicious beacon"
|
||||
desc = "A label on it reads: <i>Warning: Activating this device will send a high-ordinance explosive to your location</i>."
|
||||
origin_tech = "bluespace=1;syndicate=7"
|
||||
|
||||
/obj/item/device/radio/beacon/syndicate/bomb/attack_self(mob/user as mob)
|
||||
if(user)
|
||||
user << "\blue Locked In"
|
||||
new /obj/machinery/syndicatebomb( user.loc )
|
||||
playsound(src, 'sound/effects/pop.ogg', 100, 1, 1)
|
||||
del(src)
|
||||
return
|
||||
|
||||
|
||||
/obj/item/device/telepad_beacon
|
||||
|
||||
@@ -19,6 +19,21 @@ REAGENT SCANNER
|
||||
item_state = "electronic"
|
||||
m_amt = 150
|
||||
origin_tech = "magnets=1;engineering=1"
|
||||
var/scan_range = 1
|
||||
var/pulse_duration = 10
|
||||
|
||||
/obj/item/device/t_scanner/longer_pulse
|
||||
origin_tech = "magnets=2;engineering=2"
|
||||
pulse_duration = 50
|
||||
|
||||
/obj/item/device/t_scanner/extended_range
|
||||
origin_tech = "magnets=1;engineering=3"
|
||||
scan_range = 3
|
||||
|
||||
/obj/item/device/t_scanner/extended_range/longer_pulse
|
||||
origin_tech = "magnets=2;engineering=3"
|
||||
scan_range = 3
|
||||
pulse_duration = 50
|
||||
|
||||
/obj/item/device/t_scanner/Destroy()
|
||||
if(on)
|
||||
@@ -39,7 +54,7 @@ REAGENT SCANNER
|
||||
processing_objects.Remove(src)
|
||||
return null
|
||||
|
||||
for(var/turf/T in range(1, src.loc) )
|
||||
for(var/turf/T in range(scan_range, src.loc) )
|
||||
|
||||
if(!T.intact)
|
||||
continue
|
||||
@@ -51,7 +66,7 @@ REAGENT SCANNER
|
||||
|
||||
if(O.invisibility == 101)
|
||||
O.invisibility = 0
|
||||
spawn(10)
|
||||
spawn(pulse_duration)
|
||||
if(O)
|
||||
var/turf/U = O.loc
|
||||
if(U.intact)
|
||||
@@ -65,6 +80,7 @@ REAGENT SCANNER
|
||||
M.alpha = oldalpha
|
||||
|
||||
var/mob/living/M = locate() in T
|
||||
|
||||
if(M && M.invisibility == 2)
|
||||
M.invisibility = 0
|
||||
spawn(2)
|
||||
|
||||
@@ -60,5 +60,92 @@ effective or pretty fucking useless.
|
||||
icon_state = "battererburnt"
|
||||
|
||||
|
||||
/*
|
||||
The radioactive microlaser, a device disguised as a health analyzer used to irradiate people.
|
||||
|
||||
The strength of the radiation is determined by the 'intensity' setting, while the delay between
|
||||
the scan and the irradiation kicking in is determined by the wavelength.
|
||||
|
||||
Each scan will cause the microlaser to have a brief cooldown period. Higher intensity will increase
|
||||
the cooldown, while higher wavelength will decrease it.
|
||||
|
||||
Wavelength is also slightly increased by the intensity as well.
|
||||
*/
|
||||
|
||||
/obj/item/device/rad_laser
|
||||
name = "Health Analyzer"
|
||||
icon_state = "health"
|
||||
item_state = "analyzer"
|
||||
desc = "A hand-held body scanner able to distinguish vital signs of the subject. A strange microlaser is hooked on to the scanning end."
|
||||
flags = FPRINT | TABLEPASS | CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
discrete = 1 // Makes the item not give an attack log message for viewers.
|
||||
throwforce = 3
|
||||
w_class = 1.0
|
||||
throw_speed = 5
|
||||
throw_range = 10
|
||||
m_amt = 200
|
||||
origin_tech = "magnets=3;biotech=5;syndicate=3"
|
||||
var/intensity = 5 // how much damage the radiation does
|
||||
var/wavelength = 10 // time it takes for the radiation to kick in, in seconds
|
||||
var/used = 0 // is it cooling down?
|
||||
|
||||
/obj/item/device/rad_laser/attack(mob/living/M as mob, mob/living/user as mob)
|
||||
if(!used)
|
||||
..()
|
||||
user.visible_message("<span class='notice'> [user] has analyzed [M]'s vitals.","<span class='notice'> You have analyzed [M]'s vitals.")
|
||||
var/cooldown = round(max(100,(((intensity*8)-(wavelength/2))+(intensity*2))*10))
|
||||
used = 1
|
||||
icon_state = "health1"
|
||||
handle_cooldown(cooldown) // splits off to handle the cooldown while handling wavelength
|
||||
spawn((wavelength+(intensity*4))*10)
|
||||
if(M)
|
||||
if(intensity >= 5)
|
||||
M.apply_effect(round(intensity/1.5), PARALYZE)
|
||||
M.apply_effect(intensity*10, IRRADIATE)
|
||||
else
|
||||
user << "<span class='danger'>The radioactive microlaser is still recharging.</span>"
|
||||
|
||||
/obj/item/device/rad_laser/proc/handle_cooldown(var/cooldown)
|
||||
spawn(cooldown)
|
||||
used = 0
|
||||
icon_state = "health"
|
||||
|
||||
/obj/item/device/rad_laser/attack_self(mob/user as mob)
|
||||
..()
|
||||
interact(user)
|
||||
|
||||
/obj/item/device/rad_laser/interact(mob/user as mob)
|
||||
user.set_machine(src)
|
||||
|
||||
var/cooldown = round(max(10,((intensity*8)-(wavelength/2))+(intensity*2)))
|
||||
var/dat = {"
|
||||
Radiation Intensity: <A href='?src=\ref[src];radint=-5'>-</A><A href='?src=\ref[src];radint=-1'>-</A> [intensity] <A href='?src=\ref[src];radint=1'>+</A><A href='?src=\ref[src];radint=5'>+</A><BR>
|
||||
Radiation Wavelength: <A href='?src=\ref[src];radwav=-5'>-</A><A href='?src=\ref[src];radwav=-1'>-</A> [(wavelength+(intensity*4))] <A href='?src=\ref[src];radwav=1'>+</A><A href='?src=\ref[src];radwav=5'>+</A><BR>
|
||||
Laser Cooldown: [cooldown] Seconds<BR>
|
||||
"}
|
||||
|
||||
var/datum/browser/popup = new(user, "radlaser", "Radioactive Microlaser Interface", 400, 240)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/obj/item/device/rad_laser/Topic(href, href_list)
|
||||
if(!in_range(src, usr) || issilicon(usr) || !usr.canmove || usr.restrained())
|
||||
return 1
|
||||
|
||||
usr.set_machine(src)
|
||||
|
||||
if(href_list["radint"])
|
||||
var/amount = text2num(href_list["radint"])
|
||||
amount += intensity
|
||||
intensity = max(1,(min(10,amount)))
|
||||
|
||||
else if(href_list["radwav"])
|
||||
var/amount = text2num(href_list["radwav"])
|
||||
amount += wavelength
|
||||
wavelength = max(1,(min(120,amount)))
|
||||
|
||||
//updateUsrDialog()
|
||||
interact(usr)
|
||||
add_fingerprint(usr)
|
||||
return
|
||||
@@ -7,396 +7,26 @@
|
||||
icon_state = "violin"
|
||||
item_state = "violin"
|
||||
force = 10
|
||||
var/datum/song/song
|
||||
var/playing = 0
|
||||
var/help = 0
|
||||
var/edit = 1
|
||||
var/repeat = 0
|
||||
var/datum/song/handheld/song
|
||||
|
||||
/obj/item/device/violin/proc/playnote(var/note as text)
|
||||
//world << "Note: [note]"
|
||||
var/soundfile
|
||||
/*BYOND loads resource files at compile time if they are ''. This means you can't really manipulate them dynamically.
|
||||
Tried doing it dynamically at first but its more trouble than its worth. Would have saved many lines tho.*/
|
||||
switch(note)
|
||||
if("Cn1") soundfile = 'sound/violin/Cn1.mid'
|
||||
if("C#1") soundfile = 'sound/violin/C#1.mid'
|
||||
if("Db1") soundfile = 'sound/violin/Db1.mid'
|
||||
if("Dn1") soundfile = 'sound/violin/Dn1.mid'
|
||||
if("D#1") soundfile = 'sound/violin/D#1.mid'
|
||||
if("Eb1") soundfile = 'sound/violin/Eb1.mid'
|
||||
if("En1") soundfile = 'sound/violin/En1.mid'
|
||||
if("E#1") soundfile = 'sound/violin/E#1.mid'
|
||||
if("Fb1") soundfile = 'sound/violin/Fb1.mid'
|
||||
if("Fn1") soundfile = 'sound/violin/Fn1.mid'
|
||||
if("F#1") soundfile = 'sound/violin/F#1.mid'
|
||||
if("Gb1") soundfile = 'sound/violin/Gb1.mid'
|
||||
if("Gn1") soundfile = 'sound/violin/Gn1.mid'
|
||||
if("G#1") soundfile = 'sound/violin/G#1.mid'
|
||||
if("Ab1") soundfile = 'sound/violin/Ab1.mid'
|
||||
if("An1") soundfile = 'sound/violin/An1.mid'
|
||||
if("A#1") soundfile = 'sound/violin/A#1.mid'
|
||||
if("Bb1") soundfile = 'sound/violin/Bb1.mid'
|
||||
if("Bn1") soundfile = 'sound/violin/Bn1.mid'
|
||||
if("B#1") soundfile = 'sound/violin/B#1.mid'
|
||||
if("Cb2") soundfile = 'sound/violin/Cb2.mid'
|
||||
if("Cn2") soundfile = 'sound/violin/Cn2.mid'
|
||||
if("C#2") soundfile = 'sound/violin/C#2.mid'
|
||||
if("Db2") soundfile = 'sound/violin/Db2.mid'
|
||||
if("Dn2") soundfile = 'sound/violin/Dn2.mid'
|
||||
if("D#2") soundfile = 'sound/violin/D#2.mid'
|
||||
if("Eb2") soundfile = 'sound/violin/Eb2.mid'
|
||||
if("En2") soundfile = 'sound/violin/En2.mid'
|
||||
if("E#2") soundfile = 'sound/violin/E#2.mid'
|
||||
if("Fb2") soundfile = 'sound/violin/Fb2.mid'
|
||||
if("Fn2") soundfile = 'sound/violin/Fn2.mid'
|
||||
if("F#2") soundfile = 'sound/violin/F#2.mid'
|
||||
if("Gb2") soundfile = 'sound/violin/Gb2.mid'
|
||||
if("Gn2") soundfile = 'sound/violin/Gn2.mid'
|
||||
if("G#2") soundfile = 'sound/violin/G#2.mid'
|
||||
if("Ab2") soundfile = 'sound/violin/Ab2.mid'
|
||||
if("An2") soundfile = 'sound/violin/An2.mid'
|
||||
if("A#2") soundfile = 'sound/violin/A#2.mid'
|
||||
if("Bb2") soundfile = 'sound/violin/Bb2.mid'
|
||||
if("Bn2") soundfile = 'sound/violin/Bn2.mid'
|
||||
if("B#2") soundfile = 'sound/violin/B#2.mid'
|
||||
if("Cb3") soundfile = 'sound/violin/Cb3.mid'
|
||||
if("Cn3") soundfile = 'sound/violin/Cn3.mid'
|
||||
if("C#3") soundfile = 'sound/violin/C#3.mid'
|
||||
if("Db3") soundfile = 'sound/violin/Db3.mid'
|
||||
if("Dn3") soundfile = 'sound/violin/Dn3.mid'
|
||||
if("D#3") soundfile = 'sound/violin/D#3.mid'
|
||||
if("Eb3") soundfile = 'sound/violin/Eb3.mid'
|
||||
if("En3") soundfile = 'sound/violin/En3.mid'
|
||||
if("E#3") soundfile = 'sound/violin/E#3.mid'
|
||||
if("Fb3") soundfile = 'sound/violin/Fb3.mid'
|
||||
if("Fn3") soundfile = 'sound/violin/Fn3.mid'
|
||||
if("F#3") soundfile = 'sound/violin/F#3.mid'
|
||||
if("Gb3") soundfile = 'sound/violin/Gb3.mid'
|
||||
if("Gn3") soundfile = 'sound/violin/Gn3.mid'
|
||||
if("G#3") soundfile = 'sound/violin/G#3.mid'
|
||||
if("Ab3") soundfile = 'sound/violin/Ab3.mid'
|
||||
if("An3") soundfile = 'sound/violin/An3.mid'
|
||||
if("A#3") soundfile = 'sound/violin/A#3.mid'
|
||||
if("Bb3") soundfile = 'sound/violin/Bb3.mid'
|
||||
if("Bn3") soundfile = 'sound/violin/Bn3.mid'
|
||||
if("B#3") soundfile = 'sound/violin/B#3.mid'
|
||||
if("Cb4") soundfile = 'sound/violin/Cb4.mid'
|
||||
if("Cn4") soundfile = 'sound/violin/Cn4.mid'
|
||||
if("C#4") soundfile = 'sound/violin/C#4.mid'
|
||||
if("Db4") soundfile = 'sound/violin/Db4.mid'
|
||||
if("Dn4") soundfile = 'sound/violin/Dn4.mid'
|
||||
if("D#4") soundfile = 'sound/violin/D#4.mid'
|
||||
if("Eb4") soundfile = 'sound/violin/Eb4.mid'
|
||||
if("En4") soundfile = 'sound/violin/En4.mid'
|
||||
if("E#4") soundfile = 'sound/violin/E#4.mid'
|
||||
if("Fb4") soundfile = 'sound/violin/Fb4.mid'
|
||||
if("Fn4") soundfile = 'sound/violin/Fn4.mid'
|
||||
if("F#4") soundfile = 'sound/violin/F#4.mid'
|
||||
if("Gb4") soundfile = 'sound/violin/Gb4.mid'
|
||||
if("Gn4") soundfile = 'sound/violin/Gn4.mid'
|
||||
if("G#4") soundfile = 'sound/violin/G#4.mid'
|
||||
if("Ab4") soundfile = 'sound/violin/Ab4.mid'
|
||||
if("An4") soundfile = 'sound/violin/An4.mid'
|
||||
if("A#4") soundfile = 'sound/violin/A#4.mid'
|
||||
if("Bb4") soundfile = 'sound/violin/Bb4.mid'
|
||||
if("Bn4") soundfile = 'sound/violin/Bn4.mid'
|
||||
if("B#4") soundfile = 'sound/violin/B#4.mid'
|
||||
if("Cb5") soundfile = 'sound/violin/Cb5.mid'
|
||||
if("Cn5") soundfile = 'sound/violin/Cn5.mid'
|
||||
if("C#5") soundfile = 'sound/violin/C#5.mid'
|
||||
if("Db5") soundfile = 'sound/violin/Db5.mid'
|
||||
if("Dn5") soundfile = 'sound/violin/Dn5.mid'
|
||||
if("D#5") soundfile = 'sound/violin/D#5.mid'
|
||||
if("Eb5") soundfile = 'sound/violin/Eb5.mid'
|
||||
if("En5") soundfile = 'sound/violin/En5.mid'
|
||||
if("E#5") soundfile = 'sound/violin/E#5.mid'
|
||||
if("Fb5") soundfile = 'sound/violin/Fb5.mid'
|
||||
if("Fn5") soundfile = 'sound/violin/Fn5.mid'
|
||||
if("F#5") soundfile = 'sound/violin/F#5.mid'
|
||||
if("Gb5") soundfile = 'sound/violin/Gb5.mid'
|
||||
if("Gn5") soundfile = 'sound/violin/Gn5.mid'
|
||||
if("G#5") soundfile = 'sound/violin/G#5.mid'
|
||||
if("Ab5") soundfile = 'sound/violin/Ab5.mid'
|
||||
if("An5") soundfile = 'sound/violin/An5.mid'
|
||||
if("A#5") soundfile = 'sound/violin/A#5.mid'
|
||||
if("Bb5") soundfile = 'sound/violin/Bb5.mid'
|
||||
if("Bn5") soundfile = 'sound/violin/Bn5.mid'
|
||||
if("B#5") soundfile = 'sound/violin/B#5.mid'
|
||||
if("Cb6") soundfile = 'sound/violin/Cb6.mid'
|
||||
if("Cn6") soundfile = 'sound/violin/Cn6.mid'
|
||||
if("C#6") soundfile = 'sound/violin/C#6.mid'
|
||||
if("Db6") soundfile = 'sound/violin/Db6.mid'
|
||||
if("Dn6") soundfile = 'sound/violin/Dn6.mid'
|
||||
if("D#6") soundfile = 'sound/violin/D#6.mid'
|
||||
if("Eb6") soundfile = 'sound/violin/Eb6.mid'
|
||||
if("En6") soundfile = 'sound/violin/En6.mid'
|
||||
if("E#6") soundfile = 'sound/violin/E#6.mid'
|
||||
if("Fb6") soundfile = 'sound/violin/Fb6.mid'
|
||||
if("Fn6") soundfile = 'sound/violin/Fn6.mid'
|
||||
if("F#6") soundfile = 'sound/violin/F#6.mid'
|
||||
if("Gb6") soundfile = 'sound/violin/Gb6.mid'
|
||||
if("Gn6") soundfile = 'sound/violin/Gn6.mid'
|
||||
if("G#6") soundfile = 'sound/violin/G#6.mid'
|
||||
if("Ab6") soundfile = 'sound/violin/Ab6.mid'
|
||||
if("An6") soundfile = 'sound/violin/An6.mid'
|
||||
if("A#6") soundfile = 'sound/violin/A#6.mid'
|
||||
if("Bb6") soundfile = 'sound/violin/Bb6.mid'
|
||||
if("Bn6") soundfile = 'sound/violin/Bn6.mid'
|
||||
if("B#6") soundfile = 'sound/violin/B#6.mid'
|
||||
if("Cb7") soundfile = 'sound/violin/Cb7.mid'
|
||||
if("Cn7") soundfile = 'sound/violin/Cn7.mid'
|
||||
if("C#7") soundfile = 'sound/violin/C#7.mid'
|
||||
if("Db7") soundfile = 'sound/violin/Db7.mid'
|
||||
if("Dn7") soundfile = 'sound/violin/Dn7.mid'
|
||||
if("D#7") soundfile = 'sound/violin/D#7.mid'
|
||||
if("Eb7") soundfile = 'sound/violin/Eb7.mid'
|
||||
if("En7") soundfile = 'sound/violin/En7.mid'
|
||||
if("E#7") soundfile = 'sound/violin/E#7.mid'
|
||||
if("Fb7") soundfile = 'sound/violin/Fb7.mid'
|
||||
if("Fn7") soundfile = 'sound/violin/Fn7.mid'
|
||||
if("F#7") soundfile = 'sound/violin/F#7.mid'
|
||||
if("Gb7") soundfile = 'sound/violin/Gb7.mid'
|
||||
if("Gn7") soundfile = 'sound/violin/Gn7.mid'
|
||||
if("G#7") soundfile = 'sound/violin/G#7.mid'
|
||||
if("Ab7") soundfile = 'sound/violin/Ab7.mid'
|
||||
if("An7") soundfile = 'sound/violin/An7.mid'
|
||||
if("A#7") soundfile = 'sound/violin/A#7.mid'
|
||||
if("Bb7") soundfile = 'sound/violin/Bb7.mid'
|
||||
if("Bn7") soundfile = 'sound/violin/Bn7.mid'
|
||||
if("B#7") soundfile = 'sound/violin/B#7.mid'
|
||||
if("Cb8") soundfile = 'sound/violin/Cb8.mid'
|
||||
if("Cn8") soundfile = 'sound/violin/Cn8.mid'
|
||||
if("C#8") soundfile = 'sound/violin/C#8.mid'
|
||||
if("Db8") soundfile = 'sound/violin/Db8.mid'
|
||||
if("Dn8") soundfile = 'sound/violin/Dn8.mid'
|
||||
if("D#8") soundfile = 'sound/violin/D#8.mid'
|
||||
if("Eb8") soundfile = 'sound/violin/Eb8.mid'
|
||||
if("En8") soundfile = 'sound/violin/En8.mid'
|
||||
if("E#8") soundfile = 'sound/violin/E#8.mid'
|
||||
if("Fb8") soundfile = 'sound/violin/Fb8.mid'
|
||||
if("Fn8") soundfile = 'sound/violin/Fn8.mid'
|
||||
if("F#8") soundfile = 'sound/violin/F#8.mid'
|
||||
if("Gb8") soundfile = 'sound/violin/Gb8.mid'
|
||||
if("Gn8") soundfile = 'sound/violin/Gn8.mid'
|
||||
if("G#8") soundfile = 'sound/violin/G#8.mid'
|
||||
if("Ab8") soundfile = 'sound/violin/Ab8.mid'
|
||||
if("An8") soundfile = 'sound/violin/An8.mid'
|
||||
if("A#8") soundfile = 'sound/violin/A#8.mid'
|
||||
if("Bb8") soundfile = 'sound/violin/Bb8.mid'
|
||||
if("Bn8") soundfile = 'sound/violin/Bn8.mid'
|
||||
if("B#8") soundfile = 'sound/violin/B#8.mid'
|
||||
if("Cb9") soundfile = 'sound/violin/Cb9.mid'
|
||||
if("Cn9") soundfile = 'sound/violin/Cn9.mid'
|
||||
else return
|
||||
/obj/item/device/violin/New()
|
||||
song = new("violin", src)
|
||||
song.instrumentExt = "ogg"
|
||||
|
||||
hearers(15, get_turf(src)) << sound(soundfile)
|
||||
|
||||
/obj/item/device/violin/proc/playsong()
|
||||
do
|
||||
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 song.lines)
|
||||
//world << line
|
||||
for(var/beat in text2list(lowertext(line), ","))
|
||||
//world << "beat: [beat]"
|
||||
var/list/notes = text2list(beat, "/")
|
||||
for(var/note in text2list(notes[1], "-"))
|
||||
//world << "note: [note]"
|
||||
if(!playing || !isliving(loc))//If the violin is playing, or isn't held by a person
|
||||
playing = 0
|
||||
return
|
||||
if(lentext(note) == 0)
|
||||
continue
|
||||
//world << "Parse: [copytext(note,1,2)]"
|
||||
var/cur_note = text2ascii(note) - 96
|
||||
if(cur_note < 1 || cur_note > 7)
|
||||
continue
|
||||
for(var/i=2 to lentext(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] = ni
|
||||
playnote(uppertext(copytext(note,1,2)) + cur_acc[cur_note] + cur_oct[cur_note])
|
||||
if(notes.len >= 2 && text2num(notes[2]))
|
||||
sleep(song.tempo / text2num(notes[2]))
|
||||
else
|
||||
sleep(song.tempo)
|
||||
if(repeat > 0)
|
||||
repeat-- //Infinite loops are baaaad.
|
||||
while(repeat > 0)
|
||||
playing = 0
|
||||
/obj/item/device/violin/Destroy()
|
||||
del(song)
|
||||
song = null
|
||||
..()
|
||||
|
||||
/obj/item/device/violin/attack_self(mob/user as mob)
|
||||
if(!isliving(user) || user.stat || user.restrained() || user.lying) return
|
||||
user.set_machine(src)
|
||||
interact(user)
|
||||
|
||||
var/dat = "<HEAD><TITLE>Violin</TITLE></HEAD><BODY>"
|
||||
|
||||
if(song)
|
||||
if(song.lines.len > 0 && !(playing))
|
||||
dat += "<A href='?src=\ref[src];play=1'>Play Song</A><BR><BR>"
|
||||
dat += "<A href='?src=\ref[src];repeat=1'>Repeat Song: [repeat] times.</A><BR><BR>"
|
||||
if(playing)
|
||||
dat += "<A href='?src=\ref[src];stop=1'>Stop Playing</A><BR>"
|
||||
dat += "Repeats left: [repeat].<BR><BR>"
|
||||
if(!edit)
|
||||
dat += "<A href='?src=\ref[src];edit=2'>Show Editor</A><BR><BR>"
|
||||
else
|
||||
dat += "<A href='?src=\ref[src];edit=1'>Hide Editor</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];newsong=1'>Start a New Song</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];import=1'>Import a Song</A><BR><BR>"
|
||||
if(song)
|
||||
var/calctempo = (10/song.tempo)*60
|
||||
dat += "Tempo : <A href='?src=\ref[src];tempo=10'>-</A><A href='?src=\ref[src];tempo=1'>-</A> [calctempo] BPM <A href='?src=\ref[src];tempo=-1'>+</A><A href='?src=\ref[src];tempo=-10'>+</A><BR><BR>"
|
||||
var/linecount = 0
|
||||
for(var/line in song.lines)
|
||||
linecount += 1
|
||||
dat += "Line [linecount]: [line] <A href='?src=\ref[src];deleteline=[linecount]'>Delete Line</A> <A href='?src=\ref[src];modifyline=[linecount]'>Modify Line</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];newline=1'>Add Line</A><BR><BR>"
|
||||
if(help)
|
||||
dat += "<A href='?src=\ref[src];help=1'>Hide Help</A><BR>"
|
||||
dat += {"
|
||||
Lines are a series of chords, separated by commas (,), each with notes seperated by hyphens (-).<br>
|
||||
Every note in a chord will play together, with chord timed by the tempo.<br>
|
||||
<br>
|
||||
Notes are played by the names of the note, and optionally, the accidental, and/or the octave number.<br>
|
||||
By default, every note is natural and in octave 3. Defining otherwise is remembered for each note.<br>
|
||||
Example: <i>C,D,E,F,G,A,B</i> will play a C major scale.<br>
|
||||
After a note has an accidental placed, it will be remembered: <i>C,C4,C,C3</i> is C3,C4,C4,C3</i><br>
|
||||
Chords can be played simply by seperating each note with a hyphon: <i>A-C#,Cn-E,E-G#,Gn-B</i><br>
|
||||
A pause may be denoted by an empty chord: <i>C,E,,C,G</i><br>
|
||||
To make a chord be a different time, end it with /x, where the chord length will be length<br>
|
||||
defined by tempo / x: <i>C,G/2,E/4</i><br>
|
||||
Combined, an example is: <i>E-E4/4,/2,G#/8,B/8,E3-E4/4</i>
|
||||
<br>
|
||||
Lines may be up to 50 characters.<br>
|
||||
A song may only contain up to 50 lines.<br>
|
||||
"}
|
||||
else
|
||||
dat += "<A href='?src=\ref[src];help=2'>Show Help</A><BR>"
|
||||
dat += "</BODY></HTML>"
|
||||
user << browse(dat, "window=violin;size=700x300")
|
||||
onclose(user, "violin")
|
||||
|
||||
/obj/item/device/violin/Topic(href, href_list)
|
||||
|
||||
if(!in_range(src, usr) || issilicon(usr) || !isliving(usr) || !usr.canmove || usr.restrained())
|
||||
usr << browse(null, "window=violin;size=700x300")
|
||||
onclose(usr, "violin")
|
||||
/obj/item/device/violin/interact(mob/user as mob)
|
||||
if(!user)
|
||||
return
|
||||
|
||||
if(href_list["newsong"])
|
||||
song = new()
|
||||
else if(song)
|
||||
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.
|
||||
var/tempnum = input("How many times do you want to repeat this piece? (max:10)") as num|null
|
||||
if(tempnum > 10)
|
||||
tempnum = 10
|
||||
if(tempnum < 0)
|
||||
tempnum = 0
|
||||
repeat = round(tempnum)
|
||||
if(!isliving(user) || user.stat || user.restrained() || user.lying)
|
||||
return
|
||||
|
||||
else if(href_list["tempo"])
|
||||
song.tempo += round(text2num(href_list["tempo"]))
|
||||
if(song.tempo < 1)
|
||||
song.tempo = 1
|
||||
|
||||
else if(href_list["play"])
|
||||
if(song)
|
||||
playing = 1
|
||||
spawn() playsong()
|
||||
|
||||
else if(href_list["newline"])
|
||||
var/newline = html_encode(input("Enter your line: ", "violin") as text|null)
|
||||
if(!newline)
|
||||
return
|
||||
if(song.lines.len > 50)
|
||||
return
|
||||
if(lentext(newline) > 50)
|
||||
newline = copytext(newline, 1, 50)
|
||||
song.lines.Add(newline)
|
||||
|
||||
else if(href_list["deleteline"])
|
||||
var/num = round(text2num(href_list["deleteline"]))
|
||||
if(num > song.lines.len || num < 1)
|
||||
return
|
||||
song.lines.Cut(num, num+1)
|
||||
|
||||
else if(href_list["modifyline"])
|
||||
var/num = round(text2num(href_list["modifyline"]),1)
|
||||
var/content = html_encode(input("Enter your line: ", "violin", song.lines[num]) as text|null)
|
||||
if(!content)
|
||||
return
|
||||
if(lentext(content) > 50)
|
||||
content = copytext(content, 1, 50)
|
||||
if(num > song.lines.len || num < 1)
|
||||
return
|
||||
song.lines[num] = content
|
||||
|
||||
else if(href_list["stop"])
|
||||
playing = 0
|
||||
|
||||
else if(href_list["help"])
|
||||
help = text2num(href_list["help"]) - 1
|
||||
|
||||
else if(href_list["edit"])
|
||||
edit = text2num(href_list["edit"]) - 1
|
||||
|
||||
else if(href_list["import"])
|
||||
var/t = ""
|
||||
do
|
||||
t = html_encode(input(usr, "Please paste the entire song, formatted:", text("[]", name), t) as message)
|
||||
if(!in_range(src, usr))
|
||||
return
|
||||
|
||||
if(lentext(t) >= 3072)
|
||||
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(lentext(t) > 3072)
|
||||
|
||||
//split into lines
|
||||
spawn()
|
||||
var/list/lines = text2list(t, "\n")
|
||||
var/tempo = 5
|
||||
if(copytext(lines[1],1,6) == "BPM: ")
|
||||
tempo = 600 / text2num(copytext(lines[1],6))
|
||||
lines.Cut(1,2)
|
||||
if(lines.len > 50)
|
||||
usr << "Too many lines!"
|
||||
lines.Cut(51)
|
||||
var/linenum = 1
|
||||
for(var/l in lines)
|
||||
if(lentext(l) > 50)
|
||||
usr << "Line [linenum] too long!"
|
||||
lines.Remove(l)
|
||||
else
|
||||
linenum++
|
||||
song = new()
|
||||
song.lines = lines
|
||||
song.tempo = tempo
|
||||
|
||||
add_fingerprint(usr)
|
||||
for(var/mob/M in viewers(1, loc))
|
||||
if((M.client && M.machine == src))
|
||||
attack_self(M)
|
||||
return
|
||||
|
||||
|
||||
/obj/item/device/violin/guitar
|
||||
name = "engraved guitar"
|
||||
desc = "An aged wooden acoustic guitar It has an engraving on the back: \"For my loyal robotic companion, S.A.M. -LWK\"."
|
||||
icon = 'icons/obj/musician.dmi'
|
||||
icon_state = "guitar"
|
||||
item_state = "guitar"
|
||||
slot_flags = SLOT_BACK
|
||||
user.set_machine(src)
|
||||
song.interact(user)
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
* Plasma Glass Sheets
|
||||
* Reinforced Plasma Glass Sheets (AKA Holy fuck strong windows)
|
||||
|
||||
Todo: Create a unified construct_window(sheet, user, created_window, full_window)
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -98,6 +100,7 @@
|
||||
W = new /obj/structure/window/basic( user.loc, 0 )
|
||||
W.dir = dir_to_set
|
||||
W.ini_dir = W.dir
|
||||
W.state = 0
|
||||
W.anchored = 0
|
||||
src.use(1)
|
||||
if("Full Window")
|
||||
@@ -110,6 +113,7 @@
|
||||
user << "\red There is a full window in the way."
|
||||
return 1
|
||||
var/obj/structure/window/W = new full_window( user.loc, 0 )
|
||||
W.state = 0
|
||||
W.anchored = 0
|
||||
src.use(2)
|
||||
return 0
|
||||
@@ -126,6 +130,8 @@
|
||||
g_amt = 3750
|
||||
m_amt = 1875
|
||||
origin_tech = "materials=2"
|
||||
var/created_window = /obj/structure/window/reinforced
|
||||
var/full_window = /obj/structure/window/full/reinforced
|
||||
|
||||
/obj/item/stack/sheet/rglass/cyborg
|
||||
name = "reinforced glass"
|
||||
@@ -190,11 +196,8 @@
|
||||
if(locate(/obj/structure/window/full) in user.loc)
|
||||
user << "\red There is a window in the way."
|
||||
return 1
|
||||
var/obj/structure/window/W
|
||||
W = new /obj/structure/window/reinforced( user.loc, 1 )
|
||||
var/obj/structure/window/W = new full_window( user.loc, 0 )
|
||||
W.state = 0
|
||||
W.dir = SOUTHWEST
|
||||
W.ini_dir = SOUTHWEST
|
||||
W.anchored = 0
|
||||
src.use(2)
|
||||
|
||||
@@ -237,106 +240,6 @@
|
||||
|
||||
return 0
|
||||
|
||||
/*
|
||||
* Glass shards - TODO: Move this into code/game/object/item/weapons
|
||||
*/
|
||||
/obj/item/weapon/shard
|
||||
resetVariables()
|
||||
var/list/exclude = list("pixel_y", "pixel_x", "icon_state")
|
||||
exclude += args
|
||||
..(exclude)
|
||||
|
||||
/obj/item/weapon/shard/Bump()
|
||||
spawn( 0 )
|
||||
if (prob(20))
|
||||
src.force = 15
|
||||
else
|
||||
src.force = 4
|
||||
..()
|
||||
return
|
||||
return
|
||||
|
||||
/obj/item/weapon/shard
|
||||
name = "shard"
|
||||
desc = "A nasty looking shard of glass."
|
||||
icon = 'icons/obj/shards.dmi'
|
||||
icon_state = "large"
|
||||
w_class = 1.0
|
||||
force = 5.0
|
||||
throwforce = 15.0
|
||||
item_state = "shard-glass"
|
||||
g_amt = 3750
|
||||
attack_verb = list("stabbed", "slashed", "sliced", "cut")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
|
||||
suicide_act(mob/user)
|
||||
viewers(user) << pick("<span class='suicide'>[user] is slitting \his wrists with the shard of glass! It looks like \he's trying to commit suicide.</span>", \
|
||||
"<span class='suicide'>[user] is slitting \his throat with the shard of glass! It looks like \he's trying to commit suicide.</span>")
|
||||
return (BRUTELOSS)
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/shard/New()
|
||||
|
||||
src.icon_state = pick("large", "medium", "small")
|
||||
switch(src.icon_state)
|
||||
if("small")
|
||||
src.pixel_x = rand(-12, 12)
|
||||
src.pixel_y = rand(-12, 12)
|
||||
if("medium")
|
||||
src.pixel_x = rand(-8, 8)
|
||||
src.pixel_y = rand(-8, 8)
|
||||
if("large")
|
||||
src.pixel_x = rand(-5, 5)
|
||||
src.pixel_y = rand(-5, 5)
|
||||
else
|
||||
return
|
||||
|
||||
/obj/item/weapon/shard/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
..()
|
||||
if ( istype(W, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
if(WT.remove_fuel(0, user))
|
||||
var/obj/item/stack/sheet/glass/NG = new (user.loc)
|
||||
for (var/obj/item/stack/sheet/glass/G in user.loc)
|
||||
if(G==NG)
|
||||
continue
|
||||
if(G.amount>=G.max_amount)
|
||||
continue
|
||||
G.attackby(NG, user)
|
||||
usr << "You add the newly-formed glass to the stack. It now contains [NG.amount] sheets."
|
||||
//SN src = null
|
||||
returnToPool(src)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/shard/Crossed(AM as mob|obj)
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
M << "\red <B>You step in the broken glass!</B>"
|
||||
playsound(src.loc, 'sound/effects/glass_step.ogg', 50, 1)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
|
||||
if(H.species.flags & IS_SYNTHETIC)
|
||||
return
|
||||
|
||||
if( !H.shoes && ( !H.wear_suit || !(H.wear_suit.body_parts_covered & FEET) ) )
|
||||
var/datum/organ/external/affecting = H.get_organ(pick("l_foot", "r_foot"))
|
||||
if(affecting.status & ORGAN_ROBOT)
|
||||
return
|
||||
H.Weaken(3)
|
||||
if(affecting.take_damage(5, 0))
|
||||
H.UpdateDamageIcon()
|
||||
H.updatehealth()
|
||||
..()
|
||||
|
||||
|
||||
/*
|
||||
|
||||
* Plasma Glass sheets
|
||||
|
||||
*/
|
||||
|
||||
/obj/item/stack/sheet/plasmaglass
|
||||
name = "plasma glass"
|
||||
@@ -349,7 +252,7 @@
|
||||
var/full_window = /obj/structure/window/full/plasmabasic
|
||||
|
||||
|
||||
/obj/item/stack/sheet/glass/plasmaglass/attack_self(mob/user as mob)
|
||||
/obj/item/stack/sheet/plasmaglass/attack_self(mob/user as mob)
|
||||
construct_window(user)
|
||||
|
||||
/obj/item/stack/sheet/plasmaglass/attackby(obj/item/W, mob/user)
|
||||
@@ -375,7 +278,7 @@
|
||||
if(!user.IsAdvancedToolUser())
|
||||
user << "\red You don't have the dexterity to do this!"
|
||||
return 0
|
||||
var/title = "Sheet-PlasmaGlass"
|
||||
var/title = "Plasma-glass alloy"
|
||||
title += " ([src.amount] sheet\s left)"
|
||||
switch(alert(title, "Would you like full tile glass or one direction?", "One Direction", "Full Window", "Cancel", null))
|
||||
if("One Direction")
|
||||
@@ -406,6 +309,7 @@
|
||||
W = new /obj/structure/window/plasmabasic( user.loc, 0 )
|
||||
W.dir = dir_to_set
|
||||
W.ini_dir = W.dir
|
||||
W.state = 0
|
||||
W.anchored = 0
|
||||
src.use(1)
|
||||
if("Full Window")
|
||||
@@ -417,10 +321,8 @@
|
||||
if(locate(/obj/structure/window) in user.loc)
|
||||
user << "\red There is a window in the way."
|
||||
return 1
|
||||
var/obj/structure/window/W
|
||||
W = new /obj/structure/window/plasmabasic( user.loc, 0 )
|
||||
W.dir = SOUTHWEST
|
||||
W.ini_dir = SOUTHWEST
|
||||
var/obj/structure/window/W = new full_window( user.loc, 0 )
|
||||
W.state = 0
|
||||
W.anchored = 0
|
||||
src.use(2)
|
||||
return 0
|
||||
@@ -440,5 +342,60 @@
|
||||
var/full_window = /obj/structure/window/full/plasmareinforced
|
||||
|
||||
|
||||
/obj/item/stack/sheet/glass/plasmarglass/attack_self(mob/user as mob)
|
||||
/obj/item/stack/sheet/plasmarglass/attack_self(mob/user as mob)
|
||||
construct_window(user)
|
||||
|
||||
/obj/item/stack/sheet/plasmarglass/proc/construct_window(mob/user as mob)
|
||||
if(!user || !src) return 0
|
||||
if(!istype(user.loc,/turf)) return 0
|
||||
if(!user.IsAdvancedToolUser())
|
||||
user << "\red You don't have the dexterity to do this!"
|
||||
return 0
|
||||
var/title = "Reinforced plasma-glass alloy"
|
||||
title += " ([src.amount] sheet\s left)"
|
||||
switch(alert(title, "Would you like full tile glass or one direction?", "One Direction", "Full Window", "Cancel", null))
|
||||
if("One Direction")
|
||||
if(!src) return 1
|
||||
if(src.loc != user) return 1
|
||||
var/list/directions = new/list(cardinal)
|
||||
var/i = 0
|
||||
for (var/obj/structure/window/win in user.loc)
|
||||
i++
|
||||
if(i >= 4)
|
||||
user << "\red There are too many windows in this location."
|
||||
return 1
|
||||
directions-=win.dir
|
||||
if(!(win.ini_dir in cardinal))
|
||||
user << "\red Can't let you do that."
|
||||
return 1
|
||||
//Determine the direction. It will first check in the direction the person making the window is facing, if it finds an already made window it will try looking at the next cardinal direction, etc.
|
||||
var/dir_to_set = 2
|
||||
for(var/direction in list( user.dir, turn(user.dir,90), turn(user.dir,180), turn(user.dir,270) ))
|
||||
var/found = 0
|
||||
for(var/obj/structure/window/WT in user.loc)
|
||||
if(WT.dir == direction)
|
||||
found = 1
|
||||
if(!found)
|
||||
dir_to_set = direction
|
||||
break
|
||||
var/obj/structure/window/W
|
||||
W = new /obj/structure/window/plasmareinforced( user.loc, 0 )
|
||||
W.dir = dir_to_set
|
||||
W.ini_dir = W.dir
|
||||
W.state = 0
|
||||
W.anchored = 0
|
||||
src.use(1)
|
||||
if("Full Window")
|
||||
if(!src) return 1
|
||||
if(src.loc != user) return 1
|
||||
if(src.amount < 2)
|
||||
user << "\red You need more glass to do that."
|
||||
return 1
|
||||
if(locate(/obj/structure/window) in user.loc)
|
||||
user << "\red There is a window in the way."
|
||||
return 1
|
||||
var/obj/structure/window/W = new full_window( user.loc, 0 )
|
||||
W.state = 0
|
||||
W.anchored = 0
|
||||
src.use(2)
|
||||
return 0
|
||||
|
||||
@@ -424,7 +424,7 @@
|
||||
desc = "Your palm is oozing this stuff!"
|
||||
icon = 'icons/mob/slimes.dmi'
|
||||
icon_state = "red slime extract"
|
||||
throwforce = 30.0
|
||||
throwforce = 5.0
|
||||
throw_speed = 10
|
||||
throw_range = 30
|
||||
w_class = 1
|
||||
@@ -927,9 +927,9 @@ obj/item/toy/cards/deck/syndicate
|
||||
desc = "A deck of space-grade playing cards. They seem unusually rigid."
|
||||
deckstyle = "syndicate"
|
||||
card_hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
card_force = 15
|
||||
card_throwforce = 15
|
||||
card_throw_speed = 6
|
||||
card_force = 5
|
||||
card_throwforce = 10
|
||||
card_throw_speed = 3
|
||||
card_throw_range = 20
|
||||
card_attack_verb = list("attacked", "sliced", "diced", "slashed", "cut")
|
||||
|
||||
@@ -952,13 +952,18 @@ obj/item/toy/cards/deck/syndicate/black
|
||||
|
||||
/obj/item/toy/nuke/attack_self(mob/user)
|
||||
if (cooldown < world.time)
|
||||
cooldown = world.time + 3000 //5 minutes
|
||||
cooldown = world.time + 1800 //3 minutes
|
||||
user.visible_message("<span class='warning'>[user] presses a button on [src]</span>", "<span class='notice'>You activate [src], it plays a loud noise!</span>", "<span class='notice'>You hear the click of a button.</span>")
|
||||
spawn(5) //gia said so
|
||||
icon_state = "nuketoy"
|
||||
playsound(src, 'sound/machines/Alarm.ogg', 100, 0, surround = 0)
|
||||
playsound(src, 'sound/machines/Alarm.ogg', 100, 0, 0)
|
||||
sleep(135)
|
||||
icon_state = "nuketoycool"
|
||||
sleep(cooldown - world.time)
|
||||
icon_state = "nuketoyidle"
|
||||
else
|
||||
var/timeleft = (cooldown - world.time)
|
||||
user << "<span class='alert'>Nothing happens, and '</span>[round(timeleft/10)]<span class='alert'>' appears on a small display.</span>"
|
||||
|
||||
|
||||
/obj/item/toy/therapy_red
|
||||
|
||||
@@ -297,7 +297,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
item_state = "pipeoff"
|
||||
icon_on = "pipeon" //Note - these are in masks.dmi
|
||||
icon_off = "pipeoff"
|
||||
smoketime = 100
|
||||
smoketime = 1000
|
||||
chem_volume = 50
|
||||
|
||||
/obj/item/clothing/mask/cigarette/pipe/light(var/flavor_text = "[usr] lights the [name].")
|
||||
if(!src.lit)
|
||||
@@ -353,7 +354,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
item_state = "cobpipeoff"
|
||||
icon_on = "cobpipeon" //Note - these are in masks.dmi
|
||||
icon_off = "cobpipeoff"
|
||||
smoketime = 400
|
||||
smoketime = 800
|
||||
chem_volume = 40
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/obj/item/weapon/dnascrambler
|
||||
name = "dna scrambler"
|
||||
desc = "An illegal genetic serum designed to randomize the user's identity."
|
||||
icon = 'icons/obj/syringe.dmi'
|
||||
item_state = "syringe_0"
|
||||
icon_state = "b10"
|
||||
var/used = null
|
||||
|
||||
update_icon()
|
||||
if(used)
|
||||
icon_state = "b0"
|
||||
else
|
||||
icon_state = "b10"
|
||||
|
||||
attack(mob/M as mob, mob/user as mob)
|
||||
if(!M || !user)
|
||||
return
|
||||
|
||||
if(!ishuman(M) || !ishuman(user))
|
||||
return
|
||||
|
||||
if(src.used)
|
||||
return
|
||||
|
||||
if(M == user)
|
||||
user.visible_message("\red <b>[user.name] injects \himself with [src]!</b>")
|
||||
src.injected(user,user)
|
||||
else
|
||||
user.visible_message("\red <b>[user.name] is trying to inject [M.name] with [src]!</b>")
|
||||
if (do_mob(user,M,30))
|
||||
user.visible_message("\red <b>[user.name] injects [M.name] with [src].</b>")
|
||||
src.injected(M, user)
|
||||
else
|
||||
user << "\red You failed to inject [M.name]."
|
||||
|
||||
proc/injected(var/mob/living/carbon/target, var/mob/living/carbon/user)
|
||||
target.generate_name()
|
||||
target.real_name = target.name
|
||||
|
||||
scramble(1, target, 100)
|
||||
|
||||
log_attack("[key_name(user)] injected [key_name(target)] with the [name]")
|
||||
log_game("[key_name_admin(user)] injected [key_name_admin(target)] with the [name]")
|
||||
|
||||
src.used = 1
|
||||
src.update_icon()
|
||||
src.name = "used " + src.name
|
||||
@@ -35,7 +35,7 @@
|
||||
/obj/item/weapon/grenade/spawnergrenade/manhacks
|
||||
name = "manhack delivery grenade"
|
||||
spawner_type = /mob/living/simple_animal/hostile/viscerator
|
||||
deliveryamt = 3
|
||||
deliveryamt = 5
|
||||
origin_tech = "materials=3;magnets=4;syndicate=4"
|
||||
|
||||
/obj/item/weapon/grenade/spawnergrenade/spesscarp
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/obj/item/weapon/grenade/syndieminibomb
|
||||
desc = "A syndicate manufactured explosive used to sow destruction and chaos"
|
||||
name = "syndicate minibomb"
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
icon_state = "syndicate"
|
||||
item_state = "flashbang"
|
||||
origin_tech = "materials=3;magnets=4;syndicate=4"
|
||||
|
||||
/obj/item/weapon/grenade/syndieminibomb/prime()
|
||||
update_mob()
|
||||
explosion(src.loc,1,2,4)
|
||||
del(src)
|
||||
@@ -343,20 +343,20 @@ the implant may become unstable and either pre-maturely inject the subject or si
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/implant/traitor
|
||||
name = "Greytide Implant"
|
||||
desc = "Greytide Station wide"
|
||||
name = "Mindslave Implant"
|
||||
desc = "Divide and Conquer"
|
||||
icon_state = "implant_evil"
|
||||
|
||||
get_data()
|
||||
var/dat = {"
|
||||
<b>Implant Specifications:</b><BR>
|
||||
<b>Name:</b> Greytide Mind-Slave Implant<BR>
|
||||
<b>Name:</b> Mind-Slave Implant<BR>
|
||||
<b>Life:</b> ??? <BR>
|
||||
<b>Important Notes:</b> Any humanoid injected with this implant will become loyal to the injector and the greytide, unless of course the host is already loyal to someone else.<BR>
|
||||
<b>Important Notes:</b> Any humanoid injected with this implant will become loyal to the injector, unless of course the host is already loyal to someone else.<BR>
|
||||
<HR>
|
||||
<b>Implant Details:</b><BR>
|
||||
<b>Function:</b> Contains a small pod of nanobots that manipulate the host's mental functions.<BR>
|
||||
<b>Special Features:</b> Glory to the Greytide!<BR>
|
||||
<b>Special Features:</b> Diplomacy was never so easy.<BR>
|
||||
<b>Integrity:</b> Implant will last so long as the nanobots are inside the bloodstream."}
|
||||
return dat
|
||||
|
||||
@@ -367,9 +367,9 @@ the implant may become unstable and either pre-maturely inject the subject or si
|
||||
if(!M.mind) return 0
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(M == user)
|
||||
user << "<span class='notice'>You feel quite stupid for doing that.</span>"
|
||||
user << "<span class='notice'>Making yourself loyal to yourself was a great idea! Perhaps the best idea, ever! Actually, you just feel like an idiot.</span>"
|
||||
if(isliving(user))
|
||||
user:brainloss += 10
|
||||
user:brainloss += 20
|
||||
return
|
||||
if(locate(/obj/item/weapon/implant/traitor) in H.contents || locate(/obj/item/weapon/implant/traitor) in H.contents)
|
||||
H.visible_message("[H] seems to resist the implant!", "You feel a strange sensation in your head that quickly dissipates.")
|
||||
@@ -389,7 +389,7 @@ the implant may become unstable and either pre-maturely inject the subject or si
|
||||
ticker.mode:implanter[ref] = implanters
|
||||
ticker.mode.traitors += H.mind
|
||||
H.mind.special_role = "traitor"
|
||||
H << "<B>\red You've been shown the Greytide by [user.name]!</B> You now must lay down your life to protect them and assist in their goals at any cost."
|
||||
H << "<B>\red You're now completely loyal to [user.name]!</B> You now must lay down your life to protect them and assist in their goals at any cost."
|
||||
var/datum/objective/protect/p = new
|
||||
p.owner = H.mind
|
||||
p.target = user:mind
|
||||
@@ -405,7 +405,7 @@ the implant may become unstable and either pre-maturely inject the subject or si
|
||||
/obj/item/weapon/implant/adrenalin
|
||||
name = "adrenalin"
|
||||
desc = "Removes all stuns and knockdowns."
|
||||
var/uses
|
||||
var/uses = 3
|
||||
|
||||
get_data()
|
||||
var/dat = {"
|
||||
@@ -414,8 +414,8 @@ the implant may become unstable and either pre-maturely inject the subject or si
|
||||
<b>Life:</b> Five days.<BR>
|
||||
<b>Important Notes:</b> <font color='red'>Illegal</font><BR>
|
||||
<HR>
|
||||
<b>Implant Details:</b> Subjects injected with implant can activate a massive injection of adrenalin.<BR>
|
||||
<b>Function:</b> Contains nanobots to stimulate body to mass-produce Adrenalin.<BR>
|
||||
<b>Implant Details:</b> Subjects injected with implant can activate an injection of medical cocktails.<BR>
|
||||
<b>Function:</b> Removes stuns, increases speed, and has a mild healing effect.<BR>
|
||||
<b>Special Features:</b> Will prevent and cure most forms of brainwashing.<BR>
|
||||
<b>Integrity:</b> Implant can only be used three times before the nanobots are depleted."}
|
||||
return dat
|
||||
@@ -429,6 +429,12 @@ the implant may become unstable and either pre-maturely inject the subject or si
|
||||
source.SetStunned(0)
|
||||
source.SetWeakened(0)
|
||||
source.SetParalysis(0)
|
||||
source.lying = 0
|
||||
source.update_canmove()
|
||||
|
||||
source.reagents.add_reagent("synaptizine", 10)
|
||||
source.reagents.add_reagent("tricordrazine", 10)
|
||||
source.reagents.add_reagent("hyperzine", 10)
|
||||
|
||||
return
|
||||
|
||||
|
||||
@@ -138,3 +138,14 @@
|
||||
src.imp = new /obj/item/weapon/implant/death_alarm( src )
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/weapon/implantcase/freedom
|
||||
name = "Glass Case- 'Freedom'"
|
||||
desc = "A case containing a freedom implant."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "implantcase-b"
|
||||
|
||||
New()
|
||||
src.imp = new /obj/item/weapon/implant/freedom( src )
|
||||
..()
|
||||
return
|
||||
@@ -54,8 +54,8 @@
|
||||
|
||||
|
||||
/obj/item/weapon/implanter/traitor
|
||||
name = "implanter-greytide"
|
||||
desc = "Greytide Stationwide."
|
||||
name = "implanter-mindslave"
|
||||
desc = "Divide and Conquer."
|
||||
|
||||
New()
|
||||
src.imp = new /obj/item/weapon/implant/traitor(src)
|
||||
|
||||
@@ -676,7 +676,7 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<iframe width='100%' height='97%' src="http://80.244.78.90/wiki/index.php?title=Space_law&printable=yes" frameborder="0" id="main_frame"></iframe> </body>
|
||||
<iframe width='100%' height='97%' src="http://nanotrasen.se/wiki/index.php?title=Space_law&printable=yes" frameborder="0" id="main_frame"></iframe> </body>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
// Glass shards
|
||||
|
||||
/obj/item/weapon/shard
|
||||
name = "glass shard"
|
||||
icon = 'icons/obj/shards.dmi'
|
||||
icon_state = "large"
|
||||
sharp = 1
|
||||
edge = 1
|
||||
desc = "Could probably be used as ... a throwing weapon?"
|
||||
w_class = 2.0
|
||||
force = 5.0
|
||||
throwforce = 8.0
|
||||
item_state = "shard-glass"
|
||||
// matter = list("glass" = 3750)
|
||||
attack_verb = list("stabbed", "slashed", "sliced", "cut")
|
||||
|
||||
/obj/item/weapon/shard/suicide_act(mob/user)
|
||||
viewers(user) << pick("\red <b>[user] is slitting \his wrists with \the [src]! It looks like \he's trying to commit suicide.</b>", \
|
||||
"\red <b>[user] is slitting \his throat with \the [src]! It looks like \he's trying to commit suicide.</b>")
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/weapon/shard/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
|
||||
playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/shard/Bump()
|
||||
|
||||
spawn( 0 )
|
||||
if (prob(20))
|
||||
src.force = 15
|
||||
else
|
||||
src.force = 4
|
||||
..()
|
||||
return
|
||||
return
|
||||
|
||||
/obj/item/weapon/shard/New()
|
||||
|
||||
src.icon_state = pick("large", "medium", "small")
|
||||
switch(src.icon_state)
|
||||
if("small")
|
||||
src.pixel_x = rand(-12, 12)
|
||||
src.pixel_y = rand(-12, 12)
|
||||
if("medium")
|
||||
src.pixel_x = rand(-8, 8)
|
||||
src.pixel_y = rand(-8, 8)
|
||||
if("large")
|
||||
src.pixel_x = rand(-5, 5)
|
||||
src.pixel_y = rand(-5, 5)
|
||||
else
|
||||
return
|
||||
|
||||
/obj/item/weapon/shard/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
..()
|
||||
if ( istype(W, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
if(WT.remove_fuel(0, user))
|
||||
var/obj/item/stack/sheet/glass/NG = new (user.loc)
|
||||
for (var/obj/item/stack/sheet/glass/G in user.loc)
|
||||
if(G==NG)
|
||||
continue
|
||||
if(G.amount>=G.max_amount)
|
||||
continue
|
||||
G.attackby(NG, user)
|
||||
usr << "You add the newly-formed glass to the stack. It now contains [NG.amount] sheets."
|
||||
//SN src = null
|
||||
del(src)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/shard/Crossed(AM as mob|obj)
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
M << "\red <B>You step on \the [src]!</B>"
|
||||
playsound(src.loc, 'sound/effects/glass_step.ogg', 50, 1) // not sure how to handle metal shards with sounds
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
|
||||
if(H.species.flags & IS_SYNTHETIC)
|
||||
return
|
||||
|
||||
if( !H.shoes && ( !H.wear_suit || !(H.wear_suit.body_parts_covered & FEET) ) )
|
||||
var/datum/organ/external/affecting = H.get_organ(pick("l_foot", "r_foot"))
|
||||
if(affecting.status & ORGAN_ROBOT)
|
||||
return
|
||||
H.Weaken(3)
|
||||
if(affecting.take_damage(5, 0))
|
||||
H.UpdateDamageIcon()
|
||||
H.updatehealth()
|
||||
..()
|
||||
|
||||
// Shrapnel
|
||||
|
||||
/obj/item/weapon/shard/shrapnel
|
||||
name = "shrapnel"
|
||||
icon = 'icons/obj/shards.dmi'
|
||||
icon_state = "shrapnellarge"
|
||||
desc = "A bunch of tiny bits of shattered metal."
|
||||
|
||||
/obj/item/weapon/shard/shrapnel/New()
|
||||
|
||||
src.icon_state = pick("shrapnellarge", "shrapnelmedium", "shrapnelsmall")
|
||||
switch(src.icon_state)
|
||||
if("shrapnelsmall")
|
||||
src.pixel_x = rand(-12, 12)
|
||||
src.pixel_y = rand(-12, 12)
|
||||
if("shrapnelmedium")
|
||||
src.pixel_x = rand(-8, 8)
|
||||
src.pixel_y = rand(-8, 8)
|
||||
if("shrapnellarge")
|
||||
src.pixel_x = rand(-5, 5)
|
||||
src.pixel_y = rand(-5, 5)
|
||||
else
|
||||
return
|
||||
@@ -38,11 +38,6 @@
|
||||
if(crit_fail)
|
||||
user << "\red The Bluespace generator isn't working."
|
||||
return
|
||||
if(istype(W, /obj/item/weapon/storage/backpack/holding) && !W.crit_fail)
|
||||
user << "\red The Bluespace interfaces of the two devices conflict and malfunction."
|
||||
del(W)
|
||||
return
|
||||
//BoH+BoH=Singularity, commented out.
|
||||
if(istype(W, /obj/item/weapon/storage/backpack/holding) && !W.crit_fail)
|
||||
investigate_log("has become a singularity. Caused by [user.key]","singulo")
|
||||
user << "\red The Bluespace interfaces of the two devices catastrophically malfunction!"
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
|
||||
|
||||
/obj/item/weapon/storage/belt/medical
|
||||
use_to_pickup = 1 //Allow medical belt to pick up medicine
|
||||
name = "medical belt"
|
||||
desc = "Can hold various medical equipment."
|
||||
icon_state = "medicalbelt"
|
||||
@@ -124,7 +125,8 @@
|
||||
"/obj/item/device/radio/headset",
|
||||
"/obj/item/weapon/melee",
|
||||
"/obj/item/taperoll/police",
|
||||
"/obj/item/weapon/gun/energy/taser"
|
||||
"/obj/item/weapon/gun/energy/taser",
|
||||
"/obj/item/weapon/gun/energy/stunrevolver"
|
||||
)
|
||||
|
||||
/obj/item/weapon/storage/belt/soulstone
|
||||
|
||||
@@ -12,8 +12,10 @@
|
||||
autoignition_temperature = 522 // Kelvin
|
||||
|
||||
suicide_act(mob/user)
|
||||
viewers(user) << "\red <b>[user] is farting lightly on the [src.name]! It looks like \he's trying to commit suicide!</b>"
|
||||
return (user.death(1))
|
||||
user.emote("fart")
|
||||
viewers(user) << "\red <b>[user] farts on the [src.name]!</b>"
|
||||
viewers(user) << "\blue <b>A mysterious force smites [user]!</b>"
|
||||
return (user.gib(1))
|
||||
|
||||
|
||||
/obj/item/weapon/storage/bible/booze
|
||||
|
||||
@@ -167,6 +167,21 @@
|
||||
new /obj/item/ammo_casing/shotgun/birdshot(src)
|
||||
|
||||
|
||||
/obj/item/weapon/storage/box/gauge
|
||||
name = "box of 12 gauge slugs"
|
||||
desc = "It has a picture of a gun and several warning symbols on the front."
|
||||
m_amt = 50000
|
||||
|
||||
New()
|
||||
..()
|
||||
new /obj/item/ammo_casing/shotgun(src)
|
||||
new /obj/item/ammo_casing/shotgun(src)
|
||||
new /obj/item/ammo_casing/shotgun(src)
|
||||
new /obj/item/ammo_casing/shotgun(src)
|
||||
new /obj/item/ammo_casing/shotgun(src)
|
||||
new /obj/item/ammo_casing/shotgun(src)
|
||||
new /obj/item/ammo_casing/shotgun(src)
|
||||
|
||||
|
||||
/obj/item/weapon/storage/box/flashbangs
|
||||
name = "box of flashbangs (WARNING)"
|
||||
@@ -183,6 +198,21 @@
|
||||
new /obj/item/weapon/grenade/flashbang(src)
|
||||
new /obj/item/weapon/grenade/flashbang(src)
|
||||
|
||||
/obj/item/weapon/storage/box/teargas
|
||||
name = "box of tear gas grenades (WARNING)"
|
||||
desc = "<B>WARNING: These devices are extremely dangerous and can cause blindness and skin irritation.</B>"
|
||||
icon_state = "flashbang"
|
||||
|
||||
/obj/item/weapon/storage/box/teargas/New()
|
||||
..()
|
||||
new /obj/item/weapon/grenade/chem_grenade/teargas(src)
|
||||
new /obj/item/weapon/grenade/chem_grenade/teargas(src)
|
||||
new /obj/item/weapon/grenade/chem_grenade/teargas(src)
|
||||
new /obj/item/weapon/grenade/chem_grenade/teargas(src)
|
||||
new /obj/item/weapon/grenade/chem_grenade/teargas(src)
|
||||
new /obj/item/weapon/grenade/chem_grenade/teargas(src)
|
||||
new /obj/item/weapon/grenade/chem_grenade/teargas(src)
|
||||
|
||||
/obj/item/weapon/storage/box/emps
|
||||
name = "emp grenades"
|
||||
desc = "A box with 5 emp grenades."
|
||||
@@ -439,8 +469,8 @@
|
||||
new /obj/item/weapon/handcuffs(src)
|
||||
|
||||
/obj/item/weapon/storage/box/mousetraps
|
||||
name = "box of Pest-B-Gon Mousetraps"
|
||||
desc = "<B><FONT=red>WARNING:</FONT></B> <I>Keep out of reach of children</I>."
|
||||
name = "box of Pest-B-Gon mousetraps"
|
||||
desc = "<B><FONT color='red'>WARNING:</FONT></B> <I>Keep out of reach of children</I>."
|
||||
icon_state = "mousetraps"
|
||||
|
||||
New()
|
||||
|
||||
@@ -135,8 +135,17 @@
|
||||
new /obj/item/ammo_box/a357(src)
|
||||
return
|
||||
|
||||
/obj/item/weapon/storage/box/syndie_kit/greytide
|
||||
name = "box (GT)"
|
||||
/obj/item/weapon/storage/box/syndie_kit/imp_adrenal
|
||||
name = "boxed adrenal implant (with injector)"
|
||||
|
||||
New()
|
||||
..()
|
||||
var/obj/item/weapon/implanter/O = new(src)
|
||||
O.imp = new /obj/item/weapon/implant/adrenalin(O)
|
||||
O.update()
|
||||
|
||||
/obj/item/weapon/storage/box/syndie_kit/mindslave
|
||||
name = "box (MS)"
|
||||
|
||||
New()
|
||||
..()
|
||||
|
||||
@@ -8,21 +8,23 @@
|
||||
force = 10
|
||||
throwforce = 7
|
||||
w_class = 3
|
||||
var/stunforce = 10
|
||||
var/status = 0
|
||||
var/mob/foundmob = "" //Used in throwing proc.
|
||||
var/obj/item/weapon/cell/high/bcell = 0
|
||||
var/hitcost = 1500
|
||||
|
||||
origin_tech = "combat=2"
|
||||
attack_verb = list("beaten")
|
||||
var/stunforce = 0
|
||||
var/agonyforce = 60
|
||||
var/status = 0 //whether the thing is on or not
|
||||
var/obj/item/weapon/cell/high/bcell = null
|
||||
var/mob/foundmob = "" //Used in throwing proc.
|
||||
var/hitcost = 1500 //oh god why do power cells carry so much charge? We probably need to make a distinction between "industrial" sized power cells for APCs and power cells for everything else.
|
||||
|
||||
suicide_act(mob/user)
|
||||
viewers(user) << "<span class='suicide'>[user] is putting the live [name] in \his mouth! It looks like \he's trying to commit suicide.</span>"
|
||||
return (FIRELOSS)
|
||||
/obj/item/weapon/melee/baton/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is putting the live [name] in \his mouth! It looks like \he's trying to commit suicide.</span>")
|
||||
return (FIRELOSS)
|
||||
|
||||
/obj/item/weapon/melee/baton/loaded/New()
|
||||
|
||||
/obj/item/weapon/melee/baton/loaded/New() //this one starts with a cell pre-installed.
|
||||
..()
|
||||
bcell = new(src)
|
||||
bcell = new/obj/item/weapon/cell/high(src)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
@@ -116,51 +118,54 @@
|
||||
..()
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/agony = agonyforce
|
||||
var/stun = stunforce
|
||||
var/mob/living/L = M
|
||||
|
||||
var/target_zone = check_zone(user.zone_sel.selecting)
|
||||
if(user.a_intent == "hurt")
|
||||
if(!..()) return
|
||||
H.visible_message("<span class='danger'>[M] has been beaten with the [src] by [user]!</span>")
|
||||
if (!..()) //item/attack() does it's own messaging and logs
|
||||
return 0 // item/attack() will return 1 if they hit, 0 if they missed.
|
||||
agony *= 0.5 //whacking someone causes a much poorer contact than prodding them.
|
||||
stun *= 0.5
|
||||
//we can't really extract the actual hit zone from ..(), unfortunately. Just act like they attacked the area they intended to.
|
||||
else
|
||||
//copied from human_defense.dm - human defence code should really be refactored some time.
|
||||
if (ishuman(L))
|
||||
user.lastattacked = L //are these used at all, if we have logs?
|
||||
L.lastattacker = user
|
||||
|
||||
user.attack_log += "\[[time_stamp()]\]<font color='red'> Beat [H.name] ([H.ckey]) with [src.name]</font>"
|
||||
H.attack_log += "\[[time_stamp()]\]<font color='orange'> Beaten by [user.name] ([user.ckey]) with [src.name]</font>"
|
||||
msg_admin_attack("[user.name] ([user.ckey]) beat [H.name] ([H.ckey]) with [src.name] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
if (user != L) // Attacking yourself can't miss
|
||||
target_zone = get_zone_with_miss_chance(user.zone_sel.selecting, L)
|
||||
|
||||
playsound(src.loc, "swing_hit", 50, 1, -1)
|
||||
if(!target_zone)
|
||||
L.visible_message("\red <B>[user] misses [L] with \the [src]!")
|
||||
return 0
|
||||
|
||||
else if(!status)
|
||||
H.visible_message("<span class='warning'>[H] has been prodded with [src] by [user]. Luckily it was off.</span>")
|
||||
return
|
||||
|
||||
var/stunroll = (rand(1,100))
|
||||
|
||||
if(status)
|
||||
user.lastattacked = H
|
||||
H.lastattacker = user
|
||||
if(user == H) // Attacking yourself can't miss
|
||||
stunroll = 100
|
||||
if(stunroll < 40)
|
||||
H.visible_message("\red <B>[user] misses [H] with \the [src]!")
|
||||
msg_admin_attack("[key_name(user)] attempted to stun [key_name(H)] with the [src].")
|
||||
return
|
||||
H.Stun(stunforce)
|
||||
H.Weaken(stunforce)
|
||||
H.apply_effect(STUTTER, stunforce)
|
||||
|
||||
H.visible_message("<span class='danger'>[H] has been stunned with [src] by [user]!</span>")
|
||||
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
|
||||
|
||||
msg_admin_attack("[key_name(user)] stunned [key_name(H)] with the [src].")
|
||||
|
||||
user.attack_log += "\[[time_stamp()]\]<font color='red'> Stunned [H.name] ([H.ckey]) with [src.name]</font>"
|
||||
H.attack_log += "\[[time_stamp()]\]<font color='orange'> Stunned by [user.name] ([user.ckey]) with [src.name]</font>"
|
||||
|
||||
if(isrobot(loc))
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
if(R && R.cell)
|
||||
R.cell.use(hitcost)
|
||||
var/mob/living/carbon/human/H = L
|
||||
var/datum/organ/external/affecting = H.get_organ(target_zone)
|
||||
if (affecting)
|
||||
if(!status)
|
||||
L.visible_message("<span class='warning'>[L] has been prodded in the [affecting.display_name] with [src] by [user]. Luckily it was off.</span>")
|
||||
return 1
|
||||
else
|
||||
H.visible_message("<span class='danger'>[L] has been prodded in the [affecting.display_name] with [src] by [user]!</span>")
|
||||
else
|
||||
deductcharge(hitcost)
|
||||
if(!status)
|
||||
L.visible_message("<span class='warning'>[L] has been prodded with [src] by [user]. Luckily it was off.</span>")
|
||||
return 1
|
||||
else
|
||||
L.visible_message("<span class='danger'>[L] has been prodded with [src] by [user]!</span>")
|
||||
|
||||
//stun effects
|
||||
L.stun_effect_act(stun, agony, target_zone, src)
|
||||
|
||||
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
|
||||
msg_admin_attack("[key_name(user)] stunned [key_name(L)] with the [src].")
|
||||
|
||||
deductcharge(hitcost)
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/weapon/melee/baton/throw_impact(atom/hit_atom)
|
||||
@@ -169,9 +174,19 @@
|
||||
if(istype(hit_atom, /mob/living))
|
||||
var/mob/living/carbon/human/H = hit_atom
|
||||
if(status)
|
||||
H.Stun(stunforce)
|
||||
H.Weaken(stunforce)
|
||||
H.apply_effect(STUTTER, stunforce)
|
||||
//stun effects
|
||||
if (stunforce)
|
||||
H.Stun(stunforce)
|
||||
H.Weaken(stunforce)
|
||||
H.apply_effect(STUTTER, stunforce)
|
||||
|
||||
if (agonyforce)
|
||||
//Siemens coefficient?
|
||||
//TODO: Merge this with taser effects
|
||||
H.apply_effect(agonyforce,AGONY,0)
|
||||
H.apply_effect(STUTTER, agonyforce/10)
|
||||
H.apply_effect(EYE_BLUR, agonyforce/10)
|
||||
H.flash_pain()
|
||||
|
||||
deductcharge(hitcost)
|
||||
|
||||
@@ -196,11 +211,19 @@
|
||||
|
||||
/obj/item/weapon/melee/baton/emp_act(severity)
|
||||
if(bcell)
|
||||
deductcharge(1000 / severity)
|
||||
if(bcell.reliability != 100 && prob(50/severity))
|
||||
bcell.reliability -= 10 / severity
|
||||
bcell.emp_act(severity) //let's not duplicate code everywhere if we don't have to please.
|
||||
..()
|
||||
|
||||
//secborg stun baton module
|
||||
/obj/item/weapon/melee/baton/robot/attack_self(mob/user)
|
||||
//try to find our power cell
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
if (istype(R))
|
||||
bcell = R.cell
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/melee/baton/robot/attackby(obj/item/weapon/W, mob/user)
|
||||
return
|
||||
|
||||
/obj/item/weapon/melee/baton/loaded/ntcane
|
||||
name = "fancy cane"
|
||||
@@ -216,8 +239,10 @@
|
||||
item_state = "prod"
|
||||
force = 3
|
||||
throwforce = 5
|
||||
stunforce = 5
|
||||
stunforce = 0
|
||||
agonyforce = 60 //same force as a stunbaton, but uses way more charge.
|
||||
hitcost = 2500
|
||||
attack_verb = list("poked")
|
||||
slot_flags = null
|
||||
|
||||
/obj/item/weapon/melee/baton/cattleprod/update_icon()
|
||||
|
||||
@@ -137,7 +137,7 @@ Frequency:
|
||||
|
||||
/obj/item/weapon/hand_tele/attack_self(mob/user as mob)
|
||||
var/turf/current_location = get_turf(user)//What turf is the user on?
|
||||
if(!current_location||current_location.z==2||current_location.z>=7)//If turf was not found or they're on z level 2 or >7 which does not currently exist.
|
||||
if(!current_location||current_location.z==2||current_location.z>=8)//If turf was not found or they're on z level 2 or >8 which does not currently exist.
|
||||
user << "<span class='notice'>\The [src] is malfunctioning.</span>"
|
||||
return
|
||||
var/list/L = list( )
|
||||
|
||||
@@ -477,6 +477,9 @@
|
||||
if(S.brute_dam)
|
||||
S.heal_damage(15,0,0,1)
|
||||
user.visible_message("\red \The [user] patches some dents on \the [M]'s [S.display_name] with \the [src].")
|
||||
if(istype(M,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.updatehealth()
|
||||
return
|
||||
else
|
||||
user << "Nothing to fix!"
|
||||
|
||||
@@ -50,6 +50,14 @@
|
||||
if (!can_touch(user) || !climbable)
|
||||
return
|
||||
|
||||
for(var/obj/O in range(0, src))
|
||||
if(O.density == 1 && O != src && !istype(O, /obj/machinery/door/window)) //Ignores windoors, as those already block climbing, otherwise a windoor on the opposite side of a table would prevent climbing.
|
||||
user << "\red You cannot climb a [src] blocked by a solid object!"
|
||||
return
|
||||
for(var/turf/T in range(0, src))
|
||||
if(T.density == 1)
|
||||
user << "\red You cannot climb a [src] blocked by a solid object!"
|
||||
return
|
||||
var/turf/T = src.loc
|
||||
if(!T || !istype(T)) return
|
||||
|
||||
|
||||
@@ -25,10 +25,10 @@
|
||||
if(istype(O, /obj/item/device/multitool))
|
||||
user << "\red Resetting circuitry..."
|
||||
playsound(user, 'sound/machines/lockreset.ogg', 50, 1)
|
||||
sleep(50) // Sleeping time~
|
||||
src.locked = 0
|
||||
user << "\blue You disable the locking modules."
|
||||
update_icon()
|
||||
if(do_after(user, 20))
|
||||
src.locked = 0
|
||||
user << "<span class = 'caution'> You disable the locking modules.</span>"
|
||||
update_icon()
|
||||
return
|
||||
else if(istype(O, /obj/item/weapon))
|
||||
var/obj/item/weapon/W = O
|
||||
@@ -87,6 +87,9 @@
|
||||
src.locked = 1
|
||||
user << "\blue You re-enable the locking modules."
|
||||
playsound(user, 'sound/machines/lockenable.ogg', 50, 1)
|
||||
if(do_after(user,20))
|
||||
src.locked = 1
|
||||
user << "<span class = 'caution'> You re-enable the locking modules.</span>"
|
||||
return
|
||||
else
|
||||
localopened = !localopened
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
new /obj/item/weapon/cell/high(src)
|
||||
new /obj/item/weapon/card/id/syndicate(src)
|
||||
new /obj/item/device/multitool(src)
|
||||
new /obj/item/weapon/shield/energy(src)
|
||||
new /obj/item/clothing/shoes/magboots(src)
|
||||
|
||||
|
||||
@@ -34,6 +33,7 @@
|
||||
new /obj/item/ammo_box/magazine/m12mm(src)
|
||||
new /obj/item/ammo_box/magazine/m12mm(src)
|
||||
new /obj/item/weapon/storage/box/handcuffs(src)
|
||||
new /obj/item/weapon/storage/box/teargas(src)
|
||||
new /obj/item/weapon/storage/box/flashbangs(src)
|
||||
new /obj/item/weapon/gun/energy/gun(src)
|
||||
new /obj/item/weapon/gun/energy/gun(src)
|
||||
@@ -47,7 +47,7 @@
|
||||
new /obj/item/weapon/pinpointer/nukeop(src)
|
||||
new /obj/item/device/pda/syndicate(src)
|
||||
var/obj/item/device/radio/uplink/U = new(src)
|
||||
U.hidden_uplink.uses = 40
|
||||
U.hidden_uplink.uses = 55
|
||||
return
|
||||
|
||||
/obj/structure/closet/syndicate/resources/
|
||||
|
||||
@@ -68,6 +68,68 @@
|
||||
return 1
|
||||
|
||||
/obj/structure/closet/crate/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/weapon/rcs) && !src.opened)
|
||||
var/obj/item/weapon/rcs/E = W
|
||||
if(E.rcharges != 0)
|
||||
if(E.mode == 0)
|
||||
if(!E.teleporting)
|
||||
var/list/L = list()
|
||||
var/list/areaindex = list()
|
||||
for(var/obj/machinery/telepad_cargo/R in world)
|
||||
if(R.stage == 0)
|
||||
var/turf/T = get_turf(R)
|
||||
var/tmpname = T.loc.name
|
||||
if(areaindex[tmpname])
|
||||
tmpname = "[tmpname] ([++areaindex[tmpname]])"
|
||||
else
|
||||
areaindex[tmpname] = 1
|
||||
L[tmpname] = R
|
||||
var/desc = input("Please select a telepad.", "RCS") in L
|
||||
E.pad = L[desc]
|
||||
playsound(E.loc, 'sound/machines/click.ogg', 50, 1)
|
||||
user << "\blue Teleporting [src.name]..."
|
||||
E.teleporting = 1
|
||||
sleep(50)
|
||||
E.teleporting = 0
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
do_teleport(src, E.pad, 0)
|
||||
E.rcharges--
|
||||
if(E.rcharges != 1)
|
||||
user << "\blue Teleport successful. [E.rcharges] charges left."
|
||||
E.desc = "Use this to send crates and closets to cargo telepads. There are [E.rcharges] charges left."
|
||||
return
|
||||
else
|
||||
user << "\blue Teleport successful. [E.rcharges] charge left."
|
||||
E.desc = "Use this to send crates and closets to cargo telepads. There is [E.rcharges] charge left."
|
||||
return
|
||||
else
|
||||
E.rand_x = rand(50,200)
|
||||
E.rand_y = rand(50,200)
|
||||
var/L = locate(E.rand_x, E.rand_y, 6)
|
||||
playsound(E.loc, 'sound/machines/click.ogg', 50, 1)
|
||||
user << "\blue Teleporting [src.name]..."
|
||||
E.teleporting = 1
|
||||
sleep(50)
|
||||
E.teleporting = 0
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
do_teleport(src, L)
|
||||
E.rcharges--
|
||||
if(E.rcharges != 1)
|
||||
user << "\blue Teleport successful. [E.rcharges] charges left."
|
||||
E.desc = "Use this to send crates and closets to cargo telepads. There are [E.rcharges] charges left."
|
||||
return
|
||||
else
|
||||
user << "\blue Teleport successful. [E.rcharges] charge left."
|
||||
E.desc = "Use this to send crates and closets to cargo telepads. There is [E.rcharges] charge left."
|
||||
return
|
||||
else
|
||||
user << "\red Out of charges."
|
||||
return
|
||||
|
||||
if(opened)
|
||||
if(isrobot(user))
|
||||
return
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
basestate = "plasmawindow"
|
||||
icon_state = "plasmawindow"
|
||||
shardtype = /obj/item/weapon/shard/plasma
|
||||
glasstype = /obj/item/stack/sheet/plasmaglass
|
||||
health = 120
|
||||
|
||||
|
||||
@@ -63,6 +64,7 @@
|
||||
basestate = "plasmarwindow"
|
||||
icon_state = "plasmarwindow"
|
||||
shardtype = /obj/item/weapon/shard/plasma
|
||||
glasstype = /obj/item/stack/sheet/plasmaglass
|
||||
reinf = 1
|
||||
health = 160
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@
|
||||
return
|
||||
|
||||
//window placing begin
|
||||
else if( istype(W,/obj/item/stack/sheet/rglass) || istype(W,/obj/item/stack/sheet/glass) )
|
||||
else if( istype(W,/obj/item/stack/sheet/rglass) || istype(W,/obj/item/stack/sheet/glass) || istype(W,/obj/item/stack/sheet/plasmaglass) || istype(W,/obj/item/stack/sheet/plasmarglass) )
|
||||
var/dir_to_set = 1
|
||||
if(loc == user.loc)
|
||||
dir_to_set = user.dir
|
||||
@@ -182,8 +182,12 @@
|
||||
var/obj/structure/window/WD
|
||||
if(istype(W,/obj/item/stack/sheet/rglass))
|
||||
WD = new/obj/structure/window/reinforced(loc) //reinforced window
|
||||
else
|
||||
else if(istype(W,/obj/item/stack/sheet/glass))
|
||||
WD = new/obj/structure/window/basic(loc) //normal window
|
||||
else if(istype(W,/obj/item/stack/sheet/plasmaglass))
|
||||
WD = new/obj/structure/window/plasmabasic(loc) //basic plasma window
|
||||
else
|
||||
WD = new/obj/structure/window/plasmareinforced(loc) //reinforced plasma window
|
||||
WD.dir = dir_to_set
|
||||
WD.ini_dir = dir_to_set
|
||||
WD.anchored = 0
|
||||
@@ -228,7 +232,7 @@
|
||||
// returns 1 if shocked, 0 otherwise
|
||||
|
||||
/obj/structure/grille/proc/shock(mob/user as mob, prb)
|
||||
if(!anchored || destroyed) // anchored/destroyed grilles are never connected
|
||||
if(!anchored || destroyed) // deanchored/destroyed grilles are never connected
|
||||
return 0
|
||||
if(!prob(prb))
|
||||
return 0
|
||||
|
||||
@@ -5,223 +5,86 @@
|
||||
var/list/lines = new()
|
||||
var/tempo = 5
|
||||
|
||||
/obj/structure/device/piano
|
||||
name = "space minimoog"
|
||||
icon = 'icons/obj/musician.dmi'
|
||||
icon_state = "minimoog"
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/datum/song/song
|
||||
var/playing = 0
|
||||
var/help = 0
|
||||
var/edit = 1
|
||||
var/repeat = 0
|
||||
var/playing = 0 // if we're playing
|
||||
var/help = 0 // if help is open
|
||||
var/edit = 1 // if we're in editing mode
|
||||
var/repeat = 0 // number of times remaining to repeat
|
||||
var/max_repeats = 10 // maximum times we can repeat
|
||||
|
||||
/obj/structure/device/piano/New()
|
||||
if(prob(50))
|
||||
name = "space minimoog"
|
||||
desc = "This is a minimoog, like a space piano, but more spacey!"
|
||||
icon_state = "minimoog"
|
||||
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)
|
||||
instrumentDir = dir
|
||||
instrumentObj = obj
|
||||
|
||||
/datum/song/proc/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(var/note, var/acc as text, var/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/[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)
|
||||
for(var/mob/M in hearers(15, source))
|
||||
M.playsound_local(source, soundfile, 100, falloff = 5)
|
||||
|
||||
/datum/song/proc/updateDialog(mob/user as mob)
|
||||
instrumentObj.updateDialog() // assumes it's an object in world, override if otherwise
|
||||
|
||||
/datum/song/proc/shouldStopPlaying()
|
||||
if(instrumentObj)
|
||||
return !instrumentObj.anchored // add special cases to stop in subclasses
|
||||
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"
|
||||
return 1
|
||||
|
||||
/obj/structure/device/piano/proc/playnote(var/note as text)
|
||||
//world << "Note: [note]"
|
||||
var/soundfile
|
||||
/*BYOND loads resource files at compile time if they are ''. This means you can't really manipulate them dynamically.
|
||||
Tried doing it dynamically at first but its more trouble than its worth. Would have saved many lines tho.*/
|
||||
switch(note)
|
||||
if("Cn1") soundfile = 'sound/piano/Cn1.ogg'
|
||||
if("C#1") soundfile = 'sound/piano/C#1.ogg'
|
||||
if("Db1") soundfile = 'sound/piano/Db1.ogg'
|
||||
if("Dn1") soundfile = 'sound/piano/Dn1.ogg'
|
||||
if("D#1") soundfile = 'sound/piano/D#1.ogg'
|
||||
if("Eb1") soundfile = 'sound/piano/Eb1.ogg'
|
||||
if("En1") soundfile = 'sound/piano/En1.ogg'
|
||||
if("E#1") soundfile = 'sound/piano/E#1.ogg'
|
||||
if("Fb1") soundfile = 'sound/piano/Fb1.ogg'
|
||||
if("Fn1") soundfile = 'sound/piano/Fn1.ogg'
|
||||
if("F#1") soundfile = 'sound/piano/F#1.ogg'
|
||||
if("Gb1") soundfile = 'sound/piano/Gb1.ogg'
|
||||
if("Gn1") soundfile = 'sound/piano/Gn1.ogg'
|
||||
if("G#1") soundfile = 'sound/piano/G#1.ogg'
|
||||
if("Ab1") soundfile = 'sound/piano/Ab1.ogg'
|
||||
if("An1") soundfile = 'sound/piano/An1.ogg'
|
||||
if("A#1") soundfile = 'sound/piano/A#1.ogg'
|
||||
if("Bb1") soundfile = 'sound/piano/Bb1.ogg'
|
||||
if("Bn1") soundfile = 'sound/piano/Bn1.ogg'
|
||||
if("B#1") soundfile = 'sound/piano/B#1.ogg'
|
||||
if("Cb2") soundfile = 'sound/piano/Cb2.ogg'
|
||||
if("Cn2") soundfile = 'sound/piano/Cn2.ogg'
|
||||
if("C#2") soundfile = 'sound/piano/C#2.ogg'
|
||||
if("Db2") soundfile = 'sound/piano/Db2.ogg'
|
||||
if("Dn2") soundfile = 'sound/piano/Dn2.ogg'
|
||||
if("D#2") soundfile = 'sound/piano/D#2.ogg'
|
||||
if("Eb2") soundfile = 'sound/piano/Eb2.ogg'
|
||||
if("En2") soundfile = 'sound/piano/En2.ogg'
|
||||
if("E#2") soundfile = 'sound/piano/E#2.ogg'
|
||||
if("Fb2") soundfile = 'sound/piano/Fb2.ogg'
|
||||
if("Fn2") soundfile = 'sound/piano/Fn2.ogg'
|
||||
if("F#2") soundfile = 'sound/piano/F#2.ogg'
|
||||
if("Gb2") soundfile = 'sound/piano/Gb2.ogg'
|
||||
if("Gn2") soundfile = 'sound/piano/Gn2.ogg'
|
||||
if("G#2") soundfile = 'sound/piano/G#2.ogg'
|
||||
if("Ab2") soundfile = 'sound/piano/Ab2.ogg'
|
||||
if("An2") soundfile = 'sound/piano/An2.ogg'
|
||||
if("A#2") soundfile = 'sound/piano/A#2.ogg'
|
||||
if("Bb2") soundfile = 'sound/piano/Bb2.ogg'
|
||||
if("Bn2") soundfile = 'sound/piano/Bn2.ogg'
|
||||
if("B#2") soundfile = 'sound/piano/B#2.ogg'
|
||||
if("Cb3") soundfile = 'sound/piano/Cb3.ogg'
|
||||
if("Cn3") soundfile = 'sound/piano/Cn3.ogg'
|
||||
if("C#3") soundfile = 'sound/piano/C#3.ogg'
|
||||
if("Db3") soundfile = 'sound/piano/Db3.ogg'
|
||||
if("Dn3") soundfile = 'sound/piano/Dn3.ogg'
|
||||
if("D#3") soundfile = 'sound/piano/D#3.ogg'
|
||||
if("Eb3") soundfile = 'sound/piano/Eb3.ogg'
|
||||
if("En3") soundfile = 'sound/piano/En3.ogg'
|
||||
if("E#3") soundfile = 'sound/piano/E#3.ogg'
|
||||
if("Fb3") soundfile = 'sound/piano/Fb3.ogg'
|
||||
if("Fn3") soundfile = 'sound/piano/Fn3.ogg'
|
||||
if("F#3") soundfile = 'sound/piano/F#3.ogg'
|
||||
if("Gb3") soundfile = 'sound/piano/Gb3.ogg'
|
||||
if("Gn3") soundfile = 'sound/piano/Gn3.ogg'
|
||||
if("G#3") soundfile = 'sound/piano/G#3.ogg'
|
||||
if("Ab3") soundfile = 'sound/piano/Ab3.ogg'
|
||||
if("An3") soundfile = 'sound/piano/An3.ogg'
|
||||
if("A#3") soundfile = 'sound/piano/A#3.ogg'
|
||||
if("Bb3") soundfile = 'sound/piano/Bb3.ogg'
|
||||
if("Bn3") soundfile = 'sound/piano/Bn3.ogg'
|
||||
if("B#3") soundfile = 'sound/piano/B#3.ogg'
|
||||
if("Cb4") soundfile = 'sound/piano/Cb4.ogg'
|
||||
if("Cn4") soundfile = 'sound/piano/Cn4.ogg'
|
||||
if("C#4") soundfile = 'sound/piano/C#4.ogg'
|
||||
if("Db4") soundfile = 'sound/piano/Db4.ogg'
|
||||
if("Dn4") soundfile = 'sound/piano/Dn4.ogg'
|
||||
if("D#4") soundfile = 'sound/piano/D#4.ogg'
|
||||
if("Eb4") soundfile = 'sound/piano/Eb4.ogg'
|
||||
if("En4") soundfile = 'sound/piano/En4.ogg'
|
||||
if("E#4") soundfile = 'sound/piano/E#4.ogg'
|
||||
if("Fb4") soundfile = 'sound/piano/Fb4.ogg'
|
||||
if("Fn4") soundfile = 'sound/piano/Fn4.ogg'
|
||||
if("F#4") soundfile = 'sound/piano/F#4.ogg'
|
||||
if("Gb4") soundfile = 'sound/piano/Gb4.ogg'
|
||||
if("Gn4") soundfile = 'sound/piano/Gn4.ogg'
|
||||
if("G#4") soundfile = 'sound/piano/G#4.ogg'
|
||||
if("Ab4") soundfile = 'sound/piano/Ab4.ogg'
|
||||
if("An4") soundfile = 'sound/piano/An4.ogg'
|
||||
if("A#4") soundfile = 'sound/piano/A#4.ogg'
|
||||
if("Bb4") soundfile = 'sound/piano/Bb4.ogg'
|
||||
if("Bn4") soundfile = 'sound/piano/Bn4.ogg'
|
||||
if("B#4") soundfile = 'sound/piano/B#4.ogg'
|
||||
if("Cb5") soundfile = 'sound/piano/Cb5.ogg'
|
||||
if("Cn5") soundfile = 'sound/piano/Cn5.ogg'
|
||||
if("C#5") soundfile = 'sound/piano/C#5.ogg'
|
||||
if("Db5") soundfile = 'sound/piano/Db5.ogg'
|
||||
if("Dn5") soundfile = 'sound/piano/Dn5.ogg'
|
||||
if("D#5") soundfile = 'sound/piano/D#5.ogg'
|
||||
if("Eb5") soundfile = 'sound/piano/Eb5.ogg'
|
||||
if("En5") soundfile = 'sound/piano/En5.ogg'
|
||||
if("E#5") soundfile = 'sound/piano/E#5.ogg'
|
||||
if("Fb5") soundfile = 'sound/piano/Fb5.ogg'
|
||||
if("Fn5") soundfile = 'sound/piano/Fn5.ogg'
|
||||
if("F#5") soundfile = 'sound/piano/F#5.ogg'
|
||||
if("Gb5") soundfile = 'sound/piano/Gb5.ogg'
|
||||
if("Gn5") soundfile = 'sound/piano/Gn5.ogg'
|
||||
if("G#5") soundfile = 'sound/piano/G#5.ogg'
|
||||
if("Ab5") soundfile = 'sound/piano/Ab5.ogg'
|
||||
if("An5") soundfile = 'sound/piano/An5.ogg'
|
||||
if("A#5") soundfile = 'sound/piano/A#5.ogg'
|
||||
if("Bb5") soundfile = 'sound/piano/Bb5.ogg'
|
||||
if("Bn5") soundfile = 'sound/piano/Bn5.ogg'
|
||||
if("B#5") soundfile = 'sound/piano/B#5.ogg'
|
||||
if("Cb6") soundfile = 'sound/piano/Cb6.ogg'
|
||||
if("Cn6") soundfile = 'sound/piano/Cn6.ogg'
|
||||
if("C#6") soundfile = 'sound/piano/C#6.ogg'
|
||||
if("Db6") soundfile = 'sound/piano/Db6.ogg'
|
||||
if("Dn6") soundfile = 'sound/piano/Dn6.ogg'
|
||||
if("D#6") soundfile = 'sound/piano/D#6.ogg'
|
||||
if("Eb6") soundfile = 'sound/piano/Eb6.ogg'
|
||||
if("En6") soundfile = 'sound/piano/En6.ogg'
|
||||
if("E#6") soundfile = 'sound/piano/E#6.ogg'
|
||||
if("Fb6") soundfile = 'sound/piano/Fb6.ogg'
|
||||
if("Fn6") soundfile = 'sound/piano/Fn6.ogg'
|
||||
if("F#6") soundfile = 'sound/piano/F#6.ogg'
|
||||
if("Gb6") soundfile = 'sound/piano/Gb6.ogg'
|
||||
if("Gn6") soundfile = 'sound/piano/Gn6.ogg'
|
||||
if("G#6") soundfile = 'sound/piano/G#6.ogg'
|
||||
if("Ab6") soundfile = 'sound/piano/Ab6.ogg'
|
||||
if("An6") soundfile = 'sound/piano/An6.ogg'
|
||||
if("A#6") soundfile = 'sound/piano/A#6.ogg'
|
||||
if("Bb6") soundfile = 'sound/piano/Bb6.ogg'
|
||||
if("Bn6") soundfile = 'sound/piano/Bn6.ogg'
|
||||
if("B#6") soundfile = 'sound/piano/B#6.ogg'
|
||||
if("Cb7") soundfile = 'sound/piano/Cb7.ogg'
|
||||
if("Cn7") soundfile = 'sound/piano/Cn7.ogg'
|
||||
if("C#7") soundfile = 'sound/piano/C#7.ogg'
|
||||
if("Db7") soundfile = 'sound/piano/Db7.ogg'
|
||||
if("Dn7") soundfile = 'sound/piano/Dn7.ogg'
|
||||
if("D#7") soundfile = 'sound/piano/D#7.ogg'
|
||||
if("Eb7") soundfile = 'sound/piano/Eb7.ogg'
|
||||
if("En7") soundfile = 'sound/piano/En7.ogg'
|
||||
if("E#7") soundfile = 'sound/piano/E#7.ogg'
|
||||
if("Fb7") soundfile = 'sound/piano/Fb7.ogg'
|
||||
if("Fn7") soundfile = 'sound/piano/Fn7.ogg'
|
||||
if("F#7") soundfile = 'sound/piano/F#7.ogg'
|
||||
if("Gb7") soundfile = 'sound/piano/Gb7.ogg'
|
||||
if("Gn7") soundfile = 'sound/piano/Gn7.ogg'
|
||||
if("G#7") soundfile = 'sound/piano/G#7.ogg'
|
||||
if("Ab7") soundfile = 'sound/piano/Ab7.ogg'
|
||||
if("An7") soundfile = 'sound/piano/An7.ogg'
|
||||
if("A#7") soundfile = 'sound/piano/A#7.ogg'
|
||||
if("Bb7") soundfile = 'sound/piano/Bb7.ogg'
|
||||
if("Bn7") soundfile = 'sound/piano/Bn7.ogg'
|
||||
if("B#7") soundfile = 'sound/piano/B#7.ogg'
|
||||
if("Cb8") soundfile = 'sound/piano/Cb8.ogg'
|
||||
if("Cn8") soundfile = 'sound/piano/Cn8.ogg'
|
||||
if("C#8") soundfile = 'sound/piano/C#8.ogg'
|
||||
if("Db8") soundfile = 'sound/piano/Db8.ogg'
|
||||
if("Dn8") soundfile = 'sound/piano/Dn8.ogg'
|
||||
if("D#8") soundfile = 'sound/piano/D#8.ogg'
|
||||
if("Eb8") soundfile = 'sound/piano/Eb8.ogg'
|
||||
if("En8") soundfile = 'sound/piano/En8.ogg'
|
||||
if("E#8") soundfile = 'sound/piano/E#8.ogg'
|
||||
if("Fb8") soundfile = 'sound/piano/Fb8.ogg'
|
||||
if("Fn8") soundfile = 'sound/piano/Fn8.ogg'
|
||||
if("F#8") soundfile = 'sound/piano/F#8.ogg'
|
||||
if("Gb8") soundfile = 'sound/piano/Gb8.ogg'
|
||||
if("Gn8") soundfile = 'sound/piano/Gn8.ogg'
|
||||
if("G#8") soundfile = 'sound/piano/G#8.ogg'
|
||||
if("Ab8") soundfile = 'sound/piano/Ab8.ogg'
|
||||
if("An8") soundfile = 'sound/piano/An8.ogg'
|
||||
if("A#8") soundfile = 'sound/piano/A#8.ogg'
|
||||
if("Bb8") soundfile = 'sound/piano/Bb8.ogg'
|
||||
if("Bn8") soundfile = 'sound/piano/Bn8.ogg'
|
||||
if("B#8") soundfile = 'sound/piano/B#8.ogg'
|
||||
if("Cb9") soundfile = 'sound/piano/Cb9.ogg'
|
||||
if("Cn9") soundfile = 'sound/piano/Cn9.ogg'
|
||||
else return
|
||||
|
||||
hearers(15, src) << sound(soundfile)
|
||||
|
||||
/obj/structure/device/piano/proc/playsong()
|
||||
do
|
||||
/datum/song/proc/playsong(mob/user as mob)
|
||||
while(repeat >= 0)
|
||||
var/cur_oct[7]
|
||||
var/cur_acc[7]
|
||||
for(var/i = 1 to 7)
|
||||
cur_oct[i] = "3"
|
||||
cur_oct[i] = 3
|
||||
cur_acc[i] = "n"
|
||||
|
||||
for(var/line in song.lines)
|
||||
for(var/line in lines)
|
||||
//world << line
|
||||
for(var/beat in text2list(lowertext(line), ","))
|
||||
//world << "beat: [beat]"
|
||||
var/list/notes = text2list(beat, "/")
|
||||
for(var/note in text2list(notes[1], "-"))
|
||||
//world << "note: [note]"
|
||||
if(!playing || !anchored)//If the piano is playing, or is loose
|
||||
if(!playing || shouldStopPlaying())//If the instrument is playing, or special case
|
||||
playing = 0
|
||||
return
|
||||
if(lentext(note) == 0)
|
||||
@@ -238,48 +101,52 @@
|
||||
else if(ni == "s")
|
||||
cur_acc[cur_note] = "#" // so shift is never required
|
||||
else
|
||||
cur_oct[cur_note] = ni
|
||||
playnote(uppertext(copytext(note,1,2)) + cur_acc[cur_note] + cur_oct[cur_note])
|
||||
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(song.tempo / text2num(notes[2]))
|
||||
sleep(tempo / text2num(notes[2]))
|
||||
else
|
||||
sleep(song.tempo)
|
||||
if(repeat > 0)
|
||||
repeat-- //Infinite loops are baaaad.
|
||||
while(repeat > 0)
|
||||
sleep(tempo)
|
||||
repeat--
|
||||
if(repeat >= 0) // don't show the last -1 repeat
|
||||
updateDialog(user)
|
||||
playing = 0
|
||||
updateUsrDialog()
|
||||
repeat = 0
|
||||
updateDialog(user)
|
||||
|
||||
/obj/structure/device/piano/attack_hand(var/mob/user as mob)
|
||||
if(!anchored)
|
||||
return
|
||||
/datum/song/proc/interact(mob/user as mob)
|
||||
var/dat = ""
|
||||
|
||||
usr.machine = src
|
||||
var/dat = "<HEAD><TITLE>Piano</TITLE></HEAD><BODY>"
|
||||
|
||||
if(song)
|
||||
if(song.lines.len > 0 && !(playing))
|
||||
dat += "<A href='?src=\ref[src];play=1'>Play Song</A><BR><BR>"
|
||||
dat += "<A href='?src=\ref[src];repeat=1'>Repeat Song: [repeat] times.</A><BR><BR>"
|
||||
if(playing)
|
||||
dat += "<A href='?src=\ref[src];stop=1'>Stop Playing</A><BR>"
|
||||
dat += "Repeats left: [repeat].<BR><BR>"
|
||||
if(lines.len > 0)
|
||||
dat += "<H3>Playback</H3>"
|
||||
if(!playing)
|
||||
dat += "<A href='?src=\ref[src];play=1'>Play</A> <SPAN CLASS='linkOn'>Stop</SPAN><BR><BR>"
|
||||
dat += "Repeat Song: "
|
||||
dat += repeat > 0 ? "<A href='?src=\ref[src];repeat=-10'>-</A><A href='?src=\ref[src];repeat=-1'>-</A>" : "<SPAN CLASS='linkOff'>-</SPAN><SPAN CLASS='linkOff'>-</SPAN>"
|
||||
dat += " [repeat] times "
|
||||
dat += repeat < max_repeats ? "<A href='?src=\ref[src];repeat=1'>+</A><A href='?src=\ref[src];repeat=10'>+</A>" : "<SPAN CLASS='linkOff'>+</SPAN><SPAN CLASS='linkOff'>+</SPAN>"
|
||||
dat += "<BR>"
|
||||
else
|
||||
dat += "<SPAN CLASS='linkOn'>Play</SPAN> <A href='?src=\ref[src];stop=1'>Stop</A><BR>"
|
||||
dat += "Repeats left: <B>[repeat]</B><BR>"
|
||||
if(!edit)
|
||||
dat += "<A href='?src=\ref[src];edit=2'>Show Editor</A><BR><BR>"
|
||||
dat += "<BR><B><A href='?src=\ref[src];edit=2'>Show Editor</A></B><BR>"
|
||||
else
|
||||
dat += "<A href='?src=\ref[src];edit=1'>Hide Editor</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];newsong=1'>Start a New Song</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];import=1'>Import a Song</A><BR><BR>"
|
||||
if(song)
|
||||
var/calctempo = (10/song.tempo)*60
|
||||
dat += "Tempo : <A href='?src=\ref[src];tempo=10'>-</A><A href='?src=\ref[src];tempo=1'>-</A> [calctempo] BPM <A href='?src=\ref[src];tempo=-1'>+</A><A href='?src=\ref[src];tempo=-10'>+</A><BR><BR>"
|
||||
var/linecount = 0
|
||||
for(var/line in song.lines)
|
||||
linecount += 1
|
||||
dat += "Line [linecount]: [line] <A href='?src=\ref[src];deleteline=[linecount]'>Delete Line</A> <A href='?src=\ref[src];modifyline=[linecount]'>Modify Line</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];newline=1'>Add Line</A><BR><BR>"
|
||||
dat += "<H3>Editing</H3>"
|
||||
dat += "<B><A href='?src=\ref[src];edit=1'>Hide Editor</A></B>"
|
||||
dat += " <A href='?src=\ref[src];newsong=1'>Start a New Song</A>"
|
||||
dat += " <A href='?src=\ref[src];import=1'>Import a Song</A><BR><BR>"
|
||||
var/calctempo = round(600 / tempo)
|
||||
var/calcstep = tempo - 600 / (calctempo+1)
|
||||
var/calcstep_b = tempo - 600 / (calctempo+10)
|
||||
dat += "Tempo: <A href='?src=\ref[src];tempo=[calcstep_b]'>-</A><A href='?src=\ref[src];tempo=[calcstep]'>-</A> [calctempo] BPM <A href='?src=\ref[src];tempo=-[calcstep]'>+</A><A href='?src=\ref[src];tempo=-[calcstep_b]'>+</A><BR><BR>"
|
||||
var/linecount = 0
|
||||
for(var/line in lines)
|
||||
linecount += 1
|
||||
dat += "Line [linecount]: <A href='?src=\ref[src];modifyline=[linecount]'>Edit</A> <A href='?src=\ref[src];deleteline=[linecount]'>X</A> [line]<BR>"
|
||||
dat += "<A href='?src=\ref[src];newline=1'>Add Line</A><BR><BR>"
|
||||
if(help)
|
||||
dat += "<A href='?src=\ref[src];help=1'>Hide Help</A><BR>"
|
||||
dat += "<B><A href='?src=\ref[src];help=1'>Hide Help</A></B><BR>"
|
||||
dat += {"
|
||||
Lines are a series of chords, separated by commas (,), each with notes seperated by hyphens (-).<br>
|
||||
Every note in a chord will play together, with chord timed by the tempo.<br>
|
||||
@@ -292,140 +159,198 @@
|
||||
A pause may be denoted by an empty chord: <i>C,E,,C,G</i><br>
|
||||
To make a chord be a different time, end it with /x, where the chord length will be length<br>
|
||||
defined by tempo / x: <i>C,G/2,E/4</i><br>
|
||||
Combined, an example is: <i>E-E4/4,/2,G#/8,B/8,E3-E4/4</i>
|
||||
Combined, an example is: <i>E-E4/4,F#/2,G#/8,B/8,E3-E4/4</i>
|
||||
<br>
|
||||
Lines may be up to 50 characters.<br>
|
||||
A song may only contain up to 50 lines.<br>
|
||||
"}
|
||||
else
|
||||
dat += "<A href='?src=\ref[src];help=2'>Show Help</A><BR>"
|
||||
dat += "</BODY></HTML>"
|
||||
user << browse(dat, "window=piano;size=700x300")
|
||||
onclose(user, "piano")
|
||||
dat += "<B><A href='?src=\ref[src];help=2'>Show Help</A></B><BR>"
|
||||
|
||||
/obj/structure/device/piano/Topic(href, href_list)
|
||||
var/datum/browser/popup = new(user, "instrument", instrumentObj.name, 700, 500)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(instrumentObj.icon, instrumentObj.icon_state))
|
||||
popup.open()
|
||||
|
||||
if(!in_range(src, usr) || issilicon(usr) || !anchored || !usr.canmove || usr.restrained())
|
||||
usr << browse(null, "window=piano;size=700x300")
|
||||
onclose(usr, "piano")
|
||||
|
||||
/datum/song/Topic(href, href_list)
|
||||
if(!in_range(instrumentObj, usr) || (issilicon(usr) && instrumentObj.loc != usr) || !isliving(usr) || !usr.canmove || usr.restrained())
|
||||
usr << browse(null, "window=instrument")
|
||||
usr.unset_machine()
|
||||
return
|
||||
|
||||
instrumentObj.add_fingerprint(usr)
|
||||
|
||||
if(href_list["newsong"])
|
||||
song = new()
|
||||
else if(song)
|
||||
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.
|
||||
var/tempnum = input("How many times do you want to repeat this piece? (max:10)") as num|null
|
||||
if(tempnum > 10)
|
||||
tempnum = 10
|
||||
if(tempnum < 0)
|
||||
tempnum = 0
|
||||
repeat = round(tempnum)
|
||||
lines = new()
|
||||
tempo = 5 // default 120 BPM
|
||||
name = ""
|
||||
|
||||
else if(href_list["tempo"])
|
||||
song.tempo += round(text2num(href_list["tempo"]))
|
||||
if(song.tempo < 1)
|
||||
song.tempo = 1
|
||||
|
||||
else if(href_list["play"])
|
||||
if(song)
|
||||
playing = 1
|
||||
spawn() playsong()
|
||||
|
||||
else if(href_list["newline"])
|
||||
var/newline = html_encode(input("Enter your line: ", "Piano") as text|null)
|
||||
if(!newline)
|
||||
else if(href_list["import"])
|
||||
var/t = ""
|
||||
do
|
||||
t = html_encode(input(usr, "Please paste the entire song, formatted:", text("[]", name), t) as message)
|
||||
if(!in_range(instrumentObj, usr))
|
||||
return
|
||||
if(song.lines.len > 50)
|
||||
return
|
||||
if(lentext(newline) > 50)
|
||||
newline = copytext(newline, 1, 50)
|
||||
song.lines.Add(newline)
|
||||
|
||||
else if(href_list["deleteline"])
|
||||
var/num = round(text2num(href_list["deleteline"]))
|
||||
if(num > song.lines.len || num < 1)
|
||||
return
|
||||
song.lines.Cut(num, num+1)
|
||||
if(lentext(t) >= 3072)
|
||||
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(lentext(t) > 3072)
|
||||
|
||||
else if(href_list["modifyline"])
|
||||
var/num = round(text2num(href_list["modifyline"]),1)
|
||||
var/content = html_encode(input("Enter your line: ", "Piano", song.lines[num]) as text|null)
|
||||
if(!content)
|
||||
return
|
||||
if(lentext(content) > 50)
|
||||
content = copytext(content, 1, 50)
|
||||
if(num > song.lines.len || num < 1)
|
||||
return
|
||||
song.lines[num] = content
|
||||
//split into lines
|
||||
spawn()
|
||||
lines = text2list(t, "\n")
|
||||
if(copytext(lines[1],1,6) == "BPM: ")
|
||||
tempo = 600 / max(1, text2num(copytext(lines[1],6)))
|
||||
lines.Cut(1,2)
|
||||
else
|
||||
tempo = 5 // default 120 BPM
|
||||
if(lines.len > 50)
|
||||
usr << "Too many lines!"
|
||||
lines.Cut(51)
|
||||
var/linenum = 1
|
||||
for(var/l in lines)
|
||||
if(lentext(l) > 50)
|
||||
usr << "Line [linenum] too long!"
|
||||
lines.Remove(l)
|
||||
else
|
||||
linenum++
|
||||
updateDialog(usr) // make sure updates when complete
|
||||
|
||||
else if(href_list["stop"])
|
||||
playing = 0
|
||||
else if(href_list["help"])
|
||||
help = text2num(href_list["help"]) - 1
|
||||
|
||||
else if(href_list["help"])
|
||||
help = text2num(href_list["help"]) - 1
|
||||
else if(href_list["edit"])
|
||||
edit = text2num(href_list["edit"]) - 1
|
||||
|
||||
else if(href_list["edit"])
|
||||
edit = text2num(href_list["edit"]) - 1
|
||||
if(href_list["repeat"]) //Changing this from a toggle to a number of repeats to avoid infinite loops.
|
||||
if(playing)
|
||||
return //So that people cant keep adding to repeat. If the do it intentionally, it could result in the server crashing.
|
||||
repeat += round(text2num(href_list["repeat"]))
|
||||
if(repeat < 0)
|
||||
repeat = 0
|
||||
if(repeat > max_repeats)
|
||||
repeat = max_repeats
|
||||
|
||||
else if(href_list["import"])
|
||||
var/t = ""
|
||||
do
|
||||
t = html_encode(input(usr, "Please paste the entire song, formatted:", text("[]", src.name), t) as message)
|
||||
if (!in_range(src, usr))
|
||||
return
|
||||
else if(href_list["tempo"])
|
||||
tempo += text2num(href_list["tempo"])
|
||||
if(tempo < 1)
|
||||
tempo = 1
|
||||
if(tempo > 600)
|
||||
tempo = 600
|
||||
|
||||
if(lentext(t) >= 3072)
|
||||
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(lentext(t) > 3072)
|
||||
else if(href_list["play"])
|
||||
playing = 1
|
||||
spawn()
|
||||
playsong(usr)
|
||||
|
||||
//split into lines
|
||||
spawn()
|
||||
var/list/lines = text2list(t, "\n")
|
||||
var/tempo = 5
|
||||
if(copytext(lines[1],1,6) == "BPM: ")
|
||||
tempo = 600 / text2num(copytext(lines[1],6))
|
||||
lines.Cut(1,2)
|
||||
if(lines.len > 50)
|
||||
usr << "Too many lines!"
|
||||
lines.Cut(51)
|
||||
var/linenum = 1
|
||||
for(var/l in lines)
|
||||
if(lentext(l) > 50)
|
||||
usr << "Line [linenum] too long!"
|
||||
lines.Remove(l)
|
||||
else
|
||||
linenum++
|
||||
song = new()
|
||||
song.lines = lines
|
||||
song.tempo = tempo
|
||||
updateUsrDialog()
|
||||
else if(href_list["newline"])
|
||||
var/newline = html_encode(input("Enter your line: ", instrumentObj.name) as text|null)
|
||||
if(!newline || !in_range(instrumentObj, usr))
|
||||
return
|
||||
if(lines.len > 50)
|
||||
return
|
||||
if(lentext(newline) > 50)
|
||||
newline = copytext(newline, 1, 50)
|
||||
lines.Add(newline)
|
||||
|
||||
add_fingerprint(usr)
|
||||
updateUsrDialog()
|
||||
else if(href_list["deleteline"])
|
||||
var/num = round(text2num(href_list["deleteline"]))
|
||||
if(num > lines.len || num < 1)
|
||||
return
|
||||
lines.Cut(num, num+1)
|
||||
|
||||
else if(href_list["modifyline"])
|
||||
var/num = round(text2num(href_list["modifyline"]),1)
|
||||
var/content = html_encode(input("Enter your line: ", instrumentObj.name, lines[num]) as text|null)
|
||||
if(!content || !in_range(instrumentObj, usr))
|
||||
return
|
||||
if(lentext(content) > 50)
|
||||
content = copytext(content, 1, 50)
|
||||
if(num > lines.len || num < 1)
|
||||
return
|
||||
lines[num] = content
|
||||
|
||||
else if(href_list["stop"])
|
||||
playing = 0
|
||||
|
||||
updateDialog(usr)
|
||||
return
|
||||
|
||||
/obj/structure/device/piano/attackby(obj/item/O as obj, mob/user as mob)
|
||||
|
||||
// subclass for handheld instruments, like violin
|
||||
/datum/song/handheld
|
||||
|
||||
/datum/song/handheld/updateDialog(mob/user as mob)
|
||||
instrumentObj.interact(user)
|
||||
|
||||
/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()
|
||||
del(song)
|
||||
song = null
|
||||
..()
|
||||
|
||||
/obj/structure/piano/attack_hand(mob/user as mob)
|
||||
interact(user)
|
||||
|
||||
/obj/structure/piano/interact(mob/user as mob)
|
||||
if(!user || !anchored)
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
song.interact(user)
|
||||
|
||||
/obj/structure/piano/attackby(obj/item/O as obj, mob/user as mob)
|
||||
if (istype(O, /obj/item/weapon/wrench))
|
||||
if (anchored)
|
||||
if (!anchored && !isinspace())
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
user << "\blue You begin to loosen \the [src]'s casters..."
|
||||
if (do_after(user, 40))
|
||||
user.visible_message( \
|
||||
"[user] loosens \the [src]'s casters.", \
|
||||
"\blue You have loosened \the [src]. Now it can be pulled somewhere else.", \
|
||||
"You hear ratchet.")
|
||||
src.anchored = 0
|
||||
else
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
user << "\blue You begin to tighten \the [src] to the floor..."
|
||||
user << "<span class='notice'> You begin to tighten \the [src] to the floor...</span>"
|
||||
if (do_after(user, 20))
|
||||
user.visible_message( \
|
||||
"[user] tightens \the [src]'s casters.", \
|
||||
"\blue You have tightened \the [src]'s casters. Now it can be played again.", \
|
||||
"<span class='notice'> You have tightened \the [src]'s casters. Now it can be played again.</span>", \
|
||||
"You hear ratchet.")
|
||||
src.anchored = 1
|
||||
anchored = 1
|
||||
else if(anchored)
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
user << "<span class='notice'> You begin to loosen \the [src]'s casters...</span>"
|
||||
if (do_after(user, 40))
|
||||
user.visible_message( \
|
||||
"[user] loosens \the [src]'s casters.", \
|
||||
"<span class='notice'> You have loosened \the [src]. Now it can be pulled somewhere else.</span>", \
|
||||
"You hear ratchet.")
|
||||
anchored = 0
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
var/reinf = 0
|
||||
var/basestate
|
||||
var/shardtype = /obj/item/weapon/shard
|
||||
var/glasstype = /obj/item/stack/sheet/glass
|
||||
var/disassembled = 0
|
||||
var/sheets = 1 // Number of sheets needed to build this window (determines how much shit is spawned by destroy())
|
||||
// var/silicate = 0 // number of units of silicate
|
||||
// var/icon/silicateIcon = null // the silicated icon
|
||||
@@ -173,6 +175,7 @@
|
||||
|
||||
/obj/structure/window/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(!istype(W)) return//I really wish I did not need this
|
||||
if(W.flags & NOBLUDGEON) return
|
||||
|
||||
if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2)
|
||||
var/obj/item/weapon/grab/G = W
|
||||
@@ -231,6 +234,32 @@
|
||||
state = 1 - state
|
||||
playsound(loc, 'sound/items/Crowbar.ogg', 75, 1)
|
||||
user << (state ? "<span class='notice'>You have pried the window into the frame.</span>" : "<span class='notice'>You have pried the window out of the frame.</span>")
|
||||
else if(istype(W, /obj/item/weapon/wrench) && !anchored && health > 7) //Disassemble deconstructed window into parts
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
for(var/i=0;i<sheets;i++)
|
||||
var/obj/item/stack/sheet/glass/NG = getFromPool(glasstype, src.loc)
|
||||
for (var/obj/item/stack/sheet/glass/G in src.loc) //Stack em up
|
||||
if(G==NG)
|
||||
continue
|
||||
if(G.amount>=G.max_amount)
|
||||
continue
|
||||
G.attackby(NG, user)
|
||||
|
||||
if (reinf)
|
||||
var/obj/item/stack/rods/NR = new (src.loc)
|
||||
for (var/obj/item/stack/rods/R in src.loc)
|
||||
if(R==NR)
|
||||
continue
|
||||
if(R.amount>=R.max_amount)
|
||||
continue
|
||||
R.attackby(NR, user)
|
||||
|
||||
user << "<span class='notice'>You have disassembled the window.</span>"
|
||||
disassembled = 1
|
||||
density = 0
|
||||
update_nearby_tiles()
|
||||
update_nearby_icons()
|
||||
del(src)
|
||||
else
|
||||
if(W.damtype == BRUTE || W.damtype == BURN)
|
||||
hit(W.force)
|
||||
@@ -337,7 +366,7 @@
|
||||
/obj/structure/window/Destroy()
|
||||
density = 0
|
||||
update_nearby_tiles()
|
||||
if(loc)
|
||||
if(loc && !disassembled)
|
||||
playsound(get_turf(src), "shatter", 70, 1)
|
||||
update_nearby_icons()
|
||||
..()
|
||||
@@ -390,6 +419,7 @@
|
||||
basestate = "plasmawindow"
|
||||
icon_state = "plasmawindow"
|
||||
shardtype = /obj/item/weapon/shard/plasma
|
||||
glasstype = /obj/item/stack/sheet/plasmaglass
|
||||
health = 120
|
||||
|
||||
/obj/structure/window/plasmabasic/New(Loc,re=0)
|
||||
@@ -411,6 +441,7 @@
|
||||
basestate = "plasmarwindow"
|
||||
icon_state = "plasmarwindow"
|
||||
shardtype = /obj/item/weapon/shard/plasma
|
||||
glasstype = /obj/item/stack/sheet/plasmaglass
|
||||
reinf = 1
|
||||
health = 160
|
||||
explosion_resistance = 4
|
||||
|
||||
Reference in New Issue
Block a user