mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-11 07:03:30 +01:00
Updates/fixes instrument ui to be a nanoui
This commit is contained in:
@@ -20,17 +20,19 @@
|
||||
return ..()
|
||||
|
||||
/obj/item/device/guitar/attack_self(mob/user as mob)
|
||||
interact(user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/item/device/guitar/interact(mob/user as mob)
|
||||
/obj/item/device/guitar/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
if(!user)
|
||||
return
|
||||
|
||||
if(!isliving(user) || user.stat || user.restrained() || user.lying)
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
song.interact(user)
|
||||
song.ui_interact(user, ui_key, ui, force_open)
|
||||
|
||||
/obj/item/device/guitar/Topic(href, href_list)
|
||||
song.Topic(href, href_list)
|
||||
|
||||
/datum/table_recipe/guitar
|
||||
name = "Guitar"
|
||||
|
||||
@@ -24,14 +24,16 @@
|
||||
..()
|
||||
|
||||
/obj/item/device/violin/attack_self(mob/user as mob)
|
||||
interact(user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/item/device/violin/interact(mob/user as mob)
|
||||
/obj/item/device/violin/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
if(!user)
|
||||
return
|
||||
|
||||
if(!isliving(user) || user.stat || user.restrained() || user.lying)
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
song.interact(user)
|
||||
song.ui_interact(user, ui_key, ui, force_open)
|
||||
|
||||
/obj/item/device/violin/Topic(href, href_list)
|
||||
song.Topic(href, href_list)
|
||||
@@ -3,13 +3,12 @@
|
||||
/datum/song
|
||||
var/name = "Untitled"
|
||||
var/list/lines = new()
|
||||
var/tempo = 5 // delay between notes
|
||||
var/tempo = 5 // delay between notes
|
||||
|
||||
var/playing = 0 // if we're playing
|
||||
var/help = 0 // if help is open
|
||||
var/edit = 1 // if we're in editing mode
|
||||
var/repeat = 0 // number of times remaining to repeat
|
||||
var/max_repeats = 10 // maximum times we can repeat
|
||||
var/playing = 0 // if we're playing
|
||||
var/help = 0 // if help is open
|
||||
var/repeat = 0 // number of times remaining to repeat
|
||||
var/max_repeat = 10 // maximum times we can repeat
|
||||
|
||||
var/instrumentDir = "piano" // the folder with the sounds
|
||||
var/instrumentExt = "ogg" // the file extension
|
||||
@@ -63,9 +62,6 @@
|
||||
continue
|
||||
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(mob/user)
|
||||
if(instrumentObj)
|
||||
//if(!user.canUseTopic(instrumentObj))
|
||||
@@ -113,68 +109,31 @@
|
||||
else
|
||||
sleep(tempo)
|
||||
repeat--
|
||||
if(repeat >= 0) // don't show the last -1 repeat
|
||||
updateDialog(user)
|
||||
playing = 0
|
||||
repeat = 0
|
||||
updateDialog(user)
|
||||
|
||||
/datum/song/proc/interact(mob/user as mob)
|
||||
var/dat = ""
|
||||
/datum/song/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/data[0]
|
||||
|
||||
if(lines.len > 0)
|
||||
dat += "<H3>Playback</H3>"
|
||||
if(!playing)
|
||||
dat += "<A href='?src=\ref[src];play=1'>Play</A> <SPAN CLASS='linkOn'>Stop</SPAN><BR><BR>"
|
||||
dat += "Repeat Song: "
|
||||
dat += repeat > 0 ? "<A href='?src=\ref[src];repeat=-10'>-</A><A href='?src=\ref[src];repeat=-1'>-</A>" : "<SPAN CLASS='linkOff'>-</SPAN><SPAN CLASS='linkOff'>-</SPAN>"
|
||||
dat += " [repeat] times "
|
||||
dat += repeat < max_repeats ? "<A href='?src=\ref[src];repeat=1'>+</A><A href='?src=\ref[src];repeat=10'>+</A>" : "<SPAN CLASS='linkOff'>+</SPAN><SPAN CLASS='linkOff'>+</SPAN>"
|
||||
dat += "<BR>"
|
||||
else
|
||||
dat += "<SPAN CLASS='linkOn'>Play</SPAN> <A href='?src=\ref[src];stop=1'>Stop</A><BR>"
|
||||
dat += "Repeats left: <B>[repeat]</B><BR>"
|
||||
if(!edit)
|
||||
dat += "<BR><B><A href='?src=\ref[src];edit=2'>Show Editor</A></B><BR>"
|
||||
else
|
||||
dat += "<H3>Editing</H3>"
|
||||
dat += "<B><A href='?src=\ref[src];edit=1'>Hide Editor</A></B>"
|
||||
dat += " <A href='?src=\ref[src];newsong=1'>Start a New Song</A>"
|
||||
dat += " <A href='?src=\ref[src];import=1'>Import a Song</A><BR><BR>"
|
||||
var/bpm = round(600 / tempo)
|
||||
dat += "Tempo: <A href='?src=\ref[src];tempo=[world.tick_lag]'>-</A> [bpm] BPM <A href='?src=\ref[src];tempo=-[world.tick_lag]'>+</A><BR><BR>"
|
||||
var/linecount = 0
|
||||
for(var/line in lines)
|
||||
linecount += 1
|
||||
dat += "Line [linecount]: <A href='?src=\ref[src];modifyline=[linecount]'>Edit</A> <A href='?src=\ref[src];deleteline=[linecount]'>X</A> [line]<BR>"
|
||||
dat += "<A href='?src=\ref[src];newline=1'>Add Line</A><BR><BR>"
|
||||
if(help)
|
||||
dat += "<B><A href='?src=\ref[src];help=1'>Hide Help</A></B><BR>"
|
||||
dat += {"
|
||||
Lines are a series of chords, separated by commas (,), each with notes 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,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 += "<B><A href='?src=\ref[src];help=2'>Show Help</A></B><BR>"
|
||||
data["lines"] = lines
|
||||
data["tempo"] = tempo
|
||||
|
||||
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()
|
||||
data["playing"] = playing
|
||||
data["help"] = help
|
||||
data["repeat"] = repeat
|
||||
data["maxRepeat"] = max_repeat
|
||||
data["minTempo"] = world.tick_lag
|
||||
data["maxTempo"] = 600
|
||||
|
||||
if(!instrumentObj)
|
||||
return
|
||||
|
||||
ui = nanomanager.try_update_ui(user, instrumentObj, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, instrumentObj, ui_key, "song.tmpl", instrumentObj.name, 700, 500)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/datum/song/Topic(href, href_list)
|
||||
if(!in_range(instrumentObj, usr) || (issilicon(usr) && instrumentObj.loc != usr) || !isliving(usr) || !usr.canmove || usr.restrained())
|
||||
@@ -185,14 +144,16 @@
|
||||
instrumentObj.add_fingerprint(usr)
|
||||
|
||||
if(href_list["newsong"])
|
||||
playing = 0
|
||||
lines = new()
|
||||
tempo = sanitize_tempo(5) // default 120 BPM
|
||||
name = ""
|
||||
|
||||
else if(href_list["import"])
|
||||
playing = 0
|
||||
var/t = ""
|
||||
do
|
||||
t = html_encode(input(usr, "Please paste the entire song, formatted:", text("[]", name), t) as message)
|
||||
t = html_encode(input(usr, "Please paste the entire song, formatted:", text("[]", name), t) as message)
|
||||
if(!in_range(instrumentObj, usr))
|
||||
return
|
||||
|
||||
@@ -220,13 +181,9 @@
|
||||
lines.Remove(l)
|
||||
else
|
||||
linenum++
|
||||
updateDialog(usr) // make sure updates when complete
|
||||
|
||||
else if(href_list["help"])
|
||||
help = text2num(href_list["help"]) - 1
|
||||
|
||||
else if(href_list["edit"])
|
||||
edit = text2num(href_list["edit"]) - 1
|
||||
help = !help
|
||||
|
||||
if(href_list["repeat"]) //Changing this from a toggle to a number of repeats to avoid infinite loops.
|
||||
if(playing)
|
||||
@@ -234,18 +191,24 @@
|
||||
repeat += round(text2num(href_list["repeat"]))
|
||||
if(repeat < 0)
|
||||
repeat = 0
|
||||
if(repeat > max_repeats)
|
||||
repeat = max_repeats
|
||||
if(repeat > max_repeat)
|
||||
repeat = max_repeat
|
||||
|
||||
else if(href_list["tempo"])
|
||||
tempo = sanitize_tempo(tempo + text2num(href_list["tempo"]))
|
||||
tempo = sanitize_tempo(tempo + text2num(href_list["tempo"]) * world.tick_lag)
|
||||
|
||||
else if(href_list["play"])
|
||||
if(playing)
|
||||
return
|
||||
playing = 1
|
||||
spawn()
|
||||
playsong(usr)
|
||||
|
||||
else if(href_list["newline"])
|
||||
else if(href_list["insertline"])
|
||||
var/num = round(text2num(href_list["insertline"]))
|
||||
if(num < 1 || num > lines.len + 1)
|
||||
return
|
||||
|
||||
var/newline = html_encode(input("Enter your line: ", instrumentObj.name) as text|null)
|
||||
if(!newline || !in_range(instrumentObj, usr))
|
||||
return
|
||||
@@ -253,16 +216,17 @@
|
||||
return
|
||||
if(lentext(newline) > 50)
|
||||
newline = copytext(newline, 1, 50)
|
||||
lines.Add(newline)
|
||||
|
||||
lines.Insert(num, newline)
|
||||
|
||||
else if(href_list["deleteline"])
|
||||
var/num = round(text2num(href_list["deleteline"]))
|
||||
if(num > lines.len || num < 1)
|
||||
return
|
||||
lines.Cut(num, num+1)
|
||||
lines.Cut(num, num + 1)
|
||||
|
||||
else if(href_list["modifyline"])
|
||||
var/num = round(text2num(href_list["modifyline"]),1)
|
||||
var/num = round(text2num(href_list["modifyline"]))
|
||||
var/content = html_encode(input("Enter your line: ", instrumentObj.name, lines[num]) as text|null)
|
||||
if(!content || !in_range(instrumentObj, usr))
|
||||
return
|
||||
@@ -275,19 +239,12 @@
|
||||
else if(href_list["stop"])
|
||||
playing = 0
|
||||
|
||||
updateDialog(usr)
|
||||
return
|
||||
|
||||
/datum/song/proc/sanitize_tempo(new_tempo)
|
||||
new_tempo = abs(new_tempo)
|
||||
return max(round(new_tempo, world.tick_lag), world.tick_lag)
|
||||
|
||||
// subclass for handheld instruments, like violin
|
||||
/datum/song/handheld
|
||||
|
||||
/datum/song/handheld/updateDialog(mob/user as mob)
|
||||
instrumentObj.interact(user)
|
||||
|
||||
/datum/song/handheld/shouldStopPlaying()
|
||||
if(instrumentObj)
|
||||
return !isliving(instrumentObj.loc)
|
||||
@@ -329,14 +286,16 @@
|
||||
..()
|
||||
|
||||
/obj/structure/piano/attack_hand(mob/user as mob)
|
||||
interact(user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/structure/piano/interact(mob/user as mob)
|
||||
/obj/structure/piano/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
if(!user || !anchored)
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
song.interact(user)
|
||||
song.ui_interact(user, ui_key, ui, force_open)
|
||||
|
||||
/obj/structure/piano/Topic(href, href_list)
|
||||
song.Topic(href, href_list)
|
||||
|
||||
/obj/structure/piano/attackby(obj/item/O as obj, mob/user as mob, params)
|
||||
if (istype(O, /obj/item/weapon/wrench))
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
<!--
|
||||
Title: Instrument UI
|
||||
Used In File(s): \code\game\objects\structures\musician.dm
|
||||
-->
|
||||
|
||||
<div class="block">
|
||||
<div class="item">
|
||||
<div class="itemLabel"><b>Playback</b></div>
|
||||
<div class="itemContent">
|
||||
{{:helper.link('New', 'document', {'newsong': 1})}}
|
||||
{{:helper.link('Import', 'folder-open', {'import': 1})}}
|
||||
{{:helper.link('Play', 'play', {'play': 1}, data.lines.length > 0 ? (data.playing ? 'selected' : null) : 'disabled')}}
|
||||
{{:helper.link('Stop', 'stop', {'stop': 1}, !data.playing ? 'selected' : null)}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel">Repeat Song:</div>
|
||||
{{:helper.link('-', null, {'repeat' : -10}, data.repeat > 0 && !data.playing ? null : 'disabled')}}
|
||||
{{:helper.link('-', null, {'repeat' : -1}, data.repeat > 0 && !data.playing ? null : 'disabled')}}
|
||||
<span style="float: left; width: 80px; text-align: center;">{{:data.repeat}}</span>
|
||||
{{:helper.link('+', null, {'repeat' : 1}, data.repeat < data.maxRepeat && !data.playing ? null : 'disabled')}}
|
||||
{{:helper.link('+', null, {'repeat' : 10}, data.repeat < data.maxRepeat && !data.playing ? null : 'disabled')}}
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel">Tempo:</div>
|
||||
{{:helper.link('-', null, {'tempo' : 10}, data.tempo < data.maxTempo ? null : 'disabled')}}
|
||||
{{:helper.link('-', null, {'tempo' : 1}, data.tempo < data.maxTempo ? null : 'disabled')}}
|
||||
<span style="float: left; width: 80px; text-align: center;">{{:helper.round(600 / data.tempo)}} BPM</span>
|
||||
{{:helper.link('+', null, {'tempo' : -1}, data.tempo > data.minTempo ? null : 'disabled')}}
|
||||
{{:helper.link('+', null, {'tempo' : -10}, data.tempo > data.minTempo ? null : 'disabled')}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>Editor</h3>
|
||||
{{for data.lines}}
|
||||
<div class="line" style="padding:4px;{{if index % 2 == 1}}background-color: #444{{/if}}">
|
||||
<div class="floatLeft highlight">{{:index + 1}}: </div>
|
||||
<div class="floatRight">
|
||||
{{:helper.link('Edit', 'pencil', {'modifyline': index+1}, data.playing ? 'disabled' : null)}}
|
||||
{{:helper.link('Insert', 'arrowreturn-1-n', {'insertline': index+1}, data.playing ? 'disabled' : null)}}
|
||||
{{:helper.link('Delete', 'trash', {'deleteline': index+1}, data.playing ? 'disabled' : null)}}
|
||||
</div>
|
||||
<div>{{:value}}</div>
|
||||
</div>
|
||||
{{/for}}
|
||||
<div class="floatRight">
|
||||
{{:helper.link('Add Line', 'arrowreturn-1-s', {'insertline': data.lines.length + 1}, data.playing ? 'disabled' : null)}}
|
||||
</div>
|
||||
<div class="clearBoth"></div>
|
||||
<hr>
|
||||
|
||||
<div class="item">
|
||||
<div class="itemLabelNarrow">
|
||||
{{:helper.link('Help', data.help ? 'close' : 'help', {'help': 1})}}
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{if data.help}}
|
||||
<p>
|
||||
Lines are a series of chords, separated by commas <span class="highlight">(,)</span>, each with notes seperated by hyphens <span class="highlight">(-)</span>.
|
||||
<br>
|
||||
Every note in a chord will play together, with the chord timed by the <span class="highlight">tempo</span> as defined above.
|
||||
</p>
|
||||
<p>
|
||||
Notes are played by the <span class="good">names of the note</span>, and optionally, the <span class="average">accidental</span>, and/or the <span class="bad">octave number</span>.
|
||||
<br>
|
||||
By default, every note is <span class="average">natural</span> and in <span class="bad">octave 3</span>. Defining a different state for either is remembered for each <span class="good">note</span>.
|
||||
<ul>
|
||||
<li><span class="highlight">Example:</span> <i>C,D,E,F,G,A,B</i> will play a <span class="good">C</span> <span class="average">major</span> scale.</li>
|
||||
<li>After a note has an <span class="average">accidental</span> or <span class="bad">octave</span> placed, it will be remembered: <i>C,C4,C#,C3</i> is C3,C4,C4#,C3#</i></li>
|
||||
</ul>
|
||||
</p>
|
||||
<p>
|
||||
<span class="highlight">Chords</span> can be played simply by seperating each note with a hyphon: <i>A-C#,Cn-E,E-G#,Gn-B</i>.<br>
|
||||
A <span class="highlight">pause</span> 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 defined by <span class="highlight">tempo / x</span>, <span class="highlight">eg:</span> <i>C,G/2,E/4</i>.
|
||||
</p>
|
||||
<p>
|
||||
Combined, an example line is: <i>E-E4/4,F#/2,G#/8,B/8,E3-E4/4</i>.
|
||||
<ul>
|
||||
<li>Lines may be up to 50 characters.</li>
|
||||
<li>A song may only contain up to 50 lines.</li>
|
||||
</ul>
|
||||
</p>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user