What am I doing wrong?
#1
Bug 
I was trying to write a plugin that lets u spectate a other player.
homeDir = 'Plugins/Spectate' 

function Initialize(Plugin)
	require "posix"
	Plugin:SetName("Spectate")
	Plugin:SetVersion(1)
	PluginManager = cRoot:Get():GetPluginManager()
	PluginManager:BindCommand("/spectate","spectate.spectate",HandleSpectateCommand," - Spectate!")
	LOGINFO("Initialized " .. Plugin:GetName() .. " v." .. Plugin:GetVersion())
	return true;
end

function HandleSpectateCommand(Split, Player)
  time = 10
		username = Player:GetName()
		Playername = Split[2]
		_player = GetPlayerByName(Playername)
	while testzeit >= 0 do
	spectate(Player, Split)
	end
	return true
end

function GetPlayerByName( inPlayerName )
	local _player
	local PlayerSetter = function( Player )
		_player = Player
	end
	cRoot:Get():FindAndDoWithPlayer( inPlayerName, PlayerSetter )
	return _player
end

function spectate(Player, Split)
		posix.sleep(1)
		time = time - 1
		X = _player:GetPosX()
		Y = _player:GetPosY()
		Z = _player:GetPosZ()
		Y=Y+2
		Player:TeleportToCoords(X, Y, Z)
end
For the time delay I am using lua posix.
Here is my problem: For some reason the spectated player seems to stay at one place for the spectator.
I got absolutely no idea why that happens and I hope that someone can help me :)
Reply
Thanks given by:
#2
You can't sleep in the command handler, it blocks the server from doing anything else. The plugins don't run in preemptive multitasking, they run in cooperated multitasking, which basically means that "while a function is running, the entire server is waiting for it to finish". That's why we have all the hooks and callbacks, they are mostly to support asynchronicity.

As for the specific question, the Player:TeleportToCoords() function only sets a flag, saying "when this player is next considered for physics, teleport them to these coords". But the physics thread is blocked, waiting for your plugin to finish executing, so the new position doesn't get sent.
Reply
Thanks given by: jakibaki
#3
If you want to wait for a period use the MCServer API: cWorld:ScheduleTask(function,World)
Reply
Thanks given by: jakibaki
#4
Thank You so mutch Smile
That will help me fixing the problem
Reply
Thanks given by:
#5
So you'd use something like this:
local NUM_TICKS = 5

function HandleSpectateCommand(a_Split, a_Player)
  -- Store the player name of the spectator and the spectated player, so that you can access them later on:
  local SpectatorName = a_Player:GetName()
  local SpectatedName = a_Split[2]
  if (SpectatedName == nil) then
    -- TODO: handle error
  end

  local Callback = function(a_World)
    -- This is the callback that will be called after NUM_TICKS ticks
    -- Note that it CANNOT access a_Player!
    -- (because the player could have disconnected in the meantime and the object would be invalid then, making the server crash)
    -- Instead, we need to look up both players by name:
    a_World:DoWithPlayer(SpectatorName,
      function (a_Spectator)  -- This function will be called and a_Spectator will be set to the cPlayer object of the spectator, *if* they exist
        a_World:DoWithPlayer(SpectatedName,
          function (a_Spectated)  -- This function will be called and a_Spectated will be set to the cPlayer object of the spectated player, *if* they exist
            local pos = a_Spectated:GetPosition()
            pos.y = pos.y + 2
            a_Spectator:TeleportToCoords(pos.x, pos.y, pos.z)
            a_World:ScheduleTask(NUM_TICKS, Callback)  -- re-schedule for after another 5 ticks
          end
        )  -- DoWithPlayer(SpectatedName)
      end
    )  -- DoWithPlayer(SpectatorName)
  end

  -- Schedule the callback to be called after NUM_TICKS ticks:
  a_World:ScheduleTask(NUM_TICKS, Callback)
end

Note that my code doesn't handle the end-of-spectating, that will need even more magic (a global table of who's spectating, g_Spectating[SpectatorName] = SpectatedName) and the end-spectate command writing into that table. Also I didn't test the code at all, it might not even run.
Reply
Thanks given by: jakibaki




Users browsing this thread: 3 Guest(s)