1
0

Merge branch 'master' into cmake

This commit is contained in:
Tycho Bickerstaff 2013-12-18 19:06:11 +00:00
commit e627f2f98c
53 changed files with 1357 additions and 312 deletions

View File

@ -1567,12 +1567,14 @@ a_Player:OpenWindow(Window);
AddFoodExhaustion = { Params = "Exhaustion", Return = "", Notes = "Adds the specified number to the food exhaustion. Only positive numbers expected." },
AddToGroup = { Params = "GroupName", Return = "", Notes = "Temporarily adds the player to the specified group. The assignment is lost when the player disconnects." },
CalcLevelFromXp = { Params = "XPAmount", Return = "number", Notes = "Returns the level which is reached with the specified amount of XP. Inverse of XpForLevel()." },
CanFly = { Return = "bool", Notes = "Returns if the player is able to fly." },
CanUseCommand = { Params = "Command", Return = "bool", Notes = "Returns true if the player is allowed to use the specified command." },
CloseWindow = { Params = "[CanRefuse]", Return = "", Notes = "Closes the currently open UI window. If CanRefuse is true (default), the window may refuse the closing." },
CloseWindowIfID = { Params = "WindowID, [CanRefuse]", Return = "", Notes = "Closes the currently open UI window if its ID matches the given ID. If CanRefuse is true (default), the window may refuse the closing." },
DeltaExperience = { Params = "DeltaXP", Return = "", Notes = "Adds or removes XP from the current XP amount. Won't allow XP to go negative. Returns the new experience, -1 on error (XP overflow)." },
Feed = { Params = "AddFood, AddSaturation", Return = "bool", Notes = "Tries to add the specified amounts to food level and food saturation level (only positive amounts expected). Returns true if player was hungry and the food was consumed, false if too satiated." },
FoodPoison = { Params = "NumTicks", Return = "", Notes = "Starts the food poisoning for the specified amount of ticks; if already foodpoisoned, sets FoodPoisonedTicksRemaining to the larger of the two" },
ForceSetSpeed = { Params = "{{Vector3d|Direction}}", Notes = "Forces the player to move to the given direction." },
GetAirLevel = { Params = "", Return = "number", Notes = "Returns the air level (number of ticks of air left)." },
GetClientHandle = { Params = "", Return = "{{cClientHandle}}", Notes = "Returns the client handle representing the player's connection. May be nil (AI players)." },
GetColor = { Return = "string", Notes = "Returns the full color code to be used for this player (based on the first group). Prefix player messages with this code." },
@ -1605,6 +1607,7 @@ a_Player:OpenWindow(Window);
HasPermission = { Params = "PermissionString", Return = "bool", Notes = "Returns true if the player has the specified permission" },
Heal = { Params = "HitPoints", Return = "", Notes = "Heals the player by the specified amount of HPs. Only positive amounts are expected. Sends a health update to the client." },
IsEating = { Params = "", Return = "bool", Notes = "Returns true if the player is currently eating the item in their hand." },
IsFlying = { Return = "bool", Notes = "Returns true if the player is flying." },
IsGameModeAdventure = { Params = "", Return = "bool", Notes = "Returns true if the player is in the gmAdventure gamemode, or has their gamemode unset and the world is a gmAdventure world." },
IsGameModeCreative = { Params = "", Return = "bool", Notes = "Returns true if the player is in the gmCreative gamemode, or has their gamemode unset and the world is a gmCreative world." },
IsGameModeSurvival = { Params = "", Return = "bool", Notes = "Returns true if the player is in the gmSurvival gamemode, or has their gamemode unset and the world is a gmSurvival world." },
@ -1621,8 +1624,10 @@ a_Player:OpenWindow(Window);
RemoveFromGroup = { Params = "GroupName", Return = "", Notes = "Temporarily removes the player from the specified group. This change is lost when the player disconnects." },
Respawn = { Params = "", Return = "", Notes = "Restores the health, extinguishes fire, makes visible and sends the Respawn packet." },
SendMessage = { Params = "MessageString", Return = "", Notes = "Sends the specified message to the player." },
SetCanFly = { Params = "CanFly", Notes = "Sets if the player can fly or not." },
SetCrouch = { Params = "IsCrouched", Return = "", Notes = "Sets the crouch state, broadcasts the change to other players." },
SetCurrentExperience = { Params = "XPAmount", Return = "", Notes = "Sets the current amount of experience (and indirectly, the XP level)." },
SetFlying = { Params = "IsFlying", Notes = "Sets if the player is flying or not." },
SetFoodExhaustionLevel = { Params = "ExhaustionLevel", Return = "", Notes = "Sets the food exhaustion to the specified level." },
SetFoodLevel = { Params = "FoodLevel", Return = "", Notes = "Sets the food level (number of half-drumsticks on-screen)" },
SetFoodPoisonedTicksRemaining = { Params = "FoodPoisonedTicksRemaining", Return = "", Notes = "Sets the number of ticks remaining for food poisoning. Doesn't send foodpoisoning effect to the client, use FoodPoison() for that." },
@ -2708,8 +2713,8 @@ end
"os",
"string",
"table",
"g_TrackedPages",
"g_Stats",
"g_TrackedPages",
},
IgnoreFunctions =
@ -2742,6 +2747,15 @@ end
"WriteStats",
},
IgnoreConstants =
{
"cChestEntity.__cBlockEntityWindowOwner__",
"cDropSpenserEntity.__cBlockEntityWindowOwner__",
"cFurnaceEntity.__cBlockEntityWindowOwner__",
"cHopperEntity.__cBlockEntityWindowOwner__",
"cLuaWindow.__cItemGrid__cListener__",
},
IgnoreVariables =
{
"__.*__", -- tolua exports multiple inheritance this way

View File

@ -700,6 +700,15 @@ function ReadDescriptions(a_API)
end
);
-- Remove ignored constants:
local NewConstants = {};
for j, cn in ipairs(cls.Constants) do
if (not(IsFunctionIgnored(cls.Name, cn.Name))) then
table.insert(NewConstants, cn);
end
end -- for j, cn
cls.Constants = NewConstants;
-- Sort the constants:
table.sort(cls.Constants,
function(c1, c2)
@ -707,7 +716,7 @@ function ReadDescriptions(a_API)
end
);
-- Remove ignored functions:
-- Remove ignored member variables:
local NewVariables = {};
for j, var in ipairs(cls.Variables) do
if (not(IsVariableIgnored(cls.Name .. "." .. var.Name))) then

View File

@ -2384,10 +2384,11 @@ bool cConnection::HandleServerStatusResponse(void)
Log(" Response: %s", Response.c_str());
// Modify the response to show that it's being proto-proxied:
size_t idx = Response.find("\"description\":\"");
const char DescSearch[] = "\"description\":{\"text\":\"";
size_t idx = Response.find(DescSearch);
if (idx != AString::npos)
{
Response.assign(Response.substr(0, idx + 15) + "ProtoProxy: " + Response.substr(idx + 15));
Response.assign(Response.substr(0, idx + sizeof(DescSearch) - 1) + "ProtoProxy: " + Response.substr(idx + sizeof(DescSearch) - 1));
}
cByteBuffer Packet(1000);
Packet.WriteVarInt(0); // Packet type - status response

View File

@ -37,6 +37,7 @@ $cfile "../Entities/Player.h"
$cfile "../Entities/Pickup.h"
$cfile "../Entities/ProjectileEntity.h"
$cfile "../Entities/TNTEntity.h"
$cfile "../Entities/Effects.h"
$cfile "../Server.h"
$cfile "../World.h"
$cfile "../Inventory.h"

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 12/14/13 16:22:45.
** Generated automatically by tolua++-1.0.92 on 12/18/13 16:09:11.
*/
#ifndef __cplusplus
@ -8,7 +8,7 @@
#endif
#include "string.h"
#include "tolua++/include/tolua++.h"
#include "tolua++.h"
/* Exported function */
TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S);
@ -35,6 +35,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S);
#include "../Entities/Pickup.h"
#include "../Entities/ProjectileEntity.h"
#include "../Entities/TNTEntity.h"
#include "../Entities/Effects.h"
#include "../Server.h"
#include "../World.h"
#include "../Inventory.h"
@ -219,45 +220,46 @@ static void tolua_reg_types (lua_State* tolua_S)
tolua_usertype(tolua_S,"cItemGrid");
tolua_usertype(tolua_S,"cHTTPServer::cCallbacks");
tolua_usertype(tolua_S,"cLuaWindow");
tolua_usertype(tolua_S,"cInventory");
tolua_usertype(tolua_S,"cServer");
tolua_usertype(tolua_S,"cHopperEntity");
tolua_usertype(tolua_S,"std::vector<AString>");
tolua_usertype(tolua_S,"cBlockEntityWithItems");
tolua_usertype(tolua_S,"cWindow");
tolua_usertype(tolua_S,"cBlockEntityWithItems");
tolua_usertype(tolua_S,"cCraftingGrid");
tolua_usertype(tolua_S,"cBlockArea");
tolua_usertype(tolua_S,"cGroup");
tolua_usertype(tolua_S,"cTracer");
tolua_usertype(tolua_S,"cItem");
tolua_usertype(tolua_S,"cBoundingBox");
tolua_usertype(tolua_S,"cItem");
tolua_usertype(tolua_S,"cCuboid");
tolua_usertype(tolua_S,"cArrowEntity");
tolua_usertype(tolua_S,"cDropSpenserEntity");
tolua_usertype(tolua_S,"cCuboid");
tolua_usertype(tolua_S,"Vector3i");
tolua_usertype(tolua_S,"Vector3d");
tolua_usertype(tolua_S,"cTNTEntity");
tolua_usertype(tolua_S,"cNoteEntity");
tolua_usertype(tolua_S,"cServer");
tolua_usertype(tolua_S,"cWebAdmin");
tolua_usertype(tolua_S,"cBlockEntity");
tolua_usertype(tolua_S,"cCriticalSection");
tolua_usertype(tolua_S,"HTTPTemplateRequest");
tolua_usertype(tolua_S,"cPickup");
tolua_usertype(tolua_S,"cItems");
tolua_usertype(tolua_S,"cClientHandle");
tolua_usertype(tolua_S,"cWebAdmin");
tolua_usertype(tolua_S,"cChatColor");
tolua_usertype(tolua_S,"HTTPRequest");
tolua_usertype(tolua_S,"cIniFile");
tolua_usertype(tolua_S,"cChatColor");
tolua_usertype(tolua_S,"HTTPFormData");
tolua_usertype(tolua_S,"cIniFile");
tolua_usertype(tolua_S,"cSignEntity");
tolua_usertype(tolua_S,"cDropperEntity");
tolua_usertype(tolua_S,"cPawn");
tolua_usertype(tolua_S,"cThrownEggEntity");
tolua_usertype(tolua_S,"cGroupManager");
tolua_usertype(tolua_S,"cBlockEntityWindowOwner");
tolua_usertype(tolua_S,"cPluginManager");
tolua_usertype(tolua_S,"cDropperEntity");
tolua_usertype(tolua_S,"cProjectileEntity");
tolua_usertype(tolua_S,"cItemGrid::cListener");
tolua_usertype(tolua_S,"cInventory");
tolua_usertype(tolua_S,"cPlayer");
tolua_usertype(tolua_S,"cTNTEntity");
}
/* method: new of class cIniFile */
@ -3278,6 +3280,23 @@ static int tolua_AllToLua_cLuaWindow_GetContents00(lua_State* tolua_S)
}
#endif //#ifndef TOLUA_DISABLE
/* get function: __cItemGrid of class cLuaWindow */
#ifndef TOLUA_DISABLE_tolua_get_cLuaWindow___cItemGrid__cListener__
static int tolua_get_cLuaWindow___cItemGrid__cListener__(lua_State* tolua_S)
{
cLuaWindow* self = (cLuaWindow*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable '__cItemGrid'",NULL);
#endif
#ifdef __cplusplus
tolua_pushusertype(tolua_S,(void*)static_cast<cItemGrid::cListener*>(self), "cItemGrid::cListener");
#else
tolua_pushusertype(tolua_S,(void*)((cItemGrid::cListener*)self), "cItemGrid::cListener");
#endif
return 1;
}
#endif //#ifndef TOLUA_DISABLE
/* function: BlockStringToType */
#ifndef TOLUA_DISABLE_tolua_AllToLua_BlockStringToType00
static int tolua_AllToLua_BlockStringToType00(lua_State* tolua_S)
@ -7425,6 +7444,41 @@ static int tolua_AllToLua_cEntity_AddSpeedZ00(lua_State* tolua_S)
}
#endif //#ifndef TOLUA_DISABLE
/* method: HandleSpeedFromAttachee of class cEntity */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_HandleSpeedFromAttachee00
static int tolua_AllToLua_cEntity_HandleSpeedFromAttachee00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) ||
!tolua_isnumber(tolua_S,2,0,&tolua_err) ||
!tolua_isnumber(tolua_S,3,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,4,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0);
float a_Forward = ((float) tolua_tonumber(tolua_S,2,0));
float a_Sideways = ((float) tolua_tonumber(tolua_S,3,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HandleSpeedFromAttachee'", NULL);
#endif
{
self->HandleSpeedFromAttachee(a_Forward,a_Sideways);
}
}
return 0;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'HandleSpeedFromAttachee'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: SteerVehicle of class cEntity */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SteerVehicle00
static int tolua_AllToLua_cEntity_SteerVehicle00(lua_State* tolua_S)
@ -9394,6 +9448,39 @@ static int tolua_AllToLua_cPlayer_GetIP00(lua_State* tolua_S)
}
#endif //#ifndef TOLUA_DISABLE
/* method: ForceSetSpeed of class cPlayer */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_ForceSetSpeed00
static int tolua_AllToLua_cPlayer_ForceSetSpeed00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
(tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3d",0,&tolua_err)) ||
!tolua_isnoobj(tolua_S,3,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
Vector3d a_Direction = *((Vector3d*) tolua_tousertype(tolua_S,2,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ForceSetSpeed'", NULL);
#endif
{
self->ForceSetSpeed(a_Direction);
}
}
return 0;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'ForceSetSpeed'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: MoveTo of class cPlayer */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_MoveTo00
static int tolua_AllToLua_cPlayer_MoveTo00(lua_State* tolua_S)
@ -10459,6 +10546,38 @@ static int tolua_AllToLua_cPlayer_IsEating00(lua_State* tolua_S)
}
#endif //#ifndef TOLUA_DISABLE
/* method: IsFlying of class cPlayer */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_IsFlying00
static int tolua_AllToLua_cPlayer_IsFlying00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"const cPlayer",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,2,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsFlying'", NULL);
#endif
{
bool tolua_ret = (bool) self->IsFlying();
tolua_pushboolean(tolua_S,(bool)tolua_ret);
}
}
return 1;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'IsFlying'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: Respawn of class cPlayer */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_Respawn00
static int tolua_AllToLua_cPlayer_Respawn00(lua_State* tolua_S)
@ -10848,6 +10967,72 @@ static int tolua_AllToLua_cPlayer_SetSprint00(lua_State* tolua_S)
}
#endif //#ifndef TOLUA_DISABLE
/* method: SetFlying of class cPlayer */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetFlying00
static int tolua_AllToLua_cPlayer_SetFlying00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
!tolua_isboolean(tolua_S,2,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,3,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
bool a_IsFlying = ((bool) tolua_toboolean(tolua_S,2,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetFlying'", NULL);
#endif
{
self->SetFlying(a_IsFlying);
}
}
return 0;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'SetFlying'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: SetCanFly of class cPlayer */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetCanFly00
static int tolua_AllToLua_cPlayer_SetCanFly00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
!tolua_isboolean(tolua_S,2,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,3,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
bool a_CanFly = ((bool) tolua_toboolean(tolua_S,2,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetCanFly'", NULL);
#endif
{
self->SetCanFly(a_CanFly);
}
}
return 0;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'SetCanFly'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: IsSwimming of class cPlayer */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_IsSwimming00
static int tolua_AllToLua_cPlayer_IsSwimming00(lua_State* tolua_S)
@ -10912,6 +11097,38 @@ static int tolua_AllToLua_cPlayer_IsSubmerged00(lua_State* tolua_S)
}
#endif //#ifndef TOLUA_DISABLE
/* method: CanFly of class cPlayer */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_CanFly00
static int tolua_AllToLua_cPlayer_CanFly00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"const cPlayer",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,2,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CanFly'", NULL);
#endif
{
bool tolua_ret = (bool) self->CanFly();
tolua_pushboolean(tolua_S,(bool)tolua_ret);
}
}
return 1;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'CanFly'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: new of class cPickup */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_new00
static int tolua_AllToLua_cPickup_new00(lua_State* tolua_S)
@ -18627,6 +18844,23 @@ static int tolua_AllToLua_cBlockEntityWithItems_GetContents00(lua_State* tolua_S
}
#endif //#ifndef TOLUA_DISABLE
/* get function: __cBlockEntityWindowOwner__ of class cChestEntity */
#ifndef TOLUA_DISABLE_tolua_get_cChestEntity___cBlockEntityWindowOwner__
static int tolua_get_cChestEntity___cBlockEntityWindowOwner__(lua_State* tolua_S)
{
cChestEntity* self = (cChestEntity*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable '__cBlockEntityWindowOwner__'",NULL);
#endif
#ifdef __cplusplus
tolua_pushusertype(tolua_S,(void*)static_cast<cBlockEntityWindowOwner*>(self), "cBlockEntityWindowOwner");
#else
tolua_pushusertype(tolua_S,(void*)((cBlockEntityWindowOwner*)self), "cBlockEntityWindowOwner");
#endif
return 1;
}
#endif //#ifndef TOLUA_DISABLE
/* method: AddDropSpenserDir of class cDropSpenserEntity */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cDropSpenserEntity_AddDropSpenserDir00
static int tolua_AllToLua_cDropSpenserEntity_AddDropSpenserDir00(lua_State* tolua_S)
@ -18733,6 +18967,23 @@ static int tolua_AllToLua_cDropSpenserEntity_SetRedstonePower00(lua_State* tolua
}
#endif //#ifndef TOLUA_DISABLE
/* get function: __cBlockEntityWindowOwner__ of class cDropSpenserEntity */
#ifndef TOLUA_DISABLE_tolua_get_cDropSpenserEntity___cBlockEntityWindowOwner__
static int tolua_get_cDropSpenserEntity___cBlockEntityWindowOwner__(lua_State* tolua_S)
{
cDropSpenserEntity* self = (cDropSpenserEntity*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable '__cBlockEntityWindowOwner__'",NULL);
#endif
#ifdef __cplusplus
tolua_pushusertype(tolua_S,(void*)static_cast<cBlockEntityWindowOwner*>(self), "cBlockEntityWindowOwner");
#else
tolua_pushusertype(tolua_S,(void*)((cBlockEntityWindowOwner*)self), "cBlockEntityWindowOwner");
#endif
return 1;
}
#endif //#ifndef TOLUA_DISABLE
/* method: GetInputSlot of class cFurnaceEntity */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cFurnaceEntity_GetInputSlot00
static int tolua_AllToLua_cFurnaceEntity_GetInputSlot00(lua_State* tolua_S)
@ -19056,6 +19307,40 @@ static int tolua_AllToLua_cFurnaceEntity_HasFuelTimeLeft00(lua_State* tolua_S)
}
#endif //#ifndef TOLUA_DISABLE
/* get function: __cBlockEntityWindowOwner__ of class cFurnaceEntity */
#ifndef TOLUA_DISABLE_tolua_get_cFurnaceEntity___cBlockEntityWindowOwner__
static int tolua_get_cFurnaceEntity___cBlockEntityWindowOwner__(lua_State* tolua_S)
{
cFurnaceEntity* self = (cFurnaceEntity*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable '__cBlockEntityWindowOwner__'",NULL);
#endif
#ifdef __cplusplus
tolua_pushusertype(tolua_S,(void*)static_cast<cBlockEntityWindowOwner*>(self), "cBlockEntityWindowOwner");
#else
tolua_pushusertype(tolua_S,(void*)((cBlockEntityWindowOwner*)self), "cBlockEntityWindowOwner");
#endif
return 1;
}
#endif //#ifndef TOLUA_DISABLE
/* get function: __cBlockEntityWindowOwner__ of class cHopperEntity */
#ifndef TOLUA_DISABLE_tolua_get_cHopperEntity___cBlockEntityWindowOwner__
static int tolua_get_cHopperEntity___cBlockEntityWindowOwner__(lua_State* tolua_S)
{
cHopperEntity* self = (cHopperEntity*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable '__cBlockEntityWindowOwner__'",NULL);
#endif
#ifdef __cplusplus
tolua_pushusertype(tolua_S,(void*)static_cast<cBlockEntityWindowOwner*>(self), "cBlockEntityWindowOwner");
#else
tolua_pushusertype(tolua_S,(void*)((cBlockEntityWindowOwner*)self), "cBlockEntityWindowOwner");
#endif
return 1;
}
#endif //#ifndef TOLUA_DISABLE
/* method: GetRecord of class cJukeboxEntity */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cJukeboxEntity_GetRecord00
static int tolua_AllToLua_cJukeboxEntity_GetRecord00(lua_State* tolua_S)
@ -29860,7 +30145,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"HOOK_COLLECTING_PICKUP",cPluginManager::HOOK_COLLECTING_PICKUP);
tolua_constant(tolua_S,"HOOK_CRAFTING_NO_RECIPE",cPluginManager::HOOK_CRAFTING_NO_RECIPE);
tolua_constant(tolua_S,"HOOK_DISCONNECT",cPluginManager::HOOK_DISCONNECT);
tolua_constant(tolua_S,"HOOK_ENTITY_ANIMATION",cPluginManager::HOOK_ENTITY_ANIMATION);
tolua_constant(tolua_S,"HOOK_PLAYER_ANIMATION",cPluginManager::HOOK_PLAYER_ANIMATION);
tolua_constant(tolua_S,"HOOK_EXECUTE_COMMAND",cPluginManager::HOOK_EXECUTE_COMMAND);
tolua_constant(tolua_S,"HOOK_EXPLODED",cPluginManager::HOOK_EXPLODED);
tolua_constant(tolua_S,"HOOK_EXPLODING",cPluginManager::HOOK_EXPLODING);
@ -29946,6 +30231,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_function(tolua_S,".call",tolua_AllToLua_cLuaWindow_new00_local);
tolua_function(tolua_S,"delete",tolua_AllToLua_cLuaWindow_delete00);
tolua_function(tolua_S,"GetContents",tolua_AllToLua_cLuaWindow_GetContents00);
tolua_variable(tolua_S,"__cItemGrid__cListener__",tolua_get_cLuaWindow___cItemGrid__cListener__,NULL);
tolua_endmodule(tolua_S);
tolua_constant(tolua_S,"E_BLOCK_AIR",E_BLOCK_AIR);
tolua_constant(tolua_S,"E_BLOCK_STONE",E_BLOCK_STONE);
@ -30876,6 +31162,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_function(tolua_S,"AddSpeedX",tolua_AllToLua_cEntity_AddSpeedX00);
tolua_function(tolua_S,"AddSpeedY",tolua_AllToLua_cEntity_AddSpeedY00);
tolua_function(tolua_S,"AddSpeedZ",tolua_AllToLua_cEntity_AddSpeedZ00);
tolua_function(tolua_S,"HandleSpeedFromAttachee",tolua_AllToLua_cEntity_HandleSpeedFromAttachee00);
tolua_function(tolua_S,"SteerVehicle",tolua_AllToLua_cEntity_SteerVehicle00);
tolua_function(tolua_S,"GetUniqueID",tolua_AllToLua_cEntity_GetUniqueID00);
tolua_function(tolua_S,"IsDestroyed",tolua_AllToLua_cEntity_IsDestroyed00);
@ -30945,6 +31232,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_function(tolua_S,"IsGameModeSurvival",tolua_AllToLua_cPlayer_IsGameModeSurvival00);
tolua_function(tolua_S,"IsGameModeAdventure",tolua_AllToLua_cPlayer_IsGameModeAdventure00);
tolua_function(tolua_S,"GetIP",tolua_AllToLua_cPlayer_GetIP00);
tolua_function(tolua_S,"ForceSetSpeed",tolua_AllToLua_cPlayer_ForceSetSpeed00);
tolua_function(tolua_S,"MoveTo",tolua_AllToLua_cPlayer_MoveTo00);
tolua_function(tolua_S,"GetWindow",tolua_AllToLua_cPlayer_GetWindow00);
tolua_function(tolua_S,"CloseWindow",tolua_AllToLua_cPlayer_CloseWindow00);
@ -30977,6 +31265,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_function(tolua_S,"AddFoodExhaustion",tolua_AllToLua_cPlayer_AddFoodExhaustion00);
tolua_function(tolua_S,"FoodPoison",tolua_AllToLua_cPlayer_FoodPoison00);
tolua_function(tolua_S,"IsEating",tolua_AllToLua_cPlayer_IsEating00);
tolua_function(tolua_S,"IsFlying",tolua_AllToLua_cPlayer_IsFlying00);
tolua_function(tolua_S,"Respawn",tolua_AllToLua_cPlayer_Respawn00);
tolua_function(tolua_S,"SetVisible",tolua_AllToLua_cPlayer_SetVisible00);
tolua_function(tolua_S,"IsVisible",tolua_AllToLua_cPlayer_IsVisible00);
@ -30989,8 +31278,11 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_function(tolua_S,"SetSprintingMaxSpeed",tolua_AllToLua_cPlayer_SetSprintingMaxSpeed00);
tolua_function(tolua_S,"SetCrouch",tolua_AllToLua_cPlayer_SetCrouch00);
tolua_function(tolua_S,"SetSprint",tolua_AllToLua_cPlayer_SetSprint00);
tolua_function(tolua_S,"SetFlying",tolua_AllToLua_cPlayer_SetFlying00);
tolua_function(tolua_S,"SetCanFly",tolua_AllToLua_cPlayer_SetCanFly00);
tolua_function(tolua_S,"IsSwimming",tolua_AllToLua_cPlayer_IsSwimming00);
tolua_function(tolua_S,"IsSubmerged",tolua_AllToLua_cPlayer_IsSubmerged00);
tolua_function(tolua_S,"CanFly",tolua_AllToLua_cPlayer_CanFly00);
tolua_endmodule(tolua_S);
#ifdef __cplusplus
tolua_cclass(tolua_S,"cPickup","cPickup","cEntity",tolua_collect_cPickup);
@ -31064,6 +31356,29 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_function(tolua_S,"GetCounterTime",tolua_AllToLua_cTNTEntity_GetCounterTime00);
tolua_function(tolua_S,"GetMaxFuseTime",tolua_AllToLua_cTNTEntity_GetMaxFuseTime00);
tolua_endmodule(tolua_S);
tolua_constant(tolua_S,"E_EFFECT_SPEED",E_EFFECT_SPEED);
tolua_constant(tolua_S,"E_EFFECT_SLOWNESS",E_EFFECT_SLOWNESS);
tolua_constant(tolua_S,"E_EFFECT_HASTE",E_EFFECT_HASTE);
tolua_constant(tolua_S,"E_EFFECT_MINING_FATIGUE",E_EFFECT_MINING_FATIGUE);
tolua_constant(tolua_S,"E_EFFECT_STENGTH",E_EFFECT_STENGTH);
tolua_constant(tolua_S,"E_EFFECT_INSTANT_HEALTH",E_EFFECT_INSTANT_HEALTH);
tolua_constant(tolua_S,"E_EFFECT_INSTANT_DAMAGE",E_EFFECT_INSTANT_DAMAGE);
tolua_constant(tolua_S,"E_EFFECT_JUMP_BOOST",E_EFFECT_JUMP_BOOST);
tolua_constant(tolua_S,"E_EFFECT_NAUSEA",E_EFFECT_NAUSEA);
tolua_constant(tolua_S,"E_EFFECT_REGENERATION",E_EFFECT_REGENERATION);
tolua_constant(tolua_S,"E_EFFECT_RESISTANCE",E_EFFECT_RESISTANCE);
tolua_constant(tolua_S,"E_EFFECT_FIRE_RESISTANCE",E_EFFECT_FIRE_RESISTANCE);
tolua_constant(tolua_S,"E_EFFECT_WATER_BREATHING",E_EFFECT_WATER_BREATHING);
tolua_constant(tolua_S,"E_EFFECT_INVISIBILITY",E_EFFECT_INVISIBILITY);
tolua_constant(tolua_S,"E_EFFECT_BLINDNESS",E_EFFECT_BLINDNESS);
tolua_constant(tolua_S,"E_EFFECT_NIGHT_VISION",E_EFFECT_NIGHT_VISION);
tolua_constant(tolua_S,"E_EFFECT_HUNGER",E_EFFECT_HUNGER);
tolua_constant(tolua_S,"E_EFFECT_WEAKNESS",E_EFFECT_WEAKNESS);
tolua_constant(tolua_S,"E_EFFECT_POISON",E_EFFECT_POISON);
tolua_constant(tolua_S,"E_EFFECT_WITHER",E_EFFECT_WITHER);
tolua_constant(tolua_S,"E_EFFECT_HEALTH_BOOST",E_EFFECT_HEALTH_BOOST);
tolua_constant(tolua_S,"E_EFFECT_ABSORPTION",E_EFFECT_ABSORPTION);
tolua_constant(tolua_S,"E_EFFECT_SATURATION",E_EFFECT_SATURATION);
tolua_cclass(tolua_S,"cServer","cServer","",NULL);
tolua_beginmodule(tolua_S,"cServer");
tolua_function(tolua_S,"GetDescription",tolua_AllToLua_cServer_GetDescription00);
@ -31357,6 +31672,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_beginmodule(tolua_S,"cChestEntity");
tolua_constant(tolua_S,"ContentsHeight",cChestEntity::ContentsHeight);
tolua_constant(tolua_S,"ContentsWidth",cChestEntity::ContentsWidth);
tolua_variable(tolua_S,"__cBlockEntityWindowOwner__",tolua_get_cChestEntity___cBlockEntityWindowOwner__,NULL);
tolua_endmodule(tolua_S);
tolua_cclass(tolua_S,"cDropSpenserEntity","cDropSpenserEntity","cBlockEntityWithItems",NULL);
tolua_beginmodule(tolua_S,"cDropSpenserEntity");
@ -31365,6 +31681,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_function(tolua_S,"AddDropSpenserDir",tolua_AllToLua_cDropSpenserEntity_AddDropSpenserDir00);
tolua_function(tolua_S,"Activate",tolua_AllToLua_cDropSpenserEntity_Activate00);
tolua_function(tolua_S,"SetRedstonePower",tolua_AllToLua_cDropSpenserEntity_SetRedstonePower00);
tolua_variable(tolua_S,"__cBlockEntityWindowOwner__",tolua_get_cDropSpenserEntity___cBlockEntityWindowOwner__,NULL);
tolua_endmodule(tolua_S);
tolua_cclass(tolua_S,"cDispenserEntity","cDispenserEntity","cDropSpenserEntity",NULL);
tolua_beginmodule(tolua_S,"cDispenserEntity");
@ -31389,12 +31706,14 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_function(tolua_S,"GetCookTimeLeft",tolua_AllToLua_cFurnaceEntity_GetCookTimeLeft00);
tolua_function(tolua_S,"GetFuelBurnTimeLeft",tolua_AllToLua_cFurnaceEntity_GetFuelBurnTimeLeft00);
tolua_function(tolua_S,"HasFuelTimeLeft",tolua_AllToLua_cFurnaceEntity_HasFuelTimeLeft00);
tolua_variable(tolua_S,"__cBlockEntityWindowOwner__",tolua_get_cFurnaceEntity___cBlockEntityWindowOwner__,NULL);
tolua_endmodule(tolua_S);
tolua_cclass(tolua_S,"cHopperEntity","cHopperEntity","cBlockEntityWithItems",NULL);
tolua_beginmodule(tolua_S,"cHopperEntity");
tolua_constant(tolua_S,"ContentsHeight",cHopperEntity::ContentsHeight);
tolua_constant(tolua_S,"ContentsWidth",cHopperEntity::ContentsWidth);
tolua_constant(tolua_S,"TICKS_PER_TRANSFER",cHopperEntity::TICKS_PER_TRANSFER);
tolua_variable(tolua_S,"__cBlockEntityWindowOwner__",tolua_get_cHopperEntity___cBlockEntityWindowOwner__,NULL);
tolua_endmodule(tolua_S);
tolua_cclass(tolua_S,"cJukeboxEntity","cJukeboxEntity","cBlockEntity",NULL);
tolua_beginmodule(tolua_S,"cJukeboxEntity");

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 12/14/13 16:22:46.
** Generated automatically by tolua++-1.0.92 on 12/18/13 16:09:11.
*/
/* Exported function */

View File

@ -33,10 +33,10 @@ Additionally, to forbid Lua from deleting this object while it is used by player
cPlayer:OpenWindow check if the window is of this class, and if so, make a global Lua reference for this object.
This reference needs to be unreferenced in the Destroy() function.
*/
class cLuaWindow : // tolua_export
public cItemGrid::cListener,
// tolua_begin
public cWindow
// tolua_begin
class cLuaWindow :
public cWindow,
public cItemGrid::cListener
{
typedef cWindow super;

View File

@ -18,6 +18,7 @@
#include "../BlockEntities/DropperEntity.h"
#include "../BlockEntities/FurnaceEntity.h"
#include "../BlockEntities/HopperEntity.h"
#include "../BlockEntities/NoteEntity.h"
#include "md5/md5.h"
#include "../LineBlockTracer.h"
@ -2217,6 +2218,7 @@ void ManualBindings::Bind(lua_State * tolua_S)
tolua_function(tolua_S, "DoWithDropperAt", tolua_DoWithXYZ<cWorld, cDropperEntity, &cWorld::DoWithDropperAt>);
tolua_function(tolua_S, "DoWithEntityByID", tolua_DoWithID< cWorld, cEntity, &cWorld::DoWithEntityByID>);
tolua_function(tolua_S, "DoWithFurnaceAt", tolua_DoWithXYZ<cWorld, cFurnaceEntity, &cWorld::DoWithFurnaceAt>);
tolua_function(tolua_S, "DoWithNoteBlockAt", tolua_DoWithXYZ<cWorld, cNoteEntity, &cWorld::DoWithNoteBlockAt>);
tolua_function(tolua_S, "DoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::DoWithPlayer>);
tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::FindAndDoWithPlayer>);
tolua_function(tolua_S, "ForEachBlockEntityInChunk", tolua_ForEachInChunk<cWorld, cBlockEntity, &cWorld::ForEachBlockEntityInChunk>);

View File

@ -64,7 +64,7 @@ public:
virtual bool OnHopperPushingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum) = 0;
virtual bool OnKilling (cEntity & a_Victim, cEntity * a_Killer) = 0;
virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) = 0;
virtual bool OnEntityAnimation (cEntity & a_Entity, int a_Animation) = 0;
virtual bool OnPlayerAnimation (cPlayer & a_Player, int a_Animation) = 0;
virtual bool OnPlayerBreakingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0;
virtual bool OnPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0;
virtual bool OnPlayerEating (cPlayer & a_Player) = 0;

View File

@ -550,14 +550,14 @@ bool cPluginLua::OnLogin(cClientHandle * a_Client, int a_ProtocolVersion, const
bool cPluginLua::OnEntityAnimation(cEntity & a_Entity, int a_Animation)
bool cPluginLua::OnPlayerAnimation(cPlayer & a_Player, int a_Animation)
{
cCSLock Lock(m_CriticalSection);
bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_ENTITY_ANIMATION];
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLAYER_ANIMATION];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{
m_LuaState.Call((int)(**itr), &a_Entity, a_Animation, cLuaState::Return, res);
m_LuaState.Call((int)(**itr), &a_Player, a_Animation, cLuaState::Return, res);
if (res)
{
return true;
@ -1302,7 +1302,7 @@ const char * cPluginLua::GetHookFnName(int a_HookType)
case cPluginManager::HOOK_COLLECTING_PICKUP: return "OnCollectingPickup";
case cPluginManager::HOOK_CRAFTING_NO_RECIPE: return "OnCraftingNoRecipe";
case cPluginManager::HOOK_DISCONNECT: return "OnDisconnect";
case cPluginManager::HOOK_ENTITY_ANIMATION: return "OnEntityAnimation";
case cPluginManager::HOOK_PLAYER_ANIMATION: return "OnPlayerAnimation";
case cPluginManager::HOOK_EXECUTE_COMMAND: return "OnExecuteCommand";
case cPluginManager::HOOK_HANDSHAKE: return "OnHandshake";
case cPluginManager::HOOK_KILLING: return "OnKilling";

View File

@ -61,7 +61,7 @@ public:
virtual bool OnHopperPushingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum) override;
virtual bool OnKilling (cEntity & a_Victim, cEntity * a_Killer) override;
virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) override;
virtual bool OnEntityAnimation (cEntity & a_Entity, int a_Animation) override;
virtual bool OnPlayerAnimation (cPlayer & a_Player, int a_Animation) override;
virtual bool OnPlayerBreakingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
virtual bool OnPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
virtual bool OnPlayerEating (cPlayer & a_Player) override;

View File

@ -602,16 +602,16 @@ bool cPluginManager::CallHookLogin(cClientHandle * a_Client, int a_ProtocolVersi
bool cPluginManager::CallHookEntityAnimation(cEntity & a_Entity, int a_Animation)
bool cPluginManager::CallHookPlayerAnimation(cPlayer & a_Player, int a_Animation)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_ENTITY_ANIMATION);
HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_ANIMATION);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnEntityAnimation(a_Entity, a_Animation))
if ((*itr)->OnPlayerAnimation(a_Player, a_Animation))
{
return true;
}

View File

@ -68,7 +68,7 @@ public: // tolua_export
HOOK_COLLECTING_PICKUP,
HOOK_CRAFTING_NO_RECIPE,
HOOK_DISCONNECT,
HOOK_ENTITY_ANIMATION,
HOOK_PLAYER_ANIMATION,
HOOK_EXECUTE_COMMAND,
HOOK_EXPLODED,
HOOK_EXPLODING,
@ -163,7 +163,7 @@ public: // tolua_export
bool CallHookHopperPushingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum);
bool CallHookKilling (cEntity & a_Victim, cEntity * a_Killer);
bool CallHookLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username);
bool CallHookEntityAnimation (cEntity & a_Entity, int a_Animation);
bool CallHookPlayerAnimation (cPlayer & a_Player, int a_Animation);
bool CallHookPlayerBreakingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
bool CallHookPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
bool CallHookPlayerEating (cPlayer & a_Player);

13
src/Bindings/tolua++.h Normal file
View File

@ -0,0 +1,13 @@
// tolua++.h
// Redirection file, needed because ToLua++ generates the Bindings.cpp file with >> #include "tolua++.h" <<
#include "tolua++/include/tolua++.h"

View File

@ -161,6 +161,9 @@ static void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBB
// cBlockArea:
cBlockArea::cBlockArea(void) :
m_OriginX(0),
m_OriginY(0),
m_OriginZ(0),
m_SizeX(0),
m_SizeY(0),
m_SizeZ(0),
@ -190,6 +193,9 @@ void cBlockArea::Clear(void)
delete[] m_BlockMetas; m_BlockMetas = NULL;
delete[] m_BlockLight; m_BlockLight = NULL;
delete[] m_BlockSkyLight; m_BlockSkyLight = NULL;
m_OriginX = 0;
m_OriginY = 0;
m_OriginZ = 0;
m_SizeX = 0;
m_SizeY = 0;
m_SizeZ = 0;

View File

@ -21,10 +21,10 @@ class cNBTData;
class cChestEntity : // tolua_export
public cBlockEntityWindowOwner,
// tolua_begin
public cBlockEntityWithItems
// tolua_begin
class cChestEntity :
public cBlockEntityWithItems,
public cBlockEntityWindowOwner
{
typedef cBlockEntityWithItems super;

View File

@ -29,10 +29,10 @@ class cServer;
class cDropSpenserEntity : // tolua_export
public cBlockEntityWindowOwner,
// tolua_begin
public cBlockEntityWithItems
// tolua_begin
class cDropSpenserEntity :
public cBlockEntityWithItems,
public cBlockEntityWindowOwner
{
typedef cBlockEntityWithItems super;

View File

@ -21,10 +21,10 @@ class cNBTData;
class cEnderChestEntity : // tolua_export
public cBlockEntityWindowOwner,
// tolua_begin
public cBlockEntityWithItems
// tolua_begin
class cEnderChestEntity :
public cBlockEntityWithItems,
public cBlockEntityWindowOwner
{
typedef cBlockEntityWithItems super;

View File

@ -21,10 +21,10 @@ class cServer;
class cFurnaceEntity : // tolua_export
public cBlockEntityWindowOwner,
// tolua_begin
public cBlockEntityWithItems
// tolua_begin
class cFurnaceEntity :
public cBlockEntityWithItems,
public cBlockEntityWindowOwner
{
typedef cBlockEntityWithItems super;

View File

@ -16,10 +16,10 @@
class cHopperEntity : // tolua_export
public cBlockEntityWindowOwner,
// tolua_begin
public cBlockEntityWithItems
// tolua_begin
class cHopperEntity :
public cBlockEntityWithItems,
public cBlockEntityWindowOwner
{
typedef cBlockEntityWithItems super;

View File

@ -40,6 +40,7 @@
#include "BlockMelon.h"
#include "BlockMushroom.h"
#include "BlockMycelium.h"
#include "BlockNetherWart.h"
#include "BlockNote.h"
#include "BlockOre.h"
#include "BlockPiston.h"
@ -160,6 +161,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_MYCELIUM: return new cBlockMyceliumHandler (a_BlockType);
case E_BLOCK_NETHER_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_NETHER_PORTAL: return new cBlockPortalHandler (a_BlockType);
case E_BLOCK_NETHER_WART: return new cBlockNetherWartHandler (a_BlockType);
case E_BLOCK_NOTE_BLOCK: return new cBlockNoteHandler (a_BlockType);
case E_BLOCK_PISTON: return new cBlockPistonHandler (a_BlockType);
case E_BLOCK_PISTON_EXTENSION: return new cBlockPistonHeadHandler ( );

View File

@ -0,0 +1,52 @@
#pragma once
#include "BlockHandler.h"
#include "../MersenneTwister.h"
#include "../World.h"
/// Common class that takes care of carrots, potatoes and wheat
class cBlockNetherWartHandler :
public cBlockHandler
{
public:
cBlockNetherWartHandler(BLOCKTYPE a_BlockType)
: cBlockHandler(a_BlockType)
{
}
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_Meta) override
{
MTRand rand;
if (a_Meta == 0x7)
{
// Is fully grown, drop the entire produce:
a_Pickups.push_back(cItem(E_ITEM_NETHER_WART, 1 + (int)(rand.randInt(2) + rand.randInt(2)) / 2, 0));
}
else
{
a_Pickups.push_back(cItem(E_ITEM_NETHER_WART));
}
}
void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
{
NIBBLETYPE Meta = a_Chunk.GetMeta (a_RelX, a_RelY, a_RelZ);
if (Meta < 7)
{
a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_NETHER_WART, ++Meta);
}
}
virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) == E_BLOCK_SOULSAND));
}
} ;

View File

@ -2225,6 +2225,38 @@ bool cChunk::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceC
bool cChunk::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback)
{
// The blockentity list is locked by the parent chunkmap's CS
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(), itr2 = itr; itr != m_BlockEntities.end(); itr = itr2)
{
++itr2;
if (((*itr)->GetPosX() != a_BlockX) || ((*itr)->GetPosY() != a_BlockY) || ((*itr)->GetPosZ() != a_BlockZ))
{
continue;
}
if ((*itr)->GetBlockType() != E_BLOCK_NOTE_BLOCK)
{
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
return false;
}
// The correct block entity is here,
if (a_Callback.Item((cNoteEntity *)*itr))
{
return false;
}
return true;
} // for itr - m_BlockEntitites[]
// Not found:
return false;
}
bool cChunk::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4)
{
// The blockentity list is locked by the parent chunkmap's CS
@ -2557,6 +2589,22 @@ void cChunk::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandl
void cChunk::BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude)
{
for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr )
{
if (*itr == a_Exclude)
{
continue;
}
(*itr)->SendEntityEffect(a_Entity, a_EffectID, a_Amplifier, a_Duration);
} // for itr - LoadedByClient[]
}
void cChunk::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude)
{
for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr )
@ -2701,6 +2749,22 @@ void cChunk::BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation
void cChunk::BroadcastRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude)
{
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr )
{
if (*itr == a_Exclude)
{
continue;
}
(*itr)->SendRemoveEntityEffect(a_Entity, a_EffectID);
} // for itr - LoadedByClient[]
}
void cChunk::BroadcastSoundEffect(const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude)
{
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr )

View File

@ -35,7 +35,6 @@ namespace Json
class cWorld;
class cFurnaceEntity;
class cClientHandle;
class cServer;
class MTRand;
@ -44,6 +43,7 @@ class cChunkMap;
class cChestEntity;
class cDispenserEntity;
class cFurnaceEntity;
class cNoteEntity;
class cBlockArea;
class cPawn;
class cPickup;
@ -58,6 +58,7 @@ typedef cItemCallback<cEntity> cEntityCallback;
typedef cItemCallback<cChestEntity> cChestCallback;
typedef cItemCallback<cDispenserEntity> cDispenserCallback;
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
typedef cItemCallback<cNoteEntity> cNoteBlockCallback;
@ -246,6 +247,9 @@ public:
/// Calls the callback for the furnace at the specified coords; returns false if there's no furnace at those coords or callback returns true, returns true if found
bool DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback); // Lua-accessible
/// Calls the callback for the noteblock at the specified coords; returns false if there's no noteblock at those coords or callback returns true, returns true if found
bool DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback);
/// Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found
bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Lua-accessible
@ -263,6 +267,7 @@ public:
void BroadcastChunkData (cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL);
void BroadcastCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL);
void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
@ -272,6 +277,7 @@ public:
void BroadcastEntityStatus (const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityAnimation (const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL);
void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL);
void BroadcastSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL); // a_Src coords are Block * 8
void BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = NULL);
void BroadcastSpawnEntity (cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);

View File

@ -445,6 +445,22 @@ void cChunkMap::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHa
void cChunkMap::BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude)
{
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ());
if (Chunk == NULL)
{
return;
}
// It's perfectly legal to broadcast packets even to invalid chunks!
Chunk->BroadcastEntityEffect(a_Entity, a_EffectID, a_Amplifier, a_Duration);
}
void cChunkMap::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude)
{
cCSLock Lock(m_CSLayers);
@ -589,6 +605,23 @@ void cChunkMap::BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animat
void cChunkMap::BroadcastRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude)
{
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ());
if (Chunk == NULL)
{
return;
}
// It's perfectly legal to broadcast packets even to invalid chunks!
Chunk->BroadcastRemoveEntityEffect(a_Entity, a_EffectID, a_Exclude);
}
void cChunkMap::BroadcastSoundEffect(const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude)
{
cCSLock Lock(m_CSLayers);
@ -1899,6 +1932,23 @@ bool cChunkMap::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurna
bool cChunkMap::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback)
{
int ChunkX, ChunkZ;
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
if ((Chunk == NULL) && !Chunk->IsValid())
{
return false;
}
return Chunk->DoWithNoteBlockAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
}
bool cChunkMap::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4)
{

View File

@ -22,6 +22,7 @@ class cDispenserEntity;
class cDropperEntity;
class cDropSpenserEntity;
class cFurnaceEntity;
class cNoteEntity;
class cPawn;
class cPickup;
class cChunkDataSerializer;
@ -38,6 +39,7 @@ typedef cItemCallback<cDispenserEntity> cDispenserCallback;
typedef cItemCallback<cDropperEntity> cDropperCallback;
typedef cItemCallback<cDropSpenserEntity> cDropSpenserCallback;
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
typedef cItemCallback<cNoteEntity> cNoteBlockCallback;
typedef cItemCallback<cChunk> cChunkCallback;
@ -62,6 +64,7 @@ public:
void BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL);
void BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL);
void BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityHeadLook(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityLook(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
@ -71,6 +74,7 @@ public:
void BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityVelocity(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL);
void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL);
void BroadcastSoundEffect(const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL); // a_Src coords are Block * 8
void BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = NULL);
void BroadcastSpawnEntity(cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
@ -228,6 +232,9 @@ public:
/// Calls the callback for the furnace at the specified coords; returns false if there's no furnace at those coords or callback returns true, returns true if found
bool DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback); // Lua-accessible
/// Calls the callback for the noteblock at the specified coords; returns false if there's no noteblock at those coords or callback returns true, returns true if found
bool DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback); // Lua-accessible
/// Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found
bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Lua-accessible

View File

@ -270,9 +270,6 @@ void cClientHandle::Authenticate(void)
m_Player->Initialize(World);
m_State = csAuthenticated;
// Broadcast this player's spawning to all other players in the same chunk
m_Player->GetWorld()->BroadcastSpawnEntity(*m_Player, this);
cRoot::Get()->GetPluginManager()->CallHookPlayerSpawned(*m_Player);
}
@ -490,6 +487,16 @@ void cClientHandle::HandleCreativeInventory(short a_SlotNum, const cItem & a_Hel
void cClientHandle::HandlePlayerAbilities(bool a_CanFly, bool a_IsFlying, float FlyingSpeed, float WalkingSpeed)
{
m_Player->SetCanFly(a_CanFly);
m_Player->SetFlying(a_IsFlying);
}
void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ, double a_Stance, bool a_IsOnGround)
{
if ((m_Player == NULL) || (m_State != csPlaying))
@ -1053,7 +1060,7 @@ void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_
void cClientHandle::HandleAnimation(char a_Animation)
{
if (cPluginManager::Get()->CallHookEntityAnimation(*m_Player, a_Animation))
if (cPluginManager::Get()->CallHookPlayerAnimation(*m_Player, a_Animation))
{
// Plugin disagrees, bail out
return;
@ -1469,12 +1476,6 @@ void cClientHandle::Tick(float a_Dt)
}
m_Protocol->DataReceived(IncomingData.data(), IncomingData.size());
if (m_State == csAuthenticated)
{
StreamChunks();
m_State = csDownloadingWorld;
}
m_TimeSinceLastPacket += a_Dt;
if (m_TimeSinceLastPacket > 30000.f) // 30 seconds time-out
{
@ -1488,13 +1489,8 @@ void cClientHandle::Tick(float a_Dt)
}
// If the chunk the player's in was just sent, spawn the player:
if (m_HasSentPlayerChunk && (m_State != csPlaying) && !IsDestroying())
if (m_HasSentPlayerChunk && (m_State == csDownloadingWorld))
{
if (!cRoot::Get()->GetPluginManager()->CallHookPlayerJoined(*m_Player))
{
// Broadcast that this player has joined the game! Yay~
m_Player->GetWorld()->BroadcastChat(m_Username + " joined the game!", this);
}
m_Protocol->SendPlayerMoveLook();
m_State = csPlaying;
}
@ -1534,6 +1530,49 @@ void cClientHandle::Tick(float a_Dt)
void cClientHandle::ServerTick(float a_Dt)
{
// Handle clients that are waiting for final close while destroyed:
if (m_State == csDestroyedWaiting)
{
// Do not wait while the client is not in the world, simply cut them off.
m_State = csDestroyed;
return;
}
// Process received network data:
AString IncomingData;
{
cCSLock Lock(m_CSIncomingData);
std::swap(IncomingData, m_IncomingData);
}
m_Protocol->DataReceived(IncomingData.data(), IncomingData.size());
if (m_State == csAuthenticated)
{
StreamChunks();
// Remove the client handle from the server, it will be ticked from its cPlayer object from now on
cRoot::Get()->GetServer()->ClientMovedToWorld(this);
// Add the player to the world (start ticking from there):
m_State = csDownloadingWorld;
m_Player->GetWorld()->AddPlayer(m_Player);
return;
}
m_TimeSinceLastPacket += a_Dt;
if (m_TimeSinceLastPacket > 30000.f) // 30 seconds time-out
{
SendDisconnect("Nooooo!! You timed out! D: Come back!");
Destroy();
}
}
void cClientHandle::SendAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle)
{
m_Protocol->SendAttachEntity(a_Entity, a_Vehicle);
@ -1673,6 +1712,15 @@ void cClientHandle::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ)
void cClientHandle::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration)
{
m_Protocol->SendEntityEffect(a_Entity, a_EffectID, a_Amplifier, a_Duration);
}
void cClientHandle::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item)
{
m_Protocol->SendEntityEquipment(a_Entity, a_SlotNum, a_Item);
@ -1746,8 +1794,6 @@ void cClientHandle::SendEntityStatus(const cEntity & a_Entity, char a_Status)
void cClientHandle::SendEntityVelocity(const cEntity & a_Entity)
{
ASSERT(a_Entity.GetUniqueID() != m_Player->GetUniqueID()); // Must not send for self
m_Protocol->SendEntityVelocity(a_Entity);
}
@ -1822,6 +1868,15 @@ void cClientHandle::SendEntityAnimation(const cEntity & a_Entity, char a_Animati
void cClientHandle::SendPlayerAbilities()
{
m_Protocol->SendPlayerAbilities();
}
void cClientHandle::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline)
{
m_Protocol->SendPlayerListItem(a_Player, a_IsOnline);
@ -1882,6 +1937,15 @@ void cClientHandle::SendPlayerSpawn(const cPlayer & a_Player)
void cClientHandle::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID)
{
m_Protocol->SendRemoveEntityEffect(a_Entity, a_EffectID);
}
void cClientHandle::SendRespawn(void)
{
m_Protocol->SendRespawn();

View File

@ -29,7 +29,6 @@ class cExpOrb;
class cPickup;
class cPlayer;
class cProtocol;
class cRedstone;
class cWindow;
class cFallingBlock;
class cItemHandler;
@ -79,7 +78,11 @@ public:
inline bool IsLoggedIn(void) const { return (m_State >= csAuthenticating); }
/// Called while the client is being ticked from the world via its cPlayer object
void Tick(float a_Dt);
/// Called while the client is being ticked from the cServer object
void ServerTick(float a_Dt);
void Destroy(void);
@ -100,6 +103,7 @@ public:
void SendDestroyEntity (const cEntity & a_Entity);
void SendDisconnect (const AString & a_Reason);
void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ);
void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration);
void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item);
void SendEntityHeadLook (const cEntity & a_Entity);
void SendEntityLook (const cEntity & a_Entity);
@ -115,11 +119,13 @@ public:
void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item);
void SendPickupSpawn (const cPickup & a_Pickup);
void SendEntityAnimation (const cEntity & a_Entity, char a_Animation);
void SendPlayerAbilities (void);
void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline);
void SendPlayerMaxSpeed (void); ///< Informs the client of the maximum player speed (1.6.1+)
void SendPlayerMoveLook (void);
void SendPlayerPosition (void);
void SendPlayerSpawn (const cPlayer & a_Player);
void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID);
void SendRespawn (void);
void SendExperience (void);
void SendExperienceOrb (const cExpOrb & a_ExpOrb);
@ -173,6 +179,7 @@ public:
void HandleKeepAlive (int a_KeepAliveID);
void HandleLeftClick (int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status);
void HandlePing (void);
void HandlePlayerAbilities (bool a_CanFly, bool a_IsFlying, float FlyingSpeed, float WalkingSpeed);
void HandlePlayerLook (float a_Rotation, float a_Pitch, bool a_IsOnGround);
void HandlePlayerMoveLook (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Rotation, float a_Pitch, bool a_IsOnGround); // While m_bPositionConfirmed (normal gameplay)
void HandlePlayerPos (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, bool a_IsOnGround);

View File

@ -39,6 +39,15 @@ void cBoat::DoTakeDamage(TakeDamageInfo & TDI)
if (GetHealth() == 0)
{
if (TDI.Attacker != NULL)
{
if (TDI.Attacker->IsPlayer())
{
cItems Pickups;
Pickups.Add(cItem(E_ITEM_BOAT));
m_World->SpawnItemPickups(Pickups, GetPosX(), GetPosY(), GetPosZ(), 0, 0, 0, true);
}
}
Destroy(true);
}
}
@ -76,12 +85,32 @@ void cBoat::OnRightClicked(cPlayer & a_Player)
void cBoat::HandlePhysics(float a_Dt, cChunk & a_Chunk)
void cBoat::Tick(float a_Dt, cChunk & a_Chunk)
{
super::HandlePhysics(a_Dt, a_Chunk);
super::Tick(a_Dt, a_Chunk);
BroadcastMovementUpdate();
SetSpeed(GetSpeed() * 0.97); // Slowly decrease the speed.
if (IsBlockWater(m_World->GetBlock((int) GetPosX(), (int) GetPosY(), (int) GetPosZ())))
{
SetSpeedY(1);
}
}
void cBoat::HandleSpeedFromAttachee(float a_Forward, float a_Sideways)
{
if (GetSpeed().Length() > 7)
{
return;
}
Vector3d ToAddSpeed(m_Attachee->GetLookVector() * (a_Sideways * 1.5));
ToAddSpeed.y = 0;
AddSpeed(ToAddSpeed);
}

View File

@ -27,7 +27,8 @@ public:
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
virtual void OnRightClicked(cPlayer & a_Player) override;
virtual void DoTakeDamage(TakeDamageInfo & TDI) override;
virtual void HandlePhysics(float a_Dt, cChunk & a_Chunk) override;
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
virtual void HandleSpeedFromAttachee(float a_Forward, float a_Sideways) override;
cBoat(double a_X, double a_Y, double a_Z);
} ;

30
src/Entities/Effects.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
// tolua_begin
enum ENUM_ENTITY_EFFECT
{
E_EFFECT_SPEED = 1,
E_EFFECT_SLOWNESS = 2,
E_EFFECT_HASTE = 3,
E_EFFECT_MINING_FATIGUE = 4,
E_EFFECT_STENGTH = 5,
E_EFFECT_INSTANT_HEALTH = 6,
E_EFFECT_INSTANT_DAMAGE = 7,
E_EFFECT_JUMP_BOOST = 8,
E_EFFECT_NAUSEA = 9,
E_EFFECT_REGENERATION = 10,
E_EFFECT_RESISTANCE = 11,
E_EFFECT_FIRE_RESISTANCE = 12,
E_EFFECT_WATER_BREATHING = 13,
E_EFFECT_INVISIBILITY = 14,
E_EFFECT_BLINDNESS = 15,
E_EFFECT_NIGHT_VISION = 16,
E_EFFECT_HUNGER = 17,
E_EFFECT_WEAKNESS = 18,
E_EFFECT_POISON = 19,
E_EFFECT_WITHER = 20,
E_EFFECT_HEALTH_BOOST = 21,
E_EFFECT_ABSORPTION = 22,
E_EFFECT_SATURATION = 23,
} ;
// tolua_end

View File

@ -1341,6 +1341,19 @@ void cEntity::AddSpeedZ(double a_AddSpeedZ)
void cEntity::HandleSpeedFromAttachee(float a_Forward, float a_Sideways)
{
Vector3d LookVector = m_Attachee->GetLookVector();
double AddSpeedX = LookVector.x * a_Forward + LookVector.z * a_Sideways;
double AddSpeedZ = LookVector.z * a_Forward - LookVector.x * a_Sideways;
SetSpeed(AddSpeedX, 0, AddSpeedZ);
BroadcastMovementUpdate();
}
void cEntity::SteerVehicle(float a_Forward, float a_Sideways)
{
if (m_AttachedTo == NULL)
@ -1349,10 +1362,7 @@ void cEntity::SteerVehicle(float a_Forward, float a_Sideways)
}
if ((a_Forward != 0) || (a_Sideways != 0))
{
Vector3d LookVector = GetLookVector();
double AddSpeedX = LookVector.x * a_Forward + LookVector.z * a_Sideways;
double AddSpeedZ = LookVector.z * a_Forward - LookVector.x * a_Sideways;
m_AttachedTo->AddSpeed(AddSpeedX, 0, AddSpeedZ);
m_AttachedTo->HandleSpeedFromAttachee(a_Forward, a_Sideways);
}
}

View File

@ -197,6 +197,7 @@ public:
void AddSpeedY (double a_AddSpeedY);
void AddSpeedZ (double a_AddSpeedZ);
virtual void HandleSpeedFromAttachee(float a_Forward, float a_Sideways);
void SteerVehicle(float a_Forward, float a_Sideways);
inline int GetUniqueID(void) const { return m_UniqueID; }

View File

@ -54,7 +54,7 @@ void cExpOrb::Tick(float a_Dt, cChunk & a_Chunk)
Destroy(true);
}
a_Distance.Normalize();
a_Distance *= ((float) (5.5 - Distance));
a_Distance *= ((float) (5.5 - Distance));
SetSpeedX( a_Distance.x );
SetSpeedY( a_Distance.y );
SetSpeedZ( a_Distance.z );

View File

@ -63,6 +63,8 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
, m_IsSprinting(false)
, m_IsSwimming(false)
, m_IsSubmerged(false)
, m_IsFlying(false)
, m_CanFly(false)
, m_EatingFinishTick(-1)
, m_IsChargingBow(false)
, m_BowCharge(0)
@ -135,28 +137,6 @@ cPlayer::~cPlayer(void)
bool cPlayer::Initialize(cWorld * a_World)
{
ASSERT(a_World != NULL);
if (super::Initialize(a_World))
{
// Remove the client handle from the server, it will be ticked from this object from now on
if (m_ClientHandle != NULL)
{
cRoot::Get()->GetServer()->ClientMovedToWorld(m_ClientHandle);
}
GetWorld()->AddPlayer(this);
return true;
}
return false;
}
void cPlayer::Destroyed()
{
CloseWindow(false);
@ -557,9 +537,13 @@ void cPlayer::FoodPoison(int a_NumTicks)
m_FoodPoisonedTicksRemaining = std::max(m_FoodPoisonedTicksRemaining, a_NumTicks);
if (!HasBeenFoodPoisoned)
{
// TODO: Send the poisoning indication to the client - how?
m_World->BroadcastRemoveEntityEffect(*this, E_EFFECT_HUNGER);
SendHealth();
}
else
{
m_World->BroadcastEntityEffect(*this, E_EFFECT_HUNGER, 0, 400); // Give the player the "Hunger" effect for 20 seconds.
}
}
@ -747,6 +731,36 @@ void cPlayer::SetSprint(bool a_IsSprinting)
void cPlayer::SetCanFly(bool a_CanFly)
{
if (a_CanFly == m_CanFly)
{
return;
}
m_CanFly = a_CanFly;
m_ClientHandle->SendPlayerAbilities();
}
void cPlayer::SetFlying(bool a_IsFlying)
{
if (a_IsFlying == m_IsFlying)
{
return;
}
m_IsFlying = a_IsFlying;
m_ClientHandle->SendPlayerAbilities();
}
void cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI)
{
if (a_TDI.DamageType != dtInVoid)
@ -1033,6 +1047,16 @@ Vector3d cPlayer::GetThrowSpeed(double a_SpeedCoeff) const
void cPlayer::ForceSetSpeed(Vector3d a_Direction)
{
SetSpeed(a_Direction);
m_ClientHandle->SendEntityVelocity(*this);
}
void cPlayer::MoveTo( const Vector3d & a_NewPos )
{
if ((a_NewPos.y < -990) && (GetPosY() > -100))
@ -1471,6 +1495,7 @@ bool cPlayer::LoadFromDisk()
m_FoodExhaustionLevel = root.get("foodExhaustion", 0).asDouble();
m_LifetimeTotalXp = (short) root.get("xpTotal", 0).asInt();
m_CurrentXp = (short) root.get("xpCurrent", 0).asInt();
m_IsFlying = root.get("isflying", 0).asBool();
//SetExperience(root.get("experience", 0).asInt());
@ -1521,7 +1546,8 @@ bool cPlayer::SaveToDisk()
root["foodSaturation"] = m_FoodSaturationLevel;
root["foodTickTimer"] = m_FoodTickTimer;
root["foodExhaustion"] = m_FoodExhaustionLevel;
root["world"] = GetWorld()->GetName();
root["world"] = GetWorld()->GetName();
root["isflying"] = IsFlying();
if (m_GameMode == GetWorld()->GetGameMode())
{
@ -1704,6 +1730,10 @@ void cPlayer::HandleFood(void)
m_FoodPoisonedTicksRemaining--;
m_FoodExhaustionLevel += 0.025; // 0.5 per second = 0.025 per tick
}
else
{
m_World->BroadcastRemoveEntityEffect(*this, E_EFFECT_HUNGER); // Remove the "Hunger" effect.
}
// Apply food exhaustion that has accumulated:
if (m_FoodExhaustionLevel >= 4)

View File

@ -41,8 +41,6 @@ public:
cPlayer(cClientHandle * a_Client, const AString & a_PlayerName);
virtual ~cPlayer();
virtual bool Initialize(cWorld * a_World) override;
virtual void SpawnOn(cClientHandle & a_Client) override;
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
@ -167,6 +165,9 @@ public:
// Sets the current gamemode, doesn't check validity, doesn't send update packets to client
void LoginSetGameMode(eGameMode a_GameMode);
/// Forces the player to move in the given direction.
void ForceSetSpeed(Vector3d a_Direction); // tolua_export
/// Tries to move to a new position, with attachment-related checks (y == -999)
void MoveTo(const Vector3d & a_NewPos); // tolua_export
@ -250,6 +251,8 @@ public:
/// Returns true if the player is currently in the process of eating the currently equipped item
bool IsEating(void) const { return (m_EatingFinishTick >= 0); }
/// Returns true if the player is currently flying.
bool IsFlying(void) const { return m_IsFlying; }
// tolua_end
/// Starts eating the currently equipped item. Resets the eating timer and sends the proper animation packet
@ -319,12 +322,20 @@ public:
/// Starts or stops sprinting, sends the max speed update to the client, if needed
void SetSprint(bool a_IsSprinting);
/// Flags the player as flying
void SetFlying(bool a_IsFlying);
/// If true the player can fly even when he's not in creative.
void SetCanFly(bool a_CanFly);
/// Returns whether the player is swimming or not
virtual bool IsSwimming(void) const{ return m_IsSwimming; }
/// Return whether the player is under water or not
virtual bool IsSubmerged(void) const{ return m_IsSubmerged; }
/// Returns wheter the player can fly or not.
virtual bool CanFly(void) const { return m_CanFly; }
// tolua_end
// cEntity overrides:
@ -415,10 +426,12 @@ protected:
bool m_IsCrouched;
bool m_IsSprinting;
bool m_IsFlying;
bool m_IsSwimming;
bool m_IsSubmerged;
bool m_CanFly; // If this is true the player can fly. Even if he is not in creative.
/// The world tick in which eating will be finished. -1 if not eating
Int64 m_EatingFinishTick;

View File

@ -124,9 +124,6 @@ typedef unsigned short UInt16;
#include <semaphore.h>
#include <errno.h>
#include <fcntl.h>
#if !defined(ANDROID_NDK)
#include <tr1/memory>
#endif
#endif
#if defined(ANDROID_NDK)
@ -220,6 +217,7 @@ public:
// Common headers (part 2, with macros):
#include "ChunkDef.h"
#include "BlockID.h"
#include "Entities/Effects.h"

View File

@ -10,6 +10,7 @@
#pragma once
#include "../Entities/Boat.h"
#include "../LineBlockTracer.h"
@ -30,23 +31,47 @@ public:
virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override
{
if (a_Dir < 0)
if (a_Dir > 0)
{
return false;
}
class cCallbacks :
public cBlockTracer::cCallbacks
{
public:
Vector3d Pos;
virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override
{
if (a_BlockType != E_BLOCK_AIR)
{
Pos = Vector3d(a_BlockX, a_BlockY, a_BlockZ);
return true;
}
return false;
}
} Callbacks;
double x = (double)a_BlockX + 0.5;
double y = (double)a_BlockY + 0.5;
double z = (double)a_BlockZ + 0.5;
cLineBlockTracer Tracer(*a_World, Callbacks);
Vector3d Start(a_Player->GetEyePosition() + a_Player->GetLookVector());
Vector3d End(a_Player->GetEyePosition() + a_Player->GetLookVector() * 5);
cBoat * Boat = NULL;
Tracer.Trace(Start.x, Start.y, Start.z, End.x, End.y, End.z);
Boat = new cBoat (x, y, z);
double x = Callbacks.Pos.x;
double y = Callbacks.Pos.y;
double z = Callbacks.Pos.z;
if ((x == 0) && (y == 0) && (z == 0))
{
return false;
}
cBoat * Boat = new cBoat(x + 0.5, y + 1, z + 0.5);
Boat->Initialize(a_World);
return true;
}
} ;

View File

@ -5,6 +5,7 @@
#include "../World.h"
#include "../Simulator/FluidSimulator.h"
#include "../Blocks/BlockHandler.h"
#include "../LineBlockTracer.h"
@ -39,61 +40,54 @@ public:
bool ScoopUpFluid(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace)
{
if (a_BlockFace < 0)
if (a_BlockFace > 0)
{
return false;
}
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
BLOCKTYPE ClickedBlock;
NIBBLETYPE ClickedMeta;
a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, ClickedBlock, ClickedMeta);
LOGD("Bucket Clicked BlockType %d, meta %d", ClickedBlock, ClickedMeta);
if (ClickedMeta != 0)
Vector3i BlockPos;
if (!GetBlockFromTrace(a_World, a_Player, BlockPos))
{
return false; // Nothing in range.
}
if (a_World->GetBlockMeta(BlockPos.x, BlockPos.y, BlockPos.z) != 0)
{
// Not a source block
return false;
}
if (a_Player->GetGameMode() == gmCreative)
BLOCKTYPE Block = a_World->GetBlock(BlockPos.x, BlockPos.y, BlockPos.z);
ENUM_ITEM_ID NewItem;
if (IsBlockWater(Block))
{
// In creative mode don't modify the inventory, just remove the fluid:
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
return true;
NewItem = E_ITEM_WATER_BUCKET;
}
else if (IsBlockLava(Block))
{
NewItem = E_ITEM_LAVA_BUCKET;
}
else
{
return false;
}
ENUM_ITEM_ID NewItem = E_ITEM_EMPTY;
switch (ClickedBlock)
// Give new bucket, filled with fluid when the gamemode is not creative:
if (!a_Player->IsGameModeCreative())
{
case E_BLOCK_WATER:
case E_BLOCK_STATIONARY_WATER:
// Remove the bucket from the inventory
if (!a_Player->GetInventory().RemoveOneEquippedItem())
{
NewItem = E_ITEM_WATER_BUCKET;
break;
LOG("Clicked with an empty bucket, but cannot remove one from the inventory? WTF?");
ASSERT(!"Inventory bucket mismatch");
return true;
}
case E_BLOCK_LAVA:
case E_BLOCK_STATIONARY_LAVA:
{
NewItem = E_ITEM_LAVA_BUCKET;
break;
}
default: return false;
a_Player->GetInventory().AddItem(cItem(NewItem), true, true);
}
// Remove the bucket from the inventory
if (!a_Player->GetInventory().RemoveOneEquippedItem())
{
LOG("Clicked with an empty bucket, but cannot remove one from the inventory? WTF?");
ASSERT(!"Inventory bucket mismatch");
return true;
}
// Give new bucket, filled with fluid:
cItem Item(NewItem, 1);
a_Player->GetInventory().AddItem(Item, true, true);
// Remove water / lava block
a_Player->GetWorld()->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
a_Player->GetWorld()->SetBlock(BlockPos.x, BlockPos.y, BlockPos.z, E_BLOCK_AIR, 0);
return true;
}
@ -157,4 +151,52 @@ public:
return true;
}
bool GetBlockFromTrace(cWorld * a_World, cPlayer * a_Player, Vector3i & BlockPos)
{
class cCallbacks :
public cBlockTracer::cCallbacks
{
public:
Vector3i m_Pos;
bool m_HasHitFluid;
cCallbacks(void) :
m_HasHitFluid(false)
{
}
virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override
{
if (a_BlockMeta != 0) // Even if it was a water block it would not be a source.
{
return false;
}
if (IsBlockWater(a_BlockType) || IsBlockLava(a_BlockType))
{
m_HasHitFluid = true;
m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ);
return true;
}
return false;
}
} Callbacks;
cLineBlockTracer Tracer(*a_World, Callbacks);
Vector3d Start(a_Player->GetEyePosition() + a_Player->GetLookVector());
Vector3d End(a_Player->GetEyePosition() + a_Player->GetLookVector() * 5);
Tracer.Trace(Start.x, Start.y, Start.z, End.x, End.y, End.z);
if (!Callbacks.m_HasHitFluid)
{
return false;
}
BlockPos.Set(Callbacks.m_Pos.x, Callbacks.m_Pos.y, Callbacks.m_Pos.z);
return true;
}
};

View File

@ -23,6 +23,7 @@
#include "ItemLeaves.h"
#include "ItemLighter.h"
#include "ItemMinecart.h"
#include "ItemNetherWart.h"
#include "ItemPickaxe.h"
#include "ItemThrowable.h"
#include "ItemRedstoneDust.h"
@ -101,6 +102,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType)
case E_ITEM_FIREWORK_ROCKET: return new cItemFireworkHandler();
case E_ITEM_FLINT_AND_STEEL: return new cItemLighterHandler(a_ItemType);
case E_ITEM_FLOWER_POT: return new cItemFlowerPotHandler(a_ItemType);
case E_ITEM_NETHER_WART: return new cItemNetherWartHandler(a_ItemType);
case E_ITEM_REDSTONE_DUST: return new cItemRedstoneDustHandler(a_ItemType);
case E_ITEM_REDSTONE_REPEATER: return new cItemRedstoneRepeaterHandler(a_ItemType);
case E_ITEM_SHEARS: return new cItemShearsHandler(a_ItemType);

View File

@ -0,0 +1,54 @@
#pragma once
#include "ItemHandler.h"
#include "../World.h"
class cItemNetherWartHandler :
public cItemHandler
{
public:
cItemNetherWartHandler(int a_ItemType) :
cItemHandler(a_ItemType)
{
}
virtual bool IsPlaceable(void) override
{
return true;
}
virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
if (a_BlockFace != BLOCK_FACE_TOP)
{
// Only allow planting nether wart from the top side of the block
return false;
}
// Only allow placement on farmland
int X = a_BlockX;
int Y = a_BlockY;
int Z = a_BlockZ;
AddFaceDirection(X, Y, Z, a_BlockFace, true);
if (a_World->GetBlock(X, Y, Z) != E_BLOCK_SOULSAND)
{
return false;
}
a_BlockMeta = 0;
a_BlockType = E_BLOCK_NETHER_WART;
return true;
}
} ;

View File

@ -62,6 +62,7 @@ public:
virtual void SendDestroyEntity (const cEntity & a_Entity) = 0;
virtual void SendDisconnect (const AString & a_Reason) = 0;
virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) = 0; ///< Request the client to open up the sign editor for the sign (1.6+)
virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) = 0;
virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) = 0;
virtual void SendEntityHeadLook (const cEntity & a_Entity) = 0;
virtual void SendEntityLook (const cEntity & a_Entity) = 0;
@ -85,6 +86,7 @@ public:
virtual void SendPlayerMoveLook (void) = 0;
virtual void SendPlayerPosition (void) = 0;
virtual void SendPlayerSpawn (const cPlayer & a_Player) = 0;
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) = 0;
virtual void SendRespawn (void) = 0;
virtual void SendExperience (void) = 0;
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) = 0;

View File

@ -73,7 +73,9 @@ enum
PACKET_ENT_STATUS = 0x26,
PACKET_ATTACH_ENTITY = 0x27,
PACKET_METADATA = 0x28,
PACKET_ENTITY_EFFECT = 0x29,
PACKET_SPAWN_EXPERIENCE_ORB = 0x1A,
PACKET_REMOVE_ENTITY_EFFECT = 0x2a,
PACKET_EXPERIENCE = 0x2b,
PACKET_PRE_CHUNK = 0x32,
PACKET_MAP_CHUNK = 0x33,
@ -300,6 +302,21 @@ void cProtocol125::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ)
void cProtocol125::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration)
{
cCSLock Lock(m_CSPacket);
WriteByte (PACKET_ENTITY_EFFECT);
WriteInt (a_Entity.GetUniqueID());
WriteByte (a_EffectID);
WriteByte (a_Amplifier);
WriteShort(a_Duration);
Flush();
}
void cProtocol125::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item)
{
cCSLock Lock(m_CSPacket);
@ -678,6 +695,19 @@ void cProtocol125::SendPlayerSpawn(const cPlayer & a_Player)
void cProtocol125::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID)
{
cCSLock Lock(m_CSPacket);
WriteByte (PACKET_REMOVE_ENTITY_EFFECT);
WriteInt (a_Entity.GetUniqueID());
WriteByte (a_EffectID);
Flush();
}
void cProtocol125::SendRespawn(void)
{
cCSLock Lock(m_CSPacket);

View File

@ -38,6 +38,7 @@ public:
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
virtual void SendDisconnect (const AString & a_Reason) override;
virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+)
virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override;
virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override;
virtual void SendEntityHeadLook (const cEntity & a_Entity) override;
virtual void SendEntityLook (const cEntity & a_Entity) override;
@ -61,6 +62,7 @@ public:
virtual void SendPlayerMoveLook (void) override;
virtual void SendPlayerPosition (void) override;
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
virtual void SendRespawn (void) override;
virtual void SendExperience (void) override;
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;

View File

@ -236,6 +236,19 @@ void cProtocol172::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ)
void cProtocol172::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration)
{
cPacketizer Pkt(*this, 0x1D); // Entity Effect packet
Pkt.WriteInt(a_Entity.GetUniqueID());
Pkt.WriteByte(a_EffectID);
Pkt.WriteByte(a_Amplifier);
Pkt.WriteShort(a_Duration);
}
void cProtocol172::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item)
{
cPacketizer Pkt(*this, 0x04); // Entity Equipment packet
@ -478,7 +491,15 @@ void cProtocol172::SendPlayerAbilities(void)
{
Flags |= 0x01;
}
// TODO: Other flags (god mode, flying, can fly
if (m_Client->GetPlayer()->IsFlying())
{
Flags |= 0x02;
}
if (m_Client->GetPlayer()->CanFly())
{
Flags |= 0x04;
}
// TODO: Other flags (god mode)
Pkt.WriteByte(Flags);
// TODO: Pkt.WriteFloat(m_Client->GetPlayer()->GetMaxFlyingSpeed());
Pkt.WriteFloat(0.05f);
@ -541,7 +562,11 @@ void cProtocol172::SendPlayerMoveLook(void)
{
cPacketizer Pkt(*this, 0x08); // Player Position And Look packet
Pkt.WriteDouble(m_Client->GetPlayer()->GetPosX());
Pkt.WriteDouble(m_Client->GetPlayer()->GetPosY());
// Protocol docs say this is PosY, but #323 says this is eye-pos
// Moreover, the "+ 0.001" is there because otherwise the player falls through the block they were standing on.
Pkt.WriteDouble(m_Client->GetPlayer()->GetStance() + 0.001);
Pkt.WriteDouble(m_Client->GetPlayer()->GetPosZ());
Pkt.WriteFloat((float)m_Client->GetPlayer()->GetYaw());
Pkt.WriteFloat((float)m_Client->GetPlayer()->GetPitch());
@ -585,6 +610,17 @@ void cProtocol172::SendPlayerSpawn(const cPlayer & a_Player)
void cProtocol172::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID)
{
cPacketizer Pkt(*this, 0x1E);
Pkt.WriteInt(a_Entity.GetUniqueID());
Pkt.WriteByte(a_EffectID);
}
void cProtocol172::SendRespawn(void)
{
cPacketizer Pkt(*this, 0x07); // Respawn packet
@ -921,7 +957,6 @@ void cProtocol172::SendWindowProperty(const cWindow & a_Window, short a_Property
void cProtocol172::AddReceivedData(const char * a_Data, int a_Size)
{
LOGD("Received %d bytes of data", a_Size);
if (!m_ReceivedData.Write(a_Data, a_Size))
{
// Too much data in the incoming queue, report to caller:
@ -958,9 +993,6 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size)
return;
}
// DEBUG:
LOGD("Packet 0x%x, len %d (0x%x), start at %d", PacketType, PacketLen, PacketLen, PacketStart);
HandlePacket(bb, PacketType);
if (bb.GetReadableSpace() != 1)
@ -1258,7 +1290,25 @@ void cProtocol172::HandlePacketPlayerAbilities(cByteBuffer & a_ByteBuffer)
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Flags);
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, FlyingSpeed);
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, WalkingSpeed);
// TODO: m_Client->HandlePlayerAbilities();
bool IsFlying, CanFly;
if ((Flags & 2) != 0)
{
IsFlying = true;
}
else
{
IsFlying = false;
}
if ((Flags & 4) != 0)
{
CanFly = true;
}
else
{
CanFly = false;
}
m_Client->HandlePlayerAbilities(CanFly, IsFlying, FlyingSpeed, WalkingSpeed);
}

View File

@ -47,6 +47,7 @@ public:
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
virtual void SendDisconnect (const AString & a_Reason) override;
virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+)
virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override;
virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override;
virtual void SendEntityHeadLook (const cEntity & a_Entity) override;
virtual void SendEntityLook (const cEntity & a_Entity) override;
@ -70,6 +71,7 @@ public:
virtual void SendPlayerMoveLook (void) override;
virtual void SendPlayerPosition (void) override;
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
virtual void SendRespawn (void) override;
virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; // a_Src coords are Block * 8
virtual void SendExperience (void) override;

View File

@ -216,6 +216,16 @@ void cProtocolRecognizer::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ)
void cProtocolRecognizer::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration)
{
ASSERT(m_Protocol != NULL);
m_Protocol->SendEntityEffect(a_Entity, a_EffectID, a_Amplifier, a_Duration);
}
void cProtocolRecognizer::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item)
{
ASSERT(m_Protocol != NULL);
@ -456,6 +466,16 @@ void cProtocolRecognizer::SendPlayerSpawn(const cPlayer & a_Player)
void cProtocolRecognizer::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID)
{
ASSERT(m_Protocol != NULL);
m_Protocol->SendRemoveEntityEffect(a_Entity, a_EffectID);
}
void cProtocolRecognizer::SendRespawn(void)
{
ASSERT(m_Protocol != NULL);

View File

@ -73,6 +73,7 @@ public:
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
virtual void SendDisconnect (const AString & a_Reason) override;
virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+)
virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override;
virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override;
virtual void SendEntityHeadLook (const cEntity & a_Entity) override;
virtual void SendEntityLook (const cEntity & a_Entity) override;
@ -96,6 +97,7 @@ public:
virtual void SendPlayerMoveLook (void) override;
virtual void SendPlayerPosition (void) override;
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
virtual void SendRespawn (void) override;
virtual void SendExperience (void) override;
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;

View File

@ -402,7 +402,7 @@ void cServer::TickClients(float a_Dt)
itr = m_Clients.erase(itr);
continue;
}
(*itr)->Tick(a_Dt);
(*itr)->ServerTick(a_Dt);
++itr;
} // for itr - m_Clients[]
}

View File

@ -3,6 +3,7 @@
#include "RedstoneSimulator.h"
#include "../BlockEntities/DropSpenserEntity.h"
#include "../BlockEntities/NoteEntity.h"
#include "../Entities/TNTEntity.h"
#include "../Blocks/BlockTorch.h"
#include "../Blocks/BlockDoor.h"
@ -81,18 +82,24 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
{
int RelX = itr->a_SourcePos.x - a_ChunkX * cChunkDef::Width;
int RelZ = itr->a_SourcePos.z - a_ChunkZ * cChunkDef::Width;
int DestRelX = itr->a_BlockPos.x - a_ChunkX * cChunkDef::Width;
int DestRelZ = itr->a_BlockPos.z - a_ChunkZ * cChunkDef::Width;
BLOCKTYPE SourceBlockType;
NIBBLETYPE SourceBlockMeta;
if (!a_Chunk->UnboundedRelGetBlock(RelX, itr->a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta))
BLOCKTYPE DestBlockType;
if (
!a_Chunk->UnboundedRelGetBlock(RelX, itr->a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta) ||
!a_Chunk->UnboundedRelGetBlockType(DestRelX, itr->a_BlockPos.y, DestRelZ, DestBlockType)
)
{
continue;
}
if (SourceBlockType != itr->a_SourceBlock)
{
itr = m_PoweredBlocks.erase(itr);
LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past block type mismatch", ItemToFullString(itr->a_SourceBlock).c_str());
itr = m_PoweredBlocks.erase(itr);
}
else if (
// Changeable sources
@ -102,8 +109,14 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
(((SourceBlockType == E_BLOCK_STONE_BUTTON) || (SourceBlockType == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(SourceBlockMeta)))
)
{
itr = m_PoweredBlocks.erase(itr);
LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past metadata mismatch", ItemToFullString(itr->a_SourceBlock).c_str());
itr = m_PoweredBlocks.erase(itr);
}
else if ((SourceBlockType == E_BLOCK_REDSTONE_WIRE) && (DestBlockType == E_BLOCK_REDSTONE_WIRE))
{
// It is simply not allowed that a wire powers another wire, presuming that data here is sane and a dest and source are beside each other
LOGD("cRedstoneSimulator: Erased redstone wire from powered blocks list because it's source was also wire");
itr = m_PoweredBlocks.erase(itr);
}
else
{
@ -132,13 +145,13 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
if (SourceBlockType != itr->a_SourceBlock)
{
itr = m_LinkedPoweredBlocks.erase(itr);
LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past block type mismatch", ItemToFullString(itr->a_SourceBlock).c_str());
itr = m_LinkedPoweredBlocks.erase(itr);
}
else if (MiddleBlockType != itr->a_MiddleBlock)
{
itr = m_LinkedPoweredBlocks.erase(itr);
LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past middle block mismatch", ItemToFullString(itr->a_SourceBlock).c_str());
itr = m_LinkedPoweredBlocks.erase(itr);
}
else if (
// Things that can send power through a block but which depends on meta
@ -147,8 +160,8 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
(((SourceBlockType == E_BLOCK_STONE_BUTTON) || (SourceBlockType == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(SourceBlockMeta)))
)
{
itr = m_LinkedPoweredBlocks.erase(itr);
LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past metadata mismatch", ItemToFullString(itr->a_SourceBlock).c_str());
itr = m_LinkedPoweredBlocks.erase(itr);
}
else
{
@ -196,6 +209,7 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
case E_BLOCK_TNT: HandleTNT(a_X, dataitr->y, a_Z); break;
case E_BLOCK_TRAPDOOR: HandleTrapdoor(a_X, dataitr->y, a_Z); break;
case E_BLOCK_REDSTONE_WIRE: HandleRedstoneWire(a_X, dataitr->y, a_Z); break;
case E_BLOCK_NOTE_BLOCK: HandleNoteBlock(a_X, dataitr->y, a_Z); break;
case E_BLOCK_REDSTONE_TORCH_OFF:
case E_BLOCK_REDSTONE_TORCH_ON:
@ -392,20 +406,32 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl
int x, y, z;
} gCrossCoords[] =
{
{ 1, 0, 0},
{ 1, 0, 0}, /* Wires on same level start */
{-1, 0, 0},
{ 0, 0, 1},
{ 0, 0, -1},
{ 1, 1, 0}, // From here to end, check for wire placed on sides of blocks
{ 0, 0, -1}, /* Wires on same level stop */
{ 1, 1, 0}, /* Wires one higher, surrounding self start */
{-1, 1, 0},
{ 0, 1, 1},
{ 0, 1, -1},
{ 1,-1, 0},
{ 0, 1, -1}, /* Wires one higher, surrounding self stop */
{ 1,-1, 0}, /* Wires one lower, surrounding self start */
{-1,-1, 0},
{ 0,-1, 1},
{ 0,-1, -1},
{ 0,-1, -1}, /* Wires one lower, surrounding self stop */
} ;
static const struct // Define which directions the wire will check for repeater prescence
{
int x, y, z;
} gSideCoords[] =
{
{ 1, 0, 0 },
{-1, 0, 0 },
{ 0, 0, 1 },
{ 0, 0,-1 },
{ 0, 1, 0 },
};
// Check to see if directly beside a power source
if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ))
{
@ -419,6 +445,21 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl
for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) // Loop through all directions to transfer or receive power
{
if ((i >= 4) && (i <= 7)) // If we are currently checking for wire surrounding ourself one block above...
{
if (g_BlockIsSolid[m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ)]) // If there is something solid above us (wire cut off)...
{
continue; // We don't receive power from that wire
}
}
else if ((i >= 8) && (i <= 11)) // See above, but this is for wire below us
{
if (g_BlockIsSolid[m_World.GetBlock(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y + 1, a_BlockZ + gCrossCoords[i].z)])
{
continue;
}
}
BLOCKTYPE SurroundType;
NIBBLETYPE SurroundMeta;
m_World.GetBlockTypeMeta(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z, SurroundType, SurroundMeta);
@ -459,12 +500,20 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl
}
}
// Wire still powered, power blocks beneath
SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, E_BLOCK_REDSTONE_WIRE);
if (m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) != 0) // A powered wire
{
for (size_t i = 0; i < ARRAYCOUNT(gSideCoords); i++) // Look for repeaters immediately surrounding self and try to power them
{
if (m_World.GetBlock(a_BlockX + gSideCoords[i].x, a_BlockY + gSideCoords[i].y, a_BlockZ + gSideCoords[i].z) == E_BLOCK_REDSTONE_REPEATER_OFF)
{
SetBlockPowered(a_BlockX + gSideCoords[i].x, a_BlockY + gSideCoords[i].y, a_BlockZ + gSideCoords[i].z, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
}
}
// Wire still powered, power blocks beneath
SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, E_BLOCK_REDSTONE_WIRE);
switch (GetWireDirection(a_BlockX, a_BlockY, a_BlockZ))
{
case REDSTONE_NONE:
@ -481,37 +530,25 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl
}
case REDSTONE_X_POS:
{
if (m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockPowered(a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
}
SetBlockPowered(a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, E_BLOCK_REDSTONE_WIRE);
break;
}
case REDSTONE_X_NEG:
{
if (m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockPowered(a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
}
SetBlockPowered(a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, E_BLOCK_REDSTONE_WIRE);
break;
}
case REDSTONE_Z_POS:
{
if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
}
SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZP, E_BLOCK_REDSTONE_WIRE);
break;
}
case REDSTONE_Z_NEG:
{
if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
}
SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, E_BLOCK_REDSTONE_WIRE);
break;
}
@ -525,109 +562,75 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl
void cRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState)
{
// We do this so that the repeater can continually update block power status (without being affected by it's own block type, which would happen if the block powering code was in an IF statement)
bool IsOn = false;
if (a_MyState == E_BLOCK_REDSTONE_REPEATER_ON)
{
IsOn = true;
}
NIBBLETYPE a_Meta = m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
if (IsRepeaterPowered(a_BlockX, a_BlockY, a_BlockZ, a_Meta & 0x3))
// We do this so that the repeater can continually update block power status (without being affected by it's own block type, which would happen if the block powering code was in an IF statement)
bool IsOn = ((a_MyState == E_BLOCK_REDSTONE_REPEATER_ON) ? true : false);
bool IsSelfPowered = IsRepeaterPowered(a_BlockX, a_BlockY, a_BlockZ, a_Meta & 0x3);
if (IsSelfPowered && !IsOn) // Queue a power change if I am receiving power but not on
{
if (!IsOn)
QueueRepeaterPowerChange(a_BlockX, a_BlockY, a_BlockZ, a_Meta, 0, true);
}
else if (!IsSelfPowered && IsOn) // Queue a power change if I am not receiving power but on
{
QueueRepeaterPowerChange(a_BlockX, a_BlockY, a_BlockZ, a_Meta, 0, false);
}
for (RepeatersDelayList::iterator itr = m_RepeatersDelayList.begin(); itr != m_RepeatersDelayList.end(); itr++)
{
if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
{
bool ShouldCreate = true;
// If repeater is not on already (and is POWERED), see if it is in repeater list, or has reached delay time
for (RepeatersDelayList::iterator itr = m_RepeatersDelayList.begin(); itr != m_RepeatersDelayList.end(); itr++)
continue;
}
if (itr->a_ElapsedTicks >= itr->a_DelayTicks) // Has the elapsed ticks reached the target ticks?
{
if (itr->ShouldPowerOn)
{
if (itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON, a_Meta);
switch (a_Meta & 0x3) // We only want the direction (bottom) bits
{
if (itr->a_DelayTicks <= itr->a_ElapsedTicks) // Shouldn't need <=; just in case something happens
case 0x0:
{
m_RepeatersDelayList.erase(itr);
ShouldCreate = false;
break; // Delay time reached, break straight out, and into the powering code
SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON);
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, E_BLOCK_REDSTONE_REPEATER_ON);
break;
}
else
case 0x1:
{
itr->a_ElapsedTicks++; // Increment elapsed ticks and quit
return;
SetBlockPowered(a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON);
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, E_BLOCK_REDSTONE_REPEATER_ON);
break;
}
case 0x2:
{
SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON);
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZP, E_BLOCK_REDSTONE_REPEATER_ON);
break;
}
case 0x3:
{
SetBlockPowered(a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON);
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, E_BLOCK_REDSTONE_REPEATER_ON);
break;
}
}
}
if (ShouldCreate)
{
// Self not in list, add self to list
sRepeatersDelayList RC;
RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ);
RC.a_DelayTicks = ((a_Meta & 0xC) >> 0x2) + 1; // Gets the top two bits (delay time), shifts them into the lower two bits, and adds one (meta 0 = 1 tick; 1 = 2 etc.)
RC.a_ElapsedTicks = 0;
m_RepeatersDelayList.push_back(RC);
m_RepeatersDelayList.erase(itr);
return;
}
m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON, a_Meta); // Only set if not on; SetBlock otherwise server doesn't set it in time for SimulateChunk's invalidation
}
switch (a_Meta & 0x3) // We only want the direction (bottom) bits
{
case 0x0:
else
{
SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON);
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, E_BLOCK_REDSTONE_REPEATER_ON);
break;
}
case 0x1:
{
SetBlockPowered(a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON);
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, E_BLOCK_REDSTONE_REPEATER_ON);
break;
}
case 0x2:
{
SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON);
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZP, E_BLOCK_REDSTONE_REPEATER_ON);
break;
}
case 0x3:
{
SetBlockPowered(a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON);
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, E_BLOCK_REDSTONE_REPEATER_ON);
break;
m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, a_Meta);
m_RepeatersDelayList.erase(itr);
return;
}
}
}
else
{
if (IsOn)
else
{
// If repeater is not off already (and is NOT POWERED), see if it is in repeater list, or has reached delay time
for (RepeatersDelayList::iterator itr = m_RepeatersDelayList.begin(); itr != m_RepeatersDelayList.end(); itr++)
{
if (itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
{
if (itr->a_DelayTicks <= itr->a_ElapsedTicks) // Shouldn't need <=; just in case something happens
{
m_RepeatersDelayList.erase(itr);
m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, a_Meta);
return;
}
else
{
itr->a_ElapsedTicks++; // Increment elapsed ticks and quit
return;
}
}
}
// Self not in list, add self to list
sRepeatersDelayList RC;
RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ);
RC.a_DelayTicks = ((a_Meta & 0xC) >> 0x2); // Repeaters power off slower than they power on, so no +1. Why? No idea.
RC.a_ElapsedTicks = 0;
m_RepeatersDelayList.push_back(RC);
itr->a_ElapsedTicks++;
return;
}
}
@ -821,6 +824,48 @@ void cRedstoneSimulator::HandleTrapdoor(int a_BlockX, int a_BlockY, int a_BlockZ
void cRedstoneSimulator::HandleNoteBlock(int a_BlockX, int a_BlockY, int a_BlockZ)
{
bool m_bAreCoordsPowered = AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ);
if (m_bAreCoordsPowered)
{
if (!AreCoordsSimulated(a_BlockX, a_BlockY, a_BlockZ, true))
{
class cSetPowerToNoteBlock :
public cNoteBlockCallback
{
bool m_IsPowered;
public:
cSetPowerToNoteBlock(bool a_IsPowered) : m_IsPowered(a_IsPowered) {}
virtual bool Item(cNoteEntity * a_NoteBlock) override
{
if (m_IsPowered)
{
a_NoteBlock->MakeSound();
}
return false;
}
} NoteBlockSP(m_bAreCoordsPowered);
m_World.DoWithNoteBlockAt(a_BlockX, a_BlockY, a_BlockZ, NoteBlockSP);
SetPlayerToggleableBlockAsSimulated(a_BlockX, a_BlockY, a_BlockZ, true);
}
}
else
{
if (!AreCoordsSimulated(a_BlockX, a_BlockY, a_BlockZ, false))
{
SetPlayerToggleableBlockAsSimulated(a_BlockX, a_BlockY, a_BlockZ, false);
}
}
}
bool cRedstoneSimulator::AreCoordsDirectlyPowered(int a_BlockX, int a_BlockY, int a_BlockZ)
{
for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) // Check powered list
@ -1103,11 +1148,17 @@ void cRedstoneSimulator::SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_B
void cRedstoneSimulator::SetBlockPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock)
{
if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_AIR)
BLOCKTYPE Block = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ);
if (Block == E_BLOCK_AIR)
{
// Don't set air, fixes some bugs (wires powering themselves)
return;
}
if ((Block == E_BLOCK_REDSTONE_WIRE) && (a_SourceBlock == E_BLOCK_REDSTONE_WIRE))
{
// Wires cannot power themselves normally, instead, the wire handler will manually set meta
return;
}
for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) // Check powered list
{
@ -1214,6 +1265,30 @@ void cRedstoneSimulator::SetPlayerToggleableBlockAsSimulated(int a_BlockX, int a
void cRedstoneSimulator::QueueRepeaterPowerChange(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta, short a_ElapsedTicks, bool ShouldPowerOn)
{
for (RepeatersDelayList::iterator itr = m_RepeatersDelayList.begin(); itr != m_RepeatersDelayList.end(); itr++)
{
if (itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
{
return;
}
}
// Self not in list, add self to list
sRepeatersDelayList RC;
RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ);
RC.a_DelayTicks = ((a_Meta & 0xC) >> 0x2) + 1; // Gets the top two bits (delay time), shifts them into the lower two bits, and adds one (meta 0 = 1 tick; 1 = 2 etc.)
RC.a_ElapsedTicks = 0;
RC.ShouldPowerOn = ShouldPowerOn;
m_RepeatersDelayList.push_back(RC);
return;
}
cRedstoneSimulator::eRedstoneDirection cRedstoneSimulator::GetWireDirection(int a_BlockX, int a_BlockY, int a_BlockZ)
{
int Dir = REDSTONE_NONE;

View File

@ -62,6 +62,7 @@ private:
Vector3i a_BlockPos;
short a_DelayTicks;
short a_ElapsedTicks;
bool ShouldPowerOn;
};
typedef std::vector <sPoweredBlocks> PoweredBlocksList;
@ -112,6 +113,8 @@ private:
void HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType);
/// <summary>Handles trapdoors</summary>
void HandleTrapdoor(int a_BlockX, int a_BlockY, int a_BlockZ);
/// <summary>Handles noteblocks</summary>
void HandleNoteBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
/* ===================== */
/* ====== Helper functions ====== */
@ -125,6 +128,8 @@ private:
void SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceBlock);
/// <summary>Marks all blocks immediately surrounding a coordinate as powered</summary>
void SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock);
/// <summary>Queues a repeater to be powered or unpowered</summary>
void QueueRepeaterPowerChange(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta, short a_ElapsedTicks, bool ShouldPowerOn);
/// <summary>Returns if a coordinate is powered or linked powered</summary>
bool AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ) { return AreCoordsDirectlyPowered(a_BlockX, a_BlockY, a_BlockZ) || AreCoordsLinkedPowered(a_BlockX, a_BlockY, a_BlockZ); }

View File

@ -234,7 +234,6 @@ cWorld::cWorld(const AString & a_WorldName) :
m_WorldAge(0),
m_TimeOfDay(0),
m_LastTimeUpdate(0),
m_RSList(0),
m_Weather(eWeather_Sunny),
m_WeatherInterval(24000), // Guaranteed 1 day of sunshine at server start :)
m_TickThread(*this),
@ -716,29 +715,6 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec)
}
TickMobs(a_Dt);
std::vector<int> m_RSList_copy(m_RSList);
m_RSList.clear();
std::vector<int>::const_iterator cii; // FIXME - Please rename this variable, WTF is cii??? Use human readable variable names or common abbreviations (i, idx, itr, iter)
for (cii = m_RSList_copy.begin(); cii != m_RSList_copy.end();)
{
int tempX = *cii; cii++;
int tempY = *cii; cii++;
int tempZ = *cii; cii++;
int state = *cii; cii++;
if ((state == 11111) && ((int)GetBlock(tempX, tempY, tempZ) == E_BLOCK_REDSTONE_TORCH_OFF))
{
FastSetBlock(tempX, tempY, tempZ, E_BLOCK_REDSTONE_TORCH_ON, (int)GetBlockMeta(tempX, tempY, tempZ));
}
else if ((state == 00000) && ((int)GetBlock(tempX, tempY, tempZ) == E_BLOCK_REDSTONE_TORCH_ON))
{
FastSetBlock(tempX, tempY, tempZ, E_BLOCK_REDSTONE_TORCH_OFF, (int)GetBlockMeta(tempX, tempY, tempZ));
}
}
m_RSList_copy.erase(m_RSList_copy.begin(),m_RSList_copy.end());
}
@ -1129,6 +1105,15 @@ bool cWorld::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceC
bool cWorld::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback)
{
return m_ChunkMap->DoWithNoteBlockAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
}
bool cWorld::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4)
{
return m_ChunkMap->GetSignLines(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4);
@ -1804,6 +1789,15 @@ void cWorld::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandl
void cWorld::BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude)
{
m_ChunkMap->BroadcastEntityEffect(a_Entity, a_EffectID, a_Amplifier, a_Duration, a_Exclude);
}
void cWorld::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude)
{
m_ChunkMap->BroadcastEntityEquipment(a_Entity, a_SlotNum, a_Item, a_Exclude);
@ -1902,6 +1896,15 @@ void cWorld::BroadcastPlayerListItem (const cPlayer & a_Player, bool a_IsOnline,
void cWorld::BroadcastRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude)
{
m_ChunkMap->BroadcastRemoveEntityEffect(a_Entity, a_EffectID, a_Exclude);
}
void cWorld::BroadcastSoundEffect(const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude)
{
m_ChunkMap->BroadcastSoundEffect(a_SoundName, a_SrcX, a_SrcY, a_SrcZ, a_Volume, a_Pitch, a_Exclude);

View File

@ -27,7 +27,6 @@
class cRedstone;
class cFireSimulator;
class cFluidSimulator;
class cSandSimulator;
@ -42,6 +41,7 @@ class cChunkGenerator; // The thread responsible for generating chunks
class cChestEntity;
class cDispenserEntity;
class cFurnaceEntity;
class cNoteEntity;
class cMobCensus;
typedef std::list< cPlayer * > cPlayerList;
@ -51,6 +51,7 @@ typedef cItemCallback<cEntity> cEntityCallback;
typedef cItemCallback<cChestEntity> cChestCallback;
typedef cItemCallback<cDispenserEntity> cDispenserCallback;
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
typedef cItemCallback<cNoteEntity> cNoteBlockCallback;
@ -151,6 +152,7 @@ public:
void BroadcastChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL);
void BroadcastCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL);
void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
@ -161,6 +163,7 @@ public:
void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityAnimation (const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL);
void BroadcastPlayerListItem (const cPlayer & a_Player, bool a_IsOnline, const cClientHandle * a_Exclude = NULL);
void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL);
void BroadcastSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL); // tolua_export a_Src coords are Block * 8
void BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = NULL); // tolua_export
void BroadcastSpawnEntity (cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
@ -444,6 +447,9 @@ public:
/// Calls the callback for the furnace at the specified coords; returns false if there's no furnace at those coords or callback returns true, returns true if found
bool DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback); // Exported in ManualBindings.cpp
/// Calls the callback for the noteblock at the specified coords; returns false if there's no noteblock at those coords or callback returns true, returns true if found
bool DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback); // Exported in ManualBindings.cpp
/// Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found
bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Exported in ManualBindings.cpp
@ -661,10 +667,6 @@ private:
bool m_bEnabledPVP;
bool m_IsDeepSnowEnabled;
bool m_ShouldLavaSpawnFire;
// The cRedstone class simulates redstone and needs access to m_RSList
// friend class cRedstone;
std::vector<int> m_RSList;
std::vector<BlockTickQueueItem *> m_BlockTickQueue;
std::vector<BlockTickQueueItem *> m_BlockTickQueueCopy; // Second is for safely removing the objects from the queue