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) endFor 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. |