mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-12 23:53:47 +01:00
Merge remote-tracking branch 'remotes/git-svn' into bs12_with_tgport
Conflicts: code/controllers/configuration.dm code/game/atoms.dm code/game/gamemodes/changeling/modularchangling.dm code/game/gamemodes/factions.dm code/game/objects/items/devices/uplinks.dm code/game/verbs/ooc.dm code/game/verbs/who.dm code/modules/admin/admin.dm code/modules/admin/admin_verbs.dm code/modules/admin/player_panel.dm code/modules/admin/verbs/adminpm.dm code/modules/admin/verbs/getlogs.dm code/modules/client/client defines.dm code/modules/client/client procs.dm code/modules/mob/living/login.dm code/modules/mob/new_player/preferences_setup.dm code/modules/paperwork/paper.dm config/config.txt html/changelog.html icons/mob/human.dmi icons/mob/human_face.dmi Signed-off-by: Cael_Aislinn <cael_aislinn@yahoo.com.au>
This commit is contained in:
@@ -282,7 +282,6 @@ Code:
|
||||
if (43) //Muskets' and Rockdtben's power monitor :D
|
||||
menu = "<h4><img src=pda_power.png> Power Monitors - Please select one</h4><BR>"
|
||||
powmonitor = null
|
||||
powermonitors = null
|
||||
powermonitors = list()
|
||||
var/powercount = 0
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
A.loc = src
|
||||
user << "<span class='notice'>You attach the [item] to the valve controls and secure it.</span>"
|
||||
A.holder = src
|
||||
A.toggle_secure()
|
||||
A.toggle_secure() //this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb).
|
||||
|
||||
bombers += "[key_name(user)] attached a [item] to a transfer valve."
|
||||
message_admins("[key_name_admin(user)] attached a [item] to a transfer valve.")
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<<<<<<< HEAD
|
||||
//This could either be split into the proper DM files or placed somewhere else all together, but it'll do for now -Nodrak
|
||||
|
||||
/*
|
||||
@@ -373,3 +374,380 @@ A list of items and costs is stored under the datum of every game mode, alongsid
|
||||
|
||||
|
||||
|
||||
=======
|
||||
//This could either be split into the proper DM files or placed somewhere else all together, but it'll do for now -Nodrak
|
||||
|
||||
/*
|
||||
|
||||
A list of items and costs is stored under the datum of every game mode, alongside the number of crystals, and the welcoming message.
|
||||
|
||||
*/
|
||||
|
||||
/obj/item/device/uplink
|
||||
var/welcome // Welcoming menu message
|
||||
var/items // List of items
|
||||
var/item_data // raw item text
|
||||
var/list/ItemList // Parsed list of items
|
||||
var/uses // Numbers of crystals
|
||||
// List of items not to shove in their hands.
|
||||
var/list/NotInHand = list(/obj/machinery/singularity_beacon/syndicate)
|
||||
|
||||
/obj/item/device/uplink/New()
|
||||
welcome = ticker.mode.uplink_welcome
|
||||
if(!item_data)
|
||||
items = dd_replacetext(ticker.mode.uplink_items, "\n", "") // Getting the text string of items
|
||||
else
|
||||
items = dd_replacetext(item_data)
|
||||
ItemList = dd_text2list(src.items, ";") // Parsing the items text string
|
||||
uses = ticker.mode.uplink_uses
|
||||
|
||||
//Let's build a menu!
|
||||
/obj/item/device/uplink/proc/generate_menu()
|
||||
|
||||
var/dat = "<B>[src.welcome]</B><BR>"
|
||||
dat += "Tele-Crystals left: [src.uses]<BR>"
|
||||
dat += "<HR>"
|
||||
dat += "<B>Request item:</B><BR>"
|
||||
dat += "<I>Each item costs a number of tele-crystals as indicated by the number following their name.</I><br><BR>"
|
||||
|
||||
var/cost
|
||||
var/item
|
||||
var/name
|
||||
var/path_obj
|
||||
var/path_text
|
||||
var/category_items = 1 //To prevent stupid :P
|
||||
|
||||
for(var/D in ItemList)
|
||||
var/list/O = stringsplit(D, ":")
|
||||
if(O.len != 3) //If it is not an actual item, make a break in the menu.
|
||||
if(O.len == 1) //If there is one item, it's probably a title
|
||||
dat += "<b>[O[1]]</b><br>"
|
||||
category_items = 0
|
||||
else //Else, it's a white space.
|
||||
if(category_items < 1) //If there were no itens in the last category...
|
||||
dat += "<i>We apologize, as you could not afford anything from this category.</i><br>"
|
||||
dat += "<br>"
|
||||
continue
|
||||
|
||||
path_text = O[1]
|
||||
cost = text2num(O[2])
|
||||
|
||||
if(cost>uses)
|
||||
continue
|
||||
|
||||
path_obj = text2path(path_text)
|
||||
item = new path_obj()
|
||||
name = O[3]
|
||||
del item
|
||||
|
||||
dat += "<A href='byond://?src=\ref[src];buy_item=[path_text];cost=[cost]'>[name]</A> ([cost])<BR>"
|
||||
category_items++
|
||||
|
||||
dat += "<A href='byond://?src=\ref[src];buy_item=random'>Random Item (??)</A><br>"
|
||||
dat += "<HR>"
|
||||
return dat
|
||||
|
||||
//If 'random' was selected
|
||||
/obj/item/device/uplink/proc/chooseRandomItem()
|
||||
var/list/randomItems = list()
|
||||
|
||||
//Sorry for all the ifs, but it makes it 1000 times easier for other people/servers to add or remove items from this list
|
||||
//Add only items the player can afford:
|
||||
if(uses > 19)
|
||||
randomItems.Add("/obj/item/weapon/circuitboard/teleporter") //Teleporter Circuit Board (costs 20, for nuke ops)
|
||||
|
||||
if(uses > 9)
|
||||
randomItems.Add("/obj/item/toy/syndicateballoon")//Syndicate Balloon
|
||||
randomItems.Add("/obj/item/weapon/storage/syndie_kit/imp_uplink") //Uplink Implanter
|
||||
randomItems.Add("/obj/item/weapon/storage/box/syndicate") //Syndicate bundle
|
||||
|
||||
//if(uses > 8) //Nothing... yet.
|
||||
//if(uses > 7) //Nothing... yet.
|
||||
|
||||
if(uses > 6)
|
||||
randomItems.Add("/obj/item/weapon/aiModule/syndicate") //Hacked AI Upload Module
|
||||
randomItems.Add("/obj/item/device/radio/beacon/syndicate") //Singularity Beacon
|
||||
|
||||
if(uses > 5)
|
||||
randomItems.Add("/obj/item/weapon/gun/projectile") //Revolver
|
||||
|
||||
if(uses > 4)
|
||||
randomItems.Add("/obj/item/weapon/gun/energy/crossbow") //Energy Crossbow
|
||||
randomItems.Add("/obj/item/device/powersink") //Powersink
|
||||
|
||||
if(uses > 3)
|
||||
randomItems.Add("/obj/item/weapon/melee/energy/sword") //Energy Sword
|
||||
randomItems.Add("/obj/item/clothing/mask/gas/voice") //Voice Changer
|
||||
randomItems.Add("/obj/item/device/chameleon") //Chameleon Projector
|
||||
|
||||
if(uses > 2)
|
||||
randomItems.Add("/obj/item/weapon/storage/emp_kit") //EMP Grenades
|
||||
randomItems.Add("/obj/item/weapon/pen/paralysis") //Paralysis Pen
|
||||
randomItems.Add("/obj/item/weapon/cartridge/syndicate") //Detomatix Cartridge
|
||||
randomItems.Add("/obj/item/clothing/under/chameleon") //Chameleon Jumpsuit
|
||||
randomItems.Add("/obj/item/weapon/card/id/syndicate") //Agent ID Card
|
||||
randomItems.Add("/obj/item/weapon/card/emag") //Cryptographic Sequencer
|
||||
randomItems.Add("/obj/item/weapon/storage/syndie_kit/space") //Syndicate Space Suit
|
||||
randomItems.Add("/obj/item/device/encryptionkey/binary") //Binary Translator Key
|
||||
randomItems.Add("/obj/item/weapon/storage/syndie_kit/imp_freedom") //Freedom Implant
|
||||
randomItems.Add("/obj/item/clothing/glasses/thermal/syndi") //Thermal Imaging Goggles
|
||||
|
||||
if(uses > 1)
|
||||
/*
|
||||
var/list/usrItems = usr.get_contents() //Checks to see if the user has a revolver before giving ammo
|
||||
var/hasRevolver = 0
|
||||
for(var/obj/I in usrItems) //Only add revolver ammo if the user has a gun that can shoot it
|
||||
if(istype(I,/obj/item/weapon/gun/projectile))
|
||||
hasRevolver = 1
|
||||
|
||||
if(hasRevolver) randomItems.Add("/obj/item/ammo_magazine/a357") //Revolver ammo
|
||||
*/
|
||||
randomItems.Add("/obj/item/ammo_magazine/a357") //Revolver ammo
|
||||
randomItems.Add("/obj/item/clothing/shoes/syndigaloshes") //No-Slip Syndicate Shoes
|
||||
randomItems.Add("/obj/item/weapon/plastique") //C4
|
||||
|
||||
if(uses > 0)
|
||||
randomItems.Add("/obj/item/weapon/soap/syndie") //Syndicate Soap
|
||||
randomItems.Add("/obj/item/weapon/storage/toolbox/syndicate") //Syndicate Toolbox
|
||||
|
||||
if(!randomItems.len)
|
||||
del(randomItems)
|
||||
return 0
|
||||
else
|
||||
var/buyItem = pick(randomItems)
|
||||
|
||||
switch(buyItem) //Ok, this gets a little messy, sorry.
|
||||
if("/obj/item/weapon/circuitboard/teleporter")
|
||||
uses -= 20
|
||||
if("/obj/item/toy/syndicateballoon" , "/obj/item/weapon/storage/syndie_kit/imp_uplink" , "/obj/item/weapon/storage/box/syndicate")
|
||||
uses -= 10
|
||||
if("/obj/item/weapon/aiModule/syndicate" , "/obj/item/device/radio/beacon/syndicate")
|
||||
uses -= 7
|
||||
if("/obj/item/weapon/gun/projectile")
|
||||
uses -= 6
|
||||
if("/obj/item/weapon/gun/energy/crossbow" , "/obj/item/device/powersink")
|
||||
uses -= 5
|
||||
if("/obj/item/weapon/melee/energy/sword" , "/obj/item/clothing/mask/gas/voice" , "/obj/item/device/chameleon")
|
||||
uses -= 4
|
||||
if("/obj/item/weapon/storage/emp_kit" , "/obj/item/weapon/pen/paralysis" , "/obj/item/weapon/cartridge/syndicate" , "/obj/item/clothing/under/chameleon" , \
|
||||
"/obj/item/weapon/card/emag" , "/obj/item/weapon/storage/syndie_kit/space" , "/obj/item/device/encryptionkey/binary" , \
|
||||
"/obj/item/weapon/storage/syndie_kit/imp_freedom" , "/obj/item/clothing/glasses/thermal/syndi")
|
||||
uses -= 3
|
||||
if("/obj/item/ammo_magazine/a357" , "/obj/item/clothing/shoes/syndigaloshes" , "/obj/item/weapon/plastique", "/obj/item/weapon/card/id/syndicate")
|
||||
uses -= 2
|
||||
if("/obj/item/weapon/soap/syndie" , "/obj/item/weapon/storage/toolbox/syndicate")
|
||||
uses -= 1
|
||||
del(randomItems)
|
||||
return buyItem
|
||||
|
||||
/obj/item/device/uplink/proc/handleStatTracking(var/boughtItem)
|
||||
//For stat tracking, sorry for making it so ugly
|
||||
if(!boughtItem) return
|
||||
|
||||
switch(boughtItem)
|
||||
if("/obj/item/weapon/circuitboard/teleporter")
|
||||
feedback_add_details("traitor_uplink_items_bought","TP")
|
||||
if("/obj/item/toy/syndicateballoon")
|
||||
feedback_add_details("traitor_uplink_items_bought","BS")
|
||||
if("/obj/item/weapon/storage/syndie_kit/imp_uplink")
|
||||
feedback_add_details("traitor_uplink_items_bought","UI")
|
||||
if("/obj/item/weapon/storage/box/syndicate")
|
||||
feedback_add_details("traitor_uplink_items_bought","BU")
|
||||
if("/obj/item/weapon/aiModule/syndicate")
|
||||
feedback_add_details("traitor_uplink_items_bought","AI")
|
||||
if("/obj/item/device/radio/beacon/syndicate")
|
||||
feedback_add_details("traitor_uplink_items_bought","SB")
|
||||
if("/obj/item/weapon/gun/projectile")
|
||||
feedback_add_details("traitor_uplink_items_bought","RE")
|
||||
if("/obj/item/weapon/gun/energy/crossbow")
|
||||
feedback_add_details("traitor_uplink_items_bought","XB")
|
||||
if("/obj/item/device/powersink")
|
||||
feedback_add_details("traitor_uplink_items_bought","PS")
|
||||
if("/obj/item/weapon/melee/energy/sword")
|
||||
feedback_add_details("traitor_uplink_items_bought","ES")
|
||||
if("/obj/item/clothing/mask/gas/voice")
|
||||
feedback_add_details("traitor_uplink_items_bought","VC")
|
||||
if("/obj/item/device/chameleon")
|
||||
feedback_add_details("traitor_uplink_items_bought","CP")
|
||||
if("/obj/item/weapon/storage/emp_kit")
|
||||
feedback_add_details("traitor_uplink_items_bought","EM")
|
||||
if("/obj/item/weapon/pen/paralysis")
|
||||
feedback_add_details("traitor_uplink_items_bought","PP")
|
||||
if("/obj/item/weapon/cartridge/syndicate")
|
||||
feedback_add_details("traitor_uplink_items_bought","DC")
|
||||
if("/obj/item/clothing/under/chameleon")
|
||||
feedback_add_details("traitor_uplink_items_bought","CJ")
|
||||
if("/obj/item/weapon/card/id/syndicate")
|
||||
feedback_add_details("traitor_uplink_items_bought","AC")
|
||||
if("/obj/item/weapon/card/emag")
|
||||
feedback_add_details("traitor_uplink_items_bought","EC")
|
||||
if("/obj/item/weapon/storage/syndie_kit/space")
|
||||
feedback_add_details("traitor_uplink_items_bought","SS")
|
||||
if("/obj/item/device/encryptionkey/binary")
|
||||
feedback_add_details("traitor_uplink_items_bought","BT")
|
||||
if("/obj/item/weapon/storage/syndie_kit/imp_freedom")
|
||||
feedback_add_details("traitor_uplink_items_bought","FI")
|
||||
if("/obj/item/clothing/glasses/thermal/syndi")
|
||||
feedback_add_details("traitor_uplink_items_bought","TM")
|
||||
if("/obj/item/ammo_magazine/a357")
|
||||
feedback_add_details("traitor_uplink_items_bought","RA")
|
||||
if("/obj/item/clothing/shoes/syndigaloshes")
|
||||
feedback_add_details("traitor_uplink_items_bought","SH")
|
||||
if("/obj/item/weapon/plastique")
|
||||
feedback_add_details("traitor_uplink_items_bought","C4")
|
||||
if("/obj/item/weapon/soap/syndie")
|
||||
feedback_add_details("traitor_uplink_items_bought","SP")
|
||||
if("/obj/item/weapon/storage/toolbox/syndicate")
|
||||
feedback_add_details("traitor_uplink_items_bought","ST")
|
||||
|
||||
/obj/item/device/uplink/Topic(href, href_list)
|
||||
|
||||
if (href_list["buy_item"])
|
||||
if(href_list["buy_item"] == "random")
|
||||
var/boughtItem = chooseRandomItem()
|
||||
if(boughtItem)
|
||||
href_list["buy_item"] = boughtItem
|
||||
feedback_add_details("traitor_uplink_items_bought","RN")
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
else
|
||||
if(text2num(href_list["cost"]) > uses) // Not enough crystals for the item
|
||||
return 0
|
||||
|
||||
//if(usr:mind && ticker.mode.traitors[usr:mind])
|
||||
//var/datum/traitorinfo/info = ticker.mode.traitors[usr:mind]
|
||||
//info.spawnlist += href_list["buy_item"]
|
||||
|
||||
uses -= text2num(href_list["cost"])
|
||||
handleStatTracking(href_list["buy_item"]) //Note: chooseRandomItem handles it's own stat tracking. This proc is not meant for 'random'.
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
// HIDDEN UPLINK - Can be stored in anything but the host item has to have a trigger for it.
|
||||
/* How to create an uplink in 3 easy steps!
|
||||
|
||||
1. All obj/item 's have a hidden_uplink var. By default it's null. Give the item one with "new(src)", it must be in it's contents. Feel free to add "uses".
|
||||
|
||||
2. Code in the triggers. Use check_trigger for this, I recommend closing the item's menu with "usr << browse(null, "window=windowname") if it returns true.
|
||||
The var/value is the value that will be compared with the var/target. If they are equal it will activate the menu.
|
||||
|
||||
3. If you want the menu to stay until the users locks his uplink, add an active_uplink_check(mob/user as mob) in your interact/attack_hand proc.
|
||||
Then check if it's true, if true return. This will stop the normal menu appearing and will instead show the uplink menu.
|
||||
*/
|
||||
|
||||
/obj/item/device/uplink/hidden
|
||||
name = "Hidden Uplink."
|
||||
desc = "There is something wrong if you're examining this."
|
||||
var/active = 0
|
||||
var/list/purchase_log = list()
|
||||
|
||||
// The hidden uplink MUST be inside an obj/item's contents.
|
||||
/obj/item/device/uplink/hidden/New()
|
||||
spawn(2)
|
||||
if(!istype(src.loc, /obj/item))
|
||||
del(src)
|
||||
..()
|
||||
|
||||
// Toggles the uplink on and off. Normally this will bypass the item's normal functions and go to the uplink menu, if activated.
|
||||
/obj/item/device/uplink/hidden/proc/toggle()
|
||||
active = !active
|
||||
|
||||
// Directly trigger the uplink. Turn on if it isn't already.
|
||||
/obj/item/device/uplink/hidden/proc/trigger(mob/user as mob)
|
||||
if(!active)
|
||||
toggle()
|
||||
interact(user)
|
||||
|
||||
// Checks to see if the value meets the target. Like a frequency being a traitor_frequency, in order to unlock a headset.
|
||||
// If true, it accesses trigger() and returns 1. If it fails, it returns false. Use this to see if you need to close the
|
||||
// current item's menu.
|
||||
/obj/item/device/uplink/hidden/proc/check_trigger(mob/user as mob, var/value, var/target)
|
||||
if(value == target)
|
||||
trigger(user)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
// Interaction code. Gathers a list of items purchasable from the paren't uplink and displays it. It also adds a lock button.
|
||||
/obj/item/device/uplink/hidden/proc/interact(mob/user as mob)
|
||||
|
||||
var/dat = "<body link='yellow' alink='white' bgcolor='#601414'><font color='white'>"
|
||||
dat += src.generate_menu()
|
||||
dat += "<A href='byond://?src=\ref[src];lock=1'>Lock</a>"
|
||||
dat += "</font></body>"
|
||||
user << browse(dat, "window=hidden")
|
||||
onclose(user, "hidden")
|
||||
return
|
||||
|
||||
// The purchasing code.
|
||||
/obj/item/device/uplink/hidden/Topic(href, href_list)
|
||||
|
||||
if (usr.stat || usr.restrained())
|
||||
return
|
||||
|
||||
if (!( istype(usr, /mob/living/carbon/human)))
|
||||
return 0
|
||||
|
||||
if ((usr.contents.Find(src.loc) || (in_range(src.loc, usr) && istype(src.loc.loc, /turf))))
|
||||
usr.machine = src
|
||||
if(href_list["lock"])
|
||||
toggle()
|
||||
usr << browse(null, "window=hidden")
|
||||
return 1
|
||||
|
||||
if(..(href, href_list) == 1)
|
||||
var/path_obj = text2path(href_list["buy_item"])
|
||||
var/obj/I = new path_obj(get_turf(usr))
|
||||
if(ishuman(usr))
|
||||
var/mob/living/carbon/human/A = usr
|
||||
A.put_in_any_hand_if_possible(I)
|
||||
purchase_log += "[usr] ([usr.ckey]) bought [I]."
|
||||
interact(usr)
|
||||
return
|
||||
|
||||
// I placed this here because of how relevant it is.
|
||||
// You place this in your uplinkable item to check if an uplink is active or not.
|
||||
// If it is, it will display the uplink menu and return 1, else it'll return false.
|
||||
// If it returns true, I recommend closing the item's normal menu with "user << browse(null, "window=name")"
|
||||
/obj/item/proc/active_uplink_check(mob/user as mob)
|
||||
// Activates the uplink if it's active
|
||||
if(src.hidden_uplink)
|
||||
if(src.hidden_uplink.active)
|
||||
src.hidden_uplink.trigger(user)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
// PRESET UPLINKS
|
||||
// A collection of preset uplinks.
|
||||
//
|
||||
// Includes normal radio uplink, multitool uplink,
|
||||
// implant uplink (not the implant tool) and a preset headset uplink.
|
||||
|
||||
/obj/item/device/radio/uplink/New()
|
||||
hidden_uplink = new(src)
|
||||
icon_state = "radio"
|
||||
|
||||
/obj/item/device/radio/uplink/attack_self(mob/user as mob)
|
||||
if(hidden_uplink)
|
||||
hidden_uplink.trigger(user)
|
||||
|
||||
/obj/item/device/multitool/uplink/New()
|
||||
hidden_uplink = new(src)
|
||||
|
||||
/obj/item/device/multitool/uplink/attack_self(mob/user as mob)
|
||||
if(hidden_uplink)
|
||||
hidden_uplink.trigger(user)
|
||||
|
||||
/obj/item/device/radio/headset/uplink
|
||||
traitor_frequency = 1445
|
||||
|
||||
/obj/item/device/radio/headset/uplink/New()
|
||||
..()
|
||||
hidden_uplink = new(src)
|
||||
hidden_uplink.uses = 10
|
||||
|
||||
|
||||
|
||||
>>>>>>> remotes/git-svn
|
||||
|
||||
@@ -0,0 +1,393 @@
|
||||
//copy pasta of the space piano, don't hurt me -Pete
|
||||
|
||||
/obj/item/device/violin
|
||||
name = "space violin"
|
||||
desc = "A wooden musical instrument with four strings and a bow. \"The devil went down to space, he was looking for an assistant to grief.\""
|
||||
icon = 'icons/obj/musician.dmi'
|
||||
icon_state = "violin"
|
||||
item_state = "violin"
|
||||
force = 10
|
||||
var/datum/song/song
|
||||
var/playing = 0
|
||||
var/help = 0
|
||||
var/edit = 1
|
||||
var/repeat = 0
|
||||
|
||||
/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.ogg'
|
||||
if("C#1") soundfile = 'sound/violin/C#1.ogg'
|
||||
if("Db1") soundfile = 'sound/violin/Db1.ogg'
|
||||
if("Dn1") soundfile = 'sound/violin/Dn1.ogg'
|
||||
if("D#1") soundfile = 'sound/violin/D#1.ogg'
|
||||
if("Eb1") soundfile = 'sound/violin/Eb1.ogg'
|
||||
if("En1") soundfile = 'sound/violin/En1.ogg'
|
||||
if("E#1") soundfile = 'sound/violin/E#1.ogg'
|
||||
if("Fb1") soundfile = 'sound/violin/Fb1.ogg'
|
||||
if("Fn1") soundfile = 'sound/violin/Fn1.ogg'
|
||||
if("F#1") soundfile = 'sound/violin/F#1.ogg'
|
||||
if("Gb1") soundfile = 'sound/violin/Gb1.ogg'
|
||||
if("Gn1") soundfile = 'sound/violin/Gn1.ogg'
|
||||
if("G#1") soundfile = 'sound/violin/G#1.ogg'
|
||||
if("Ab1") soundfile = 'sound/violin/Ab1.ogg'
|
||||
if("An1") soundfile = 'sound/violin/An1.ogg'
|
||||
if("A#1") soundfile = 'sound/violin/A#1.ogg'
|
||||
if("Bb1") soundfile = 'sound/violin/Bb1.ogg'
|
||||
if("Bn1") soundfile = 'sound/violin/Bn1.ogg'
|
||||
if("B#1") soundfile = 'sound/violin/B#1.ogg'
|
||||
if("Cb2") soundfile = 'sound/violin/Cb2.ogg'
|
||||
if("Cn2") soundfile = 'sound/violin/Cn2.ogg'
|
||||
if("C#2") soundfile = 'sound/violin/C#2.ogg'
|
||||
if("Db2") soundfile = 'sound/violin/Db2.ogg'
|
||||
if("Dn2") soundfile = 'sound/violin/Dn2.ogg'
|
||||
if("D#2") soundfile = 'sound/violin/D#2.ogg'
|
||||
if("Eb2") soundfile = 'sound/violin/Eb2.ogg'
|
||||
if("En2") soundfile = 'sound/violin/En2.ogg'
|
||||
if("E#2") soundfile = 'sound/violin/E#2.ogg'
|
||||
if("Fb2") soundfile = 'sound/violin/Fb2.ogg'
|
||||
if("Fn2") soundfile = 'sound/violin/Fn2.ogg'
|
||||
if("F#2") soundfile = 'sound/violin/F#2.ogg'
|
||||
if("Gb2") soundfile = 'sound/violin/Gb2.ogg'
|
||||
if("Gn2") soundfile = 'sound/violin/Gn2.ogg'
|
||||
if("G#2") soundfile = 'sound/violin/G#2.ogg'
|
||||
if("Ab2") soundfile = 'sound/violin/Ab2.ogg'
|
||||
if("An2") soundfile = 'sound/violin/An2.ogg'
|
||||
if("A#2") soundfile = 'sound/violin/A#2.ogg'
|
||||
if("Bb2") soundfile = 'sound/violin/Bb2.ogg'
|
||||
if("Bn2") soundfile = 'sound/violin/Bn2.ogg'
|
||||
if("B#2") soundfile = 'sound/violin/B#2.ogg'
|
||||
if("Cb3") soundfile = 'sound/violin/Cb3.ogg'
|
||||
if("Cn3") soundfile = 'sound/violin/Cn3.ogg'
|
||||
if("C#3") soundfile = 'sound/violin/C#3.ogg'
|
||||
if("Db3") soundfile = 'sound/violin/Db3.ogg'
|
||||
if("Dn3") soundfile = 'sound/violin/Dn3.ogg'
|
||||
if("D#3") soundfile = 'sound/violin/D#3.ogg'
|
||||
if("Eb3") soundfile = 'sound/violin/Eb3.ogg'
|
||||
if("En3") soundfile = 'sound/violin/En3.ogg'
|
||||
if("E#3") soundfile = 'sound/violin/E#3.ogg'
|
||||
if("Fb3") soundfile = 'sound/violin/Fb3.ogg'
|
||||
if("Fn3") soundfile = 'sound/violin/Fn3.ogg'
|
||||
if("F#3") soundfile = 'sound/violin/F#3.ogg'
|
||||
if("Gb3") soundfile = 'sound/violin/Gb3.ogg'
|
||||
if("Gn3") soundfile = 'sound/violin/Gn3.ogg'
|
||||
if("G#3") soundfile = 'sound/violin/G#3.ogg'
|
||||
if("Ab3") soundfile = 'sound/violin/Ab3.ogg'
|
||||
if("An3") soundfile = 'sound/violin/An3.ogg'
|
||||
if("A#3") soundfile = 'sound/violin/A#3.ogg'
|
||||
if("Bb3") soundfile = 'sound/violin/Bb3.ogg'
|
||||
if("Bn3") soundfile = 'sound/violin/Bn3.ogg'
|
||||
if("B#3") soundfile = 'sound/violin/B#3.ogg'
|
||||
if("Cb4") soundfile = 'sound/violin/Cb4.ogg'
|
||||
if("Cn4") soundfile = 'sound/violin/Cn4.ogg'
|
||||
if("C#4") soundfile = 'sound/violin/C#4.ogg'
|
||||
if("Db4") soundfile = 'sound/violin/Db4.ogg'
|
||||
if("Dn4") soundfile = 'sound/violin/Dn4.ogg'
|
||||
if("D#4") soundfile = 'sound/violin/D#4.ogg'
|
||||
if("Eb4") soundfile = 'sound/violin/Eb4.ogg'
|
||||
if("En4") soundfile = 'sound/violin/En4.ogg'
|
||||
if("E#4") soundfile = 'sound/violin/E#4.ogg'
|
||||
if("Fb4") soundfile = 'sound/violin/Fb4.ogg'
|
||||
if("Fn4") soundfile = 'sound/violin/Fn4.ogg'
|
||||
if("F#4") soundfile = 'sound/violin/F#4.ogg'
|
||||
if("Gb4") soundfile = 'sound/violin/Gb4.ogg'
|
||||
if("Gn4") soundfile = 'sound/violin/Gn4.ogg'
|
||||
if("G#4") soundfile = 'sound/violin/G#4.ogg'
|
||||
if("Ab4") soundfile = 'sound/violin/Ab4.ogg'
|
||||
if("An4") soundfile = 'sound/violin/An4.ogg'
|
||||
if("A#4") soundfile = 'sound/violin/A#4.ogg'
|
||||
if("Bb4") soundfile = 'sound/violin/Bb4.ogg'
|
||||
if("Bn4") soundfile = 'sound/violin/Bn4.ogg'
|
||||
if("B#4") soundfile = 'sound/violin/B#4.ogg'
|
||||
if("Cb5") soundfile = 'sound/violin/Cb5.ogg'
|
||||
if("Cn5") soundfile = 'sound/violin/Cn5.ogg'
|
||||
if("C#5") soundfile = 'sound/violin/C#5.ogg'
|
||||
if("Db5") soundfile = 'sound/violin/Db5.ogg'
|
||||
if("Dn5") soundfile = 'sound/violin/Dn5.ogg'
|
||||
if("D#5") soundfile = 'sound/violin/D#5.ogg'
|
||||
if("Eb5") soundfile = 'sound/violin/Eb5.ogg'
|
||||
if("En5") soundfile = 'sound/violin/En5.ogg'
|
||||
if("E#5") soundfile = 'sound/violin/E#5.ogg'
|
||||
if("Fb5") soundfile = 'sound/violin/Fb5.ogg'
|
||||
if("Fn5") soundfile = 'sound/violin/Fn5.ogg'
|
||||
if("F#5") soundfile = 'sound/violin/F#5.ogg'
|
||||
if("Gb5") soundfile = 'sound/violin/Gb5.ogg'
|
||||
if("Gn5") soundfile = 'sound/violin/Gn5.ogg'
|
||||
if("G#5") soundfile = 'sound/violin/G#5.ogg'
|
||||
if("Ab5") soundfile = 'sound/violin/Ab5.ogg'
|
||||
if("An5") soundfile = 'sound/violin/An5.ogg'
|
||||
if("A#5") soundfile = 'sound/violin/A#5.ogg'
|
||||
if("Bb5") soundfile = 'sound/violin/Bb5.ogg'
|
||||
if("Bn5") soundfile = 'sound/violin/Bn5.ogg'
|
||||
if("B#5") soundfile = 'sound/violin/B#5.ogg'
|
||||
if("Cb6") soundfile = 'sound/violin/Cb6.ogg'
|
||||
if("Cn6") soundfile = 'sound/violin/Cn6.ogg'
|
||||
if("C#6") soundfile = 'sound/violin/C#6.ogg'
|
||||
if("Db6") soundfile = 'sound/violin/Db6.ogg'
|
||||
if("Dn6") soundfile = 'sound/violin/Dn6.ogg'
|
||||
if("D#6") soundfile = 'sound/violin/D#6.ogg'
|
||||
if("Eb6") soundfile = 'sound/violin/Eb6.ogg'
|
||||
if("En6") soundfile = 'sound/violin/En6.ogg'
|
||||
if("E#6") soundfile = 'sound/violin/E#6.ogg'
|
||||
if("Fb6") soundfile = 'sound/violin/Fb6.ogg'
|
||||
if("Fn6") soundfile = 'sound/violin/Fn6.ogg'
|
||||
if("F#6") soundfile = 'sound/violin/F#6.ogg'
|
||||
if("Gb6") soundfile = 'sound/violin/Gb6.ogg'
|
||||
if("Gn6") soundfile = 'sound/violin/Gn6.ogg'
|
||||
if("G#6") soundfile = 'sound/violin/G#6.ogg'
|
||||
if("Ab6") soundfile = 'sound/violin/Ab6.ogg'
|
||||
if("An6") soundfile = 'sound/violin/An6.ogg'
|
||||
if("A#6") soundfile = 'sound/violin/A#6.ogg'
|
||||
if("Bb6") soundfile = 'sound/violin/Bb6.ogg'
|
||||
if("Bn6") soundfile = 'sound/violin/Bn6.ogg'
|
||||
if("B#6") soundfile = 'sound/violin/B#6.ogg'
|
||||
if("Cb7") soundfile = 'sound/violin/Cb7.ogg'
|
||||
if("Cn7") soundfile = 'sound/violin/Cn7.ogg'
|
||||
if("C#7") soundfile = 'sound/violin/C#7.ogg'
|
||||
if("Db7") soundfile = 'sound/violin/Db7.ogg'
|
||||
if("Dn7") soundfile = 'sound/violin/Dn7.ogg'
|
||||
if("D#7") soundfile = 'sound/violin/D#7.ogg'
|
||||
if("Eb7") soundfile = 'sound/violin/Eb7.ogg'
|
||||
if("En7") soundfile = 'sound/violin/En7.ogg'
|
||||
if("E#7") soundfile = 'sound/violin/E#7.ogg'
|
||||
if("Fb7") soundfile = 'sound/violin/Fb7.ogg'
|
||||
if("Fn7") soundfile = 'sound/violin/Fn7.ogg'
|
||||
if("F#7") soundfile = 'sound/violin/F#7.ogg'
|
||||
if("Gb7") soundfile = 'sound/violin/Gb7.ogg'
|
||||
if("Gn7") soundfile = 'sound/violin/Gn7.ogg'
|
||||
if("G#7") soundfile = 'sound/violin/G#7.ogg'
|
||||
if("Ab7") soundfile = 'sound/violin/Ab7.ogg'
|
||||
if("An7") soundfile = 'sound/violin/An7.ogg'
|
||||
if("A#7") soundfile = 'sound/violin/A#7.ogg'
|
||||
if("Bb7") soundfile = 'sound/violin/Bb7.ogg'
|
||||
if("Bn7") soundfile = 'sound/violin/Bn7.ogg'
|
||||
if("B#7") soundfile = 'sound/violin/B#7.ogg'
|
||||
if("Cb8") soundfile = 'sound/violin/Cb8.ogg'
|
||||
if("Cn8") soundfile = 'sound/violin/Cn8.ogg'
|
||||
if("C#8") soundfile = 'sound/violin/C#8.ogg'
|
||||
if("Db8") soundfile = 'sound/violin/Db8.ogg'
|
||||
if("Dn8") soundfile = 'sound/violin/Dn8.ogg'
|
||||
if("D#8") soundfile = 'sound/violin/D#8.ogg'
|
||||
if("Eb8") soundfile = 'sound/violin/Eb8.ogg'
|
||||
if("En8") soundfile = 'sound/violin/En8.ogg'
|
||||
if("E#8") soundfile = 'sound/violin/E#8.ogg'
|
||||
if("Fb8") soundfile = 'sound/violin/Fb8.ogg'
|
||||
if("Fn8") soundfile = 'sound/violin/Fn8.ogg'
|
||||
if("F#8") soundfile = 'sound/violin/F#8.ogg'
|
||||
if("Gb8") soundfile = 'sound/violin/Gb8.ogg'
|
||||
if("Gn8") soundfile = 'sound/violin/Gn8.ogg'
|
||||
if("G#8") soundfile = 'sound/violin/G#8.ogg'
|
||||
if("Ab8") soundfile = 'sound/violin/Ab8.ogg'
|
||||
if("An8") soundfile = 'sound/violin/An8.ogg'
|
||||
if("A#8") soundfile = 'sound/violin/A#8.ogg'
|
||||
if("Bb8") soundfile = 'sound/violin/Bb8.ogg'
|
||||
if("Bn8") soundfile = 'sound/violin/Bn8.ogg'
|
||||
if("B#8") soundfile = 'sound/violin/B#8.ogg'
|
||||
if("Cb9") soundfile = 'sound/violin/Cb9.ogg'
|
||||
if("Cn9") soundfile = 'sound/violin/Cn9.ogg'
|
||||
else return
|
||||
|
||||
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 dd_text2list(lowertext(line), ","))
|
||||
//world << "beat: [beat]"
|
||||
var/list/notes = dd_text2list(beat, "/")
|
||||
for(var/note in dd_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/attack_self(mob/user as mob)
|
||||
if(!isliving(user) || user.stat || user.restrained() || user.lying) return
|
||||
user.machine = src
|
||||
|
||||
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")
|
||||
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)
|
||||
|
||||
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 = dd_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
|
||||
@@ -0,0 +1,87 @@
|
||||
/obj/item/weapon/lipstick
|
||||
name = "red lipstick"
|
||||
desc = "A generic brand of lipstick."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "lipstick"
|
||||
flags = FPRINT | TABLEPASS
|
||||
w_class = 1.0
|
||||
var/colour = "red"
|
||||
var/open = 0
|
||||
|
||||
|
||||
/obj/item/weapon/lipstick/purple
|
||||
name = "purple lipstick"
|
||||
colour = "purple"
|
||||
|
||||
/obj/item/weapon/lipstick/jade
|
||||
name = "jade lipstick"
|
||||
colour = "jade"
|
||||
|
||||
/obj/item/weapon/lipstick/black
|
||||
name = "black lipstick"
|
||||
colour = "black"
|
||||
|
||||
|
||||
/obj/item/weapon/lipstick/random
|
||||
name = "lipstick"
|
||||
|
||||
/obj/item/weapon/lipstick/random/New()
|
||||
colour = pick("red","purple","jade","black")
|
||||
name = "[colour] lipstick"
|
||||
|
||||
|
||||
/obj/item/weapon/lipstick/attack_self(mob/user as mob)
|
||||
user << "<span class='notice'>You twist \the [src] [open ? "closed" : "open"].</span>"
|
||||
open = !open
|
||||
if(open)
|
||||
icon_state = "[initial(icon_state)]_[colour]"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/item/weapon/lipstick/attack(mob/M as mob, mob/user as mob)
|
||||
if(!open) return
|
||||
|
||||
if(!istype(M, /mob)) return
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.lip_style) //if they already have lipstick on
|
||||
user << "<span class='notice'>You need to wipe off the old lipstick first!</span>"
|
||||
return
|
||||
if(H == user)
|
||||
user.visible_message("<span class='notice'>[user] does their lips with \the [src].</span>", \
|
||||
"<span class='notice'>You take a moment to apply \the [src]. Perfect!</span>")
|
||||
H.lip_style = colour
|
||||
H.update_body()
|
||||
else
|
||||
user.visible_message("<span class='warning'>[user] begins to do [H]'s lips with \the [src].</span>", \
|
||||
"<span class='notice'>You begin to apply \the [src].</span>")
|
||||
if(do_after(user, 20) && do_after(H, 20, 5, 0)) //user needs to keep their active hand, H does not.
|
||||
user.visible_message("<span class='notice'>[user] does [H]'s lips with \the [src].</span>", \
|
||||
"<span class='notice'>You apply \the [src].</span>")
|
||||
H.lip_style = colour
|
||||
H.update_body()
|
||||
else
|
||||
user << "<span class='notice'>Where are the lips on that?</span>"
|
||||
|
||||
//you can wipe off lipstick with paper!
|
||||
/obj/item/weapon/paper/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
|
||||
if(user.zone_sel.selecting == "mouth")
|
||||
if(!istype(M, /mob)) return
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H == user)
|
||||
user << "<span class='notice'>You wipe off the lipstick with [src].</span>"
|
||||
H.lip_style = null
|
||||
H.update_body()
|
||||
else
|
||||
user.visible_message("<span class='warning'>[user] begins to wipe [H]'s lipstick off with \the [src].</span>", \
|
||||
"<span class='notice'>You begin to wipe off [H]'s lipstick.</span>")
|
||||
if(do_after(user, 10) && do_after(H, 10, 5, 0)) //user needs to keep their active hand, H does not.
|
||||
user.visible_message("<span class='notice'>[user] wipes [H]'s lipstick off with \the [src].</span>", \
|
||||
"<span class='notice'>You wipe off [H]'s lipstick.</span>")
|
||||
H.lip_style = null
|
||||
H.update_body()
|
||||
else
|
||||
..()
|
||||
@@ -3,8 +3,6 @@
|
||||
name = "mop"
|
||||
icon = 'icons/obj/janitor.dmi'
|
||||
icon_state = "mop"
|
||||
var/mopping = 0
|
||||
var/mopcount = 0
|
||||
force = 3.0
|
||||
throwforce = 10.0
|
||||
throw_speed = 5
|
||||
@@ -12,6 +10,8 @@
|
||||
w_class = 3.0
|
||||
flags = FPRINT | TABLEPASS
|
||||
attack_verb = list("mopped", "bashed", "bludgeoned", "whacked")
|
||||
var/mopping = 0
|
||||
var/mopcount = 0
|
||||
|
||||
|
||||
/obj/item/weapon/mop/New()
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
|
||||
obj/item/weapon/mop/proc/clean(turf/simulated/A as turf)
|
||||
src.reagents.reaction(A,1,10)
|
||||
reagents.reaction(A,1,10)
|
||||
A.clean_blood()
|
||||
for(var/obj/effect/O in A)
|
||||
if( istype(O,/obj/effect/rune) || istype(O,/obj/effect/decal/cleanable) || istype(O,/obj/effect/overlay) )
|
||||
@@ -35,35 +35,20 @@ obj/item/weapon/mop/proc/clean(turf/simulated/A as turf)
|
||||
|
||||
|
||||
/obj/item/weapon/mop/afterattack(atom/A, mob/user as mob)
|
||||
if (src.reagents.total_volume < 1 || mopcount >= 5)
|
||||
user << "\blue Your mop is dry!"
|
||||
if(reagents.total_volume < 1 || mopcount >= 5)
|
||||
user << "<span class='notice'>Your mop is dry!</span>"
|
||||
return
|
||||
|
||||
if (istype(A, /turf/simulated))
|
||||
for(var/mob/O in viewers(user, null))
|
||||
O.show_message("\red <B>[user] begins to clean \the [A]</B>", 1)
|
||||
sleep(40)
|
||||
if(A)
|
||||
clean(A)
|
||||
user << "\blue You have finished mopping!"
|
||||
mopcount++
|
||||
else if (istype(A, /obj/effect/decal/cleanable) || istype(A, /obj/effect/overlay) || istype(A, /obj/effect/rune))
|
||||
for(var/mob/O in viewers(user, null))
|
||||
O.show_message("\red <B>[user] begins to clean \the [get_turf(A)]</B>", 1)
|
||||
sleep(40)
|
||||
if(A)
|
||||
clean(get_turf(A))
|
||||
user << "\blue You have finished mopping!"
|
||||
mopcount++
|
||||
if(istype(A, /turf/simulated) || istype(A, /obj/effect/decal/cleanable) || istype(A, /obj/effect/overlay) || istype(A, /obj/effect/rune))
|
||||
user.visible_message("<span class='warning'>[user] begins to clean \the [get_turf(A)].</span>")
|
||||
if(do_after(user, 40))
|
||||
if(A)
|
||||
clean(get_turf(A))
|
||||
user << "<span class='notice'>You have finished mopping!</span>"
|
||||
mopcount++
|
||||
|
||||
if(mopcount >= 5) //Okay this stuff is an ugly hack and i feel bad about it.
|
||||
spawn(5)
|
||||
src.reagents.clear_reagents()
|
||||
reagents.clear_reagents()
|
||||
mopcount = 0
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return
|
||||
@@ -7,7 +7,6 @@
|
||||
var/reliability = 100 //Used by SOME devices to determine how reliable they are.
|
||||
var/crit_fail = 0
|
||||
var/unacidable = 0 //universal "unacidabliness" var, here so you can use it in any obj.
|
||||
var/datum/marked_datum
|
||||
animate_movement = 2
|
||||
var/throwforce = 1
|
||||
var/list/attack_verb = list() //Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]"
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
if(!broken)
|
||||
if(prob(50/severity))
|
||||
src.locked = !src.locked
|
||||
src.update_icon()
|
||||
if(prob(20/severity) && !opened)
|
||||
if(!locked)
|
||||
open()
|
||||
|
||||
@@ -2,305 +2,514 @@
|
||||
|
||||
/datum/song
|
||||
var/name = "Untitled"
|
||||
var/list/lines = new()
|
||||
|
||||
var/sourcestring = ""
|
||||
var/compiledstring = ""
|
||||
var/compilesuccess = 0
|
||||
|
||||
//For those other infidels who uses this datum
|
||||
//VIOLINSSS
|
||||
var/list/lines
|
||||
|
||||
var/tempo = 5
|
||||
|
||||
var/global/gid = 1
|
||||
var/id = 0
|
||||
New()
|
||||
id = gid
|
||||
gid++;
|
||||
|
||||
//Same text2list, but 20000 cap instead of 1000
|
||||
/proc/dd_text2list_highcap(text, separator, var/list/withinList)
|
||||
var/textlength = length(text)
|
||||
var/separatorlength = length(separator)
|
||||
if(withinList && !withinList.len) withinList = null
|
||||
var/list/textList = new()
|
||||
var/searchPosition = 1
|
||||
var/findPosition = 1
|
||||
var/loops = 0
|
||||
while(1)
|
||||
if(loops >= 20000)
|
||||
break
|
||||
loops++
|
||||
|
||||
findPosition = findtext(text, separator, searchPosition, 0)
|
||||
var/buggyText = copytext(text, searchPosition, findPosition)
|
||||
if(!withinList || (buggyText in withinList)) textList += "[buggyText]"
|
||||
if(!findPosition) return textList
|
||||
searchPosition = findPosition + separatorlength
|
||||
if(searchPosition > textlength)
|
||||
textList += ""
|
||||
return textList
|
||||
return
|
||||
|
||||
/obj/structure/device/piano
|
||||
name = "space minimoog"
|
||||
icon = 'icons/obj/musician.dmi'
|
||||
icon_state = "minimoog"
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/datum/song/song
|
||||
|
||||
var/datum/song/currentsong = new()
|
||||
var/list/internalsongs = new()
|
||||
|
||||
var/playing = 0
|
||||
var/help = 0
|
||||
var/edit = 1
|
||||
var/repeat = 0
|
||||
var/repeat = 1
|
||||
|
||||
/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"
|
||||
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"
|
||||
var/showcontrol = 1
|
||||
var/showeditor = 0
|
||||
var/showhelp = 0
|
||||
|
||||
/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
|
||||
var/status = "Ok"
|
||||
|
||||
hearers(15, src) << sound(soundfile)
|
||||
var/global/list/soundlist = new()
|
||||
|
||||
/obj/structure/device/piano/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"
|
||||
New()
|
||||
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"
|
||||
|
||||
for(var/line in song.lines)
|
||||
//world << line
|
||||
for(var/beat in dd_text2list(lowertext(line), ","))
|
||||
//world << "beat: [beat]"
|
||||
var/list/notes = dd_text2list(beat, "/")
|
||||
for(var/note in dd_text2list(notes[1], "-"))
|
||||
//world << "note: [note]"
|
||||
if(!playing || !anchored)//If the piano is playing, or is loose
|
||||
playing = 0
|
||||
//This shit is not used anywhere, but is needed to cache the sounds
|
||||
soundlist["Cn1"] = 'sound/piano/Cn1.ogg'
|
||||
soundlist["C#1"] = 'sound/piano/C#1.ogg'
|
||||
//soundlist["Db1"] = 'sound/piano/Db1.ogg'
|
||||
soundlist["Dn1"] = 'sound/piano/Dn1.ogg'
|
||||
soundlist["D#1"] = 'sound/piano/D#1.ogg'
|
||||
//soundlist["Eb1"] = 'sound/piano/Eb1.ogg'
|
||||
soundlist["En1"] = 'sound/piano/En1.ogg'
|
||||
soundlist["E#1"] = 'sound/piano/E#1.ogg'
|
||||
//soundlist["Fb1"] = 'sound/piano/Fb1.ogg'
|
||||
soundlist["Fn1"] = 'sound/piano/Fn1.ogg'
|
||||
soundlist["F#1"] = 'sound/piano/F#1.ogg'
|
||||
//soundlist["Gb1"] = 'sound/piano/Gb1.ogg'
|
||||
soundlist["Gn1"] = 'sound/piano/Gn1.ogg'
|
||||
soundlist["G#1"] = 'sound/piano/G#1.ogg'
|
||||
//soundlist["Ab1"] = 'sound/piano/Ab1.ogg'
|
||||
soundlist["An1"] = 'sound/piano/An1.ogg'
|
||||
soundlist["A#1"] = 'sound/piano/A#1.ogg'
|
||||
//soundlist["Bb1"] = 'sound/piano/Bb1.ogg'
|
||||
soundlist["Bn1"] = 'sound/piano/Bn1.ogg'
|
||||
soundlist["B#1"] = 'sound/piano/B#1.ogg'
|
||||
soundlist["Cb2"] = 'sound/piano/Cb2.ogg'
|
||||
soundlist["Cn2"] = 'sound/piano/Cn2.ogg'
|
||||
soundlist["C#2"] = 'sound/piano/C#2.ogg'
|
||||
//soundlist["Db2"] = 'sound/piano/Db2.ogg'
|
||||
soundlist["Dn2"] = 'sound/piano/Dn2.ogg'
|
||||
soundlist["D#2"] = 'sound/piano/D#2.ogg'
|
||||
//soundlist["Eb2"] = 'sound/piano/Eb2.ogg'
|
||||
soundlist["En2"] = 'sound/piano/En2.ogg'
|
||||
soundlist["E#2"] = 'sound/piano/E#2.ogg'
|
||||
//soundlist["Fb2"] = 'sound/piano/Fb2.ogg'
|
||||
soundlist["Fn2"] = 'sound/piano/Fn2.ogg'
|
||||
soundlist["F#2"] = 'sound/piano/F#2.ogg'
|
||||
//soundlist["Gb2"] = 'sound/piano/Gb2.ogg'
|
||||
soundlist["Gn2"] = 'sound/piano/Gn2.ogg'
|
||||
soundlist["G#2"] = 'sound/piano/G#2.ogg'
|
||||
//soundlist["Ab2"] = 'sound/piano/Ab2.ogg'
|
||||
soundlist["An2"] = 'sound/piano/An2.ogg'
|
||||
soundlist["A#2"] = 'sound/piano/A#2.ogg'
|
||||
//soundlist["Bb2"] = 'sound/piano/Bb2.ogg'
|
||||
soundlist["Bn2"] = 'sound/piano/Bn2.ogg'
|
||||
soundlist["B#2"] = 'sound/piano/B#2.ogg'
|
||||
soundlist["Cb3"] = 'sound/piano/Cb3.ogg'
|
||||
soundlist["Cn3"] = 'sound/piano/Cn3.ogg'
|
||||
soundlist["C#3"] = 'sound/piano/C#3.ogg'
|
||||
//soundlist["Db3"] = 'sound/piano/Db3.ogg'
|
||||
soundlist["Dn3"] = 'sound/piano/Dn3.ogg'
|
||||
soundlist["D#3"] = 'sound/piano/D#3.ogg'
|
||||
//soundlist["Eb3"] = 'sound/piano/Eb3.ogg'
|
||||
soundlist["En3"] = 'sound/piano/En3.ogg'
|
||||
soundlist["E#3"] = 'sound/piano/E#3.ogg'
|
||||
//soundlist["Fb3"] = 'sound/piano/Fb3.ogg'
|
||||
soundlist["Fn3"] = 'sound/piano/Fn3.ogg'
|
||||
soundlist["F#3"] = 'sound/piano/F#3.ogg'
|
||||
//soundlist["Gb3"] = 'sound/piano/Gb3.ogg'
|
||||
soundlist["Gn3"] = 'sound/piano/Gn3.ogg'
|
||||
soundlist["G#3"] = 'sound/piano/G#3.ogg'
|
||||
//soundlist["Ab3"] = 'sound/piano/Ab3.ogg'
|
||||
soundlist["An3"] = 'sound/piano/An3.ogg'
|
||||
soundlist["A#3"] = 'sound/piano/A#3.ogg'
|
||||
//soundlist["Bb3"] = 'sound/piano/Bb3.ogg'
|
||||
soundlist["Bn3"] = 'sound/piano/Bn3.ogg'
|
||||
soundlist["B#3"] = 'sound/piano/B#3.ogg'
|
||||
soundlist["Cb4"] = 'sound/piano/Cb4.ogg'
|
||||
soundlist["Cn4"] = 'sound/piano/Cn4.ogg'
|
||||
soundlist["C#4"] = 'sound/piano/C#4.ogg'
|
||||
//soundlist["Db4"] = 'sound/piano/Db4.ogg'
|
||||
soundlist["Dn4"] = 'sound/piano/Dn4.ogg'
|
||||
soundlist["D#4"] = 'sound/piano/D#4.ogg'
|
||||
//soundlist["Eb4"] = 'sound/piano/Eb4.ogg'
|
||||
soundlist["En4"] = 'sound/piano/En4.ogg'
|
||||
soundlist["E#4"] = 'sound/piano/E#4.ogg'
|
||||
//soundlist["Fb4"] = 'sound/piano/Fb4.ogg'
|
||||
soundlist["Fn4"] = 'sound/piano/Fn4.ogg'
|
||||
soundlist["F#4"] = 'sound/piano/F#4.ogg'
|
||||
//soundlist["Gb4"] = 'sound/piano/Gb4.ogg'
|
||||
soundlist["Gn4"] = 'sound/piano/Gn4.ogg'
|
||||
soundlist["G#4"] = 'sound/piano/G#4.ogg'
|
||||
//soundlist["Ab4"] = 'sound/piano/Ab4.ogg'
|
||||
soundlist["An4"] = 'sound/piano/An4.ogg'
|
||||
soundlist["A#4"] = 'sound/piano/A#4.ogg'
|
||||
//soundlist["Bb4"] = 'sound/piano/Bb4.ogg'
|
||||
soundlist["Bn4"] = 'sound/piano/Bn4.ogg'
|
||||
soundlist["B#4"] = 'sound/piano/B#4.ogg'
|
||||
soundlist["Cb5"] = 'sound/piano/Cb5.ogg'
|
||||
soundlist["Cn5"] = 'sound/piano/Cn5.ogg'
|
||||
soundlist["C#5"] = 'sound/piano/C#5.ogg'
|
||||
//soundlist["Db5"] = 'sound/piano/Db5.ogg'
|
||||
soundlist["Dn5"] = 'sound/piano/Dn5.ogg'
|
||||
soundlist["D#5"] = 'sound/piano/D#5.ogg'
|
||||
//soundlist["Eb5"] = 'sound/piano/Eb5.ogg'
|
||||
soundlist["En5"] = 'sound/piano/En5.ogg'
|
||||
soundlist["E#5"] = 'sound/piano/E#5.ogg'
|
||||
//soundlist["Fb5"] = 'sound/piano/Fb5.ogg'
|
||||
soundlist["Fn5"] = 'sound/piano/Fn5.ogg'
|
||||
soundlist["F#5"] = 'sound/piano/F#5.ogg'
|
||||
//soundlist["Gb5"] = 'sound/piano/Gb5.ogg'
|
||||
soundlist["Gn5"] = 'sound/piano/Gn5.ogg'
|
||||
soundlist["G#5"] = 'sound/piano/G#5.ogg'
|
||||
//soundlist["Ab5"] = 'sound/piano/Ab5.ogg'
|
||||
soundlist["An5"] = 'sound/piano/An5.ogg'
|
||||
soundlist["A#5"] = 'sound/piano/A#5.ogg'
|
||||
//soundlist["Bb5"] = 'sound/piano/Bb5.ogg'
|
||||
soundlist["Bn5"] = 'sound/piano/Bn5.ogg'
|
||||
soundlist["B#5"] = 'sound/piano/B#5.ogg'
|
||||
soundlist["Cb6"] = 'sound/piano/Cb6.ogg'
|
||||
soundlist["Cn6"] = 'sound/piano/Cn6.ogg'
|
||||
soundlist["C#6"] = 'sound/piano/C#6.ogg'
|
||||
//soundlist["Db6"] = 'sound/piano/Db6.ogg'
|
||||
soundlist["Dn6"] = 'sound/piano/Dn6.ogg'
|
||||
soundlist["D#6"] = 'sound/piano/D#6.ogg'
|
||||
//soundlist["Eb6"] = 'sound/piano/Eb6.ogg'
|
||||
soundlist["En6"] = 'sound/piano/En6.ogg'
|
||||
soundlist["E#6"] = 'sound/piano/E#6.ogg'
|
||||
//soundlist["Fb6"] = 'sound/piano/Fb6.ogg'
|
||||
soundlist["Fn6"] = 'sound/piano/Fn6.ogg'
|
||||
soundlist["F#6"] = 'sound/piano/F#6.ogg'
|
||||
//soundlist["Gb6"] = 'sound/piano/Gb6.ogg'
|
||||
soundlist["Gn6"] = 'sound/piano/Gn6.ogg'
|
||||
soundlist["G#6"] = 'sound/piano/G#6.ogg'
|
||||
//soundlist["Ab6"] = 'sound/piano/Ab6.ogg'
|
||||
soundlist["An6"] = 'sound/piano/An6.ogg'
|
||||
soundlist["A#6"] = 'sound/piano/A#6.ogg'
|
||||
//soundlist["Bb6"] = 'sound/piano/Bb6.ogg'
|
||||
soundlist["Bn6"] = 'sound/piano/Bn6.ogg'
|
||||
soundlist["B#6"] = 'sound/piano/B#6.ogg'
|
||||
soundlist["Cb7"] = 'sound/piano/Cb7.ogg'
|
||||
soundlist["Cn7"] = 'sound/piano/Cn7.ogg'
|
||||
soundlist["C#7"] = 'sound/piano/C#7.ogg'
|
||||
//soundlist["Db7"] = 'sound/piano/Db7.ogg'
|
||||
soundlist["Dn7"] = 'sound/piano/Dn7.ogg'
|
||||
soundlist["D#7"] = 'sound/piano/D#7.ogg'
|
||||
//soundlist["Eb7"] = 'sound/piano/Eb7.ogg'
|
||||
soundlist["En7"] = 'sound/piano/En7.ogg'
|
||||
soundlist["E#7"] = 'sound/piano/E#7.ogg'
|
||||
//soundlist["Fb7"] = 'sound/piano/Fb7.ogg'
|
||||
soundlist["Fn7"] = 'sound/piano/Fn7.ogg'
|
||||
soundlist["F#7"] = 'sound/piano/F#7.ogg'
|
||||
//soundlist["Gb7"] = 'sound/piano/Gb7.ogg'
|
||||
soundlist["Gn7"] = 'sound/piano/Gn7.ogg'
|
||||
soundlist["G#7"] = 'sound/piano/G#7.ogg'
|
||||
//soundlist["Ab7"] = 'sound/piano/Ab7.ogg'
|
||||
soundlist["An7"] = 'sound/piano/An7.ogg'
|
||||
soundlist["A#7"] = 'sound/piano/A#7.ogg'
|
||||
//soundlist["Bb7"] = 'sound/piano/Bb7.ogg'
|
||||
soundlist["Bn7"] = 'sound/piano/Bn7.ogg'
|
||||
soundlist["B#7"] = 'sound/piano/B#7.ogg'
|
||||
soundlist["Cb8"] = 'sound/piano/Cb8.ogg'
|
||||
soundlist["Cn8"] = 'sound/piano/Cn8.ogg'
|
||||
soundlist["C#8"] = 'sound/piano/C#8.ogg'
|
||||
//soundlist["Db8"] = 'sound/piano/Db8.ogg'
|
||||
soundlist["Dn8"] = 'sound/piano/Dn8.ogg'
|
||||
soundlist["D#8"] = 'sound/piano/D#8.ogg'
|
||||
//soundlist["Eb8"] = 'sound/piano/Eb8.ogg'
|
||||
soundlist["En8"] = 'sound/piano/En8.ogg'
|
||||
soundlist["E#8"] = 'sound/piano/E#8.ogg'
|
||||
//soundlist["Fb8"] = 'sound/piano/Fb8.ogg'
|
||||
soundlist["Fn8"] = 'sound/piano/Fn8.ogg'
|
||||
soundlist["F#8"] = 'sound/piano/F#8.ogg'
|
||||
//soundlist["Gb8"] = 'sound/piano/Gb8.ogg'
|
||||
soundlist["Gn8"] = 'sound/piano/Gn8.ogg'
|
||||
soundlist["G#8"] = 'sound/piano/G#8.ogg'
|
||||
//soundlist["Ab8"] = 'sound/piano/Ab8.ogg'
|
||||
soundlist["An8"] = 'sound/piano/An8.ogg'
|
||||
soundlist["A#8"] = 'sound/piano/A#8.ogg'
|
||||
//soundlist["Bb8"] = 'sound/piano/Bb8.ogg'
|
||||
soundlist["Bn8"] = 'sound/piano/Bn8.ogg'
|
||||
soundlist["B#8"] = 'sound/piano/B#8.ogg'
|
||||
soundlist["Cb9"] = 'sound/piano/Cb9.ogg'
|
||||
soundlist["Cn9"] = 'sound/piano/Cn9.ogg'
|
||||
|
||||
proc/statusmsg( var/txt as text )
|
||||
status = txt
|
||||
updateUsrDialog()
|
||||
|
||||
proc/playsong()
|
||||
if(currentsong.compilesuccess == 0)
|
||||
playing = 0
|
||||
statusmsg("Playback Error: Compile it first!")
|
||||
return
|
||||
|
||||
var/list/tokens = dd_text2list_highcap(currentsong.compiledstring, "¤")
|
||||
|
||||
//Remove last token
|
||||
tokens.Cut(tokens.len-1)
|
||||
|
||||
var/repetitions = 0
|
||||
while(repetitions < repeat)
|
||||
repetitions++
|
||||
|
||||
for(var/token in tokens)
|
||||
if(playing == 0)
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
var/type = copytext(token, 1, 2)
|
||||
switch(type)
|
||||
if("x")
|
||||
var/soundfile = copytext(token, 2)
|
||||
soundfile = "sound/piano/[soundfile].ogg"
|
||||
|
||||
hearers(15, src) << sound(soundfile)
|
||||
if("y")
|
||||
sleep(text2num(copytext(token, 2)))
|
||||
|
||||
playing = 0
|
||||
updateUsrDialog()
|
||||
|
||||
|
||||
proc/compilesong()
|
||||
var/compilestring = ""
|
||||
|
||||
var/strippedsourcestring = dd_replacetext(currentsong.sourcestring, "\n", "")
|
||||
|
||||
|
||||
for(var/part in dd_text2list(strippedsourcestring, ","))
|
||||
var/list/x = dd_text2list(part, "/")
|
||||
var/xlen = x.len
|
||||
var/list/tones = dd_text2list(x[1], "-")
|
||||
|
||||
var/tempodiv = 1
|
||||
if(xlen==2)
|
||||
tempodiv = text2num(x[2])
|
||||
if(tempodiv == 0)
|
||||
statusmsg( "Compile Error: Can't divide by 0!\nAt Part:'[part]' Tone:" )
|
||||
return
|
||||
else if(xlen>2)
|
||||
statusmsg( "Compile Error: Tempo Syntax Error!\nAt Part:'[part]' Tone:" )
|
||||
return
|
||||
|
||||
for(var/tone in tones)
|
||||
var/len = lentext(tone)
|
||||
|
||||
if(len==0)
|
||||
break
|
||||
else if(len>3)
|
||||
statusmsg( "Compile Error: Tone Syntax Error!\nAt Part:'[part]' Tone:'[tone]'" )
|
||||
return
|
||||
|
||||
var/note = copytext(tone, 1, 2)
|
||||
var/accidental = "n"
|
||||
var/octave = "3"
|
||||
|
||||
var/notenum = text2ascii(note)
|
||||
if(notenum < 65 || notenum > 71)
|
||||
statusmsg( "Compile Error: Invalid Note Letter (A-G)\nAt Part:'[part]' Tone:'[tone]'" )
|
||||
return
|
||||
|
||||
if(len>=2)
|
||||
var/x2 = copytext(tone, 2, 3)
|
||||
var/x2num = text2num(x2)
|
||||
if(x2 == "b" || x2 == "n" || x2 == "#")
|
||||
accidental = x2
|
||||
else if(x2num >= 1 && x2num <= 9)
|
||||
octave = x2
|
||||
if(len==3)
|
||||
statusmsg( "Compile Error: Tone Syntax Error! (incorrect order)\nAt Part:'[part]' Tone:'[tone]'" )
|
||||
return
|
||||
else
|
||||
statusmsg( "Compile Error: Invalid Letter At Char (2)\nAt Part:'[part]' Tone:'[tone]'" )
|
||||
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
|
||||
|
||||
if(len==3)
|
||||
var/x3 = copytext(tone, 3, 4)
|
||||
var/x3num = text2num(x3)
|
||||
if(x3num >= 1 && x3num <= 9)
|
||||
octave = x3
|
||||
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
|
||||
updateUsrDialog()
|
||||
statusmsg( "Compile Error: Invalid Octave! (1-9)\nAt Part:'[part]' Tone:'[tone]'" )
|
||||
return
|
||||
|
||||
//Optimize part
|
||||
|
||||
// Replace a flat with a sharp from the note one step darker
|
||||
// If we're on the darkest note, we can't replace it by some darker (note != "C")
|
||||
// C D E F G A B
|
||||
if(accidental == "b" && note != "C")
|
||||
accidental = "#"
|
||||
if(note == "A")
|
||||
note = "G"
|
||||
else
|
||||
note = ascii2text(text2ascii(note)-1) // Decrement by one
|
||||
|
||||
var/finaltone = note + accidental + octave
|
||||
//Check if invalid note
|
||||
if((octave == "9" && (finaltone != "Cb9" && finaltone != "Cn9")) || finaltone == "Cb1")
|
||||
statusmsg( "Compile Error: Invalid Tone! (Check bottom of help for more info)\nAt Part:'[part]' Tone:'[tone]'" )
|
||||
return
|
||||
|
||||
// TODO: OPTIMIZE SHARPS AND FLATS
|
||||
//x indicates its a tone to be played
|
||||
compilestring += "x" + finaltone + "¤"
|
||||
|
||||
//y indicates its a sleep
|
||||
compilestring += "y[round((currentsong.tempo / tempodiv)*100)/100]¤"
|
||||
|
||||
currentsong.compiledstring = compilestring
|
||||
currentsong.compilesuccess = 1
|
||||
|
||||
statusmsg("Compiled successfully!")
|
||||
|
||||
/obj/structure/device/piano/attack_hand(var/mob/user as mob)
|
||||
if(!anchored)
|
||||
return
|
||||
|
||||
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(!edit)
|
||||
dat += "<A href='?src=\ref[src];edit=2'>Show Editor</A><BR><BR>"
|
||||
/*
|
||||
BPM TO TEMPO
|
||||
ds = 10/(BPM/60)
|
||||
|
||||
TEMPO TO BPM
|
||||
BPM = (10/ds)*60
|
||||
*/
|
||||
|
||||
var/calctempo = round((10/currentsong.tempo)*60)
|
||||
var/dat = {"
|
||||
<html>
|
||||
<head>
|
||||
<title>Piano</title>
|
||||
<style type="text/css">
|
||||
div.content
|
||||
{
|
||||
background-color:#AAAAAA;
|
||||
width:100%;
|
||||
padding:10;
|
||||
margin:5;
|
||||
}
|
||||
table.noborders {
|
||||
border-width: 0px;
|
||||
border-spacing: 0px;
|
||||
border-style: none;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table.noborders th {
|
||||
border-width: 0px;
|
||||
padding: 0px;
|
||||
border-style: inset;
|
||||
}
|
||||
table.noborders td {
|
||||
border-width: 0px;
|
||||
padding: 0px;
|
||||
border-style: inset;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<center><h1>[src.name == "space piano" ? "Space Piano" : "Space Minimoog"]</h1></center>
|
||||
<table class="noborders" width="100%"><tr>
|
||||
<td>
|
||||
<div bgcolor="#AAAAAA" class="content" style="height:100%;">"}
|
||||
if(showcontrol)
|
||||
dat += {" <a href='?src=\ref[src];controltoggle=1'>Hide Controlpanel</a><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=piano;size=700x300")
|
||||
dat += {" <a href='?src=\ref[src];controltoggle=1'>Show Controlpanel</a><br>"}
|
||||
|
||||
if(showcontrol)
|
||||
dat += {"
|
||||
|
||||
<a href='?src=\ref[src];toggleplay=1'>[playing ? "Stop Playing" : "Play [currentsong.name]"]</a><br>
|
||||
<br>
|
||||
<a href='?src=\ref[src];newsong=1'>New Song</a><br>
|
||||
<a href='?src=\ref[src];name=1'>Rename Song</a><br>
|
||||
<a href='?src=\ref[src];savesong=1'>Save [currentsong.name]</a><br>
|
||||
<br>
|
||||
<a href='?src=\ref[src];repeat=1'>Repeat: [repeat]</a><br>
|
||||
<div style="width:auto; height:auto; background-color:#888888;" bgcolor="#888888">
|
||||
<pre>Status:<br>[status]</pre>
|
||||
</div>"}
|
||||
|
||||
dat+={"
|
||||
</div>
|
||||
</td>
|
||||
<td width="150px">
|
||||
<div bgcolor="#AAAAAA" class="content" style="width:150px; height:100%; margin-left:0;">
|
||||
"}
|
||||
if(showcontrol)
|
||||
for(var/datum/song/isong in internalsongs)
|
||||
dat += "<a href='?src=\ref[src];setsong=[isong.id]'>[isong.name]</a><br>"
|
||||
dat += {"
|
||||
</div>
|
||||
</td>
|
||||
</tr></table>
|
||||
<div bgcolor="#AAAAAA" class="content" style="margin-top:0;">"}
|
||||
|
||||
if(showeditor)
|
||||
dat += {"<a href='?src=\ref[src];editortoggle=1'>Hide Editor</a><br>"}
|
||||
else
|
||||
dat += {"<a href='?src=\ref[src];editortoggle=1'>Show Editor</a><br>"}
|
||||
|
||||
if(showeditor)
|
||||
dat += {"
|
||||
Tempo:
|
||||
<a href='?src=\ref[src];tempo=-3'>-</a><a href='?src=\ref[src];tempo=-2'>-</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=2'>+</a><a href='?src=\ref[src];tempo=3'>+</a><br>
|
||||
<a href='?src=\ref[src];compile=1'>Compile</a>
|
||||
<a href='?src=\ref[src];edit=1'>Edit</a>
|
||||
<div bgcolor="#888888" style="padding-left:5px; margin-top:5px; background-color:#888888"><pre>[currentsong.sourcestring]</pre></div>"}
|
||||
dat+={"
|
||||
</div>
|
||||
<div bgcolor="#AAAAAA" class="content">"}
|
||||
|
||||
if(showhelp)
|
||||
dat += {"<a href='?src=\ref[src];helptoggle=1'>Hide Help</a><br>"}
|
||||
else
|
||||
dat += {"<a href='?src=\ref[src];helptoggle=1'>Show Help</a><br>"}
|
||||
|
||||
if(showhelp)
|
||||
dat += {"
|
||||
Songs 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>
|
||||
Octave can be a number between 1 and 9<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,Cb,C3</i> is <i>C#3,Cn4,Cb3,Cn3</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-Eb4/4,/2,G#/8,B/8,E3-E4/4</i><br>
|
||||
<br>
|
||||
A song may only contain up to 4000 letters.<br>
|
||||
If you're playing a small piece over and over, remember to put a pause at the end for it to sound properly.<br<
|
||||
<br>
|
||||
Note: Due to limitations in the engine, some tones doesn't exist. These are:<br>
|
||||
Cb1<br>
|
||||
All tones in the ninth octave <b>except Cb9 and Cn9</b>
|
||||
"}
|
||||
dat+={"
|
||||
</div>
|
||||
</body>
|
||||
</html>"}
|
||||
user << browse(dat, "window=piano;size=700x500")
|
||||
onclose(user, "piano")
|
||||
|
||||
/obj/structure/device/piano/Topic(href, href_list)
|
||||
@@ -310,98 +519,113 @@
|
||||
onclose(usr, "piano")
|
||||
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(href_list["toggleplay"])
|
||||
if(playing)
|
||||
playing = 0
|
||||
else
|
||||
playing = 1
|
||||
spawn() playsong()
|
||||
|
||||
updateUsrDialog()
|
||||
|
||||
else if(href_list["controltoggle"])
|
||||
showcontrol = 1-showcontrol
|
||||
updateUsrDialog()
|
||||
|
||||
else if(href_list["editortoggle"])
|
||||
showeditor = 1-showeditor
|
||||
updateUsrDialog()
|
||||
|
||||
else if(href_list["helptoggle"])
|
||||
showhelp = 1-showhelp
|
||||
updateUsrDialog()
|
||||
|
||||
else if(href_list["name"])
|
||||
var/input = html_encode(input(usr, "", "Rename", currentsong.name) as text|null)
|
||||
currentsong.name = copytext(input,1,30)
|
||||
updateUsrDialog()
|
||||
|
||||
else if(href_list["savesong"])
|
||||
|
||||
//Check if the song already exists in the internal
|
||||
var/foundsong = 0
|
||||
for(var/datum/song/isong in internalsongs)
|
||||
if(isong.id == currentsong.id)
|
||||
foundsong = 1
|
||||
isong.compiledstring = currentsong.compiledstring
|
||||
isong.sourcestring = currentsong.sourcestring
|
||||
isong.name = currentsong.name
|
||||
break
|
||||
|
||||
//If not, add it as new
|
||||
if(!foundsong)
|
||||
internalsongs += currentsong
|
||||
|
||||
updateUsrDialog()
|
||||
|
||||
if(playing)
|
||||
if(href_list["newsong"]||href_list["setsong"]||href_list["tempo"]||href_list["compile"]||href_list["edit"]||href_list["repeat"])
|
||||
statusmsg("Playback Error: Stop the song first!")
|
||||
else
|
||||
if(href_list["newsong"])
|
||||
var/answer = alert(usr, "This will overwrite any current song you're editing!", "Are you sure?", "Yes", "No")
|
||||
if(answer == "No")
|
||||
return
|
||||
|
||||
currentsong = new()
|
||||
updateUsrDialog()
|
||||
|
||||
else if(href_list["setsong"])
|
||||
|
||||
var/matchid = text2num(href_list["setsong"])
|
||||
for(var/datum/song/isong in internalsongs)
|
||||
if(isong.id == matchid)
|
||||
currentsong = isong
|
||||
break
|
||||
|
||||
updateUsrDialog()
|
||||
|
||||
else if(href_list["tempo"])
|
||||
song.tempo += round(text2num(href_list["tempo"]))
|
||||
if(song.tempo < 1)
|
||||
song.tempo = 1
|
||||
var/tempoinc = text2num(href_list["tempo"])
|
||||
|
||||
else if(href_list["play"])
|
||||
if(song)
|
||||
playing = 1
|
||||
spawn() playsong()
|
||||
currentsong.tempo += tempoinc*-1
|
||||
if(currentsong.tempo<1)
|
||||
currentsong.tempo = 1
|
||||
currentsong.compilesuccess = 0
|
||||
|
||||
else if(href_list["newline"])
|
||||
var/newline = html_encode(input("Enter your line: ", "Piano") 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)
|
||||
updateUsrDialog()
|
||||
|
||||
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["compile"])
|
||||
|
||||
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
|
||||
compilesong()
|
||||
|
||||
else if(href_list["stop"])
|
||||
playing = 0
|
||||
|
||||
else if(href_list["help"])
|
||||
help = text2num(href_list["help"]) - 1
|
||||
updateUsrDialog()
|
||||
|
||||
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("[]", src.name), t) as message)
|
||||
if (!in_range(src, usr))
|
||||
return
|
||||
var/input = html_encode(input(usr, "", "Edit", currentsong.sourcestring) as message|null)
|
||||
|
||||
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)
|
||||
input = dd_replacetext(input, " ", "")
|
||||
input = dd_replacetext(input, "\t", "")
|
||||
|
||||
//split into lines
|
||||
spawn()
|
||||
var/list/lines = dd_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()
|
||||
if(lentext(input)>4000)
|
||||
statusmsg("Editor Error: Song too long, end was cutoff (max 4000)")
|
||||
input = copytext(input, 1, 4001)
|
||||
|
||||
currentsong.sourcestring = input
|
||||
currentsong.compilesuccess = 0
|
||||
|
||||
updateUsrDialog()
|
||||
|
||||
else if(href_list["repeat"])
|
||||
|
||||
var/input = round(input(usr, "", "Repeat", "How many times do you want to repeat? (max 10)") as num|null)
|
||||
if(input < 1)
|
||||
input = 1
|
||||
else if(input > 10)
|
||||
input = 10
|
||||
|
||||
repeat = input
|
||||
|
||||
add_fingerprint(usr)
|
||||
updateUsrDialog()
|
||||
|
||||
Reference in New Issue
Block a user