![]() |
|
What am I doing wrong? - Printable Version +- Cuberite Forum (https://forum.cuberite.org) +-- Forum: Plugins (https://forum.cuberite.org/forum-1.html) +--- Forum: Plugin Discussion (https://forum.cuberite.org/forum-8.html) +--- Thread: What am I doing wrong? (/thread-1463.html) |
What am I doing wrong? - jakibaki - 04-29-2014 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 :) RE: What am I doing wrong? - xoft - 04-29-2014 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. RE: What am I doing wrong? - worktycho - 04-29-2014 If you want to wait for a period use the MCServer API: cWorld:ScheduleTask(function,World) RE: What am I doing wrong? - jakibaki - 04-29-2014 Thank You so mutch ![]() That will help me fixing the problem RE: What am I doing wrong? - xoft - 04-29-2014 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. |