diff --git a/.gitignore b/.gitignore index bde685901..0f5712848 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,6 @@ SymSrv cloc-ignored.txt cloc.xml cloc.xsl +*.ncb +*.user +*.suo \ No newline at end of file diff --git a/MCServer/.gitignore b/MCServer/.gitignore index e455b8cdc..8452ec2d7 100644 --- a/MCServer/.gitignore +++ b/MCServer/.gitignore @@ -6,7 +6,7 @@ banned.ini logs players whitelist.ini -world +world* API.txt *.dat schematics diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua index e2523e63e..1bc625c35 100644 --- a/MCServer/Plugins/Debuggers/Debuggers.lua +++ b/MCServer/Plugins/Debuggers/Debuggers.lua @@ -33,6 +33,8 @@ function Initialize(Plugin) PluginManager:BindCommand("/dash", "debuggers", HandleDashCmd, "Switches between fast and normal sprinting speed"); PluginManager:BindCommand("/hunger", "debuggers", HandleHungerCmd, "Lists the current hunger-related variables"); PluginManager:BindCommand("/poison", "debuggers", HandlePoisonCmd, "Sets food-poisoning for 15 seconds"); + PluginManager:BindCommand("/starve", "debuggers", HandleStarveCmd, "Sets the food level to zero"); + PluginManager:BindCommand("/fl", "debuggers", HandleFoodLevelCmd, "Sets the food level to the given value"); -- Enable the following line for BlockArea / Generator interface testing: -- PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_GENERATED); @@ -715,3 +717,28 @@ end + +function HandleStarveCmd(a_Split, a_Player) + a_Player:SetFoodLevel(0); + a_Player:SendMessage("You are now starving"); + return true; +end + + + + + +function HandleFoodLevelCmd(a_Split, a_Player) + if (#a_Split ~= 2) then + a_Player:SendMessage("Missing an argument: the food level to set"); + return true; + end + + a_Player:SetFoodLevel(tonumber(a_Split[2])); + a_Player:SendMessage("Food level set to " .. a_Player:GetFoodLevel()); + return true; +end + + + + diff --git a/Tools/ProtoProxy/.gitignore b/Tools/ProtoProxy/.gitignore new file mode 100644 index 000000000..3097f7aab --- /dev/null +++ b/Tools/ProtoProxy/.gitignore @@ -0,0 +1,4 @@ +Debug +Release +*.log +*.nbt diff --git a/Tools/ProtoProxy/Connection.cpp b/Tools/ProtoProxy/Connection.cpp index a3d3191fc..32dfe321e 100644 --- a/Tools/ProtoProxy/Connection.cpp +++ b/Tools/ProtoProxy/Connection.cpp @@ -49,13 +49,25 @@ { \ AString ToServer; \ m_ClientBuffer.ReadAgain(ToServer); \ - if (m_ServerState == csUnencrypted) \ + switch (m_ServerState) \ { \ - SERVERSEND(ToServer.data(), ToServer.size()); \ - } \ - else \ - { \ - SERVERENCRYPTSEND(ToServer.data(), ToServer.size()); \ + case csUnencrypted: \ + { \ + SERVERSEND(ToServer.data(), ToServer.size()); \ + break; \ + } \ + case csEncryptedUnderstood: \ + case csEncryptedUnknown: \ + { \ + SERVERENCRYPTSEND(ToServer.data(), ToServer.size()); \ + break; \ + } \ + case csWaitingForEncryption: \ + { \ + Log("Waiting for server encryption, queued %u bytes", ToServer.size()); \ + m_ServerEncryptionBuffer.append(ToServer.data(), ToServer.size()); \ + break; \ + } \ } \ DebugSleep(50); \ } @@ -64,13 +76,25 @@ { \ AString ToClient; \ m_ServerBuffer.ReadAgain(ToClient); \ - if (m_ClientState == csUnencrypted) \ + switch (m_ClientState) \ { \ - CLIENTSEND(ToClient.data(), ToClient.size()); \ - } \ - else \ - { \ - CLIENTENCRYPTSEND(ToClient.data(), ToClient.size()); \ + case csUnencrypted: \ + { \ + CLIENTSEND(ToClient.data(), ToClient.size()); \ + break; \ + } \ + case csEncryptedUnderstood: \ + case csEncryptedUnknown: \ + { \ + CLIENTENCRYPTSEND(ToClient.data(), ToClient.size()); \ + break; \ + } \ + case csWaitingForEncryption: \ + { \ + Log("Waiting for client encryption, queued %u bytes", ToClient.size()); \ + m_ClientEncryptionBuffer.append(ToClient.data(), ToClient.size()); \ + break; \ + } \ } \ DebugSleep(50); \ } @@ -379,6 +403,7 @@ bool cConnection::RelayFromServer(void) switch (m_ServerState) { case csUnencrypted: + case csWaitingForEncryption: { return DecodeServersPackets(Buffer, res); } @@ -419,6 +444,7 @@ bool cConnection::RelayFromClient(void) switch (m_ClientState) { case csUnencrypted: + case csWaitingForEncryption: { return DecodeClientsPackets(Buffer, res); } @@ -1543,6 +1569,9 @@ bool cConnection::HandleServerEncryptionKeyResponse(void) } Log("Server communication is now encrypted"); m_ServerState = csEncryptedUnderstood; + DataLog(m_ServerEncryptionBuffer.data(), m_ServerEncryptionBuffer.size(), "Sending the queued data to server (%u bytes):", m_ServerEncryptionBuffer.size()); + SERVERENCRYPTSEND(m_ServerEncryptionBuffer.data(), m_ServerEncryptionBuffer.size()); + m_ServerEncryptionBuffer.clear(); return true; } @@ -2459,6 +2488,7 @@ void cConnection::SendEncryptionKeyResponse(const AString & a_ServerPublicKey, c ToServer.WriteBEShort(EncryptedLength); ToServer.WriteBuf(EncryptedNonce, EncryptedLength); SERVERSEND(ToServer); + m_ServerState = csWaitingForEncryption; } @@ -2507,6 +2537,11 @@ void cConnection::StartClientEncryption(const AString & a_EncKey, const AString Log("Client connection is now encrypted"); m_ClientState = csEncryptedUnderstood; + // Send the queued data: + DataLog(m_ClientEncryptionBuffer.data(), m_ClientEncryptionBuffer.size(), "Sending the queued data to client (%u bytes):", m_ClientEncryptionBuffer.size()); + CLIENTENCRYPTSEND(m_ClientEncryptionBuffer.data(), m_ClientEncryptionBuffer.size()); + m_ClientEncryptionBuffer.clear(); + // Handle all postponed server data DecodeServersPackets(NULL, 0); } diff --git a/Tools/ProtoProxy/Connection.h b/Tools/ProtoProxy/Connection.h index 7f3a6f8bb..dafc1b36b 100644 --- a/Tools/ProtoProxy/Connection.h +++ b/Tools/ProtoProxy/Connection.h @@ -39,9 +39,10 @@ class cConnection enum eConnectionState { - csUnencrypted, // The connection is not encrypted. Packets must be decoded in order to be able to start decryption. - csEncryptedUnderstood, // The communication is encrypted and so far all packets have been understood, so they can be still decoded - csEncryptedUnknown, // The communication is encrypted, but an unknown packet has been received, so packets cannot be decoded anymore + csUnencrypted, // The connection is not encrypted. Packets must be decoded in order to be able to start decryption. + csEncryptedUnderstood, // The communication is encrypted and so far all packets have been understood, so they can be still decoded + csEncryptedUnknown, // The communication is encrypted, but an unknown packet has been received, so packets cannot be decoded anymore + csWaitingForEncryption, // The communication is waiting for the other line to establish encryption }; eConnectionState m_ClientState; @@ -72,6 +73,9 @@ protected: Decryptor m_ClientDecryptor; Encryptor m_ClientEncryptor; + AString m_ClientEncryptionBuffer; // Buffer for the data to be sent to the client once encryption is established + AString m_ServerEncryptionBuffer; // Buffer for the data to be sent to the server once encryption is established + /// Set to true when PACKET_PING is received from the client; will cause special parsing for server kick bool m_HasClientPinged; diff --git a/VC2008/icon_128.png b/VC2008/icon_128.png new file mode 100644 index 000000000..87d939a04 Binary files /dev/null and b/VC2008/icon_128.png differ diff --git a/VC2008/icon_256.png b/VC2008/icon_256.png new file mode 100644 index 000000000..9a77a490f Binary files /dev/null and b/VC2008/icon_256.png differ diff --git a/source/Bindings.cpp b/source/Bindings.cpp index a81ec2b8c..a313ce98d 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 07/29/13 02:06:10. +** Generated automatically by tolua++-1.0.92 on 07/29/13 09:54:50. */ #ifndef __cplusplus @@ -8448,166 +8448,6 @@ static int tolua_AllToLua_cPlayer_GetGameMode00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE -/* method: GetIP of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetIP00 -static int tolua_AllToLua_cPlayer_GetIP00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetIP'", NULL); -#endif - { - std::string tolua_ret = (std::string) self->GetIP(); - tolua_pushcppstring(tolua_S,(const char*)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetIP'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetLastBlockActionTime of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetLastBlockActionTime00 -static int tolua_AllToLua_cPlayer_GetLastBlockActionTime00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLastBlockActionTime'", NULL); -#endif - { - float tolua_ret = (float) self->GetLastBlockActionTime(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetLastBlockActionTime'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: GetLastBlockActionCnt of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetLastBlockActionCnt00 -static int tolua_AllToLua_cPlayer_GetLastBlockActionCnt00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetLastBlockActionCnt'", NULL); -#endif - { - int tolua_ret = (int) self->GetLastBlockActionCnt(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetLastBlockActionCnt'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetLastBlockActionCnt of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetLastBlockActionCnt00 -static int tolua_AllToLua_cPlayer_SetLastBlockActionCnt00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnumber(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); - int tolua_var_1 = ((int) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetLastBlockActionCnt'", NULL); -#endif - { - self->SetLastBlockActionCnt(tolua_var_1); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetLastBlockActionCnt'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - -/* method: SetLastBlockActionTime of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetLastBlockActionTime00 -static int tolua_AllToLua_cPlayer_SetLastBlockActionTime00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetLastBlockActionTime'", NULL); -#endif - { - self->SetLastBlockActionTime(); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetLastBlockActionTime'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - /* method: SetGameMode of class cPlayer */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetGameMode00 static int tolua_AllToLua_cPlayer_SetGameMode00(lua_State* tolua_S) @@ -8641,6 +8481,134 @@ static int tolua_AllToLua_cPlayer_SetGameMode00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: IsGameModeCreative of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_IsGameModeCreative00 +static int tolua_AllToLua_cPlayer_IsGameModeCreative00(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 'IsGameModeCreative'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsGameModeCreative(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsGameModeCreative'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsGameModeSurvival of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_IsGameModeSurvival00 +static int tolua_AllToLua_cPlayer_IsGameModeSurvival00(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 'IsGameModeSurvival'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsGameModeSurvival(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsGameModeSurvival'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsGameModeAdventure of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_IsGameModeAdventure00 +static int tolua_AllToLua_cPlayer_IsGameModeAdventure00(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 'IsGameModeAdventure'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsGameModeAdventure(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsGameModeAdventure'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetIP of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetIP00 +static int tolua_AllToLua_cPlayer_GetIP00(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 'GetIP'", NULL); +#endif + { + AString tolua_ret = (AString) self->GetIP(); + tolua_pushcppstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetIP'.",&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) @@ -9343,6 +9311,38 @@ static int tolua_AllToLua_cPlayer_GetFoodPoisonedTicksRemaining00(lua_State* tol } #endif //#ifndef TOLUA_DISABLE +/* method: IsSatiated of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_IsSatiated00 +static int tolua_AllToLua_cPlayer_IsSatiated00(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 'IsSatiated'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsSatiated(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsSatiated'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: SetFoodLevel of class cPlayer */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetFoodLevel00 static int tolua_AllToLua_cPlayer_SetFoodLevel00(lua_State* tolua_S) @@ -9610,6 +9610,38 @@ static int tolua_AllToLua_cPlayer_FoodPoison00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: IsEating of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_IsEating00 +static int tolua_AllToLua_cPlayer_IsEating00(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 'IsEating'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsEating(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsEating'.",&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) @@ -11416,6 +11448,102 @@ static int tolua_AllToLua_cWorld_GetGameMode00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: IsGameModeCreative of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_IsGameModeCreative00 +static int tolua_AllToLua_cWorld_IsGameModeCreative00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsGameModeCreative'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsGameModeCreative(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsGameModeCreative'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsGameModeSurvival of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_IsGameModeSurvival00 +static int tolua_AllToLua_cWorld_IsGameModeSurvival00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsGameModeSurvival'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsGameModeSurvival(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsGameModeSurvival'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsGameModeAdventure of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_IsGameModeAdventure00 +static int tolua_AllToLua_cWorld_IsGameModeAdventure00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cWorld* self = (const cWorld*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsGameModeAdventure'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsGameModeAdventure(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsGameModeAdventure'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: IsPVPEnabled of class cWorld */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_IsPVPEnabled00 static int tolua_AllToLua_cWorld_IsPVPEnabled00(lua_State* tolua_S) @@ -29017,6 +29145,8 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"gmSurvival",gmSurvival); tolua_constant(tolua_S,"gmCreative",gmCreative); tolua_constant(tolua_S,"gmAdventure",gmAdventure); + tolua_constant(tolua_S,"gmMax",gmMax); + tolua_constant(tolua_S,"gmMin",gmMin); tolua_constant(tolua_S,"eWeather_Sunny",eWeather_Sunny); tolua_constant(tolua_S,"eWeather_Rain",eWeather_Rain); tolua_constant(tolua_S,"eWeather_ThunderStorm",eWeather_ThunderStorm); @@ -29244,6 +29374,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_beginmodule(tolua_S,"cPlayer"); tolua_constant(tolua_S,"MAX_HEALTH",cPlayer::MAX_HEALTH); tolua_constant(tolua_S,"MAX_FOOD_LEVEL",cPlayer::MAX_FOOD_LEVEL); + tolua_constant(tolua_S,"EATING_TICKS",cPlayer::EATING_TICKS); tolua_function(tolua_S,"Initialize",tolua_AllToLua_cPlayer_Initialize00); tolua_function(tolua_S,"GetEyeHeight",tolua_AllToLua_cPlayer_GetEyeHeight00); tolua_function(tolua_S,"GetEyePosition",tolua_AllToLua_cPlayer_GetEyePosition00); @@ -29252,12 +29383,11 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"GetInventory",tolua_AllToLua_cPlayer_GetInventory00); tolua_function(tolua_S,"GetEquippedItem",tolua_AllToLua_cPlayer_GetEquippedItem00); tolua_function(tolua_S,"GetGameMode",tolua_AllToLua_cPlayer_GetGameMode00); - tolua_function(tolua_S,"GetIP",tolua_AllToLua_cPlayer_GetIP00); - tolua_function(tolua_S,"GetLastBlockActionTime",tolua_AllToLua_cPlayer_GetLastBlockActionTime00); - tolua_function(tolua_S,"GetLastBlockActionCnt",tolua_AllToLua_cPlayer_GetLastBlockActionCnt00); - tolua_function(tolua_S,"SetLastBlockActionCnt",tolua_AllToLua_cPlayer_SetLastBlockActionCnt00); - tolua_function(tolua_S,"SetLastBlockActionTime",tolua_AllToLua_cPlayer_SetLastBlockActionTime00); tolua_function(tolua_S,"SetGameMode",tolua_AllToLua_cPlayer_SetGameMode00); + tolua_function(tolua_S,"IsGameModeCreative",tolua_AllToLua_cPlayer_IsGameModeCreative00); + 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,"MoveTo",tolua_AllToLua_cPlayer_MoveTo00); tolua_function(tolua_S,"GetWindow",tolua_AllToLua_cPlayer_GetWindow00); tolua_function(tolua_S,"CloseWindow",tolua_AllToLua_cPlayer_CloseWindow00); @@ -29279,6 +29409,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"GetFoodTickTimer",tolua_AllToLua_cPlayer_GetFoodTickTimer00); tolua_function(tolua_S,"GetFoodExhaustionLevel",tolua_AllToLua_cPlayer_GetFoodExhaustionLevel00); tolua_function(tolua_S,"GetFoodPoisonedTicksRemaining",tolua_AllToLua_cPlayer_GetFoodPoisonedTicksRemaining00); + tolua_function(tolua_S,"IsSatiated",tolua_AllToLua_cPlayer_IsSatiated00); tolua_function(tolua_S,"SetFoodLevel",tolua_AllToLua_cPlayer_SetFoodLevel00); tolua_function(tolua_S,"SetFoodSaturationLevel",tolua_AllToLua_cPlayer_SetFoodSaturationLevel00); tolua_function(tolua_S,"SetFoodTickTimer",tolua_AllToLua_cPlayer_SetFoodTickTimer00); @@ -29287,6 +29418,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"Feed",tolua_AllToLua_cPlayer_Feed00); 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,"Respawn",tolua_AllToLua_cPlayer_Respawn00); tolua_function(tolua_S,"SetVisible",tolua_AllToLua_cPlayer_SetVisible00); tolua_function(tolua_S,"IsVisible",tolua_AllToLua_cPlayer_IsVisible00); @@ -29390,6 +29522,9 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"SetTimeOfDay",tolua_AllToLua_cWorld_SetTimeOfDay00); tolua_function(tolua_S,"SetWorldTime",tolua_AllToLua_cWorld_SetWorldTime00); tolua_function(tolua_S,"GetGameMode",tolua_AllToLua_cWorld_GetGameMode00); + tolua_function(tolua_S,"IsGameModeCreative",tolua_AllToLua_cWorld_IsGameModeCreative00); + tolua_function(tolua_S,"IsGameModeSurvival",tolua_AllToLua_cWorld_IsGameModeSurvival00); + tolua_function(tolua_S,"IsGameModeAdventure",tolua_AllToLua_cWorld_IsGameModeAdventure00); tolua_function(tolua_S,"IsPVPEnabled",tolua_AllToLua_cWorld_IsPVPEnabled00); tolua_function(tolua_S,"IsDeepSnowEnabled",tolua_AllToLua_cWorld_IsDeepSnowEnabled00); tolua_function(tolua_S,"GetDimension",tolua_AllToLua_cWorld_GetDimension00); diff --git a/source/Bindings.h b/source/Bindings.h index a86df572c..256a8e257 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 07/29/13 02:06:11. +** Generated automatically by tolua++-1.0.92 on 07/29/13 09:54:50. */ /* Exported function */ diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp index 155eac38a..d66e47d32 100644 --- a/source/ClientHandle.cpp +++ b/source/ClientHandle.cpp @@ -555,11 +555,8 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, ch cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem()); if (ItemHandler->IsFood()) { - if (PlgMgr->CallHookPlayerEating(*m_Player)) - { - // A plugin doesn't agree with the action. The plugin itself is responsible for handling the consequences (possible inventory mismatch) - return; - } + m_Player->AbortEating(); + return; } else { @@ -569,7 +566,7 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, ch return; } } - LOGINFO("%s: Status SHOOT / EAT not implemented", __FUNCTION__); + LOGINFO("%s: Status SHOOT not implemented", __FUNCTION__); return; } @@ -804,15 +801,19 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, c } else if (ItemHandler->IsFood()) { - cItem Item; - Item.m_ItemType = Equipped.m_ItemType; - Item.m_ItemCount = 1; - if (ItemHandler->EatItem(m_Player, &Item)) + if (m_Player->IsSatiated()) { - ItemHandler->OnFoodEaten(World, m_Player, &Item); - m_Player->GetInventory().RemoveOneEquippedItem(); + // The player is satiated, they cannot eat return; } + m_Player->StartEating(); + if (PlgMgr->CallHookPlayerEating(*m_Player)) + { + // A plugin won't let us eat, abort (send the proper packets to the client, too): + m_Player->AbortEating(); + return; + } + return; } else { diff --git a/source/ClientHandle.h b/source/ClientHandle.h index a06aca39f..9cf1a3326 100644 --- a/source/ClientHandle.h +++ b/source/ClientHandle.h @@ -281,6 +281,9 @@ private: /// Buffer for received messages to be processed in the Tick thread AStringList m_PendingMessages; + + static int s_ClientCount; + int m_UniqueID; @@ -307,14 +310,11 @@ private: /// Processes the messages in m_PendingMessages; called from the Tick thread void ProcessPendingMessages(void); - + // cSocketThreads::cCallback overrides: virtual void DataReceived (const char * a_Data, int a_Size) override; // Data is received from the client virtual void GetOutgoingData(AString & a_Data) override; // Data can be sent to client virtual void SocketClosed (void) override; // The socket has been closed for any reason - - static int s_ClientCount; - int m_UniqueID; }; // tolua_export diff --git a/source/Defines.h b/source/Defines.h index f52050a9b..94e618eb0 100644 --- a/source/Defines.h +++ b/source/Defines.h @@ -116,6 +116,10 @@ enum eGameMode gmSurvival = eGameMode_Survival, gmCreative = eGameMode_Creative, gmAdventure = eGameMode_Adventure, + + // These two are used to check GameMode for validity when converting from integers. + gmMax, // Gets automatically assigned + gmMin = 0, } ; diff --git a/source/Items/ItemFood.h b/source/Items/ItemFood.h index d4c0a012a..4ec2f7a36 100644 --- a/source/Items/ItemFood.h +++ b/source/Items/ItemFood.h @@ -4,53 +4,53 @@ #include "ItemHandler.h" -class cItemFoodHandler : public cItemHandler + + + +class cItemFoodHandler : + public cItemHandler { + typedef cItemHandler super; + public: cItemFoodHandler(int a_ItemType) - : cItemHandler(a_ItemType) + : super(a_ItemType) { } - virtual bool IsFood() override + + virtual bool IsFood(void) override { return true; } - virtual FoodInfo GetFoodInfo() override + + virtual FoodInfo GetFoodInfo(void) override { switch(m_ItemType) { - case E_ITEM_BREAD: - return FoodInfo(5, 6.f); - case E_ITEM_COOKIE: - return FoodInfo(2, 0.4f); - case E_ITEM_MELON_SLICE: - return FoodInfo(2, 1.2f); - case E_ITEM_RAW_CHICKEN: - return FoodInfo(2, 1.2f, 30); - case E_ITEM_COOKED_CHICKEN: - return FoodInfo(6, 7.2f); - case E_ITEM_RAW_BEEF: - case E_ITEM_RAW_PORKCHOP: - return FoodInfo(3, 1.8f); - case E_ITEM_STEAK: - case E_ITEM_COOKED_PORKCHOP: - return FoodInfo(8, 12.8f); - case E_ITEM_RAW_FISH: - return FoodInfo(2, 1.2f); - case E_ITEM_COOKED_FISH: - return FoodInfo(5, 6.f); - case E_ITEM_RED_APPLE: - return FoodInfo(4, 2.4f); - case E_ITEM_GOLDEN_APPLE: - return FoodInfo(4, 9.6f); - case E_ITEM_ROTTEN_FLESH: - return FoodInfo(4, 0.8f, 80); - case E_ITEM_SPIDER_EYE: - return FoodInfo(2, 3.2f, 100); + case E_ITEM_BREAD: return FoodInfo(5, 6); + case E_ITEM_COOKIE: return FoodInfo(2, 0.4); + case E_ITEM_MELON_SLICE: return FoodInfo(2, 1.2); + case E_ITEM_RAW_CHICKEN: return FoodInfo(2, 1.2, 30); + case E_ITEM_COOKED_CHICKEN: return FoodInfo(6, 7.2); + case E_ITEM_RAW_BEEF: return FoodInfo(3, 1.8); + case E_ITEM_RAW_PORKCHOP: return FoodInfo(3, 1.8); + case E_ITEM_STEAK: return FoodInfo(8, 12.8); + case E_ITEM_COOKED_PORKCHOP: return FoodInfo(8, 12.8); + case E_ITEM_RAW_FISH: return FoodInfo(2, 1.2); + case E_ITEM_COOKED_FISH: return FoodInfo(5, 6); + case E_ITEM_RED_APPLE: return FoodInfo(4, 2.4); + case E_ITEM_GOLDEN_APPLE: return FoodInfo(4, 9.6); + case E_ITEM_ROTTEN_FLESH: return FoodInfo(4, 0.8, 80); + case E_ITEM_SPIDER_EYE: return FoodInfo(2, 3.2, 100); } + LOGWARNING("%s: Unknown food item (%d), returning zero nutrition", __FUNCTION__, m_ItemType); return FoodInfo(0, 0.f); } -}; \ No newline at end of file +}; + + + + diff --git a/source/Items/ItemHandler.cpp b/source/Items/ItemHandler.cpp index d99457029..acb6b6371 100644 --- a/source/Items/ItemHandler.cpp +++ b/source/Items/ItemHandler.cpp @@ -4,6 +4,7 @@ #include "../Item.h" #include "../World.h" #include "../Player.h" +#include "../FastRandom.h" // Handlers: #include "ItemBed.h" @@ -465,15 +466,17 @@ bool cItemHandler::EatItem(cPlayer * a_Player, cItem * a_Item) { FoodInfo Info = GetFoodInfo(); - if(Info.FoodLevel > 0 || Info.Saturation > 0.f) + if ((Info.FoodLevel > 0) || (Info.Saturation > 0.f)) { bool Success = a_Player->Feed(Info.FoodLevel, Info.Saturation); - if(Success && Info.PoisionChance > 0) + + // If consumed and there's chance of foodpoisoning, do it: + if (Success && (Info.PoisonChance > 0)) { - MTRand r1; - if((r1.randInt(100) - Info.PoisionChance) <= 0) - { //Unlucky guy :D - //TODO: Make player ill + cFastRandom r1; + if ((r1.NextInt(100, a_Player->GetUniqueID()) - Info.PoisonChance) <= 0) + { + a_Player->FoodPoison(300); } } diff --git a/source/Items/ItemHandler.h b/source/Items/ItemHandler.h index 0c141dea0..f7985327a 100644 --- a/source/Items/ItemHandler.h +++ b/source/Items/ItemHandler.h @@ -38,16 +38,17 @@ public: struct FoodInfo { - FoodInfo(short a_FoodLevel, float a_Saturation, char a_PoisionChance = 0) + int FoodLevel; + double Saturation; + int PoisonChance; // 0 - 100, in percent. 0 = no chance of poisoning, 100 = sure poisoning + + FoodInfo(int a_FoodLevel, double a_Saturation, int a_PoisonChance = 0) : + FoodLevel(a_FoodLevel), + Saturation(a_Saturation), + PoisonChance(a_PoisonChance) { - FoodLevel = a_FoodLevel; - Saturation = a_Saturation; - PoisionChance = a_PoisionChance; } - short FoodLevel; - float Saturation; - char PoisionChance; //0 - 100 - }; + } ; /// Returns the FoodInfo for this item. (FoodRecovery, Saturation and PoisionChance) virtual FoodInfo GetFoodInfo(); diff --git a/source/Player.cpp b/source/Player.cpp index 83181dda6..c90f3c99c 100644 --- a/source/Player.cpp +++ b/source/Player.cpp @@ -20,6 +20,7 @@ #include "OSSupport/Timer.h" #include "MersenneTwister.h" #include "Chunk.h" +#include "Items/ItemHandler.h" #include "Vector3d.h" #include "Vector3f.h" @@ -58,6 +59,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) , m_SprintingMaxSpeed(0.13) , m_IsCrouched(false) , m_IsSprinting(false) + , m_EatingFinishTick(-1) { LOGD("Created a player object for \"%s\" @ \"%s\" at %p, ID %d", a_PlayerName.c_str(), a_Client->GetIPString().c_str(), @@ -189,6 +191,11 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk) { m_World->CollectPickupsByPlayer(this); + if ((m_EatingFinishTick >= 0) && (m_EatingFinishTick <= m_World->GetWorldAge())) + { + FinishEating(); + } + HandleFood(); } @@ -349,6 +356,57 @@ void cPlayer::FoodPoison(int a_NumTicks) +void cPlayer::StartEating(void) +{ + // Set the timer: + m_EatingFinishTick = m_World->GetWorldAge() + EATING_TICKS; + + // Send the packets: + m_World->BroadcastPlayerAnimation(*this, 5); + m_World->BroadcastEntityMetadata(*this); +} + + + + + +void cPlayer::FinishEating(void) +{ + // Reset the timer: + m_EatingFinishTick = -1; + + // Send the packets: + m_ClientHandle->SendEntityStatus(*this, ENTITY_STATUS_EATING_ACCEPTED); + m_World->BroadcastPlayerAnimation(*this, 0); + m_World->BroadcastEntityMetadata(*this); + + // consume the item: + cItem Item(GetEquippedItem()); + Item.m_ItemCount = 1; + cItemHandler * ItemHandler = cItemHandler::GetItemHandler(Item.m_ItemType); + if (!ItemHandler->EatItem(this, &Item)) + { + return; + } + ItemHandler->OnFoodEaten(m_World, this, &Item); + GetInventory().RemoveOneEquippedItem(); +} + + + + + +void cPlayer::AbortEating(void) +{ + m_EatingFinishTick = -1; + m_World->BroadcastPlayerAnimation(*this, 0); + m_World->BroadcastEntityMetadata(*this); +} + + + + + void cPlayer::SendHealth(void) { if (m_ClientHandle != NULL) @@ -505,7 +563,10 @@ void cPlayer::KilledBy(cEntity * a_Killer) void cPlayer::Respawn(void) { m_Health = GetMaxHealth(); + + // Reset food level: m_FoodLevel = 20; + m_FoodSaturationLevel = 5; m_ClientHandle->SendRespawn(); @@ -538,6 +599,36 @@ Vector3d cPlayer::GetEyePosition(void) const +bool cPlayer::IsGameModeCreative(void) const +{ + return (m_GameMode == gmCreative) || // Either the player is explicitly in Creative + ((m_GameMode == gmNotSet) && m_World->IsGameModeCreative()); // or they inherit from the world and the world is Creative +} + + + + + +bool cPlayer::IsGameModeSurvival(void) const +{ + return (m_GameMode == gmSurvival) || // Either the player is explicitly in Survival + ((m_GameMode == gmNotSet) && m_World->IsGameModeSurvival()); // or they inherit from the world and the world is Survival +} + + + + + +bool cPlayer::IsGameModeAdventure(void) const +{ + return (m_GameMode == gmCreative) || // Either the player is explicitly in Adventure + ((m_GameMode == gmNotSet) && m_World->IsGameModeCreative()); // or they inherit from the world and the world is Adventure +} + + + + + void cPlayer::OpenWindow(cWindow * a_Window) { if (a_Window != m_CurrentWindow) @@ -614,7 +705,7 @@ void cPlayer::SetLastBlockActionCnt( int a_LastBlockActionCnt ) void cPlayer::SetGameMode(eGameMode a_GameMode) { - if ((a_GameMode >= 3) || (a_GameMode < 0)) + if ((a_GameMode >= gmMin) || (a_GameMode < gmMax)) { LOGWARNING("%s: Setting invalid gamemode: %d", GetName().c_str(), a_GameMode); return; @@ -1283,8 +1374,14 @@ void cPlayer::HandleFood(void) void cPlayer::ApplyFoodExhaustionFromMovement(cChunk & a_Chunk) { + if (IsGameModeCreative()) + { + return; + } + // Calculate the distance travelled, update the last pos: Vector3d Movement(GetPosition() - m_LastFoodPos); + Movement.y = 0; // Only take XZ movement into account m_LastFoodPos = GetPosition(); // If riding anything, apply no food exhaustion diff --git a/source/Player.h b/source/Player.h index fed222157..eea8c1596 100644 --- a/source/Player.h +++ b/source/Player.h @@ -28,6 +28,7 @@ public: { MAX_HEALTH = 20, MAX_FOOD_LEVEL = 20, + EATING_TICKS = 30, ///< Number of ticks it takes to eat an item } ; // tolua_end @@ -65,7 +66,7 @@ public: double GetEyeHeight(void) const; // tolua_export Vector3d GetEyePosition(void) const; // tolua_export inline bool IsOnGround(void) const {return m_bTouchGround; } // tolua_export - inline const double GetStance(void) const { return GetPosY() + 1.62; } // tolua_export // TODO: Proper stance when crouching etc. + inline const double GetStance(void) const { return GetPosY() + 1.62; } // tolua_export // TODO: Proper stance when crouching etc. inline cInventory & GetInventory(void) { return m_Inventory; } // tolua_export inline const cInventory & GetInventory(void) const { return m_Inventory; } @@ -73,18 +74,42 @@ public: virtual void TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ) override; - eGameMode GetGameMode(void) const { return m_GameMode; } // tolua_export - std::string GetIP() { return m_IP; } // tolua_export - float GetLastBlockActionTime() { return m_LastBlockActionTime; } // tolua_export - int GetLastBlockActionCnt() { return m_LastBlockActionCnt; } // tolua_export - void SetLastBlockActionCnt( int ); // tolua_export - void SetLastBlockActionTime(); // tolua_export - void SetGameMode( eGameMode a_GameMode ); // tolua_export - void LoginSetGameMode( eGameMode a_GameMode ); + // tolua_begin + + /// Returns the current gamemode. Partly OBSOLETE, you should use IsGameModeXXX() functions wherever applicable + eGameMode GetGameMode(void) const { return m_GameMode; } + + /** Sets the gamemode for the player. + The gamemode may be gmNotSet, in that case the player inherits the world's gamemode. + Updates the gamemode on the client (sends the packet) + */ + void SetGameMode(eGameMode a_GameMode); + + /// Returns true if the player is in Creative mode, either explicitly, or by inheriting from current world + bool IsGameModeCreative(void) const; + + /// Returns true if the player is in Survival mode, either explicitly, or by inheriting from current world + bool IsGameModeSurvival(void) const; + + /// Returns true if the player is in Adventure mode, either explicitly, or by inheriting from current world + bool IsGameModeAdventure(void) const; + + AString GetIP(void) const { return m_IP; } // tolua_export + + // tolua_end + void SetIP(const AString & a_IP); + float GetLastBlockActionTime() { return m_LastBlockActionTime; } + int GetLastBlockActionCnt() { return m_LastBlockActionCnt; } + void SetLastBlockActionCnt( int ); + void SetLastBlockActionTime(); + + // Sets the current gamemode, doesn't check validity, doesn't send update packets to client + void LoginSetGameMode(eGameMode a_GameMode); + /// Tries to move to a new position, with collision checks and stuff - virtual void MoveTo( const Vector3d & a_NewPos ); // tolua_export + virtual void MoveTo( const Vector3d & a_NewPos ); // tolua_export cWindow * GetWindow(void) { return m_CurrentWindow; } // tolua_export const cWindow * GetWindow(void) const { return m_CurrentWindow; } @@ -136,6 +161,9 @@ public: double GetFoodExhaustionLevel (void) const { return m_FoodExhaustionLevel; } int GetFoodPoisonedTicksRemaining(void) const { return m_FoodPoisonedTicksRemaining; } + /// Returns true if the player is satiated, i. e. their foodlevel is at the max and they cannot eat anymore + bool IsSatiated(void) const { return (m_FoodLevel >= MAX_FOOD_LEVEL); } + void SetFoodLevel (int a_FoodLevel); void SetFoodSaturationLevel (double a_FoodSaturationLevel); void SetFoodTickTimer (int a_FoodTickTimer); @@ -151,8 +179,20 @@ public: /// Starts the food poisoning for the specified amount of ticks; if already foodpoisoned, sets FoodPoisonedTicksRemaining to the larger of the two void FoodPoison(int a_NumTicks); + /// Returns true if the player is currently in the process of eating the currently equipped item + bool IsEating(void) const { return (m_EatingFinishTick >= 0); } + // tolua_end + /// Starts eating the currently equipped item. Resets the eating timer and sends the proper animation packet + void StartEating(void); + + /// Finishes eating the currently equipped item. Consumes the item, updates health and broadcasts the packets + void FinishEating(void); + + /// Aborts the current eating operation + void AbortEating(void); + virtual void KilledBy(cEntity * a_Killer) override; void Respawn(void); // tolua_export @@ -214,6 +254,7 @@ public: // cEntity overrides: virtual bool IsCrouched (void) const { return m_IsCrouched; } virtual bool IsSprinting(void) const { return m_IsSprinting; } + virtual bool IsRclking (void) const { return IsEating(); } protected: typedef std::map< std::string, bool > PermissionMap; @@ -285,6 +326,9 @@ protected: bool m_IsCrouched; bool m_IsSprinting; + /// The world tick in which eating will be finished. -1 if not eating + Int64 m_EatingFinishTick; + virtual void Destroyed(void); diff --git a/source/World.h b/source/World.h index 5da7218e2..e67b06789 100644 --- a/source/World.h +++ b/source/World.h @@ -106,7 +106,18 @@ public: SetTimeOfDay(a_TimeOfDay); } + /// Returns the current game mode. Partly OBSOLETE, you should use IsGameModeXXX() functions wherever applicable eGameMode GetGameMode(void) const { return m_GameMode; } + + /// Returns true if the world is in Creative mode + bool IsGameModeCreative(void) const { return (m_GameMode == gmCreative); } + + /// Returns true if the world is in Survival mode + bool IsGameModeSurvival(void) const { return (m_GameMode == gmSurvival); } + + /// Returns true if the world is in Adventure mode + bool IsGameModeAdventure(void) const { return (m_GameMode == gmAdventure); } + bool IsPVPEnabled(void) const { return m_bEnabledPVP; } bool IsDeepSnowEnabled(void) const { return m_IsDeepSnowEnabled; }