Independant function calls?
#1
I got busy and started to write an MCSmash plugin (Super Smash Bros. im Minecraft), but I came across a bit of a wall. Lets say I got a sleep function:

function sleep(n)  -- seconds
  local t0 = clock()
  while clock() - t0 <= n do end
end

I want to do a little noteblock music on command, but when I do this:

		function PlayNoteBlock()
			NoteEntity:SetPitch(F5)
			NoteEntity:MakeSound()
			sleep(0.2)
			NoteEntity:MakeSound()
			sleep(0.2)
			NoteEntity:MakeSound()
			sleep(0.2)
			NoteEntity:SetPitch(D5)
			NoteEntity:MakeSound()
			sleep(0.1)
			NoteEntity:SetPitch(F5)
			NoteEntity:MakeSound()
			sleep(0.2)
			NoteEntity:MakeSound()
			sleep(0.2)
			NoteEntity:SetPitch(D5)
			NoteEntity:MakeSound()
			sleep(0.1)
			NoteEntity:SetPitch(F5)
			NoteEntity:MakeSound()
			sleep(0.1)
			NoteEntity:SetPitch(D5)
			NoteEntity:MakeSound()
			sleep(0.1)
			NoteEntity:SetPitch(F5)
			NoteEntity:MakeSound()
			sleep(0.2)
		end

The entire server freezes while that function runs. Coroutines don't seem to help much here either. Any way I could get around this?
Also, the "F5" and stuff are just numerical constants.
Reply
Thanks given by:
#2
The entire server is event-driven and the plugins are synchronous - while plugin code is executing, most of the rest of the server is waiting for it to finish. This means that you cannot use any kind of a sleep function, you need to make use of the scheduler instead. There's a cWorld:ScheduleTask() function that basically says "call this function after this many ticks". Additionally, you need to take care of the situation that your plugin is using a note entity and a player destroys the block during that time - the note entity object becomes invalid. Therefore, the code should look something like this:
--- Schedules the specified note block to play the specified melody
-- a_Melody is an array-table of notes, each note being a table with two members, delay (in ticks) and pitch
function StartPlaying(a_World, a_NoteBlockX, a_NoteBlockY, a_NoteBlockZ, a_Melody)
  for _, note in ipairs(a_Melody) do
    a_World:ScheduleTask(note.delay,
      function (a_CBWorld)
        a_CBWorld:DoWithNoteAt(a_NoteBlockX, a_NoteBlockY, a_NoteBlokZ,
          function (a_CBNoteBlock)
            a_CBNoteBlock:SetPitch(note.pitch)
            a_CBNoteBlock:MakeSound()
          end
        )
      end
    )
  end
end

-- Example usage:
local Melody =
{
  {0, F5},
  {4, F5},
  {8, F5},
  {12, D5},
  {14, F5},
}
StartPlaying(World, 100, 100, 100, Melody)
Reply
Thanks given by: Seadragon91 , DiamondToaster
#3
This is actually a pretty good example, I might use this to write a new article about the event-driven nature of the server.
Reply
Thanks given by: DiamondToaster
#4
Will the article go into the new Wiki?
http://mcserver.planetx.com
Reply
Thanks given by:
#5
No, it'd be for the LuaAPI docs ( http://mc-server.xoft.cz/LuaAPI/index.html#articles )
Reply
Thanks given by:
#6
(01-17-2015, 11:08 PM)xoft Wrote: No, it'd be for the LuaAPI docs ( http://mc-server.xoft.cz/LuaAPI/index.html#articles )

I tested that code and had to fix a few lines. For example where are you declaring delay and pitch? Huh
Reply
Thanks given by:
#7
Right, sorry, the melody table definition was wrong, it should have been:
local Melody =
{
  { delay = 0, pitch = F5},
  { delay = 4, pitch = F5},
  ...
}
That's what happens when I write code off the top of my head, without testing it. Smile
Reply
Thanks given by: DiamondToaster
#8
Thanks, I got it all working right. Smile

Now I gotta just add arenas and configs and stuff.

I actually got it to work just by using pairs without members by using note[1] note [2] instead of note.pitch and note.delay
Reply
Thanks given by:
#9
So, an smash brothers plugin? Sounds goodBig Grin
Reply
Thanks given by:
#10
Yup, Its a bit glitchy but the basic mechanics work.

I tried to make items spawn in the arena, but the cWorld:SpawnItemPickups() requires a cItems container, but when making one and trying to add items to it, it says it needs another cItems container to add to the new one when the API says it only needs a cItem. Is this an API glitch or am I doing something wrong?

Also is there a list for of sound names for cWorld:BroadcastSoundEffect() like the particle effect one?
Reply
Thanks given by:




Users browsing this thread: 3 Guest(s)