mirror of
https://github.com/StyledStrike/musical-keyboard.git
synced 2025-03-04 03:13:36 -05:00
Add wiremod support
This commit is contained in:
parent
586d3a7b73
commit
3dddac0e36
@ -40,6 +40,27 @@ function ENT:Initialize()
|
||||
|
||||
local phys = self:GetPhysicsObject()
|
||||
if IsValid( phys ) then phys:Wake() end
|
||||
|
||||
if WireLib then
|
||||
WireLib.CreateSpecialOutputs( self, { "NotePlayed" }, { "ARRAY" }, {
|
||||
[[Triggered when the user played a note.
|
||||
This array contains:
|
||||
[1] Note number,
|
||||
[2] Note velocity
|
||||
[3] Instrument index (The number near each name on the instruments list)]]
|
||||
} )
|
||||
|
||||
WireLib.CreateSpecialInputs( self, { "PlayNote" }, { "ARRAY" }, {
|
||||
[[Changing this input will play a note.
|
||||
The array should contain:
|
||||
[1] Note number (1-127)
|
||||
[2] Note velocity (1-127)
|
||||
[3] Instrument index (The number near each name on the instruments list)]]
|
||||
} )
|
||||
|
||||
self.reproduceQueue = {}
|
||||
self.transmitQueue = {}
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Use( ply )
|
||||
@ -65,3 +86,85 @@ function ENT:RemovePlayer()
|
||||
self.Ply = nil
|
||||
end
|
||||
end
|
||||
|
||||
if not WireLib then
|
||||
function ENT:OnReceiveNotes() end
|
||||
return
|
||||
end
|
||||
|
||||
local function ValidateNumber( v, default, min, max )
|
||||
return math.Clamp( math.Round( tonumber( v ) or default ), min, max )
|
||||
end
|
||||
|
||||
function ENT:TriggerInput( name, value )
|
||||
if name ~= "PlayNote" then return end
|
||||
if not isnumber( value[1] ) then return end
|
||||
|
||||
local note = ValidateNumber( value[1], 0, 0, 127 )
|
||||
if note == 0 then return end
|
||||
|
||||
local velocity = ValidateNumber( value[2], 127, 1, 127 )
|
||||
local instrument = ValidateNumber( value[3], 1, 1, 127 ) -- Max. value is based on net.WriteUInt( 7 )
|
||||
|
||||
local queue = self.transmitQueue
|
||||
|
||||
-- Remember when we started putting notes
|
||||
-- on the queue, and when we should send them
|
||||
local t = SysTime()
|
||||
|
||||
if not self.queueTimer then
|
||||
self.queueTimer = t + 0.4
|
||||
self.queueStart = t
|
||||
end
|
||||
|
||||
-- Add notes to the queue unless the limit was reached
|
||||
local noteCount = #queue
|
||||
|
||||
if noteCount < MKeyboard.NET_MAX_NOTES then
|
||||
queue[noteCount + 1] = {
|
||||
note, velocity, instrument, t - self.queueStart
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local SysTime = SysTime
|
||||
|
||||
function ENT:OnReceiveNotes( notes )
|
||||
local t = SysTime()
|
||||
local queue = self.reproduceQueue
|
||||
|
||||
for i, n in ipairs( notes ) do
|
||||
-- i * 0.01 to prevent overriding stuff already on the queue
|
||||
queue[t + n[4] + ( i * 0.01 )] = { n[1], n[2], n[3] }
|
||||
end
|
||||
end
|
||||
|
||||
local GetKeys = table.GetKeys
|
||||
|
||||
function ENT:Think()
|
||||
self:NextThink( CurTime() )
|
||||
|
||||
local now = SysTime()
|
||||
|
||||
-- If the queued notes are ready to be sent...
|
||||
if self.queueTimer and now > self.queueTimer then
|
||||
MKeyboard.BroadcastNotes( self.transmitQueue, self, true )
|
||||
|
||||
table.Empty( self.transmitQueue )
|
||||
self.queueTimer = nil
|
||||
end
|
||||
|
||||
-- Trigger the wire outputs while taking the time offsets into account
|
||||
local queue = self.reproduceQueue
|
||||
local timestamps = GetKeys( queue )
|
||||
|
||||
for _, t in ipairs( timestamps ) do
|
||||
if now > t then
|
||||
local n = queue[t]
|
||||
WireLib.TriggerOutput( self, "NotePlayed", { n[1], n[2], n[3] } )
|
||||
queue[t] = nil
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
@ -91,6 +91,8 @@ net.Receive( "mkeyboard.notes", function( _, ply )
|
||||
}
|
||||
end
|
||||
|
||||
ent:OnReceiveNotes( notes )
|
||||
|
||||
-- Then broadcast those notes
|
||||
BroadcastNotes( notes, ent, automated, ply )
|
||||
end )
|
||||
|
Loading…
Reference in New Issue
Block a user