diff options
80 files changed, 1876 insertions, 894 deletions
@@ -665,9 +665,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = source \ - iniFile \ - WebServer +INPUT = src # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is diff --git a/MCServer/Plugins/.gitignore b/MCServer/Plugins/.gitignore index 89eab800a..8553945b5 100644 --- a/MCServer/Plugins/.gitignore +++ b/MCServer/Plugins/.gitignore @@ -1,2 +1,3 @@ *.txt *.md +*/ diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index c6221f30d..0b6f33b37 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -290,6 +290,38 @@ g_APIDesc = }, -- AdditionalInfo }, -- cBlockArea + cBlockInfo = + { + Desc = [[ + This class is used to query and register block properties. + ]], + Functions = + { + FullyOccupiesVoxel = { Params = "Type", Return = "bool", Notes = "(STATIC) Returns whether the specified block fully occupies its voxel." }, + Get = { Params = "Type", Return = "{{cBlockInfo}}", Notes = "(STATIC) Returns the {{cBlockInfo}} structure for the specified type." }, + GetLightValue = { Params = "Type", Return = "number", Notes = "(STATIC) Returns how much light the specified block emits on its own." }, + GetSpreadLightFalloff = { Params = "Type", Return = "number", Notes = "(STATIC) Returns how much light the specified block consumes." }, + IsOneHitDig = { Params = "Type", Return = "bool", Notes = "(STATIC) Returns whether the specified block will be destroyed after a single hit." }, + IsPistonBreakable = { Params = "Type", Return = "bool", Notes = "(STATIC) Returns whether a piston can break the specified block." }, + IsSnowable = { Params = "Type", Return = "bool", Notes = "(STATIC) Returns whether the specified block can hold snow atop." }, + IsSolid = { Params = "Type", Return = "bool", Notes = "(STATIC) Returns whether the specified block is solid." }, + IsTransparent = { Params = "Type", Return = "bool", Notes = "(STATIC) Returns whether the specified block is transparent." }, + RequiresSpecialTool = { Params = "Type", Return = "bool", Notes = "(STATIC) Returns whether the specified block requires a special tool to drop." }, + }, + Variables = + { + m_FullyOccupiesVoxel = { Type = "bool", Notes = "Does this block fully occupy its voxel - is it a 'full' block?" }, + m_IsSnowable = { Type = "bool", Notes = "Can this block hold snow atop?" }, + m_IsSolid = { Type = "bool", Notes = "Is this block solid (player cannot walk through)?" }, + m_LightValue = { Type = "number", Notes = "How much light do the blocks emit on their own?" }, + m_OneHitDig = { Type = "bool", Notes = "Is a block destroyed after a single hit?" }, + m_PistonBreakable = { Type = "bool", Notes = "Can a piston break this block?" }, + m_RequiresSpecialTool = { Type = "bool", Notes = "Does this block require a tool to drop?" }, + m_SpreadLightFalloff = { Type = "number", Notes = "How much light do the blocks consume?" }, + m_Transparent = { Type = "bool", Notes = "Is a block completely transparent? (light doesn't get decreased(?))" }, + }, + }, -- cBlockInfo + cChatColor = { Desc = [[ @@ -1115,6 +1147,42 @@ local Item5 = cItem(E_ITEM_DIAMOND_CHESTPLATE, 1, 0, "thorns=1;unbreaking=3"); }, }, -- cItem + cObjective = + { + Desc = [[ + This class represents a single scoreboard objective. + ]], + Functions = + { + AddScore = { Params = "string, number", Return = "Score", Notes = "Adds a value to the score of the specified player and returns the new value." }, + GetDisplayName = { Params = "", Return = "string", Notes = "Returns the display name of the objective. This name will be shown to the connected players." }, + GetName = { Params = "", Return = "string", Notes = "Returns the internal name of the objective." }, + GetScore = { Params = "string", Return = "Score", Notes = "Returns the score of the specified player." }, + GetType = { Params = "", Return = "eType", Notes = "Returns the type of the objective. (i.e what is being tracked)" }, + Reset = { Params = "", Return = "", Notes = "Resets the scores of the tracked players." }, + ResetScore = { Params = "string", Return = "", Notes = "Reset the score of the specified player." }, + SetDisplayName = { Params = "string", Return = "", Notes = "Sets the display name of the objective." }, + SetScore = { Params = "string, Score", Return = "", Notes = "Sets the score of the specified player." }, + SubScore = { Params = "string, number", Return = "Score", Notes = "Subtracts a value from the score of the specified player and returns the new value." }, + }, + Constants = + { + otAchievement = { Notes = "" }, + otDeathCount = { Notes = "" }, + otDummy = { Notes = "" }, + otHealth = { Notes = "" }, + otPlayerKillCount = { Notes = "" }, + otStat = { Notes = "" }, + otStatBlockMine = { Notes = "" }, + otStatEntityKill = { Notes = "" }, + otStatEntityKilledBy = { Notes = "" }, + otStatItemBreak = { Notes = "" }, + otStatItemCraft = { Notes = "" }, + otStatItemUse = { Notes = "" }, + otTotalKillCount = { Notes = "" }, + }, + }, -- cObjective + cPainting = { Desc = "This class represents a painting in the world. These paintings are special and different from Vanilla in that they can be critical-hit.", @@ -1773,6 +1841,7 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage); BroadcastChatInfo = { Params = "Message", Return = "", Notes = "Prepends Yellow [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For informational messages, such as command usage." }, BroadcastChatSuccess = { Params = "Message", Return = "", Notes = "Prepends Green [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For success messages." }, BroadcastChatWarning = { Params = "Message", Return = "", Notes = "Prepends Rose [WARN] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For concerning events, such as plugin reload etc." }, + CreateAndInitializeWorld = { Params = "WorldName", Return = "{{cWorld|cWorld}}", Notes = "Creates a new world and initializes it. If there is a world whith the same name it returns nil." }, FindAndDoWithPlayer = { Params = "PlayerName, CallbackFunction", Return = "", Notes = "Calls the given callback function for the given player." }, ForEachPlayer = { Params = "CallbackFunction", Return = "", Notes = "Calls the given callback function for each player. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cPlayer|cPlayer}})</pre>" }, ForEachWorld = { Params = "CallbackFunction", Return = "", Notes = "Calls the given callback function for each world. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cWorld|cWorld}})</pre>" }, @@ -1821,6 +1890,36 @@ end }, }, -- cRoot + cScoreboard = + { + Desc = [[ + This class manages the objectives and teams of a single world. + ]], + Functions = + { + AddPlayerScore = { Params = "Name, Type, Value", Return = "", Notes = "Adds a value to all player scores of the specified objective type." }, + ForEachObjective = { Params = "CallBackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each objective in the scoreboard. Returns true if all objectives have been processed (including when there are zero objectives), or false if the callback function has aborted the enumeration by returning true. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cObjective|Objective}}, [CallbackData])</pre> The callback should return false or no value to continue with the next objective, or true to abort the enumeration." }, + ForEachTeam = { Params = "CallBackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each team in the scoreboard. Returns true if all teams have been processed (including when there are zero teams), or false if the callback function has aborted the enumeration by returning true. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cObjective|Objective}}, [CallbackData])</pre> The callback should return false or no value to continue with the next team, or true to abort the enumeration." }, + GetNumObjectives = { Params = "", Return = "number", Notes = "Returns the nuber of registered objectives." }, + GetNumTeams = { Params = "", Return = "number", Notes = "Returns the number of registered teams." }, + GetObjective = { Params = "string", Return = "{{cObjective}}", Notes = "Returns the objective with the specified name." }, + GetObjectiveIn = { Params = "DisplaySlot", Return = "{{cObjective}}", Notes = "Returns the objective in the specified display slot. Can be nil." }, + GetTeam = { Params = "string", Return = "{{cTeam}}", Notes = "Returns the team with the specified name." }, + RegisterObjective = { Params = "Name, DisplayName, Type", Return = "{{cObjective}}", Notes = "Registers a new scoreboard objective. Returns the {{cObjective}} instance, nil on error." }, + RegisterTeam = { Params = "Name, DisplayName, Prefix, Suffix", Return = "{{cTeam}}", Notes = "Registers a new team. Returns the {{cTeam}} instance, nil on error." }, + RemoveObjective = { Params = "string", Return = "bool", Notes = "Removes the objective with the specified name. Returns true if operation was successful." }, + RemoveTeam = { Params = "string", Return = "bool", Notes = "Removes the team with the specified name. Returns true if operation was successful." }, + SetDisplay = { Params = "Name, DisplaySlot", Return = "", Notes = "Updates the currently displayed objective." }, + }, + Constants = + { + dsCount = { Notes = "" }, + dsList = { Notes = "" }, + dsName = { Notes = "" }, + dsSidebar = { Notes = "" }, + }, + }, -- cScoreboard + cServer = { Desc = [[ @@ -1841,6 +1940,32 @@ end }, }, -- cServer + cTeam = + { + Desc = [[ + This class manages a single player team. + ]], + Functions = + { + AddPlayer = { Params = "string", Returns = "bool", Notes = "Adds a player to this team. Returns true if the operation was successful." }, + AllowsFriendlyFire = { Params = "", Return = "bool", Notes = "Returns whether team friendly fire is allowed." }, + CanSeeFriendlyInvisible = { Params = "", Return = "bool", Notes = "Returns whether players can see invisible teammates." }, + HasPlayer = { Params = "string", Returns = "bool", Notes = "Returns whether the specified player is a member of this team." }, + GetDisplayName = { Params = "", Return = "string", Notes = "Returns the display name of the team." }, + GetName = { Params = "", Return = "string", Notes = "Returns the internal name of the team." }, + GetNumPlayers = { Params = "", Return = "number", Notes = "Returns the number of registered players." }, + GetPrefix = { Params = "", Return = "string", Notes = "Returns the prefix prepended to the names of the members of this team." }, + RemovePlayer = { Params = "string", Returns = "bool", Notes = "Removes the player with the specified name from this team. Returns true if the operation was successful." }, + Reset = { Params = "", Returns = "", Notes = "Removes all players from this team." }, + GetSuffix = { Params = "", Return = "string", Notes = "Returns the suffix appended to the names of the members of this team." }, + SetCanSeeFriendlyInvisible = { Params = "bool", Return = "", Notes = "Set whether players can see invisible teammates." }, + SetDisplayName = { Params = "string", Return = "", Notes = "Sets the display name of this team. (i.e. what will be shown to the players)" }, + SetFriendlyFire = { Params = "bool", Return = "", Notes = "Sets whether team friendly fire is allowed." }, + SetPrefix = { Params = "string", Return = "", Notes = "Sets the prefix prepended to the names of the members of this team." }, + SetSuffix = { Params = "string", Return = "", Notes = "Sets the suffix appended to the names of the members of this team." }, + }, + }, -- cTeam + cTNTEntity = { Desc = "This class manages a TNT entity.", diff --git a/MCServer/Plugins/APIDump/Classes/BlockEntities.lua b/MCServer/Plugins/APIDump/Classes/BlockEntities.lua index cf258160c..61a8e8d22 100644 --- a/MCServer/Plugins/APIDump/Classes/BlockEntities.lua +++ b/MCServer/Plugins/APIDump/Classes/BlockEntities.lua @@ -196,9 +196,11 @@ World:ForEachChestInChunk(Player:GetChunkX(), Player:GetChunkZ(), Inherits = "cBlockEntity", Functions = { - EjectRecord = { Params = "", Return = "", Notes = "Ejects the current record as a {{cPickup|pickup}}. No action if there's no current record. To remove record without generating the pickup, use SetRecord(0)" }, + EjectRecord = { Params = "", Return = "bool", Notes = "Ejects the current record as a {{cPickup|pickup}}. No action if there's no current record. To remove record without generating the pickup, use SetRecord(0). Returns true if pickup ejected." }, GetRecord = { Params = "", Return = "number", Notes = "Returns the record currently present. Zero for no record, E_ITEM_*_DISC for records." }, - PlayRecord = { Params = "", Return = "", Notes = "Plays the currently present record. No action if there's no current record." }, + IsPlayingRecord = { Params = "", Return = "bool", Notes = "Returns true if the jukebox is playing a record." }, + IsRecordItem = { Params = "ItemType", Return = "bool", Notes = "Returns true if the specified item is a record that can be played." }, + PlayRecord = { Params = "RecordItemType", Return = "bool", Notes = "Plays the specified Record. Return false if the parameter isn't a playable Record (E_ITEM_XXX_DISC). If there is a record already playing, ejects it first." }, SetRecord = { Params = "number", Return = "", Notes = "Sets the currently present record. Use zero for no record, or E_ITEM_*_DISC for records." }, }, }, -- cJukeboxEntity diff --git a/MCServer/Plugins/InfoDump.lua b/MCServer/Plugins/InfoDump.lua index 8fac09d60..e7ed157e3 100644 --- a/MCServer/Plugins/InfoDump.lua +++ b/MCServer/Plugins/InfoDump.lua @@ -578,7 +578,10 @@ local function DumpPluginInfoForum(a_PluginFolder, a_PluginInfo) DumpAdditionalInfoForum(a_PluginInfo, f); DumpCommandsForum(a_PluginInfo, f); DumpPermissionsForum(a_PluginInfo, f); - + if (a_PluginInfo.SourceLocation ~= nil) then + f:write("[b][color=blue]Source:[/color] [url=", a_PluginInfo.SourceLocation, "]Link[/url][/b]"); + end + f:close(); end diff --git a/src/Bindings/AllToLua.pkg b/src/Bindings/AllToLua.pkg index 6537437cd..6b067b1e5 100644 --- a/src/Bindings/AllToLua.pkg +++ b/src/Bindings/AllToLua.pkg @@ -26,6 +26,7 @@ $cfile "WebPlugin.h" $cfile "LuaWindow.h" $cfile "../BlockID.h" +$cfile "../BlockInfo.h" $cfile "../StringUtils.h" $cfile "../Defines.h" $cfile "../ChatColor.h" @@ -75,6 +76,7 @@ $cfile "../Mobs/Monster.h" $cfile "../CompositeChat.h" $cfile "../Map.h" $cfile "../MapManager.h" +$cfile "../Scoreboard.h" diff --git a/src/Bindings/DeprecatedBindings.cpp b/src/Bindings/DeprecatedBindings.cpp new file mode 100644 index 000000000..408b1b84a --- /dev/null +++ b/src/Bindings/DeprecatedBindings.cpp @@ -0,0 +1,506 @@ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "DeprecatedBindings.h" +#include "tolua++/include/tolua++.h" + +#include "Plugin.h" +#include "PluginLua.h" +#include "PluginManager.h" +#include "LuaWindow.h" +#include "LuaChunkStay.h" + +#include "../BlockInfo.h" + + + + + +/* get function: g_BlockLightValue */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockLightValue +static int tolua_get_AllToLua_g_BlockLightValue(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + tolua_pushnumber(tolua_S,(lua_Number)cBlockInfo::GetLightValue(tolua_index)); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + + + + + +/* set function: g_BlockLightValue */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockLightValue +static int tolua_set_AllToLua_g_BlockLightValue(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + cBlockInfo::Get(tolua_index).m_LightValue = ((unsigned char) tolua_tonumber(tolua_S,3,0)); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + + + + + +/* get function: g_BlockSpreadLightFalloff */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockSpreadLightFalloff +static int tolua_get_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + tolua_pushnumber(tolua_S,(lua_Number)cBlockInfo::GetSpreadLightFalloff(tolua_index)); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + + + + + +/* set function: g_BlockSpreadLightFalloff */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockSpreadLightFalloff +static int tolua_set_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + cBlockInfo::Get(tolua_index).m_SpreadLightFalloff = ((unsigned char) tolua_tonumber(tolua_S,3,0)); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + + + + + +/* get function: g_BlockTransparent */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockTransparent +static int tolua_get_AllToLua_g_BlockTransparent(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + tolua_pushboolean(tolua_S, cBlockInfo::IsTransparent(tolua_index)); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + + + + + +/* set function: g_BlockTransparent */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockTransparent +static int tolua_set_AllToLua_g_BlockTransparent(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + cBlockInfo::Get(tolua_index).m_Transparent = (tolua_toboolean(tolua_S,3,0) != 0); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + + + + + +/* get function: g_BlockOneHitDig */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockOneHitDig +static int tolua_get_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + tolua_pushboolean(tolua_S,(bool)cBlockInfo::IsOneHitDig(tolua_index)); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + + + + + +/* set function: g_BlockOneHitDig */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockOneHitDig +static int tolua_set_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + cBlockInfo::Get(tolua_index).m_OneHitDig = (tolua_toboolean(tolua_S,3,0) != 0); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + + + + + +/* get function: g_BlockPistonBreakable */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockPistonBreakable +static int tolua_get_AllToLua_g_BlockPistonBreakable(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0 || tolua_index>=256) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + tolua_pushboolean(tolua_S,(bool)cBlockInfo::IsPistonBreakable(tolua_index)); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + + + + + +/* set function: g_BlockPistonBreakable */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockPistonBreakable +static int tolua_set_AllToLua_g_BlockPistonBreakable(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0 || tolua_index>=256) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + cBlockInfo::Get(tolua_index).m_PistonBreakable = (tolua_toboolean(tolua_S,3,0) != 0); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + + + + + +/* get function: g_BlockIsSnowable */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockIsSnowable +static int tolua_get_AllToLua_g_BlockIsSnowable(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0 || tolua_index>=256) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + tolua_pushboolean(tolua_S,(bool)cBlockInfo::IsSnowable(tolua_index)); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + + + + + +/* set function: g_BlockIsSnowable */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockIsSnowable +static int tolua_set_AllToLua_g_BlockIsSnowable(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0 || tolua_index>=256) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + cBlockInfo::Get(tolua_index).m_IsSnowable = (tolua_toboolean(tolua_S,3,0) != 0); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + + + + + +/* get function: g_BlockRequiresSpecialTool */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockRequiresSpecialTool +static int tolua_get_AllToLua_g_BlockRequiresSpecialTool(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0 || tolua_index>=256) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + tolua_pushboolean(tolua_S,(bool)cBlockInfo::RequiresSpecialTool(tolua_index)); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + + + + + +/* set function: g_BlockRequiresSpecialTool */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockRequiresSpecialTool +static int tolua_set_AllToLua_g_BlockRequiresSpecialTool(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0 || tolua_index>=256) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + cBlockInfo::Get(tolua_index).m_RequiresSpecialTool = (tolua_toboolean(tolua_S,3,0) != 0); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + + + + + +/* get function: g_BlockIsSolid */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockIsSolid +static int tolua_get_AllToLua_g_BlockIsSolid(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0 || tolua_index>=256) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + tolua_pushboolean(tolua_S,(bool)cBlockInfo::IsSolid(tolua_index)); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + + + + + +/* set function: g_BlockIsSolid */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockIsSolid +static int tolua_set_AllToLua_g_BlockIsSolid(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0 || tolua_index>=256) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + cBlockInfo::Get(tolua_index).m_IsSolid = (tolua_toboolean(tolua_S,3,0) != 0); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + + + + + +/* get function: g_BlockFullyOccupiesVoxel */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockFullyOccupiesVoxel +static int tolua_get_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0 || tolua_index>=256) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + tolua_pushboolean(tolua_S,(bool)cBlockInfo::FullyOccupiesVoxel(tolua_index)); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + + + + + +/* set function: g_BlockFullyOccupiesVoxel */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockFullyOccupiesVoxel +static int tolua_set_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0 || tolua_index>=256) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + cBlockInfo::Get(tolua_index).m_FullyOccupiesVoxel = (tolua_toboolean(tolua_S,3,0) != 0); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + + + + + +void DeprecatedBindings::Bind(lua_State * tolua_S) +{ + tolua_beginmodule(tolua_S, NULL); + + tolua_array(tolua_S, "g_BlockLightValue", tolua_get_AllToLua_g_BlockLightValue, tolua_set_AllToLua_g_BlockLightValue); + tolua_array(tolua_S, "g_BlockSpreadLightFalloff", tolua_get_AllToLua_g_BlockSpreadLightFalloff, tolua_set_AllToLua_g_BlockSpreadLightFalloff); + tolua_array(tolua_S, "g_BlockTransparent", tolua_get_AllToLua_g_BlockTransparent, tolua_set_AllToLua_g_BlockTransparent); + tolua_array(tolua_S, "g_BlockOneHitDig", tolua_get_AllToLua_g_BlockOneHitDig, tolua_set_AllToLua_g_BlockOneHitDig); + tolua_array(tolua_S, "g_BlockPistonBreakable", tolua_get_AllToLua_g_BlockPistonBreakable, tolua_set_AllToLua_g_BlockPistonBreakable); + tolua_array(tolua_S, "g_BlockIsSnowable", tolua_get_AllToLua_g_BlockIsSnowable, tolua_set_AllToLua_g_BlockIsSnowable); + tolua_array(tolua_S, "g_BlockRequiresSpecialTool", tolua_get_AllToLua_g_BlockRequiresSpecialTool, tolua_set_AllToLua_g_BlockRequiresSpecialTool); + tolua_array(tolua_S, "g_BlockIsSolid", tolua_get_AllToLua_g_BlockIsSolid, tolua_set_AllToLua_g_BlockIsSolid); + tolua_array(tolua_S, "g_BlockFullyOccupiesVoxel", tolua_get_AllToLua_g_BlockFullyOccupiesVoxel, tolua_set_AllToLua_g_BlockFullyOccupiesVoxel); + + tolua_endmodule(tolua_S); +} + + + + diff --git a/src/Bindings/DeprecatedBindings.h b/src/Bindings/DeprecatedBindings.h new file mode 100644 index 000000000..5fc3cfa80 --- /dev/null +++ b/src/Bindings/DeprecatedBindings.h @@ -0,0 +1,8 @@ +#pragma once + +struct lua_State; +class DeprecatedBindings +{ +public: + static void Bind( lua_State* tolua_S ); +}; diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 45a066efe..a5540df17 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -14,6 +14,7 @@ extern "C" #include "tolua++/include/tolua++.h" #include "Bindings.h" #include "ManualBindings.h" +#include "DeprecatedBindings.h" // fwd: SQLite/lsqlite3.c extern "C" @@ -95,6 +96,7 @@ void cLuaState::Create(void) luaL_openlibs(m_LuaState); tolua_AllToLua_open(m_LuaState); ManualBindings::Bind(m_LuaState); + DeprecatedBindings::Bind(m_LuaState); luaopen_lsqlite3(m_LuaState); luaopen_lxp(m_LuaState); m_IsOwned = true; diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 461186d3b..fcdd728be 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2583,6 +2583,11 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_beginmodule(tolua_S, "cMapManager"); tolua_function(tolua_S, "DoWithMap", tolua_DoWithID<cMapManager, cMap, &cMapManager::DoWithMap>); tolua_endmodule(tolua_S); + + tolua_beginmodule(tolua_S, "cScoreboard"); + tolua_function(tolua_S, "ForEachObjective", tolua_ForEach<cScoreboard, cObjective, &cScoreboard::ForEachObjective>); + tolua_function(tolua_S, "ForEachTeam", tolua_ForEach<cScoreboard, cTeam, &cScoreboard::ForEachTeam>); + tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cPlugin"); tolua_function(tolua_S, "Call", tolua_cPlugin_Call); diff --git a/src/BlockEntities/JukeboxEntity.h b/src/BlockEntities/JukeboxEntity.h index 01ce52494..3d1d604f7 100644 --- a/src/BlockEntities/JukeboxEntity.h +++ b/src/BlockEntities/JukeboxEntity.h @@ -38,10 +38,11 @@ public: int GetRecord(void); void SetRecord(int a_Record); - /** Play a Record. Return false, when a_Record isn't a Record */ + /** Plays the specified Record. Return false if a_Record isn't a playable Record (E_ITEM_XXX_DISC). + If there is a record already playing, ejects it first. */ bool PlayRecord(int a_Record); - /** Ejects the currently held record as a pickup. Return false when no record inserted. */ + /** Ejects the currently held record as a pickup. Return false when no record had been inserted. */ bool EjectRecord(void); /** Is in the Jukebox a Record? */ diff --git a/src/BlockID.cpp b/src/BlockID.cpp index ff1c54e3f..79e122032 100644 --- a/src/BlockID.cpp +++ b/src/BlockID.cpp @@ -12,20 +12,6 @@ -NIBBLETYPE g_BlockLightValue[256]; -NIBBLETYPE g_BlockSpreadLightFalloff[256]; -bool g_BlockTransparent[256]; -bool g_BlockOneHitDig[256]; -bool g_BlockPistonBreakable[256]; -bool g_BlockIsSnowable[256]; -bool g_BlockRequiresSpecialTool[256]; -bool g_BlockIsSolid[256]; -bool g_BlockFullyOccupiesVoxel[256]; - - - - - class cBlockIDMap { // Making the map case-insensitive: @@ -481,389 +467,4 @@ cItem GetIniItemSet(cIniFile & a_IniFile, const char * a_Section, const char * a -// This is actually just some code that needs to run at program startup, so it is wrapped into a global var's constructor: -class cBlockPropertiesInitializer -{ -public: - cBlockPropertiesInitializer(void) - { - memset(g_BlockLightValue, 0x00, sizeof(g_BlockLightValue)); - memset(g_BlockSpreadLightFalloff, 0x0f, sizeof(g_BlockSpreadLightFalloff)); // 0x0f means total falloff - memset(g_BlockTransparent, 0x00, sizeof(g_BlockTransparent)); - memset(g_BlockOneHitDig, 0x00, sizeof(g_BlockOneHitDig)); - memset(g_BlockPistonBreakable, 0x00, sizeof(g_BlockPistonBreakable)); - memset(g_BlockFullyOccupiesVoxel, 0x00, sizeof(g_BlockFullyOccupiesVoxel)); - - // Setting bools to true must be done manually, see http://forum.mc-server.org/showthread.php?tid=629&pid=5415#pid5415 - for (size_t i = 0; i < ARRAYCOUNT(g_BlockIsSnowable); i++) - { - g_BlockIsSnowable[i] = true; - } - memset(g_BlockRequiresSpecialTool, 0x00, sizeof(g_BlockRequiresSpecialTool)); // Set all blocks to false - - // Setting bools to true must be done manually, see http://forum.mc-server.org/showthread.php?tid=629&pid=5415#pid5415 - for (size_t i = 0; i < ARRAYCOUNT(g_BlockIsSolid); i++) - { - g_BlockIsSolid[i] = true; - } - - // Emissive blocks - g_BlockLightValue[E_BLOCK_FIRE] = 15; - g_BlockLightValue[E_BLOCK_GLOWSTONE] = 15; - g_BlockLightValue[E_BLOCK_JACK_O_LANTERN] = 15; - g_BlockLightValue[E_BLOCK_LAVA] = 15; - g_BlockLightValue[E_BLOCK_STATIONARY_LAVA] = 15; - g_BlockLightValue[E_BLOCK_END_PORTAL] = 15; - g_BlockLightValue[E_BLOCK_REDSTONE_LAMP_ON] = 15; - g_BlockLightValue[E_BLOCK_TORCH] = 14; - g_BlockLightValue[E_BLOCK_BURNING_FURNACE] = 13; - g_BlockLightValue[E_BLOCK_NETHER_PORTAL] = 11; - g_BlockLightValue[E_BLOCK_REDSTONE_ORE_GLOWING] = 9; - g_BlockLightValue[E_BLOCK_REDSTONE_REPEATER_ON] = 9; - g_BlockLightValue[E_BLOCK_REDSTONE_TORCH_ON] = 7; - g_BlockLightValue[E_BLOCK_BREWING_STAND] = 1; - g_BlockLightValue[E_BLOCK_BROWN_MUSHROOM] = 1; - g_BlockLightValue[E_BLOCK_DRAGON_EGG] = 1; - - // Spread blocks - g_BlockSpreadLightFalloff[E_BLOCK_AIR] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_CAKE] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_CHEST] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_COBWEB] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_CROPS] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_FENCE] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_FENCE_GATE] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_FIRE] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_GLASS] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_GLASS_PANE] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_GLOWSTONE] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_IRON_BARS] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_IRON_DOOR] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_LEAVES] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_SIGN_POST] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_TORCH] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_VINES] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_WALLSIGN] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_WOODEN_DOOR] = 1; - - // Light in water and lava dissapears faster: - g_BlockSpreadLightFalloff[E_BLOCK_LAVA] = 3; - g_BlockSpreadLightFalloff[E_BLOCK_STATIONARY_LAVA] = 3; - g_BlockSpreadLightFalloff[E_BLOCK_STATIONARY_WATER] = 3; - g_BlockSpreadLightFalloff[E_BLOCK_WATER] = 3; - - // Transparent blocks - g_BlockTransparent[E_BLOCK_ACTIVATOR_RAIL] = true; - g_BlockTransparent[E_BLOCK_AIR] = true; - g_BlockTransparent[E_BLOCK_BIG_FLOWER] = true; - g_BlockTransparent[E_BLOCK_BROWN_MUSHROOM] = true; - g_BlockTransparent[E_BLOCK_CARROTS] = true; - g_BlockTransparent[E_BLOCK_CHEST] = true; - g_BlockTransparent[E_BLOCK_COBWEB] = true; - g_BlockTransparent[E_BLOCK_CROPS] = true; - g_BlockTransparent[E_BLOCK_DANDELION] = true; - g_BlockTransparent[E_BLOCK_DETECTOR_RAIL] = true; - g_BlockTransparent[E_BLOCK_ENDER_CHEST] = true; - g_BlockTransparent[E_BLOCK_FENCE] = true; - g_BlockTransparent[E_BLOCK_FENCE_GATE] = true; - g_BlockTransparent[E_BLOCK_FIRE] = true; - g_BlockTransparent[E_BLOCK_FLOWER] = true; - g_BlockTransparent[E_BLOCK_FLOWER_POT] = true; - g_BlockTransparent[E_BLOCK_GLASS] = true; - g_BlockTransparent[E_BLOCK_GLASS_PANE] = true; - g_BlockTransparent[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE] = true; - g_BlockTransparent[E_BLOCK_ICE] = true; - g_BlockTransparent[E_BLOCK_IRON_DOOR] = true; - g_BlockTransparent[E_BLOCK_LAVA] = true; - g_BlockTransparent[E_BLOCK_LEAVES] = true; - g_BlockTransparent[E_BLOCK_LEVER] = true; - g_BlockTransparent[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE] = true; - g_BlockTransparent[E_BLOCK_MELON_STEM] = true; - g_BlockTransparent[E_BLOCK_NETHER_BRICK_FENCE] = true; - g_BlockTransparent[E_BLOCK_NEW_LEAVES] = true; - g_BlockTransparent[E_BLOCK_POTATOES] = true; - g_BlockTransparent[E_BLOCK_POWERED_RAIL] = true; - g_BlockTransparent[E_BLOCK_PISTON_EXTENSION] = true; - g_BlockTransparent[E_BLOCK_PUMPKIN_STEM] = true; - g_BlockTransparent[E_BLOCK_RAIL] = true; - g_BlockTransparent[E_BLOCK_RED_MUSHROOM] = true; - g_BlockTransparent[E_BLOCK_SIGN_POST] = true; - g_BlockTransparent[E_BLOCK_SNOW] = true; - g_BlockTransparent[E_BLOCK_STAINED_GLASS] = true; - g_BlockTransparent[E_BLOCK_STAINED_GLASS_PANE] = true; - g_BlockTransparent[E_BLOCK_STATIONARY_LAVA] = true; - g_BlockTransparent[E_BLOCK_STATIONARY_WATER] = true; - g_BlockTransparent[E_BLOCK_STONE_BUTTON] = true; - g_BlockTransparent[E_BLOCK_STONE_PRESSURE_PLATE] = true; - g_BlockTransparent[E_BLOCK_TALL_GRASS] = true; - g_BlockTransparent[E_BLOCK_TORCH] = true; - g_BlockTransparent[E_BLOCK_VINES] = true; - g_BlockTransparent[E_BLOCK_WALLSIGN] = true; - g_BlockTransparent[E_BLOCK_WATER] = true; - g_BlockTransparent[E_BLOCK_WOODEN_BUTTON] = true; - g_BlockTransparent[E_BLOCK_WOODEN_DOOR] = true; - g_BlockTransparent[E_BLOCK_WOODEN_PRESSURE_PLATE] = true; - - // TODO: Any other transparent blocks? - - // One hit break blocks: - g_BlockOneHitDig[E_BLOCK_ACTIVE_COMPARATOR] = true; - g_BlockOneHitDig[E_BLOCK_BIG_FLOWER] = true; - g_BlockOneHitDig[E_BLOCK_BROWN_MUSHROOM] = true; - g_BlockOneHitDig[E_BLOCK_CARROTS] = true; - g_BlockOneHitDig[E_BLOCK_CROPS] = true; - g_BlockOneHitDig[E_BLOCK_DANDELION] = true; - g_BlockOneHitDig[E_BLOCK_FIRE] = true; - g_BlockOneHitDig[E_BLOCK_FLOWER] = true; - g_BlockOneHitDig[E_BLOCK_FLOWER_POT] = true; - g_BlockOneHitDig[E_BLOCK_INACTIVE_COMPARATOR] = true; - g_BlockOneHitDig[E_BLOCK_MELON_STEM] = true; - g_BlockOneHitDig[E_BLOCK_POTATOES] = true; - g_BlockOneHitDig[E_BLOCK_PUMPKIN_STEM] = true; - g_BlockOneHitDig[E_BLOCK_REDSTONE_REPEATER_OFF] = true; - g_BlockOneHitDig[E_BLOCK_REDSTONE_REPEATER_ON] = true; - g_BlockOneHitDig[E_BLOCK_REDSTONE_TORCH_OFF] = true; - g_BlockOneHitDig[E_BLOCK_REDSTONE_TORCH_ON] = true; - g_BlockOneHitDig[E_BLOCK_REDSTONE_WIRE] = true; - g_BlockOneHitDig[E_BLOCK_RED_MUSHROOM] = true; - g_BlockOneHitDig[E_BLOCK_REEDS] = true; - g_BlockOneHitDig[E_BLOCK_SAPLING] = true; - g_BlockOneHitDig[E_BLOCK_TNT] = true; - g_BlockOneHitDig[E_BLOCK_TALL_GRASS] = true; - g_BlockOneHitDig[E_BLOCK_TORCH] = true; - - // Blocks that break when pushed by piston: - g_BlockPistonBreakable[E_BLOCK_ACTIVE_COMPARATOR] = true; - g_BlockPistonBreakable[E_BLOCK_AIR] = true; - g_BlockPistonBreakable[E_BLOCK_BED] = true; - g_BlockPistonBreakable[E_BLOCK_BIG_FLOWER] = true; - g_BlockPistonBreakable[E_BLOCK_BROWN_MUSHROOM] = true; - g_BlockPistonBreakable[E_BLOCK_COBWEB] = true; - g_BlockPistonBreakable[E_BLOCK_CROPS] = true; - g_BlockPistonBreakable[E_BLOCK_DANDELION] = true; - g_BlockPistonBreakable[E_BLOCK_DEAD_BUSH] = true; - g_BlockPistonBreakable[E_BLOCK_FIRE] = true; - g_BlockPistonBreakable[E_BLOCK_FLOWER] = true; - g_BlockPistonBreakable[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE] = true; - g_BlockPistonBreakable[E_BLOCK_INACTIVE_COMPARATOR] = true; - g_BlockPistonBreakable[E_BLOCK_IRON_DOOR] = true; - g_BlockPistonBreakable[E_BLOCK_JACK_O_LANTERN] = true; - g_BlockPistonBreakable[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE] = true; - g_BlockPistonBreakable[E_BLOCK_LADDER] = true; - g_BlockPistonBreakable[E_BLOCK_LAVA] = true; - g_BlockPistonBreakable[E_BLOCK_LEVER] = true; - g_BlockPistonBreakable[E_BLOCK_MELON] = true; - g_BlockPistonBreakable[E_BLOCK_MELON_STEM] = true; - g_BlockPistonBreakable[E_BLOCK_PUMPKIN] = true; - g_BlockPistonBreakable[E_BLOCK_PUMPKIN_STEM] = true; - g_BlockPistonBreakable[E_BLOCK_REDSTONE_REPEATER_OFF] = true; - g_BlockPistonBreakable[E_BLOCK_REDSTONE_REPEATER_ON] = true; - g_BlockPistonBreakable[E_BLOCK_REDSTONE_TORCH_OFF] = true; - g_BlockPistonBreakable[E_BLOCK_REDSTONE_TORCH_ON] = true; - g_BlockPistonBreakable[E_BLOCK_REDSTONE_WIRE] = true; - g_BlockPistonBreakable[E_BLOCK_RED_MUSHROOM] = true; - g_BlockPistonBreakable[E_BLOCK_REEDS] = true; - g_BlockPistonBreakable[E_BLOCK_SNOW] = true; - g_BlockPistonBreakable[E_BLOCK_STATIONARY_LAVA] = true; - g_BlockPistonBreakable[E_BLOCK_STATIONARY_WATER] = true; - g_BlockPistonBreakable[E_BLOCK_STONE_BUTTON] = true; - g_BlockPistonBreakable[E_BLOCK_STONE_PRESSURE_PLATE] = true; - g_BlockPistonBreakable[E_BLOCK_TALL_GRASS] = true; - g_BlockPistonBreakable[E_BLOCK_TORCH] = true; - g_BlockPistonBreakable[E_BLOCK_VINES] = true; - g_BlockPistonBreakable[E_BLOCK_WATER] = true; - g_BlockPistonBreakable[E_BLOCK_WOODEN_BUTTON] = true; - g_BlockPistonBreakable[E_BLOCK_WOODEN_DOOR] = true; - g_BlockPistonBreakable[E_BLOCK_WOODEN_PRESSURE_PLATE] = true; - - - // Blocks that cannot be snowed over: - g_BlockIsSnowable[E_BLOCK_ACTIVE_COMPARATOR] = false; - g_BlockIsSnowable[E_BLOCK_AIR] = false; - g_BlockIsSnowable[E_BLOCK_BIG_FLOWER] = false; - g_BlockIsSnowable[E_BLOCK_BROWN_MUSHROOM] = false; - g_BlockIsSnowable[E_BLOCK_CACTUS] = false; - g_BlockIsSnowable[E_BLOCK_CHEST] = false; - g_BlockIsSnowable[E_BLOCK_CROPS] = false; - g_BlockIsSnowable[E_BLOCK_DANDELION] = false; - g_BlockIsSnowable[E_BLOCK_FIRE] = false; - g_BlockIsSnowable[E_BLOCK_FLOWER] = false; - g_BlockIsSnowable[E_BLOCK_GLASS] = false; - g_BlockIsSnowable[E_BLOCK_ICE] = false; - g_BlockIsSnowable[E_BLOCK_INACTIVE_COMPARATOR] = false; - g_BlockIsSnowable[E_BLOCK_LAVA] = false; - g_BlockIsSnowable[E_BLOCK_LILY_PAD] = false; - g_BlockIsSnowable[E_BLOCK_REDSTONE_REPEATER_OFF] = false; - g_BlockIsSnowable[E_BLOCK_REDSTONE_REPEATER_ON] = false; - g_BlockIsSnowable[E_BLOCK_REDSTONE_TORCH_OFF] = false; - g_BlockIsSnowable[E_BLOCK_REDSTONE_TORCH_ON] = false; - g_BlockIsSnowable[E_BLOCK_REDSTONE_WIRE] = false; - g_BlockIsSnowable[E_BLOCK_RED_MUSHROOM] = false; - g_BlockIsSnowable[E_BLOCK_REEDS] = false; - g_BlockIsSnowable[E_BLOCK_SAPLING] = false; - g_BlockIsSnowable[E_BLOCK_SIGN_POST] = false; - g_BlockIsSnowable[E_BLOCK_SNOW] = false; - g_BlockIsSnowable[E_BLOCK_STAINED_GLASS] = false; - g_BlockIsSnowable[E_BLOCK_STAINED_GLASS_PANE] = false; - g_BlockIsSnowable[E_BLOCK_STATIONARY_LAVA] = false; - g_BlockIsSnowable[E_BLOCK_STATIONARY_WATER] = false; - g_BlockIsSnowable[E_BLOCK_TALL_GRASS] = false; - g_BlockIsSnowable[E_BLOCK_TNT] = false; - g_BlockIsSnowable[E_BLOCK_TORCH] = false; - g_BlockIsSnowable[E_BLOCK_VINES] = false; - g_BlockIsSnowable[E_BLOCK_WALLSIGN] = false; - g_BlockIsSnowable[E_BLOCK_WATER] = false; - - - // Blocks that don't drop without a special tool: - g_BlockRequiresSpecialTool[E_BLOCK_BRICK] = true; - g_BlockRequiresSpecialTool[E_BLOCK_CAULDRON] = true; - g_BlockRequiresSpecialTool[E_BLOCK_COAL_ORE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_COBBLESTONE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_COBBLESTONE_STAIRS] = true; - g_BlockRequiresSpecialTool[E_BLOCK_COBWEB] = true; - g_BlockRequiresSpecialTool[E_BLOCK_DIAMOND_BLOCK] = true; - g_BlockRequiresSpecialTool[E_BLOCK_DIAMOND_ORE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_DOUBLE_STONE_SLAB] = true; - g_BlockRequiresSpecialTool[E_BLOCK_EMERALD_ORE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_END_STONE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_GOLD_BLOCK] = true; - g_BlockRequiresSpecialTool[E_BLOCK_GOLD_ORE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_IRON_BLOCK] = true; - g_BlockRequiresSpecialTool[E_BLOCK_IRON_ORE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_LAPIS_BLOCK] = true; - g_BlockRequiresSpecialTool[E_BLOCK_LAPIS_ORE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_MOSSY_COBBLESTONE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_NETHERRACK] = true; - g_BlockRequiresSpecialTool[E_BLOCK_NETHER_BRICK] = true; - g_BlockRequiresSpecialTool[E_BLOCK_NETHER_BRICK_STAIRS] = true; - g_BlockRequiresSpecialTool[E_BLOCK_OBSIDIAN] = true; - g_BlockRequiresSpecialTool[E_BLOCK_REDSTONE_ORE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_REDSTONE_ORE_GLOWING] = true; - g_BlockRequiresSpecialTool[E_BLOCK_SANDSTONE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_SANDSTONE_STAIRS] = true; - g_BlockRequiresSpecialTool[E_BLOCK_SNOW] = true; - g_BlockRequiresSpecialTool[E_BLOCK_STONE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_STONE_BRICKS] = true; - g_BlockRequiresSpecialTool[E_BLOCK_STONE_BRICK_STAIRS] = true; - g_BlockRequiresSpecialTool[E_BLOCK_STONE_PRESSURE_PLATE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_STONE_SLAB] = true; - g_BlockRequiresSpecialTool[E_BLOCK_VINES] = true; - - // Nonsolid blocks: - g_BlockIsSolid[E_BLOCK_ACTIVATOR_RAIL] = false; - g_BlockIsSolid[E_BLOCK_AIR] = false; - g_BlockIsSolid[E_BLOCK_BIG_FLOWER] = false; - g_BlockIsSolid[E_BLOCK_BROWN_MUSHROOM] = false; - g_BlockIsSolid[E_BLOCK_CARROTS] = false; - g_BlockIsSolid[E_BLOCK_COBWEB] = false; - g_BlockIsSolid[E_BLOCK_CROPS] = false; - g_BlockIsSolid[E_BLOCK_DANDELION] = false; - g_BlockIsSolid[E_BLOCK_DETECTOR_RAIL] = false; - g_BlockIsSolid[E_BLOCK_END_PORTAL] = false; - g_BlockIsSolid[E_BLOCK_FIRE] = false; - g_BlockIsSolid[E_BLOCK_FLOWER] = false; - g_BlockIsSolid[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE] = false; - g_BlockIsSolid[E_BLOCK_LAVA] = false; - g_BlockIsSolid[E_BLOCK_LEVER] = false; - g_BlockIsSolid[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE] = false; - g_BlockIsSolid[E_BLOCK_MELON_STEM] = false; - g_BlockIsSolid[E_BLOCK_NETHER_PORTAL] = false; - g_BlockIsSolid[E_BLOCK_PISTON_EXTENSION] = false; - g_BlockIsSolid[E_BLOCK_POTATOES] = false; - g_BlockIsSolid[E_BLOCK_POWERED_RAIL] = false; - g_BlockIsSolid[E_BLOCK_RAIL] = false; - g_BlockIsSolid[E_BLOCK_REDSTONE_TORCH_OFF] = false; - g_BlockIsSolid[E_BLOCK_REDSTONE_TORCH_ON] = false; - g_BlockIsSolid[E_BLOCK_REDSTONE_WIRE] = false; - g_BlockIsSolid[E_BLOCK_RED_MUSHROOM] = false; - g_BlockIsSolid[E_BLOCK_REEDS] = false; - g_BlockIsSolid[E_BLOCK_SAPLING] = false; - g_BlockIsSolid[E_BLOCK_SIGN_POST] = false; - g_BlockIsSolid[E_BLOCK_SNOW] = false; - g_BlockIsSolid[E_BLOCK_STATIONARY_LAVA] = false; - g_BlockIsSolid[E_BLOCK_STATIONARY_WATER] = false; - g_BlockIsSolid[E_BLOCK_STONE_BUTTON] = false; - g_BlockIsSolid[E_BLOCK_STONE_PRESSURE_PLATE] = false; - g_BlockIsSolid[E_BLOCK_TALL_GRASS] = false; - g_BlockIsSolid[E_BLOCK_TORCH] = false; - g_BlockIsSolid[E_BLOCK_TRIPWIRE] = false; - g_BlockIsSolid[E_BLOCK_VINES] = false; - g_BlockIsSolid[E_BLOCK_WALLSIGN] = false; - g_BlockIsSolid[E_BLOCK_WATER] = false; - g_BlockIsSolid[E_BLOCK_WOODEN_BUTTON] = false; - g_BlockIsSolid[E_BLOCK_WOODEN_PRESSURE_PLATE] = false; - g_BlockIsSolid[E_BLOCK_WOODEN_SLAB] = false; - - // Torch placeable blocks: - g_BlockFullyOccupiesVoxel[E_BLOCK_NEW_LOG] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_BEDROCK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_BLOCK_OF_COAL] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_BLOCK_OF_REDSTONE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_BOOKCASE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_BRICK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_CLAY] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_COAL_ORE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_COBBLESTONE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_COMMAND_BLOCK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_CRAFTING_TABLE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_DIAMOND_BLOCK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_DIAMOND_ORE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_DIRT] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_DISPENSER] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_DOUBLE_STONE_SLAB] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_DOUBLE_WOODEN_SLAB] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_DROPPER] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_EMERALD_BLOCK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_EMERALD_ORE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_END_STONE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_FURNACE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_GLOWSTONE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_GOLD_BLOCK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_GOLD_ORE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_GRASS] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_GRAVEL] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_HARDENED_CLAY] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_HAY_BALE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_HUGE_BROWN_MUSHROOM] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_HUGE_RED_MUSHROOM] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_IRON_BLOCK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_IRON_ORE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_JACK_O_LANTERN] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_JUKEBOX] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_LAPIS_BLOCK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_LAPIS_ORE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_LOG] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_MELON] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_MOSSY_COBBLESTONE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_MYCELIUM] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_NETHERRACK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_NETHER_BRICK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_NETHER_QUARTZ_ORE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_NOTE_BLOCK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_OBSIDIAN] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_PACKED_ICE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_PLANKS] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_PUMPKIN] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_QUARTZ_BLOCK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_REDSTONE_LAMP_OFF] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_REDSTONE_LAMP_ON] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_REDSTONE_ORE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_REDSTONE_ORE_GLOWING] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_SANDSTONE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_SAND] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_SILVERFISH_EGG] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_SPONGE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_STAINED_CLAY] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_WOOL] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_STONE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_STONE_BRICKS] = true; - } -} BlockPropertiesInitializer; - - - - diff --git a/src/BlockID.h b/src/BlockID.h index 861bb8dae..1c454cd23 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -909,17 +909,3 @@ extern cItem GetIniItemSet(cIniFile & a_IniFile, const char * a_Section, const c -// Block properties: -extern NIBBLETYPE g_BlockLightValue[256]; -extern NIBBLETYPE g_BlockSpreadLightFalloff[256]; -extern bool g_BlockTransparent[256]; -extern bool g_BlockOneHitDig[256]; -extern bool g_BlockPistonBreakable[256]; -extern bool g_BlockIsSnowable[256]; -extern bool g_BlockRequiresSpecialTool[256]; -extern bool g_BlockIsSolid[256]; -extern bool g_BlockFullyOccupiesVoxel[256]; - - - - diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp new file mode 100644 index 000000000..399efcd9b --- /dev/null +++ b/src/BlockInfo.cpp @@ -0,0 +1,442 @@ + +#include "Globals.h" + +#include "BlockInfo.h" +#include "Blocks/BlockHandler.h" + + + + + +cBlockInfo cBlockInfo::ms_Info[256]; + + + + + +cBlockInfo::cBlockInfo() + : m_LightValue(0x00) + , m_SpreadLightFalloff(0x0f) + , m_Transparent(false) + , m_OneHitDig(false) + , m_PistonBreakable(false) + , m_IsSnowable(true) + , m_RequiresSpecialTool(false) + , m_IsSolid(true) + , m_FullyOccupiesVoxel(false) + , m_Handler(NULL) +{} + + + + + +cBlockInfo::~cBlockInfo() +{ + delete m_Handler; +} + + + + + +cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type) +{ + ASSERT(a_Type < 256); + + return ms_Info[a_Type]; +} + + + + + +void cBlockInfo::Initialize(void) +{ + for (unsigned int i = 0; i < 256; ++i) + { + if (ms_Info[i].m_Handler == NULL) + { + ms_Info[i].m_Handler = cBlockHandler::CreateBlockHandler((BLOCKTYPE) i); + } + } + + // Emissive blocks + ms_Info[E_BLOCK_FIRE ].m_LightValue = 15; + ms_Info[E_BLOCK_GLOWSTONE ].m_LightValue = 15; + ms_Info[E_BLOCK_JACK_O_LANTERN ].m_LightValue = 15; + ms_Info[E_BLOCK_LAVA ].m_LightValue = 15; + ms_Info[E_BLOCK_STATIONARY_LAVA ].m_LightValue = 15; + ms_Info[E_BLOCK_END_PORTAL ].m_LightValue = 15; + ms_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_LightValue = 15; + ms_Info[E_BLOCK_TORCH ].m_LightValue = 14; + ms_Info[E_BLOCK_BURNING_FURNACE ].m_LightValue = 13; + ms_Info[E_BLOCK_NETHER_PORTAL ].m_LightValue = 11; + ms_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_LightValue = 9; + ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_LightValue = 9; + ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_LightValue = 7; + ms_Info[E_BLOCK_BREWING_STAND ].m_LightValue = 1; + ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_LightValue = 1; + ms_Info[E_BLOCK_DRAGON_EGG ].m_LightValue = 1; + + + // Spread blocks + ms_Info[E_BLOCK_AIR ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_CAKE ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_CHEST ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_COBWEB ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_CROPS ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_FENCE ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_FENCE_GATE ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_FIRE ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_GLASS ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_GLASS_PANE ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_GLOWSTONE ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_IRON_BARS ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_IRON_DOOR ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_LEAVES ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_SIGN_POST ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_TORCH ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_VINES ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_WALLSIGN ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_WOODEN_DOOR ].m_SpreadLightFalloff = 1; + + // Light in water and lava dissapears faster: + ms_Info[E_BLOCK_LAVA ].m_SpreadLightFalloff = 3; + ms_Info[E_BLOCK_STATIONARY_LAVA ].m_SpreadLightFalloff = 3; + ms_Info[E_BLOCK_STATIONARY_WATER ].m_SpreadLightFalloff = 3; + ms_Info[E_BLOCK_WATER ].m_SpreadLightFalloff = 3; + + + // Transparent blocks + ms_Info[E_BLOCK_ACTIVATOR_RAIL ].m_Transparent = true; + ms_Info[E_BLOCK_AIR ].m_Transparent = true; + ms_Info[E_BLOCK_BIG_FLOWER ].m_Transparent = true; + ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_Transparent = true; + ms_Info[E_BLOCK_CARROTS ].m_Transparent = true; + ms_Info[E_BLOCK_CHEST ].m_Transparent = true; + ms_Info[E_BLOCK_COBWEB ].m_Transparent = true; + ms_Info[E_BLOCK_CROPS ].m_Transparent = true; + ms_Info[E_BLOCK_DANDELION ].m_Transparent = true; + ms_Info[E_BLOCK_DETECTOR_RAIL ].m_Transparent = true; + ms_Info[E_BLOCK_ENDER_CHEST ].m_Transparent = true; + ms_Info[E_BLOCK_FENCE ].m_Transparent = true; + ms_Info[E_BLOCK_FENCE_GATE ].m_Transparent = true; + ms_Info[E_BLOCK_FIRE ].m_Transparent = true; + ms_Info[E_BLOCK_FLOWER ].m_Transparent = true; + ms_Info[E_BLOCK_FLOWER_POT ].m_Transparent = true; + ms_Info[E_BLOCK_GLASS ].m_Transparent = true; + ms_Info[E_BLOCK_GLASS_PANE ].m_Transparent = true; + ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_Transparent = true; + ms_Info[E_BLOCK_ICE ].m_Transparent = true; + ms_Info[E_BLOCK_IRON_DOOR ].m_Transparent = true; + ms_Info[E_BLOCK_LAVA ].m_Transparent = true; + ms_Info[E_BLOCK_LEAVES ].m_Transparent = true; + ms_Info[E_BLOCK_LEVER ].m_Transparent = true; + ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_Transparent = true; + ms_Info[E_BLOCK_MELON_STEM ].m_Transparent = true; + ms_Info[E_BLOCK_NETHER_BRICK_FENCE ].m_Transparent = true; + ms_Info[E_BLOCK_NEW_LEAVES ].m_Transparent = true; + ms_Info[E_BLOCK_POTATOES ].m_Transparent = true; + ms_Info[E_BLOCK_POWERED_RAIL ].m_Transparent = true; + ms_Info[E_BLOCK_PISTON_EXTENSION ].m_Transparent = true; + ms_Info[E_BLOCK_PUMPKIN_STEM ].m_Transparent = true; + ms_Info[E_BLOCK_RAIL ].m_Transparent = true; + ms_Info[E_BLOCK_RED_MUSHROOM ].m_Transparent = true; + ms_Info[E_BLOCK_SIGN_POST ].m_Transparent = true; + ms_Info[E_BLOCK_SNOW ].m_Transparent = true; + ms_Info[E_BLOCK_STAINED_GLASS ].m_Transparent = true; + ms_Info[E_BLOCK_STAINED_GLASS_PANE ].m_Transparent = true; + ms_Info[E_BLOCK_STATIONARY_LAVA ].m_Transparent = true; + ms_Info[E_BLOCK_STATIONARY_WATER ].m_Transparent = true; + ms_Info[E_BLOCK_STONE_BUTTON ].m_Transparent = true; + ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_Transparent = true; + ms_Info[E_BLOCK_TALL_GRASS ].m_Transparent = true; + ms_Info[E_BLOCK_TORCH ].m_Transparent = true; + ms_Info[E_BLOCK_VINES ].m_Transparent = true; + ms_Info[E_BLOCK_WALLSIGN ].m_Transparent = true; + ms_Info[E_BLOCK_WATER ].m_Transparent = true; + ms_Info[E_BLOCK_WOODEN_BUTTON ].m_Transparent = true; + ms_Info[E_BLOCK_WOODEN_DOOR ].m_Transparent = true; + ms_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_Transparent = true; + + // TODO: Any other transparent blocks? + + + // One hit break blocks: + ms_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_OneHitDig = true; + ms_Info[E_BLOCK_BIG_FLOWER ].m_OneHitDig = true; + ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_OneHitDig = true; + ms_Info[E_BLOCK_CARROTS ].m_OneHitDig = true; + ms_Info[E_BLOCK_CROPS ].m_OneHitDig = true; + ms_Info[E_BLOCK_DANDELION ].m_OneHitDig = true; + ms_Info[E_BLOCK_FIRE ].m_OneHitDig = true; + ms_Info[E_BLOCK_FLOWER ].m_OneHitDig = true; + ms_Info[E_BLOCK_FLOWER_POT ].m_OneHitDig = true; + ms_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_OneHitDig = true; + ms_Info[E_BLOCK_MELON_STEM ].m_OneHitDig = true; + ms_Info[E_BLOCK_POTATOES ].m_OneHitDig = true; + ms_Info[E_BLOCK_PUMPKIN_STEM ].m_OneHitDig = true; + ms_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_OneHitDig = true; + ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_OneHitDig = true; + ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_OneHitDig = true; + ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_OneHitDig = true; + ms_Info[E_BLOCK_REDSTONE_WIRE ].m_OneHitDig = true; + ms_Info[E_BLOCK_RED_MUSHROOM ].m_OneHitDig = true; + ms_Info[E_BLOCK_REEDS ].m_OneHitDig = true; + ms_Info[E_BLOCK_SAPLING ].m_OneHitDig = true; + ms_Info[E_BLOCK_TNT ].m_OneHitDig = true; + ms_Info[E_BLOCK_TALL_GRASS ].m_OneHitDig = true; + ms_Info[E_BLOCK_TORCH ].m_OneHitDig = true; + + + // Blocks that break when pushed by piston: + ms_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_PistonBreakable = true; + ms_Info[E_BLOCK_AIR ].m_PistonBreakable = true; + ms_Info[E_BLOCK_BED ].m_PistonBreakable = true; + ms_Info[E_BLOCK_BIG_FLOWER ].m_PistonBreakable = true; + ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_PistonBreakable = true; + ms_Info[E_BLOCK_COBWEB ].m_PistonBreakable = true; + ms_Info[E_BLOCK_CROPS ].m_PistonBreakable = true; + ms_Info[E_BLOCK_DANDELION ].m_PistonBreakable = true; + ms_Info[E_BLOCK_DEAD_BUSH ].m_PistonBreakable = true; + ms_Info[E_BLOCK_FIRE ].m_PistonBreakable = true; + ms_Info[E_BLOCK_FLOWER ].m_PistonBreakable = true; + ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true; + ms_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_PistonBreakable = true; + ms_Info[E_BLOCK_IRON_DOOR ].m_PistonBreakable = true; + ms_Info[E_BLOCK_JACK_O_LANTERN ].m_PistonBreakable = true; + ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true; + ms_Info[E_BLOCK_LADDER ].m_PistonBreakable = true; + ms_Info[E_BLOCK_LAVA ].m_PistonBreakable = true; + ms_Info[E_BLOCK_LEVER ].m_PistonBreakable = true; + ms_Info[E_BLOCK_MELON ].m_PistonBreakable = true; + ms_Info[E_BLOCK_MELON_STEM ].m_PistonBreakable = true; + ms_Info[E_BLOCK_PUMPKIN ].m_PistonBreakable = true; + ms_Info[E_BLOCK_PUMPKIN_STEM ].m_PistonBreakable = true; + ms_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_PistonBreakable = true; + ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_PistonBreakable = true; + ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_PistonBreakable = true; + ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_PistonBreakable = true; + ms_Info[E_BLOCK_REDSTONE_WIRE ].m_PistonBreakable = true; + ms_Info[E_BLOCK_RED_MUSHROOM ].m_PistonBreakable = true; + ms_Info[E_BLOCK_REEDS ].m_PistonBreakable = true; + ms_Info[E_BLOCK_SNOW ].m_PistonBreakable = true; + ms_Info[E_BLOCK_STATIONARY_LAVA ].m_PistonBreakable = true; + ms_Info[E_BLOCK_STATIONARY_WATER ].m_PistonBreakable = true; + ms_Info[E_BLOCK_STONE_BUTTON ].m_PistonBreakable = true; + ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_PistonBreakable = true; + ms_Info[E_BLOCK_TALL_GRASS ].m_PistonBreakable = true; + ms_Info[E_BLOCK_TORCH ].m_PistonBreakable = true; + ms_Info[E_BLOCK_VINES ].m_PistonBreakable = true; + ms_Info[E_BLOCK_WATER ].m_PistonBreakable = true; + ms_Info[E_BLOCK_WOODEN_BUTTON ].m_PistonBreakable = true; + ms_Info[E_BLOCK_WOODEN_DOOR ].m_PistonBreakable = true; + ms_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_PistonBreakable = true; + + + // Blocks that cannot be snowed over: + ms_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_IsSnowable = false; + ms_Info[E_BLOCK_AIR ].m_IsSnowable = false; + ms_Info[E_BLOCK_BIG_FLOWER ].m_IsSnowable = false; + ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSnowable = false; + ms_Info[E_BLOCK_CACTUS ].m_IsSnowable = false; + ms_Info[E_BLOCK_CHEST ].m_IsSnowable = false; + ms_Info[E_BLOCK_CROPS ].m_IsSnowable = false; + ms_Info[E_BLOCK_DANDELION ].m_IsSnowable = false; + ms_Info[E_BLOCK_FIRE ].m_IsSnowable = false; + ms_Info[E_BLOCK_FLOWER ].m_IsSnowable = false; + ms_Info[E_BLOCK_GLASS ].m_IsSnowable = false; + ms_Info[E_BLOCK_ICE ].m_IsSnowable = false; + ms_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_IsSnowable = false; + ms_Info[E_BLOCK_LAVA ].m_IsSnowable = false; + ms_Info[E_BLOCK_LILY_PAD ].m_IsSnowable = false; + ms_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_IsSnowable = false; + ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_IsSnowable = false; + ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_IsSnowable = false; + ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_IsSnowable = false; + ms_Info[E_BLOCK_REDSTONE_WIRE ].m_IsSnowable = false; + ms_Info[E_BLOCK_RED_MUSHROOM ].m_IsSnowable = false; + ms_Info[E_BLOCK_REEDS ].m_IsSnowable = false; + ms_Info[E_BLOCK_SAPLING ].m_IsSnowable = false; + ms_Info[E_BLOCK_SIGN_POST ].m_IsSnowable = false; + ms_Info[E_BLOCK_SNOW ].m_IsSnowable = false; + ms_Info[E_BLOCK_STAINED_GLASS ].m_IsSnowable = false; + ms_Info[E_BLOCK_STAINED_GLASS_PANE ].m_IsSnowable = false; + ms_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSnowable = false; + ms_Info[E_BLOCK_STATIONARY_WATER ].m_IsSnowable = false; + ms_Info[E_BLOCK_TALL_GRASS ].m_IsSnowable = false; + ms_Info[E_BLOCK_TNT ].m_IsSnowable = false; + ms_Info[E_BLOCK_TORCH ].m_IsSnowable = false; + ms_Info[E_BLOCK_VINES ].m_IsSnowable = false; + ms_Info[E_BLOCK_WALLSIGN ].m_IsSnowable = false; + ms_Info[E_BLOCK_WATER ].m_IsSnowable = false; + + + // Blocks that don't drop without a special tool: + ms_Info[E_BLOCK_BRICK ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_CAULDRON ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_COAL_ORE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_COBBLESTONE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_COBBLESTONE_STAIRS ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_COBWEB ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_DIAMOND_BLOCK ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_DIAMOND_ORE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_EMERALD_ORE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_END_STONE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_GOLD_BLOCK ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_GOLD_ORE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_IRON_BLOCK ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_IRON_ORE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_LAPIS_BLOCK ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_LAPIS_ORE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_NETHERRACK ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_NETHER_BRICK ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_NETHER_BRICK_STAIRS ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_OBSIDIAN ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_REDSTONE_ORE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_SANDSTONE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_SANDSTONE_STAIRS ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_SNOW ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_STONE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_STONE_BRICKS ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_STONE_BRICK_STAIRS ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_STONE_SLAB ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_VINES ].m_RequiresSpecialTool = true; + + + // Nonsolid blocks: + ms_Info[E_BLOCK_ACTIVATOR_RAIL ].m_IsSolid = false; + ms_Info[E_BLOCK_AIR ].m_IsSolid = false; + ms_Info[E_BLOCK_BIG_FLOWER ].m_IsSolid = false; + ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSolid = false; + ms_Info[E_BLOCK_CARROTS ].m_IsSolid = false; + ms_Info[E_BLOCK_COBWEB ].m_IsSolid = false; + ms_Info[E_BLOCK_CROPS ].m_IsSolid = false; + ms_Info[E_BLOCK_DANDELION ].m_IsSolid = false; + ms_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSolid = false; + ms_Info[E_BLOCK_END_PORTAL ].m_IsSolid = false; + ms_Info[E_BLOCK_FIRE ].m_IsSolid = false; + ms_Info[E_BLOCK_FLOWER ].m_IsSolid = false; + ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false; + ms_Info[E_BLOCK_LAVA ].m_IsSolid = false; + ms_Info[E_BLOCK_LEVER ].m_IsSolid = false; + ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false; + ms_Info[E_BLOCK_MELON_STEM ].m_IsSolid = false; + ms_Info[E_BLOCK_NETHER_PORTAL ].m_IsSolid = false; + ms_Info[E_BLOCK_PISTON_EXTENSION ].m_IsSolid = false; + ms_Info[E_BLOCK_POTATOES ].m_IsSolid = false; + ms_Info[E_BLOCK_POWERED_RAIL ].m_IsSolid = false; + ms_Info[E_BLOCK_RAIL ].m_IsSolid = false; + ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_IsSolid = false; + ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_IsSolid = false; + ms_Info[E_BLOCK_REDSTONE_WIRE ].m_IsSolid = false; + ms_Info[E_BLOCK_RED_MUSHROOM ].m_IsSolid = false; + ms_Info[E_BLOCK_REEDS ].m_IsSolid = false; + ms_Info[E_BLOCK_SAPLING ].m_IsSolid = false; + ms_Info[E_BLOCK_SIGN_POST ].m_IsSolid = false; + ms_Info[E_BLOCK_SNOW ].m_IsSolid = false; + ms_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSolid = false; + ms_Info[E_BLOCK_STATIONARY_WATER ].m_IsSolid = false; + ms_Info[E_BLOCK_STONE_BUTTON ].m_IsSolid = false; + ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_IsSolid = false; + ms_Info[E_BLOCK_TALL_GRASS ].m_IsSolid = false; + ms_Info[E_BLOCK_TORCH ].m_IsSolid = false; + ms_Info[E_BLOCK_TRIPWIRE ].m_IsSolid = false; + ms_Info[E_BLOCK_VINES ].m_IsSolid = false; + ms_Info[E_BLOCK_WALLSIGN ].m_IsSolid = false; + ms_Info[E_BLOCK_WATER ].m_IsSolid = false; + ms_Info[E_BLOCK_WOODEN_BUTTON ].m_IsSolid = false; + ms_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_IsSolid = false; + ms_Info[E_BLOCK_WOODEN_SLAB ].m_IsSolid = false; + + + // Torch placeable blocks: + ms_Info[E_BLOCK_NEW_LOG ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_BEDROCK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_BLOCK_OF_COAL ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_BLOCK_OF_REDSTONE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_BOOKCASE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_BRICK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_CLAY ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_COAL_ORE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_COBBLESTONE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_COMMAND_BLOCK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_CRAFTING_TABLE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_DIAMOND_BLOCK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_DIAMOND_ORE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_DIRT ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_DISPENSER ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_DOUBLE_WOODEN_SLAB ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_DROPPER ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_EMERALD_BLOCK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_EMERALD_ORE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_END_STONE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_FURNACE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_GLOWSTONE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_GOLD_BLOCK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_GOLD_ORE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_GRASS ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_GRAVEL ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_HARDENED_CLAY ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_HAY_BALE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_HUGE_BROWN_MUSHROOM ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_HUGE_RED_MUSHROOM ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_IRON_BLOCK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_IRON_ORE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_JACK_O_LANTERN ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_JUKEBOX ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_LAPIS_BLOCK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_LAPIS_ORE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_LOG ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_MELON ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_MYCELIUM ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_NETHERRACK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_NETHER_BRICK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_NETHER_QUARTZ_ORE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_NOTE_BLOCK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_OBSIDIAN ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_PACKED_ICE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_PLANKS ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_PUMPKIN ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_QUARTZ_BLOCK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_REDSTONE_LAMP_OFF ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_REDSTONE_ORE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_SANDSTONE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_SAND ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_SILVERFISH_EGG ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_SPONGE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_STAINED_CLAY ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_WOOL ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_STONE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_STONE_BRICKS ].m_FullyOccupiesVoxel = true; +} + + + + + +// This is actually just some code that needs to run at program startup, so it is wrapped into a global var's constructor: +class cBlockInfoInitializer +{ +public: + cBlockInfoInitializer(void) + { + cBlockInfo::Initialize(); + } +} BlockInfoInitializer; + + + + + diff --git a/src/BlockInfo.h b/src/BlockInfo.h new file mode 100644 index 000000000..40c1db867 --- /dev/null +++ b/src/BlockInfo.h @@ -0,0 +1,103 @@ + +#pragma once + + + + + +// fwd: +class cBlockHandler; + + + + + +// tolua_begin +class cBlockInfo +{ +public: + // tolua_end + + cBlockInfo(); + + ~cBlockInfo(); + + /** (Re-)Initializes the internal BlockInfo structures. */ + static void Initialize(void); + + // tolua_begin + + /** Returns the associated BlockInfo structure. */ + static cBlockInfo & Get(BLOCKTYPE a_Type); + + + /** How much light do the blocks emit on their own? */ + NIBBLETYPE m_LightValue; + + /** How much light do the blocks consume? */ + NIBBLETYPE m_SpreadLightFalloff; + + /** Is a block completely transparent? (light doesn't get decreased(?)) */ + bool m_Transparent; + + /** Is a block destroyed after a single hit? */ + bool m_OneHitDig; + + /** Can a piston break this block? */ + bool m_PistonBreakable; + + /** Can this block hold snow atop? */ + bool m_IsSnowable; + + /** Does this block require a tool to drop? */ + bool m_RequiresSpecialTool; + + /** Is this block solid (player cannot walk through)? */ + bool m_IsSolid; + + /** Does this block fully occupy its voxel - is it a 'full' block? */ + bool m_FullyOccupiesVoxel; + + // tolua_end + + /** Associated block handler. */ + cBlockHandler * m_Handler; + + // tolua_begin + + inline static NIBBLETYPE GetLightValue (BLOCKTYPE a_Type) { return Get(a_Type).m_LightValue; } + inline static NIBBLETYPE GetSpreadLightFalloff(BLOCKTYPE a_Type) { return Get(a_Type).m_SpreadLightFalloff; } + inline static bool IsTransparent (BLOCKTYPE a_Type) { return Get(a_Type).m_Transparent; } + inline static bool IsOneHitDig (BLOCKTYPE a_Type) { return Get(a_Type).m_OneHitDig; } + inline static bool IsPistonBreakable (BLOCKTYPE a_Type) { return Get(a_Type).m_PistonBreakable; } + inline static bool IsSnowable (BLOCKTYPE a_Type) { return Get(a_Type).m_IsSnowable; } + inline static bool RequiresSpecialTool (BLOCKTYPE a_Type) { return Get(a_Type).m_RequiresSpecialTool; } + inline static bool IsSolid (BLOCKTYPE a_Type) { return Get(a_Type).m_IsSolid; } + inline static bool FullyOccupiesVoxel (BLOCKTYPE a_Type) { return Get(a_Type).m_FullyOccupiesVoxel; } + + // tolua_end + + inline static cBlockHandler * GetHandler (BLOCKTYPE a_Type) { return Get(a_Type).m_Handler; } + + +protected: + + // TODO xdot: Change to std::vector to support dynamic block IDs + static cBlockInfo ms_Info[256]; + + +}; // tolua_export + + + + + +// Shortcut to get the blockhandler for a specific block +inline cBlockHandler * BlockHandler(BLOCKTYPE a_BlockType) +{ + return cBlockInfo::Get(a_BlockType).m_Handler; +} + + + + diff --git a/src/Blocks/BlockButton.h b/src/Blocks/BlockButton.h index ca6850ced..2db9b7ec7 100644 --- a/src/Blocks/BlockButton.h +++ b/src/Blocks/BlockButton.h @@ -101,7 +101,7 @@ public: AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true); BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); - return (a_RelY > 0) && (g_BlockIsSolid[BlockIsOn]); + return (a_RelY > 0) && (cBlockInfo::IsSolid(BlockIsOn)); } } ; diff --git a/src/Blocks/BlockCactus.h b/src/Blocks/BlockCactus.h index 83595d2b9..ed441517d 100644 --- a/src/Blocks/BlockCactus.h +++ b/src/Blocks/BlockCactus.h @@ -54,7 +54,7 @@ public: NIBBLETYPE BlockMeta; if ( a_Chunk.UnboundedRelGetBlock(a_RelX + Coords[i].x, a_RelY, a_RelZ + Coords[i].z, BlockType, BlockMeta) && - (g_BlockIsSolid[BlockType]) + cBlockInfo::IsSolid(BlockType) ) { return false; diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h index 91534c5e5..544424a04 100644 --- a/src/Blocks/BlockDirt.h +++ b/src/Blocks/BlockDirt.h @@ -36,7 +36,7 @@ public: if (a_RelY < cChunkDef::Height - 1) { BLOCKTYPE Above = a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ); - if ((!g_BlockTransparent[Above] && !g_BlockOneHitDig[Above]) || IsBlockWater(Above)) + if ((!cBlockInfo::IsTransparent(Above) && !cBlockInfo::IsOneHitDig(Above)) || IsBlockWater(Above)) { a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, E_META_DIRT_NORMAL); return; @@ -77,7 +77,7 @@ public: BLOCKTYPE AboveDest; NIBBLETYPE AboveMeta; Chunk->GetBlockTypeMeta(BlockX, BlockY + 1, BlockZ, AboveDest, AboveMeta); - if ((g_BlockOneHitDig[AboveDest] || g_BlockTransparent[AboveDest]) && !IsBlockWater(AboveDest)) + if ((cBlockInfo::IsOneHitDig(AboveDest) || cBlockInfo::IsTransparent(AboveDest)) && !IsBlockWater(AboveDest)) { Chunk->FastSetBlock(BlockX, BlockY, BlockZ, E_BLOCK_GRASS, 0); } diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 834727c9a..052f88f7a 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -77,33 +77,6 @@ -bool cBlockHandler::m_HandlerInitialized = false; -cBlockHandler * cBlockHandler::m_BlockHandler[256]; - - - - - -cBlockHandler * cBlockHandler::GetBlockHandler(BLOCKTYPE a_BlockType) -{ - if (!m_HandlerInitialized) - { - // We have to initialize - memset(m_BlockHandler, 0, sizeof(m_BlockHandler)); - m_HandlerInitialized = true; - } - if (m_BlockHandler[a_BlockType] != NULL) - { - return m_BlockHandler[a_BlockType]; - } - - return m_BlockHandler[a_BlockType] = CreateBlockHandler(a_BlockType); -} - - - - - cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) { switch(a_BlockType) @@ -192,7 +165,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_REDSTONE_REPEATER_ON: return new cBlockRedstoneRepeaterHandler(a_BlockType); case E_BLOCK_REDSTONE_TORCH_OFF: return new cBlockRedstoneTorchHandler (a_BlockType); case E_BLOCK_REDSTONE_TORCH_ON: return new cBlockRedstoneTorchHandler (a_BlockType); - case E_BLOCK_REDSTONE_WIRE: return new cBlockRedstoneHandler (a_BlockType); + case E_BLOCK_REDSTONE_WIRE: return new cBlockRedstoneHandler (a_BlockType); case E_BLOCK_RED_MUSHROOM: return new cBlockMushroomHandler (a_BlockType); case E_BLOCK_RED_ROSE: return new cBlockFlowerHandler (a_BlockType); case E_BLOCK_SAND: return new cBlockSandHandler (a_BlockType); @@ -231,20 +204,6 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) -void cBlockHandler::Deinit() -{ - for (int i = 0; i < 256; i++) - { - delete m_BlockHandler[i]; - } - memset(m_BlockHandler, 0, sizeof(m_BlockHandler)); // Don't leave any dangling pointers around, just in case - m_HandlerInitialized = false; -} - - - - - cBlockHandler::cBlockHandler(BLOCKTYPE a_BlockType) { m_BlockType = a_BlockType; @@ -329,7 +288,7 @@ void cBlockHandler::NeighborChanged(cChunkInterface & a_ChunkInterface, int a_Bl { if ((a_BlockY >= 0) && (a_BlockY < cChunkDef::Height)) { - GetBlockHandler(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ))->OnNeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); + cBlockInfo::GetHandler(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ))->OnNeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); } } diff --git a/src/Blocks/BlockHandler.h b/src/Blocks/BlockHandler.h index a2913d7f8..c46a46045 100644 --- a/src/Blocks/BlockHandler.h +++ b/src/Blocks/BlockHandler.h @@ -136,30 +136,14 @@ public: /// <returns>Block meta following mirroring</returns> virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) { return a_Meta; } - /// <summary>Get the blockhandler for a specific block id</summary> - static cBlockHandler * GetBlockHandler(BLOCKTYPE a_BlockType); - - /// <summary>Deletes all initialised block handlers</summary> - static void Deinit(); - protected: BLOCKTYPE m_BlockType; // Creates a new blockhandler for the given block type. For internal use only, use ::GetBlockHandler() instead. - static cBlockHandler *CreateBlockHandler(BLOCKTYPE a_BlockType); - static cBlockHandler *m_BlockHandler[256]; - static bool m_HandlerInitialized; //used to detect if the blockhandlers are initialized -}; - - + static cBlockHandler * CreateBlockHandler(BLOCKTYPE a_BlockType); - - -// Shortcut to get the blockhandler for a specific block -inline cBlockHandler * BlockHandler(BLOCKTYPE a_BlockType) -{ - return cBlockHandler::GetBlockHandler(a_BlockType); -} + friend class cBlockInfo; +}; diff --git a/src/Blocks/BlockLadder.h b/src/Blocks/BlockLadder.h index 6a105d5c9..a3e9edc6b 100644 --- a/src/Blocks/BlockLadder.h +++ b/src/Blocks/BlockLadder.h @@ -91,7 +91,7 @@ public: AddFaceDirection( a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true); - return g_BlockIsSolid[a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ)]; + return cBlockInfo::IsSolid(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ)); } diff --git a/src/Blocks/BlockLever.h b/src/Blocks/BlockLever.h index 48c7e774b..ef6e102cd 100644 --- a/src/Blocks/BlockLever.h +++ b/src/Blocks/BlockLever.h @@ -102,7 +102,7 @@ public: AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true); BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); - return (a_RelY > 0) && (g_BlockIsSolid[BlockIsOn]); + return (a_RelY > 0) && cBlockInfo::IsSolid(BlockIsOn); } } ; diff --git a/src/Blocks/BlockRail.h b/src/Blocks/BlockRail.h index 52d6f60b3..07e9814cd 100644 --- a/src/Blocks/BlockRail.h +++ b/src/Blocks/BlockRail.h @@ -98,7 +98,7 @@ public: { return false; } - if (!g_BlockIsSolid[a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)]) + if (!cBlockInfo::IsSolid(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ))) { return false; } @@ -130,7 +130,7 @@ public: // Too close to the edge, cannot simulate return true; } - return g_BlockIsSolid[BlockType]; + return cBlockInfo::IsSolid(BlockType); } } return true; diff --git a/src/Blocks/BlockRedstone.h b/src/Blocks/BlockRedstone.h index 10de96197..a898c9acb 100644 --- a/src/Blocks/BlockRedstone.h +++ b/src/Blocks/BlockRedstone.h @@ -20,7 +20,7 @@ public: virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - return ((a_RelY > 0) && g_BlockFullyOccupiesVoxel[a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)]); + return ((a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ))); } diff --git a/src/Blocks/BlockSnow.h b/src/Blocks/BlockSnow.h index a3daf0393..b21995d3c 100644 --- a/src/Blocks/BlockSnow.h +++ b/src/Blocks/BlockSnow.h @@ -72,7 +72,7 @@ public: BLOCKTYPE BlockBelow = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ); NIBBLETYPE MetaBelow = a_Chunk.GetMeta(a_RelX, a_RelY - 1, a_RelZ); - if (g_BlockIsSnowable[BlockBelow] || ((BlockBelow == E_BLOCK_SNOW) && (MetaBelow == 7))) + if (cBlockInfo::IsSnowable(BlockBelow) || ((BlockBelow == E_BLOCK_SNOW) && (MetaBelow == 7))) { // If block below is snowable, or it is a thin slow block and has a meta of 7 (full thin snow block), say yay return true; diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index f2a4c8665..84bbb37ec 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -99,7 +99,7 @@ public: static bool CanBePlacedOn(BLOCKTYPE a_BlockType, eBlockFace a_BlockFace) { - if ( !g_BlockFullyOccupiesVoxel[a_BlockType] ) + if ( !cBlockInfo::FullyOccupiesVoxel(a_BlockType) ) { return (a_BlockFace == BLOCK_FACE_TOP); // Allow placement only when torch upright (for glass, etc.); exceptions won't even be sent by client, no need to handle } @@ -129,7 +129,7 @@ public: { return Face; } - else if ((g_BlockFullyOccupiesVoxel[BlockInQuestion]) && (i != BLOCK_FACE_BOTTOM)) + else if (cBlockInfo::FullyOccupiesVoxel(BlockInQuestion) && (i != BLOCK_FACE_BOTTOM)) { // Otherwise, if block in that direction is torch placeable and we haven't gotten to it via the bottom face, return that face return Face; @@ -163,7 +163,7 @@ public: // No need to check for upright orientation, it was done when the torch was placed return true; } - else if ( !g_BlockFullyOccupiesVoxel[BlockInQuestion] ) + else if ( !cBlockInfo::FullyOccupiesVoxel(BlockInQuestion) ) { return false; } diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h index 251044afd..a28861e69 100644 --- a/src/Blocks/BlockTrapdoor.h +++ b/src/Blocks/BlockTrapdoor.h @@ -99,7 +99,7 @@ public: AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true); BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); - return (a_RelY > 0) && (g_BlockIsSolid[BlockIsOn]); + return (a_RelY > 0) && cBlockInfo::IsSolid(BlockIsOn); } }; diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index ee7dcee8a..d8c114284 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -70,7 +70,7 @@ public: /// Returns true if the specified block type is good for vines to attach to static bool IsBlockAttachable(BLOCKTYPE a_BlockType) { - return (a_BlockType == E_BLOCK_LEAVES) || g_BlockIsSolid[a_BlockType]; + return (a_BlockType == E_BLOCK_LEAVES) || cBlockInfo::IsSolid(a_BlockType); } diff --git a/src/Blocks/ChunkInterface.cpp b/src/Blocks/ChunkInterface.cpp index b2dda19f4..540581ae7 100644 --- a/src/Blocks/ChunkInterface.cpp +++ b/src/Blocks/ChunkInterface.cpp @@ -6,7 +6,7 @@ bool cChunkInterface::DigBlock(cWorldInterface & a_WorldInterface, int a_X, int a_Y, int a_Z) { - cBlockHandler *Handler = cBlockHandler::GetBlockHandler(GetBlock(a_X, a_Y, a_Z)); + cBlockHandler * Handler = cBlockInfo::GetHandler(GetBlock(a_X, a_Y, a_Z)); Handler->OnDestroyed(*this, a_WorldInterface, a_X, a_Y, a_Z); return m_ChunkMap->DigBlock(a_X, a_Y, a_Z); } diff --git a/src/Blocks/ChunkInterface.h b/src/Blocks/ChunkInterface.h index b30eff1e4..be7c2e0e5 100644 --- a/src/Blocks/ChunkInterface.h +++ b/src/Blocks/ChunkInterface.h @@ -5,31 +5,35 @@ #include "../ForEachChunkProvider.h" #include "WorldInterface.h" -class cBlockHandler; -class cChunkInterface : public cForEachChunkProvider + + + +class cChunkInterface: + public cForEachChunkProvider { public: cChunkInterface(cChunkMap * a_ChunkMap) : m_ChunkMap(a_ChunkMap) {} - BLOCKTYPE GetBlock (int a_BlockX, int a_BlockY, int a_BlockZ) + BLOCKTYPE GetBlock(int a_BlockX, int a_BlockY, int a_BlockZ) { return m_ChunkMap->GetBlock(a_BlockX,a_BlockY,a_BlockZ); } - BLOCKTYPE GetBlock (const Vector3i & a_Pos ) + BLOCKTYPE GetBlock(const Vector3i & a_Pos) { - return GetBlock( a_Pos.x, a_Pos.y, a_Pos.z ); + return GetBlock(a_Pos.x, a_Pos.y, a_Pos.z); } - NIBBLETYPE GetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ) + NIBBLETYPE GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ) { return m_ChunkMap->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); } - bool GetBlockTypeMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) + bool GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) { return m_ChunkMap->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); } + /** Sets the block at the specified coords to the specified value. Full processing, incl. updating neighbors, is performed. */ @@ -37,7 +41,8 @@ public: { m_ChunkMap->SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); } - void SetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_MetaData) + + void SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_MetaData) { m_ChunkMap->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_MetaData); } @@ -55,7 +60,11 @@ public: { m_ChunkMap->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); } - void FastSetBlock(const Vector3i & a_Pos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ) { FastSetBlock( a_Pos.x, a_Pos.y, a_Pos.z, a_BlockType, a_BlockMeta ); } + + void FastSetBlock(const Vector3i & a_Pos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ) + { + FastSetBlock( a_Pos.x, a_Pos.y, a_Pos.z, a_BlockType, a_BlockMeta ); + } void UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) { @@ -77,3 +86,7 @@ public: private: cChunkMap * m_ChunkMap; }; + + + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 387556775..5e0731264 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -95,6 +95,7 @@ if (NOT MSVC) #add cpp files here add_library(Bindings Bindings/Bindings + Bindings/DeprecatedBindings Bindings/LuaChunkStay Bindings/LuaState Bindings/LuaWindow diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 8dfbbeef5..a75828461 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -883,7 +883,7 @@ void cChunk::ApplyWeatherToTop() FastSetBlock(X, Height, Z, E_BLOCK_SNOW, TopMeta - 1); } } - else if (g_BlockIsSnowable[TopBlock]) + else if (cBlockInfo::IsSnowable(TopBlock)) { SetBlock(X, Height + 1, Z, E_BLOCK_SNOW, 0); } @@ -1540,10 +1540,10 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT SetNibble(m_BlockMeta, index, a_BlockMeta); // ONLY recalculate lighting if it's necessary! - if( - (g_BlockLightValue[OldBlockType ] != g_BlockLightValue[a_BlockType]) || - (g_BlockSpreadLightFalloff[OldBlockType] != g_BlockSpreadLightFalloff[a_BlockType]) || - (g_BlockTransparent[OldBlockType] != g_BlockTransparent[a_BlockType]) + if ( + (cBlockInfo::GetLightValue (OldBlockType) != cBlockInfo::GetLightValue (a_BlockType)) || + (cBlockInfo::GetSpreadLightFalloff(OldBlockType) != cBlockInfo::GetSpreadLightFalloff(a_BlockType)) || + (cBlockInfo::IsTransparent (OldBlockType) != cBlockInfo::IsTransparent (a_BlockType)) ) { m_IsLightValid = false; diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index dd2116dbf..6982a6227 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -819,7 +819,7 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc if ( (m_Player->IsGameModeCreative()) || // In creative mode, digging is done immediately - g_BlockOneHitDig[a_OldBlock] // One-hit blocks get destroyed immediately, too + cBlockInfo::IsOneHitDig(a_OldBlock) // One-hit blocks get destroyed immediately, too ) { HandleBlockDigFinished(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_OldBlock, a_OldMeta); @@ -838,7 +838,7 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc cWorld * World = m_Player->GetWorld(); cChunkInterface ChunkInterface(World->GetChunkMap()); - cBlockHandler * Handler = cBlockHandler::GetBlockHandler(a_OldBlock); + cBlockHandler * Handler = cBlockInfo::GetHandler(a_OldBlock); Handler->OnDigging(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ); cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem()); @@ -852,7 +852,7 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc int pZ = a_BlockZ; AddFaceDirection(pX, pY, pZ, a_BlockFace); // Get the block in front of the clicked coordinates (m_bInverse defaulted to false) - Handler = cBlockHandler::GetBlockHandler(World->GetBlock(pX, pY, pZ)); + Handler = cBlockInfo::GetHandler(World->GetBlock(pX, pY, pZ)); if (Handler->IsClickedThrough()) { @@ -963,7 +963,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e BLOCKTYPE BlockType; NIBBLETYPE BlockMeta; World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta); - cBlockHandler * BlockHandler = cBlockHandler::GetBlockHandler(BlockType); + cBlockHandler * BlockHandler = cBlockInfo::GetHandler(BlockType); if (BlockHandler->IsUseable() && !m_Player->IsCrouched()) { diff --git a/src/Defines.h b/src/Defines.h index ba2866f83..018ecb1d3 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -17,33 +17,6 @@ typedef std::vector<int> cSlotNums; // tolua_begin -/// How much light do the blocks emit on their own? -extern unsigned char g_BlockLightValue[]; - -/// How much light do the block consume? -extern unsigned char g_BlockSpreadLightFalloff[]; - -/// Is a block completely transparent? (light doesn't get decreased(?)) -extern bool g_BlockTransparent[]; - -/// Is a block destroyed after a single hit? -extern bool g_BlockOneHitDig[]; - -/// Can a piston break this block? -extern bool g_BlockPistonBreakable[256]; - -/// Can this block hold snow atop? -extern bool g_BlockIsSnowable[256]; - -/// Does this block require a tool to drop? -extern bool g_BlockRequiresSpecialTool[256]; - -/// Is this block solid (player cannot walk through)? -extern bool g_BlockIsSolid[256]; - -/// Does this block fully occupy it's voxel - is it a 'full' block? -extern bool g_BlockFullyOccupiesVoxel[256]; - /// Experience Orb setup enum { @@ -253,6 +226,56 @@ inline const char * ClickActionToString(eClickAction a_ClickAction) +/** Returns a blockface mirrored around the Y axis (doesn't change up/down). */ +inline eBlockFace MirrorBlockFaceY(eBlockFace a_BlockFace) +{ + switch (a_BlockFace) + { + case BLOCK_FACE_XM: return BLOCK_FACE_XP; + case BLOCK_FACE_XP: return BLOCK_FACE_XM; + case BLOCK_FACE_ZM: return BLOCK_FACE_ZP; + case BLOCK_FACE_ZP: return BLOCK_FACE_ZM; + } + return a_BlockFace; +} + + + + + +/** Returns a blockface rotated around the Y axis counter-clockwise. */ +inline eBlockFace RotateBlockFaceCCW(eBlockFace a_BlockFace) +{ + switch (a_BlockFace) + { + case BLOCK_FACE_XM: return BLOCK_FACE_ZP; + case BLOCK_FACE_XP: return BLOCK_FACE_ZM; + case BLOCK_FACE_ZM: return BLOCK_FACE_XM; + case BLOCK_FACE_ZP: return BLOCK_FACE_XP; + } + return a_BlockFace; +} + + + + + +inline eBlockFace RotateBlockFaceCW(eBlockFace a_BlockFace) +{ + switch (a_BlockFace) + { + case BLOCK_FACE_XM: return BLOCK_FACE_ZM; + case BLOCK_FACE_XP: return BLOCK_FACE_ZP; + case BLOCK_FACE_ZM: return BLOCK_FACE_XP; + case BLOCK_FACE_ZP: return BLOCK_FACE_XM; + } + return a_BlockFace; +} + + + + + inline bool IsValidBlock(int a_BlockType) { if ( @@ -654,7 +677,7 @@ namespace ItemCategory inline bool BlockRequiresSpecialTool(BLOCKTYPE a_BlockType) { if(!IsValidBlock(a_BlockType)) return false; - return g_BlockRequiresSpecialTool[a_BlockType]; + return cBlockInfo::RequiresSpecialTool(a_BlockType); } diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 8554ab2a5..96e8c15a5 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -582,11 +582,11 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) int RelBlockZ = BlockZ - (NextChunk->GetPosZ() * cChunkDef::Width); BLOCKTYPE BlockIn = NextChunk->GetBlock( RelBlockX, BlockY, RelBlockZ ); BLOCKTYPE BlockBelow = (BlockY > 0) ? NextChunk->GetBlock(RelBlockX, BlockY - 1, RelBlockZ) : E_BLOCK_AIR; - if (!g_BlockIsSolid[BlockIn]) // Making sure we are not inside a solid block + if (!cBlockInfo::IsSolid(BlockIn)) // Making sure we are not inside a solid block { if (m_bOnGround) // check if it's still on the ground { - if (!g_BlockIsSolid[BlockBelow]) // Check if block below is air or water. + if (!cBlockInfo::IsSolid(BlockBelow)) // Check if block below is air or water. { m_bOnGround = false; } @@ -616,7 +616,7 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) // The pickup is too close to an unloaded chunk, bail out of any physics handling return; } - if (!g_BlockIsSolid[GotBlock]) + if (!cBlockInfo::IsSolid(GotBlock)) { NextPos.x += gCrossCoords[i].x; NextPos.z += gCrossCoords[i].z; diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index d854906b7..f52a7b6d9 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -720,7 +720,7 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta) if (GetSpeedZ() > 0) { BLOCKTYPE Block = m_World->GetBlock((int)floor(GetPosX()), (int)floor(GetPosY()), (int)ceil(GetPosZ())); - if (!IsBlockRail(Block) && g_BlockIsSolid[Block]) + if (!IsBlockRail(Block) && cBlockInfo::IsSolid(Block)) { // We could try to detect a block in front based purely on coordinates, but xoft made a bounding box system - why not use? :P cBoundingBox bbBlock(Vector3d((int)floor(GetPosX()), (int)floor(GetPosY()), (int)ceil(GetPosZ())), 0.5, 1); @@ -737,7 +737,7 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta) else if (GetSpeedZ() < 0) { BLOCKTYPE Block = m_World->GetBlock((int)floor(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ()) - 1); - if (!IsBlockRail(Block) && g_BlockIsSolid[Block]) + if (!IsBlockRail(Block) && cBlockInfo::IsSolid(Block)) { cBoundingBox bbBlock(Vector3d((int)floor(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ()) - 1), 0.5, 1); cBoundingBox bbMinecart(Vector3d(GetPosX(), floor(GetPosY()), GetPosZ() - 1), GetWidth() / 2, GetHeight()); @@ -757,7 +757,7 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta) if (GetSpeedX() > 0) { BLOCKTYPE Block = m_World->GetBlock((int)ceil(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ())); - if (!IsBlockRail(Block) && g_BlockIsSolid[Block]) + if (!IsBlockRail(Block) && cBlockInfo::IsSolid(Block)) { cBoundingBox bbBlock(Vector3d((int)ceil(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ())), 0.5, 1); cBoundingBox bbMinecart(Vector3d(GetPosX(), floor(GetPosY()), GetPosZ()), GetWidth() / 2, GetHeight()); @@ -773,7 +773,7 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta) else if (GetSpeedX() < 0) { BLOCKTYPE Block = m_World->GetBlock((int)floor(GetPosX()) - 1, (int)floor(GetPosY()), (int)floor(GetPosZ())); - if (!IsBlockRail(Block) && g_BlockIsSolid[Block]) + if (!IsBlockRail(Block) && cBlockInfo::IsSolid(Block)) { cBoundingBox bbBlock(Vector3d((int)floor(GetPosX()) - 1, (int)floor(GetPosY()), (int)floor(GetPosZ())), 0.5, 1); cBoundingBox bbMinecart(Vector3d(GetPosX() - 1, floor(GetPosY()), GetPosZ()), GetWidth() / 2, GetHeight()); @@ -798,10 +798,10 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta) BLOCKTYPE BlockZM = m_World->GetBlock((int)floor(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ()) + 1); BLOCKTYPE BlockZP = m_World->GetBlock((int)floor(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ()) + 1); if ( - (!IsBlockRail(BlockXM) && g_BlockIsSolid[BlockXM]) || - (!IsBlockRail(BlockXP) && g_BlockIsSolid[BlockXP]) || - (!IsBlockRail(BlockZM) && g_BlockIsSolid[BlockZM]) || - (!IsBlockRail(BlockZP) && g_BlockIsSolid[BlockZP]) + (!IsBlockRail(BlockXM) && cBlockInfo::IsSolid(BlockXM)) || + (!IsBlockRail(BlockXP) && cBlockInfo::IsSolid(BlockXP)) || + (!IsBlockRail(BlockZM) && cBlockInfo::IsSolid(BlockZM)) || + (!IsBlockRail(BlockZP) && cBlockInfo::IsSolid(BlockZP)) ) { SetSpeed(0, 0, 0); diff --git a/src/Entities/Painting.cpp b/src/Entities/Painting.cpp index b98c1e67a..e217556c7 100644 --- a/src/Entities/Painting.cpp +++ b/src/Entities/Painting.cpp @@ -4,6 +4,7 @@ #include "Painting.h" #include "ClientHandle.h" #include "Player.h" +#include "../Chunk.h" @@ -30,6 +31,16 @@ void cPainting::SpawnOn(cClientHandle & a_Client) +void cPainting::Tick(float a_Dt, cChunk & a_Chunk) +{ + UNUSED(a_Dt); + UNUSED(a_Chunk); +} + + + + + void cPainting::GetDrops(cItems & a_Items, cEntity * a_Killer) { if ((a_Killer != NULL) && a_Killer->IsPlayer() && !((cPlayer *)a_Killer)->IsGameModeCreative()) diff --git a/src/Entities/Painting.h b/src/Entities/Painting.h index 95afbed1e..c1024bd1b 100644 --- a/src/Entities/Painting.h +++ b/src/Entities/Painting.h @@ -24,7 +24,7 @@ public: private: virtual void SpawnOn(cClientHandle & a_Client) override; - virtual void Tick(float a_Dt, cChunk & a_Chunk) override {}; + virtual void Tick(float a_Dt, cChunk & a_Chunk) override; virtual void GetDrops(cItems & a_Items, cEntity * a_Killer) override; virtual void KilledBy(cEntity * a_Killer) override { diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index e0f0b9222..42ee14cf3 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -858,6 +858,8 @@ void cPlayer::KilledBy(cEntity * a_Killer) else if (a_Killer->IsPlayer()) { GetWorld()->BroadcastChatDeath(Printf("%s was killed by %s", GetName().c_str(), ((cPlayer *)a_Killer)->GetName().c_str())); + + m_World->GetScoreBoard().AddPlayerScore(((cPlayer *)a_Killer)->GetName(), cObjective::otPlayerKillCount, 1); } else { @@ -867,24 +869,7 @@ void cPlayer::KilledBy(cEntity * a_Killer) GetWorld()->BroadcastChatDeath(Printf("%s was killed by a %s", GetName().c_str(), KillerClass.c_str())); } - class cIncrementCounterCB - : public cObjectiveCallback - { - AString m_Name; - public: - cIncrementCounterCB(const AString & a_Name) : m_Name(a_Name) {} - - virtual bool Item(cObjective * a_Objective) override - { - a_Objective->AddScore(m_Name, 1); - return true; - } - } IncrementCounter (GetName()); - - cScoreboard & Scoreboard = m_World->GetScoreBoard(); - - // Update scoreboard objectives - Scoreboard.ForEachObjectiveWith(cObjective::E_TYPE_DEATH_COUNT, IncrementCounter); + m_World->GetScoreBoard().AddPlayerScore(GetName(), cObjective::otDeathCount, 1); } @@ -1529,14 +1514,14 @@ void cPlayer::LoadPermissionsFromDisk() std::string Groups = IniFile.GetValue(m_PlayerName, "Groups", ""); if (!Groups.empty()) { - AStringVector Split = StringSplit( Groups, "," ); - for( unsigned int i = 0; i < Split.size(); i++ ) + AStringVector Split = StringSplitAndTrim(Groups, ","); + for (AStringVector::const_iterator itr = Split.begin(), end = Split.end(); itr != end; ++itr) { - if (!cRoot::Get()->GetGroupManager()->ExistsGroup(Split[i])) + if (!cRoot::Get()->GetGroupManager()->ExistsGroup(*itr)) { - LOGWARNING("The group %s for player %s was not found!", Split[i].c_str(), m_PlayerName.c_str()); + LOGWARNING("The group %s for player %s was not found!", itr->c_str(), m_PlayerName.c_str()); } - AddToGroup(Split[i].c_str()); + AddToGroup(*itr); } } else @@ -1544,11 +1529,15 @@ void cPlayer::LoadPermissionsFromDisk() AddToGroup("Default"); } - m_Color = IniFile.GetValue(m_PlayerName, "Color", "-")[0]; + AString Color = IniFile.GetValue(m_PlayerName, "Color", "-"); + if (!Color.empty()) + { + m_Color = Color[0]; + } } else { - cRoot::Get()->GetGroupManager()->CheckUsers(); + cGroupManager::GenerateDefaultUsersIni(IniFile); AddToGroup("Default"); } ResolvePermissions(); @@ -1915,7 +1904,7 @@ void cPlayer::Detach() { for (int z = PosZ - 2; z <= (PosZ + 2); ++z) { - if (!g_BlockIsSolid[m_World->GetBlock(x, y, z)] && g_BlockIsSolid[m_World->GetBlock(x, y - 1, z)]) + if (!cBlockInfo::IsSolid(m_World->GetBlock(x, y, z)) && cBlockInfo::IsSolid(m_World->GetBlock(x, y - 1, z))) { TeleportToCoords(x, y, z); return; diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index ef82c6e94..03bc0c99d 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -50,12 +50,12 @@ protected: LOGD("Hit block %d:%d at {%d, %d, %d} face %d, %s (%s)", a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_EntryFace, - g_BlockIsSolid[a_BlockType] ? "solid" : "non-solid", + cBlockInfo::IsSolid(a_BlockType) ? "solid" : "non-solid", ItemToString(cItem(a_BlockType, 1, a_BlockMeta)).c_str() ); */ - if (g_BlockIsSolid[a_BlockType]) + if (cBlockInfo::IsSolid(a_BlockType)) { // The projectile hit a solid block // Calculate the exact hit coords: diff --git a/src/Generating/Caves.cpp b/src/Generating/Caves.cpp index 2571e6b77..98b7c8681 100644 --- a/src/Generating/Caves.cpp +++ b/src/Generating/Caves.cpp @@ -762,7 +762,7 @@ void cStructGenWormNestCaves::ClearCache(void) -void cStructGenWormNestCaves::GenStructures(cChunkDesc & a_ChunkDesc) +void cStructGenWormNestCaves::GenFinish(cChunkDesc & a_ChunkDesc) { int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); @@ -902,7 +902,7 @@ static float GetMarbleNoise( float x, float y, float z, cNoise & a_Noise ) -void cStructGenMarbleCaves::GenStructures(cChunkDesc & a_ChunkDesc) +void cStructGenMarbleCaves::GenFinish(cChunkDesc & a_ChunkDesc) { cNoise Noise(m_Seed); for (int z = 0; z < cChunkDef::Width; z++) @@ -938,7 +938,7 @@ void cStructGenMarbleCaves::GenStructures(cChunkDesc & a_ChunkDesc) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cStructGenDualRidgeCaves: -void cStructGenDualRidgeCaves::GenStructures(cChunkDesc & a_ChunkDesc) +void cStructGenDualRidgeCaves::GenFinish(cChunkDesc & a_ChunkDesc) { for (int z = 0; z < cChunkDef::Width; z++) { diff --git a/src/Generating/Caves.h b/src/Generating/Caves.h index ea7f10bf4..7c45c056b 100644 --- a/src/Generating/Caves.h +++ b/src/Generating/Caves.h @@ -20,7 +20,7 @@ class cStructGenMarbleCaves : - public cStructureGen + public cFinishGen { public: cStructGenMarbleCaves(int a_Seed) : m_Seed(a_Seed) {} @@ -29,8 +29,8 @@ protected: int m_Seed; - // cStructureGen override: - virtual void GenStructures(cChunkDesc & a_ChunkDesc) override; + // cFinishGen override: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; @@ -38,7 +38,7 @@ protected: class cStructGenDualRidgeCaves : - public cStructureGen + public cFinishGen { public: cStructGenDualRidgeCaves(int a_Seed, float a_Threshold) : @@ -55,8 +55,8 @@ protected: int m_Seed; float m_Threshold; - // cStructureGen override: - virtual void GenStructures(cChunkDesc & a_ChunkDesc) override; + // cFinishGen override: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; @@ -64,7 +64,7 @@ protected: class cStructGenWormNestCaves : - public cStructureGen + public cFinishGen { public: cStructGenWormNestCaves(int a_Seed, int a_Size = 64, int a_Grid = 96, int a_MaxOffset = 128) : @@ -94,7 +94,7 @@ protected: void GetCavesForChunk(int a_ChunkX, int a_ChunkZ, cCaveSystems & a_Caves); // cStructGen override: - virtual void GenStructures(cChunkDesc & a_ChunkDesc) override; + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; diff --git a/src/Generating/ChunkDesc.cpp b/src/Generating/ChunkDesc.cpp index d9529b4b0..308fbe423 100644 --- a/src/Generating/ChunkDesc.cpp +++ b/src/Generating/ChunkDesc.cpp @@ -209,6 +209,7 @@ bool cChunkDesc::IsUsingDefaultComposition(void) const void cChunkDesc::SetUseDefaultStructures(bool a_bUseDefaultStructures) { + LOGWARNING("%s: Structures are no longer accounted for, use Finishers instead", __FUNCTION__); m_bUseDefaultStructures = a_bUseDefaultStructures; } @@ -218,6 +219,7 @@ void cChunkDesc::SetUseDefaultStructures(bool a_bUseDefaultStructures) bool cChunkDesc::IsUsingDefaultStructures(void) const { + LOGWARNING("%s: Structures are no longer accounted for, use Finishers instead", __FUNCTION__); return m_bUseDefaultStructures; } diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index cfa7e9c6f..e96e9a645 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -133,11 +133,6 @@ cComposableGenerator::~cComposableGenerator() delete *itr; } m_FinishGens.clear(); - for (cStructureGenList::const_iterator itr = m_StructureGens.begin(); itr != m_StructureGens.end(); ++itr) - { - delete *itr; - } - m_StructureGens.clear(); delete m_CompositionGen; m_CompositionGen = NULL; @@ -164,7 +159,6 @@ void cComposableGenerator::Initialize(cIniFile & a_IniFile) InitBiomeGen(a_IniFile); InitHeightGen(a_IniFile); InitCompositionGen(a_IniFile); - InitStructureGens(a_IniFile); InitFinishGens(a_IniFile); } @@ -201,14 +195,6 @@ void cComposableGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a m_CompositionGen->ComposeTerrain(a_ChunkDesc); } - if (a_ChunkDesc.IsUsingDefaultStructures()) - { - for (cStructureGenList::iterator itr = m_StructureGens.begin(); itr != m_StructureGens.end(); ++itr) - { - (*itr)->GenStructures(a_ChunkDesc); - } // for itr - m_StructureGens[] - } - if (a_ChunkDesc.IsUsingDefaultFinish()) { for (cFinishGenList::iterator itr = m_FinishGens.begin(); itr != m_FinishGens.end(); ++itr) @@ -290,35 +276,69 @@ void cComposableGenerator::InitCompositionGen(cIniFile & a_IniFile) -void cComposableGenerator::InitStructureGens(cIniFile & a_IniFile) +void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) { - AString Structures = a_IniFile.GetValueSet("Generator", "Structures", "Ravines, WormNestCaves, WaterLakes, LavaLakes, OreNests, Trees"); - int Seed = m_ChunkGenerator.GetSeed(); - AStringVector Str = StringSplitAndTrim(Structures, ","); + eDimension Dimension = StringToDimension(a_IniFile.GetValue("General", "Dimension", "Overworld")); + + // Older configuration used "Structures" in addition to "Finishers"; we don't distinguish between the two anymore (#398) + // Therefore, we load Structures from the ini file for compatibility, but move its contents over to Finishers: + AString Structures = a_IniFile.GetValue("Generator", "Structures", ""); + AString Finishers = a_IniFile.GetValueSet("Generator", "Finishers", "Ravines, WormNestCaves, WaterLakes, LavaLakes, OreNests, Trees, SprinkleFoliage, Ice, Snow, Lilypads, BottomLava, DeadBushes, PreSimulator"); + if (!Structures.empty()) + { + LOGINFO("[Generator].Structures is deprecated, moving the contents to [Generator].Finishers."); + // Structures used to generate before Finishers, so place them first: + Structures.append(", "); + Finishers = Structures + Finishers; + a_IniFile.SetValue("Generator", "Finishers", Finishers); + } + a_IniFile.DeleteValue("Generator", "Structures"); + + // Create all requested finishers: + AStringVector Str = StringSplitAndTrim(Finishers, ","); for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr) { - if (NoCaseCompare(*itr, "DualRidgeCaves") == 0) + // Finishers, alpha-sorted: + if (NoCaseCompare(*itr, "BottomLava") == 0) { - float Threshold = (float)a_IniFile.GetValueSetF("Generator", "DualRidgeCavesThreshold", 0.3); - m_StructureGens.push_back(new cStructGenDualRidgeCaves(Seed, Threshold)); + int DefaultBottomLavaLevel = (Dimension == dimNether) ? 30 : 10; + int BottomLavaLevel = a_IniFile.GetValueSetI("Generator", "BottomLavaLevel", DefaultBottomLavaLevel); + m_FinishGens.push_back(new cFinishGenBottomLava(BottomLavaLevel)); + } + else if (NoCaseCompare(*itr, "DeadBushes") == 0) + { + m_FinishGens.push_back(new cFinishGenSingleBiomeSingleTopBlock(Seed, E_BLOCK_DEAD_BUSH, biDesert, 2, E_BLOCK_SAND, E_BLOCK_SAND)); } else if (NoCaseCompare(*itr, "DirectOverhangs") == 0) { - m_StructureGens.push_back(new cStructGenDirectOverhangs(Seed)); + m_FinishGens.push_back(new cStructGenDirectOverhangs(Seed)); } else if (NoCaseCompare(*itr, "DistortedMembraneOverhangs") == 0) { - m_StructureGens.push_back(new cStructGenDistortedMembraneOverhangs(Seed)); + m_FinishGens.push_back(new cStructGenDistortedMembraneOverhangs(Seed)); + } + else if (NoCaseCompare(*itr, "DualRidgeCaves") == 0) + { + float Threshold = (float)a_IniFile.GetValueSetF("Generator", "DualRidgeCavesThreshold", 0.3); + m_FinishGens.push_back(new cStructGenDualRidgeCaves(Seed, Threshold)); + } + else if (NoCaseCompare(*itr, "Ice") == 0) + { + m_FinishGens.push_back(new cFinishGenIce); } else if (NoCaseCompare(*itr, "LavaLakes") == 0) { int Probability = a_IniFile.GetValueSetI("Generator", "LavaLakesProbability", 10); - m_StructureGens.push_back(new cStructGenLakes(Seed * 5 + 16873, E_BLOCK_STATIONARY_LAVA, *m_HeightGen, Probability)); + m_FinishGens.push_back(new cStructGenLakes(Seed * 5 + 16873, E_BLOCK_STATIONARY_LAVA, *m_HeightGen, Probability)); + } + else if (NoCaseCompare(*itr, "LavaSprings") == 0) + { + m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_LAVA, a_IniFile, Dimension)); } else if (NoCaseCompare(*itr, "MarbleCaves") == 0) { - m_StructureGens.push_back(new cStructGenMarbleCaves(Seed)); + m_FinishGens.push_back(new cStructGenMarbleCaves(Seed)); } else if (NoCaseCompare(*itr, "MineShafts") == 0) { @@ -327,71 +347,11 @@ void cComposableGenerator::InitStructureGens(cIniFile & a_IniFile) int ChanceCorridor = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCorridor", 600); int ChanceCrossing = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCrossing", 200); int ChanceStaircase = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceStaircase", 200); - m_StructureGens.push_back(new cStructGenMineShafts( + m_FinishGens.push_back(new cStructGenMineShafts( Seed, GridSize, MaxSystemSize, ChanceCorridor, ChanceCrossing, ChanceStaircase )); } - else if (NoCaseCompare(*itr, "OreNests") == 0) - { - m_StructureGens.push_back(new cStructGenOreNests(Seed)); - } - else if (NoCaseCompare(*itr, "Ravines") == 0) - { - m_StructureGens.push_back(new cStructGenRavines(Seed, 128)); - } - else if (NoCaseCompare(*itr, "Trees") == 0) - { - m_StructureGens.push_back(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen)); - } - else if (NoCaseCompare(*itr, "WaterLakes") == 0) - { - int Probability = a_IniFile.GetValueSetI("Generator", "WaterLakesProbability", 25); - m_StructureGens.push_back(new cStructGenLakes(Seed * 3 + 652, E_BLOCK_STATIONARY_WATER, *m_HeightGen, Probability)); - } - else if (NoCaseCompare(*itr, "WormNestCaves") == 0) - { - m_StructureGens.push_back(new cStructGenWormNestCaves(Seed)); - } - else - { - LOGWARNING("Unknown structure generator: \"%s\". Ignoring.", itr->c_str()); - } - } // for itr - Str[] -} - - - - - -void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) -{ - int Seed = m_ChunkGenerator.GetSeed(); - eDimension Dimension = StringToDimension(a_IniFile.GetValue("General", "Dimension", "Overworld")); - - AString Finishers = a_IniFile.GetValueSet("Generator", "Finishers", "SprinkleFoliage,Ice,Snow,Lilypads,BottomLava,DeadBushes,PreSimulator"); - AStringVector Str = StringSplitAndTrim(Finishers, ","); - for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr) - { - // Finishers, alpha-sorted: - if (NoCaseCompare(*itr, "BottomLava") == 0) - { - int DefaultBottomLavaLevel = (Dimension == dimNether) ? 30 : 10; - int BottomLavaLevel = a_IniFile.GetValueSetI("Generator", "BottomLavaLevel", DefaultBottomLavaLevel); - m_FinishGens.push_back(new cFinishGenBottomLava(BottomLavaLevel)); - } - else if (NoCaseCompare(*itr, "DeadBushes") == 0) - { - m_FinishGens.push_back(new cFinishGenSingleBiomeSingleTopBlock(Seed, E_BLOCK_DEAD_BUSH, biDesert, 2, E_BLOCK_SAND, E_BLOCK_SAND)); - } - else if (NoCaseCompare(*itr, "Ice") == 0) - { - m_FinishGens.push_back(new cFinishGenIce); - } - else if (NoCaseCompare(*itr, "LavaSprings") == 0) - { - m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_LAVA, a_IniFile, Dimension)); - } else if (NoCaseCompare(*itr, "Lilypads") == 0) { m_FinishGens.push_back(new cFinishGenSingleBiomeSingleTopBlock(Seed, E_BLOCK_LILY_PAD, biSwampland, 4, E_BLOCK_WATER, E_BLOCK_STATIONARY_WATER)); @@ -400,10 +360,18 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) { m_FinishGens.push_back(new cFinishGenNetherClumpFoliage(Seed)); } + else if (NoCaseCompare(*itr, "OreNests") == 0) + { + m_FinishGens.push_back(new cStructGenOreNests(Seed)); + } else if (NoCaseCompare(*itr, "PreSimulator") == 0) { m_FinishGens.push_back(new cFinishGenPreSimulator); } + else if (NoCaseCompare(*itr, "Ravines") == 0) + { + m_FinishGens.push_back(new cStructGenRavines(Seed, 128)); + } else if (NoCaseCompare(*itr, "Snow") == 0) { m_FinishGens.push_back(new cFinishGenSnow); @@ -412,10 +380,27 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) { m_FinishGens.push_back(new cFinishGenSprinkleFoliage(Seed)); } + else if (NoCaseCompare(*itr, "Trees") == 0) + { + m_FinishGens.push_back(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen)); + } + else if (NoCaseCompare(*itr, "WaterLakes") == 0) + { + int Probability = a_IniFile.GetValueSetI("Generator", "WaterLakesProbability", 25); + m_FinishGens.push_back(new cStructGenLakes(Seed * 3 + 652, E_BLOCK_STATIONARY_WATER, *m_HeightGen, Probability)); + } else if (NoCaseCompare(*itr, "WaterSprings") == 0) { m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_WATER, a_IniFile, Dimension)); } + else if (NoCaseCompare(*itr, "WormNestCaves") == 0) + { + m_FinishGens.push_back(new cStructGenWormNestCaves(Seed)); + } + else + { + LOGWARNING("Unknown Finisher in the [Generator] section: \"%s\". Ignoring.", itr->c_str()); + } } // for itr - Str[] } diff --git a/src/Generating/ComposableGenerator.h b/src/Generating/ComposableGenerator.h index 29add0636..6b7627d2e 100644 --- a/src/Generating/ComposableGenerator.h +++ b/src/Generating/ComposableGenerator.h @@ -43,16 +43,16 @@ class cBiomeGen public: virtual ~cBiomeGen() {} // Force a virtual destructor in descendants - /// Generates biomes for the given chunk + /** Generates biomes for the given chunk */ virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) = 0; - /// Reads parameters from the ini file, prepares generator for use. + /** Reads parameters from the ini file, prepares generator for use. */ virtual void InitializeBiomeGen(cIniFile & a_IniFile) {} - /// Creates the correct BiomeGen descendant based on the ini file settings and the seed provided. - /// a_CacheOffByDefault gets set to whether the cache should be disabled by default - /// Used in BiomeVisualiser, too. - /// Implemented in BioGen.cpp! + /** Creates the correct BiomeGen descendant based on the ini file settings and the seed provided. + a_CacheOffByDefault gets set to whether the cache should be disabled by default. + Used in BiomeVisualiser, too. + Implemented in BioGen.cpp! */ static cBiomeGen * CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & a_CacheOffByDefault); } ; @@ -72,10 +72,10 @@ class cTerrainHeightGen public: virtual ~cTerrainHeightGen() {} // Force a virtual destructor in descendants - /// Generates heightmap for the given chunk + /** Generates heightmap for the given chunk */ virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) = 0; - /// Reads parameters from the ini file, prepares generator for use. + /** Reads parameters from the ini file, prepares generator for use. */ virtual void InitializeHeightGen(cIniFile & a_IniFile) {} /** Creates the correct TerrainHeightGen descendant based on the ini file settings and the seed provided. @@ -102,7 +102,7 @@ public: virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) = 0; - /// Reads parameters from the ini file, prepares generator for use. + /** Reads parameters from the ini file, prepares generator for use. */ virtual void InitializeCompoGen(cIniFile & a_IniFile) {} /** Creates the correct TerrainCompositionGen descendant based on the ini file settings and the seed provided. @@ -116,28 +116,12 @@ public: -/** The interface that a structure generator must implement -Structures are generated after the terrain composition took place. It should modify the blocktype data to account -for whatever structures the generator is generating. -Note that ores are considered structures too, at least from the interface point of view. -Also note that a worldgenerator may contain multiple structure generators, one for each type of structure -*/ -class cStructureGen -{ -public: - virtual ~cStructureGen() {} // Force a virtual destructor in descendants - - virtual void GenStructures(cChunkDesc & a_ChunkDesc) = 0; -} ; - -typedef std::list<cStructureGen *> cStructureGenList; - - - - - /** The interface that a finisher must implement -Finisher implements small additions after all structures have been generated. +Finisher implements changes to the chunk after the rough terrain has been generated. +Examples of finishers are trees, snow, ore, lilypads and others. +Note that a worldgenerator may contain multiple finishers. +Also note that previously we used to distinguish between a structuregen and a finisher; this distinction is +no longer relevant, all structure generators are considered finishers now (#398) */ class cFinishGen { @@ -171,7 +155,6 @@ protected: cBiomeGen * m_BiomeGen; cTerrainHeightGen * m_HeightGen; cTerrainCompositionGen * m_CompositionGen; - cStructureGenList m_StructureGens; cFinishGenList m_FinishGens; // Generators underlying the caches: @@ -180,19 +163,16 @@ protected: cTerrainCompositionGen * m_UnderlyingCompositionGen; - /// Reads the biome gen settings from the ini and initializes m_BiomeGen accordingly + /** Reads the biome gen settings from the ini and initializes m_BiomeGen accordingly */ void InitBiomeGen(cIniFile & a_IniFile); - /// Reads the HeightGen settings from the ini and initializes m_HeightGen accordingly + /** Reads the HeightGen settings from the ini and initializes m_HeightGen accordingly */ void InitHeightGen(cIniFile & a_IniFile); - /// Reads the CompositionGen settings from the ini and initializes m_CompositionGen accordingly + /** Reads the CompositionGen settings from the ini and initializes m_CompositionGen accordingly */ void InitCompositionGen(cIniFile & a_IniFile); - /// Reads the structures to generate from the ini and initializes m_StructureGens accordingly - void InitStructureGens(cIniFile & a_IniFile); - - /// Reads the finishers from the ini and initializes m_FinishGens accordingly + /** Reads the finishers from the ini and initializes m_FinishGens accordingly */ void InitFinishGens(cIniFile & a_IniFile); } ; diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index 02045f76a..f2d66af70 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -88,7 +88,7 @@ void cFinishGenNetherClumpFoliage::GenFinish(cChunkDesc & a_ChunkDesc) { continue; } - if (!g_BlockIsSolid[a_ChunkDesc.GetBlockType(PosX, y - 1, PosZ)]) // Only place on solid blocks + if (!cBlockInfo::IsSolid(a_ChunkDesc.GetBlockType(PosX, y - 1, PosZ))) // Only place on solid blocks { continue; } @@ -131,7 +131,7 @@ void cFinishGenNetherClumpFoliage::TryPlaceClump(cChunkDesc & a_ChunkDesc, int a } BLOCKTYPE BlockBelow = a_ChunkDesc.GetBlockType(x, y - 1, z); - if (!g_BlockIsSolid[BlockBelow]) // Only place on solid blocks + if (!cBlockInfo::IsSolid(BlockBelow)) // Only place on solid blocks { continue; } @@ -329,7 +329,7 @@ void cFinishGenSnow::GenFinish(cChunkDesc & a_ChunkDesc) case biFrozenOcean: { int Height = a_ChunkDesc.GetHeight(x, z); - if (g_BlockIsSnowable[a_ChunkDesc.GetBlockType(x, Height, z)]) + if (cBlockInfo::IsSnowable(a_ChunkDesc.GetBlockType(x, Height, z))) { a_ChunkDesc.SetBlockType(x, Height + 1, z, E_BLOCK_SNOW); a_ChunkDesc.SetHeight(x, z, Height + 1); diff --git a/src/Generating/MineShafts.cpp b/src/Generating/MineShafts.cpp index cc39cef7b..d9acc57bb 100644 --- a/src/Generating/MineShafts.cpp +++ b/src/Generating/MineShafts.cpp @@ -1407,7 +1407,7 @@ void cStructGenMineShafts::GetMineShaftSystemsForChunk( -void cStructGenMineShafts::GenStructures(cChunkDesc & a_ChunkDesc) +void cStructGenMineShafts::GenFinish(cChunkDesc & a_ChunkDesc) { int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); diff --git a/src/Generating/MineShafts.h b/src/Generating/MineShafts.h index c53d3bc53..ba32e75ad 100644 --- a/src/Generating/MineShafts.h +++ b/src/Generating/MineShafts.h @@ -17,7 +17,7 @@ class cStructGenMineShafts : - public cStructureGen + public cFinishGen { public: cStructGenMineShafts( @@ -52,8 +52,8 @@ protected: */ void GetMineShaftSystemsForChunk(int a_ChunkX, int a_ChunkZ, cMineShaftSystems & a_MineShaftSystems); - // cStructureGen overrides: - virtual void GenStructures(cChunkDesc & a_ChunkDesc) override; + // cFinishGen overrides: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; diff --git a/src/Generating/Ravines.cpp b/src/Generating/Ravines.cpp index cfda47e32..e64f55214 100644 --- a/src/Generating/Ravines.cpp +++ b/src/Generating/Ravines.cpp @@ -117,7 +117,7 @@ void cStructGenRavines::ClearCache(void) -void cStructGenRavines::GenStructures(cChunkDesc & a_ChunkDesc) +void cStructGenRavines::GenFinish(cChunkDesc & a_ChunkDesc) { int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); diff --git a/src/Generating/Ravines.h b/src/Generating/Ravines.h index 05164a5b2..c76b9f19f 100644 --- a/src/Generating/Ravines.h +++ b/src/Generating/Ravines.h @@ -17,7 +17,7 @@ class cStructGenRavines : - public cStructureGen + public cFinishGen { public: cStructGenRavines(int a_Seed, int a_Size); @@ -37,8 +37,8 @@ protected: /// Returns all ravines that *may* intersect the given chunk. All the ravines are valid until the next call to this function. void GetRavinesForChunk(int a_ChunkX, int a_ChunkZ, cRavines & a_Ravines); - // cStructureGen override: - virtual void GenStructures(cChunkDesc & a_ChunkDesc) override; + // cFinishGen override: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp index 47945cc2b..3cc8a09c3 100644 --- a/src/Generating/StructGen.cpp +++ b/src/Generating/StructGen.cpp @@ -54,7 +54,7 @@ const int NEST_SIZE_GRAVEL = 32; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cStructGenTrees: -void cStructGenTrees::GenStructures(cChunkDesc & a_ChunkDesc) +void cStructGenTrees::GenFinish(cChunkDesc & a_ChunkDesc) { int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); @@ -306,7 +306,7 @@ int cStructGenTrees::GetNumTrees( /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cStructGenOreNests: -void cStructGenOreNests::GenStructures(cChunkDesc & a_ChunkDesc) +void cStructGenOreNests::GenFinish(cChunkDesc & a_ChunkDesc) { int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); @@ -413,7 +413,7 @@ void cStructGenOreNests::GenerateOre(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_Ore /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cStructGenLakes: -void cStructGenLakes::GenStructures(cChunkDesc & a_ChunkDesc) +void cStructGenLakes::GenFinish(cChunkDesc & a_ChunkDesc) { int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); @@ -545,7 +545,7 @@ cStructGenDirectOverhangs::cStructGenDirectOverhangs(int a_Seed) : -void cStructGenDirectOverhangs::GenStructures(cChunkDesc & a_ChunkDesc) +void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) { // If there is no column of the wanted biome, bail out: if (!HasWantedBiome(a_ChunkDesc)) @@ -665,7 +665,7 @@ cStructGenDistortedMembraneOverhangs::cStructGenDistortedMembraneOverhangs(int a -void cStructGenDistortedMembraneOverhangs::GenStructures(cChunkDesc & a_ChunkDesc) +void cStructGenDistortedMembraneOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) { const NOISE_DATATYPE Frequency = (NOISE_DATATYPE)16; const NOISE_DATATYPE Amount = (NOISE_DATATYPE)1; diff --git a/src/Generating/StructGen.h b/src/Generating/StructGen.h index 853748bb8..9176bc192 100644 --- a/src/Generating/StructGen.h +++ b/src/Generating/StructGen.h @@ -21,7 +21,7 @@ class cStructGenTrees : - public cStructureGen + public cFinishGen { public: cStructGenTrees(int a_Seed, cBiomeGen * a_BiomeGen, cTerrainHeightGen * a_HeightGen, cTerrainCompositionGen * a_CompositionGen) : @@ -64,8 +64,8 @@ protected: const cChunkDef::BiomeMap & a_Biomes ); - // cStructureGen override: - virtual void GenStructures(cChunkDesc & a_ChunkDesc) override; + // cFinishGen override: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; @@ -73,7 +73,7 @@ protected: class cStructGenOreNests : - public cStructureGen + public cFinishGen { public: cStructGenOreNests(int a_Seed) : m_Noise(a_Seed), m_Seed(a_Seed) {} @@ -82,8 +82,8 @@ protected: cNoise m_Noise; int m_Seed; - // cStructureGen override: - virtual void GenStructures(cChunkDesc & a_ChunkDesc) override; + // cFinishGen override: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; void GenerateOre(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_OreType, int a_MaxHeight, int a_NumNests, int a_NestSize, cChunkDef::BlockTypes & a_BlockTypes, int a_Seq); } ; @@ -93,7 +93,7 @@ protected: class cStructGenLakes : - public cStructureGen + public cFinishGen { public: cStructGenLakes(int a_Seed, BLOCKTYPE a_Fluid, cTerrainHeightGen & a_HeiGen, int a_Probability) : @@ -112,8 +112,8 @@ protected: cTerrainHeightGen & m_HeiGen; int m_Probability; ///< Chance, 0 .. 100, of a chunk having the lake - // cStructureGen override: - virtual void GenStructures(cChunkDesc & a_ChunkDesc) override; + // cFinishGen override: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; /// Creates a lake image for the specified chunk into a_Lake void CreateLakeImage(int a_ChunkX, int a_ChunkZ, cBlockArea & a_Lake); @@ -125,7 +125,7 @@ protected: class cStructGenDirectOverhangs : - public cStructureGen + public cFinishGen { public: cStructGenDirectOverhangs(int a_Seed); @@ -134,8 +134,8 @@ protected: cNoise m_Noise1; cNoise m_Noise2; - // cStructureGen override: - virtual void GenStructures(cChunkDesc & a_ChunkDesc) override; + // cFinishGen override: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; bool HasWantedBiome(cChunkDesc & a_ChunkDesc) const; } ; @@ -145,7 +145,7 @@ protected: class cStructGenDistortedMembraneOverhangs : - public cStructureGen + public cFinishGen { public: cStructGenDistortedMembraneOverhangs(int a_Seed); @@ -156,8 +156,8 @@ protected: cNoise m_NoiseZ; cNoise m_NoiseH; - // cStructureGen override: - virtual void GenStructures(cChunkDesc & a_ChunkDesc) override; + // cFinishGen override: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; diff --git a/src/Globals.h b/src/Globals.h index e4737a98a..28805a83f 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -250,6 +250,7 @@ T Clamp(T a_Value, T a_Min, T a_Max) #include "ChunkDef.h" #include "BiomeDef.h" #include "BlockID.h" +#include "BlockInfo.h" #include "Entities/Effects.h" diff --git a/src/GroupManager.cpp b/src/GroupManager.cpp index 5125e7586..33b601e82 100644 --- a/src/GroupManager.cpp +++ b/src/GroupManager.cpp @@ -55,16 +55,27 @@ cGroupManager::cGroupManager() +void cGroupManager::GenerateDefaultUsersIni(cIniFile & a_IniFile) +{ + LOGWARN("Regenerating users.ini, all users will be reset"); + a_IniFile.AddHeaderComment(" This file stores the players' groups."); + a_IniFile.AddHeaderComment(" The format is:"); + a_IniFile.AddHeaderComment(" [PlayerName]"); + a_IniFile.AddHeaderComment(" Groups = GroupName1, GroupName2, ..."); + + a_IniFile.WriteFile("users.ini"); +} + + + + + void cGroupManager::CheckUsers(void) { cIniFile IniFile; if (!IniFile.ReadFile("users.ini")) { - LOGWARN("Regenerating users.ini, all users will be reset"); - IniFile.AddHeaderComment(" This is the file in which the group the player belongs to is stored"); - IniFile.AddHeaderComment(" The format is: [PlayerName] | Groups=GroupName"); - - IniFile.WriteFile("users.ini"); + GenerateDefaultUsersIni(IniFile); return; } diff --git a/src/GroupManager.h b/src/GroupManager.h index 377a54c98..9e1689a76 100644 --- a/src/GroupManager.h +++ b/src/GroupManager.h @@ -19,6 +19,9 @@ public: void LoadGroups(void); void CheckUsers(void); + /** Writes the default header to the specified ini file, and saves it as "users.ini". */ + static void GenerateDefaultUsersIni(cIniFile & a_IniFile); + private: friend class cRoot; cGroupManager(); diff --git a/src/HTTPServer/HTTPServer.cpp b/src/HTTPServer/HTTPServer.cpp index f6f5b0f8b..4e9195a00 100644 --- a/src/HTTPServer/HTTPServer.cpp +++ b/src/HTTPServer/HTTPServer.cpp @@ -29,6 +29,8 @@ class cDebugCallbacks : { virtual void OnRequestBegun(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) override { + UNUSED(a_Connection); + if (cHTTPFormParser::HasFormData(a_Request)) { a_Request.SetUserData(new cHTTPFormParser(a_Request, *this)); @@ -38,6 +40,8 @@ class cDebugCallbacks : virtual void OnRequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, int a_Size) override { + UNUSED(a_Connection); + cHTTPFormParser * FormParser = (cHTTPFormParser *)(a_Request.GetUserData()); if (FormParser != NULL) { diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index c10d13edc..1d357fcf1 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -248,6 +248,14 @@ cItemHandler::cItemHandler(int a_ItemType) bool cItemHandler::OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir) { + UNUSED(a_World); + UNUSED(a_Player); + UNUSED(a_Item); + UNUSED(a_BlockX); + UNUSED(a_BlockY); + UNUSED(a_BlockZ); + UNUSED(a_Dir); + return false; } @@ -257,6 +265,14 @@ bool cItemHandler::OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & bool cItemHandler::OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir) { + UNUSED(a_World); + UNUSED(a_Player); + UNUSED(a_Item); + UNUSED(a_BlockX); + UNUSED(a_BlockY); + UNUSED(a_BlockZ); + UNUSED(a_Dir); + return false; } @@ -266,8 +282,10 @@ bool cItemHandler::OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, const cI void cItemHandler::OnBlockDestroyed(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ) { + UNUSED(a_Item); + BLOCKTYPE Block = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); - cBlockHandler * Handler = cBlockHandler::GetBlockHandler(Block); + cBlockHandler * Handler = cBlockInfo::GetHandler(Block); if (a_Player->IsGameModeSurvival()) { @@ -288,7 +306,9 @@ void cItemHandler::OnBlockDestroyed(cWorld * a_World, cPlayer * a_Player, const void cItemHandler::OnFoodEaten(cWorld * a_World, cPlayer * a_Player, cItem * a_Item) { - + UNUSED(a_World); + UNUSED(a_Player); + UNUSED(a_Item); } @@ -461,6 +481,8 @@ bool cItemHandler::IsPlaceable(void) bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockType) { + UNUSED(a_BlockType); + return false; } @@ -499,6 +521,8 @@ bool cItemHandler::GetPlacementBlockTypeMeta( bool cItemHandler::EatItem(cPlayer * a_Player, cItem * a_Item) { + UNUSED(a_Item); + FoodInfo Info = GetFoodInfo(); if ((Info.FoodLevel > 0) || (Info.Saturation > 0.f)) diff --git a/src/Items/ItemRedstoneDust.h b/src/Items/ItemRedstoneDust.h index 18c6b8615..274d905a5 100644 --- a/src/Items/ItemRedstoneDust.h +++ b/src/Items/ItemRedstoneDust.h @@ -27,7 +27,7 @@ public: BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta ) override { - if (!g_BlockFullyOccupiesVoxel[a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)]) // Some solid blocks, such as cocoa beans, are not suitable for dust + if (!cBlockInfo::FullyOccupiesVoxel(a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ))) // Some solid blocks, such as cocoa beans, are not suitable for dust { return false; } diff --git a/src/LightingThread.cpp b/src/LightingThread.cpp index 9c81d004d..44dadb8a9 100644 --- a/src/LightingThread.cpp +++ b/src/LightingThread.cpp @@ -391,7 +391,7 @@ void cLightingThread::PrepareBlockLight(void) int idx = BaseZ + x; for (int y = m_HeightMap[idx], Index = idx + y * BlocksPerYLayer; y >= 0; y--, Index -= BlocksPerYLayer) { - if (g_BlockLightValue[m_BlockTypes[Index]] == 0) + if (cBlockInfo::GetLightValue(m_BlockTypes[Index]) == 0) { continue; } @@ -401,7 +401,7 @@ void cLightingThread::PrepareBlockLight(void) m_SeedIdx1[m_NumSeeds++] = Index; // Light it up: - m_BlockLight[Index] = g_BlockLightValue[m_BlockTypes[Index]]; + m_BlockLight[Index] = cBlockInfo::GetLightValue(m_BlockTypes[Index]); } } } diff --git a/src/LightingThread.h b/src/LightingThread.h index 72d561348..198f27248 100644 --- a/src/LightingThread.h +++ b/src/LightingThread.h @@ -169,13 +169,13 @@ protected: ASSERT(a_DstIdx >= 0); ASSERT(a_DstIdx < (int)ARRAYCOUNT(m_BlockTypes)); - if (a_Light[a_SrcIdx] <= a_Light[a_DstIdx] + g_BlockSpreadLightFalloff[m_BlockTypes[a_DstIdx]]) + if (a_Light[a_SrcIdx] <= a_Light[a_DstIdx] + cBlockInfo::GetSpreadLightFalloff(m_BlockTypes[a_DstIdx])) { // We're not offering more light than the dest block already has return; } - a_Light[a_DstIdx] = a_Light[a_SrcIdx] - g_BlockSpreadLightFalloff[m_BlockTypes[a_DstIdx]]; + a_Light[a_DstIdx] = a_Light[a_SrcIdx] - cBlockInfo::GetSpreadLightFalloff(m_BlockTypes[a_DstIdx]); if (!a_IsSeedOut[a_DstIdx]) { a_IsSeedOut[a_DstIdx] = true; diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp index c86268e63..7704f6cf3 100644 --- a/src/MobSpawner.cpp +++ b/src/MobSpawner.cpp @@ -145,7 +145,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R case cMonster::mtBat: { - return (a_RelY <= 63) && (BlockLight <= 4) && (SkyLight <= 4) && (TargetBlock == E_BLOCK_AIR) && (!g_BlockTransparent[BlockAbove]); + return (a_RelY <= 63) && (BlockLight <= 4) && (SkyLight <= 4) && (TargetBlock == E_BLOCK_AIR) && !cBlockInfo::IsTransparent(BlockAbove); } case cMonster::mtChicken: @@ -157,7 +157,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R return ( (TargetBlock == E_BLOCK_AIR) && (BlockAbove == E_BLOCK_AIR) && - (!g_BlockTransparent[BlockBelow]) && + (!cBlockInfo::IsTransparent(BlockBelow)) && (BlockBelow == E_BLOCK_GRASS) && (SkyLight >= 9) ); @@ -188,7 +188,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R (TargetBlock == E_BLOCK_AIR) && (BlockAbove == E_BLOCK_AIR) && (BlockTop == E_BLOCK_AIR) && - (!g_BlockTransparent[BlockBelow]) && + (!cBlockInfo::IsTransparent(BlockBelow)) && (SkyLight <= 7) && (BlockLight <= 7) ); @@ -215,7 +215,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R HaveFloor || ( a_Chunk->UnboundedRelGetBlockType(a_RelX + x, a_RelY - 1, a_RelZ + z, TargetBlock) && - !g_BlockTransparent[TargetBlock] + !cBlockInfo::IsTransparent(TargetBlock) ) ); } @@ -230,7 +230,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R return ( (TargetBlock == E_BLOCK_AIR) && (BlockAbove == E_BLOCK_AIR) && - (!g_BlockTransparent[BlockBelow]) && + (!cBlockInfo::IsTransparent(BlockBelow)) && (SkyLight <= 7) && (BlockLight <= 7) && (m_Random.NextInt(2, a_Biome) == 0) @@ -242,7 +242,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R return ( (TargetBlock == E_BLOCK_AIR) && (BlockAbove == E_BLOCK_AIR) && - (!g_BlockTransparent[BlockBelow]) && + (!cBlockInfo::IsTransparent(BlockBelow)) && ( (a_RelY <= 40) || (a_Biome == biSwampland) ) @@ -255,7 +255,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R return ( (TargetBlock == E_BLOCK_AIR) && (BlockAbove == E_BLOCK_AIR) && - (!g_BlockTransparent[BlockBelow]) && + (!cBlockInfo::IsTransparent(BlockBelow)) && (m_Random.NextInt(20, a_Biome) == 0) ); } diff --git a/src/Mobs/Creeper.cpp b/src/Mobs/Creeper.cpp index 40ee20e44..3471b4cf1 100644 --- a/src/Mobs/Creeper.cpp +++ b/src/Mobs/Creeper.cpp @@ -4,6 +4,7 @@ #include "Creeper.h" #include "../World.h" #include "../Entities/ProjectileEntity.h" +#include "../Entities/Player.h" @@ -13,6 +14,7 @@ cCreeper::cCreeper(void) : super("Creeper", mtCreeper, "mob.creeper.say", "mob.creeper.say", 0.6, 1.8), m_bIsBlowing(false), m_bIsCharged(false), + m_BurnedWithFlintAndSteel(false), m_ExplodingTimer(0) { } @@ -25,12 +27,25 @@ void cCreeper::Tick(float a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); - if (!ReachedFinalDestination()) + if (!ReachedFinalDestination() && !m_BurnedWithFlintAndSteel) { m_ExplodingTimer = 0; m_bIsBlowing = false; m_World->BroadcastEntityMetadata(*this); } + else + { + if (m_bIsBlowing) + { + m_ExplodingTimer += 1; + } + + if (m_ExplodingTimer == 30) + { + m_World->DoExplosionAt((m_bIsCharged ? 5 : 3), GetPosX(), GetPosY(), GetPosZ(), false, esMonster, this); + Destroy(); + } + } } @@ -80,22 +95,30 @@ void cCreeper::Attack(float a_Dt) { UNUSED(a_Dt); - m_ExplodingTimer += 1; - if (!m_bIsBlowing) { m_World->BroadcastSoundEffect("game.tnt.primed", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 1.f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); m_bIsBlowing = true; m_World->BroadcastEntityMetadata(*this); } - - if (m_ExplodingTimer == 20) - { - m_World->DoExplosionAt((m_bIsCharged ? 5 : 3), GetPosX(), GetPosY(), GetPosZ(), false, esMonster, this); - Destroy(); - } } + +void cCreeper::OnRightClicked(cPlayer & a_Player) +{ + if ((a_Player.GetEquippedItem().m_ItemType == E_ITEM_FLINT_AND_STEEL)) + { + if (!a_Player.IsGameModeCreative()) + { + a_Player.UseEquippedItem(); + } + m_World->BroadcastSoundEffect("game.tnt.primed", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 1.f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); + m_bIsBlowing = true; + m_World->BroadcastEntityMetadata(*this); + m_BurnedWithFlintAndSteel = true; + } +} + diff --git a/src/Mobs/Creeper.h b/src/Mobs/Creeper.h index 0f71e5ad2..9abca369b 100644 --- a/src/Mobs/Creeper.h +++ b/src/Mobs/Creeper.h @@ -21,13 +21,14 @@ public: virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override; virtual void Attack(float a_Dt) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override; + virtual void OnRightClicked(cPlayer & a_Player) override; bool IsBlowing(void) const {return m_bIsBlowing; } bool IsCharged(void) const {return m_bIsCharged; } private: - bool m_bIsBlowing, m_bIsCharged; + bool m_bIsBlowing, m_bIsCharged, m_BurnedWithFlintAndSteel; int m_ExplodingTimer; } ; diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index ac9137ccd..6e3c91d58 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -148,11 +148,11 @@ void cMonster::TickPathFinding() BLOCKTYPE BlockAtYPP = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY + 2, gCrossCoords[i].z + PosZ); BLOCKTYPE BlockAtYM = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY - 1, gCrossCoords[i].z + PosZ); - if ((!g_BlockIsSolid[BlockAtY]) && (!g_BlockIsSolid[BlockAtYP]) && (!IsBlockLava(BlockAtYM)) && (BlockAtY != E_BLOCK_FENCE) && (BlockAtY != E_BLOCK_FENCE_GATE)) + if ((!cBlockInfo::IsSolid(BlockAtY)) && (!cBlockInfo::IsSolid(BlockAtYP)) && (!IsBlockLava(BlockAtYM)) && (BlockAtY != E_BLOCK_FENCE) && (BlockAtY != E_BLOCK_FENCE_GATE)) { m_PotentialCoordinates.push_back(Vector3d((gCrossCoords[i].x + PosX), PosY, gCrossCoords[i].z + PosZ)); } - else if ((g_BlockIsSolid[BlockAtY]) && (!g_BlockIsSolid[BlockAtYP]) && (!g_BlockIsSolid[BlockAtYPP]) && (!IsBlockLava(BlockAtYM)) && (BlockAtY != E_BLOCK_FENCE) && (BlockAtY != E_BLOCK_FENCE_GATE)) + else if ((cBlockInfo::IsSolid(BlockAtY)) && (!cBlockInfo::IsSolid(BlockAtYP)) && (!cBlockInfo::IsSolid(BlockAtYPP)) && (!IsBlockLava(BlockAtYM)) && (BlockAtY != E_BLOCK_FENCE) && (BlockAtY != E_BLOCK_FENCE_GATE)) { m_PotentialCoordinates.push_back(Vector3d((gCrossCoords[i].x + PosX), PosY + 1, gCrossCoords[i].z + PosZ)); } @@ -416,9 +416,9 @@ int cMonster::FindFirstNonAirBlockPosition(double a_PosX, double a_PosZ) else if (PosY > cChunkDef::Height) PosY = cChunkDef::Height; - if (!g_BlockIsSolid[m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ))]) + if (!cBlockInfo::IsSolid(m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ)))) { - while (!g_BlockIsSolid[m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ))] && (PosY > 0)) + while (!cBlockInfo::IsSolid(m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ))) && (PosY > 0)) { PosY--; } @@ -427,7 +427,7 @@ int cMonster::FindFirstNonAirBlockPosition(double a_PosX, double a_PosZ) } else { - while (g_BlockIsSolid[m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ))] && (PosY < cChunkDef::Height)) + while (cBlockInfo::IsSolid(m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ))) && (PosY < cChunkDef::Height)) { PosY++; } diff --git a/src/Mobs/SnowGolem.cpp b/src/Mobs/SnowGolem.cpp index 67e3a3bb8..c1979a495 100644 --- a/src/Mobs/SnowGolem.cpp +++ b/src/Mobs/SnowGolem.cpp @@ -38,7 +38,7 @@ void cSnowGolem::Tick(float a_Dt, cChunk & a_Chunk) { BLOCKTYPE BlockBelow = m_World->GetBlock((int) floor(GetPosX()), (int) floor(GetPosY()) - 1, (int) floor(GetPosZ())); BLOCKTYPE Block = m_World->GetBlock((int) floor(GetPosX()), (int) floor(GetPosY()), (int) floor(GetPosZ())); - if (Block == E_BLOCK_AIR && g_BlockIsSolid[BlockBelow]) + if (Block == E_BLOCK_AIR && cBlockInfo::IsSolid(BlockBelow)) { m_World->SetBlock((int) floor(GetPosX()), (int) floor(GetPosY()), (int) floor(GetPosZ()), E_BLOCK_SNOW, 0); } diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index 09a6e2d09..bbd8d6aaa 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -150,7 +150,7 @@ void cVillager::HandleFarmerTryHarvestCrops() BLOCKTYPE CropBlock = m_World->GetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z); if (IsBlockFarmable(CropBlock) && m_World->GetBlockMeta(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z) == 0x7) { - cBlockHandler * Handler = cBlockHandler::GetBlockHandler(CropBlock); + cBlockHandler * Handler = cBlockInfo::GetHandler(CropBlock); cChunkInterface ChunkInterface(m_World->GetChunkMap()); cBlockInServerPluginInterface PluginInterface(*m_World); Handler->DropBlock(ChunkInterface, *m_World, PluginInterface, this, m_CropsPos.x, m_CropsPos.y, m_CropsPos.z); diff --git a/src/OSSupport/BlockingTCPLink.cpp b/src/OSSupport/BlockingTCPLink.cpp index af50eda5d..e9c00d6d4 100644 --- a/src/OSSupport/BlockingTCPLink.cpp +++ b/src/OSSupport/BlockingTCPLink.cpp @@ -89,6 +89,8 @@ bool cBlockingTCPLink::Connect(const char * iAddress, unsigned int iPort) int cBlockingTCPLink::Send(char * a_Data, unsigned int a_Size, int a_Flags /* = 0 */ ) { + UNUSED(a_Flags); + ASSERT(m_Socket.IsValid()); if (!m_Socket.IsValid()) { @@ -104,6 +106,8 @@ int cBlockingTCPLink::Send(char * a_Data, unsigned int a_Size, int a_Flags /* = int cBlockingTCPLink::SendMessage( const char* a_Message, int a_Flags /* = 0 */ ) { + UNUSED(a_Flags); + ASSERT(m_Socket.IsValid()); if (!m_Socket.IsValid()) { diff --git a/src/Piston.cpp b/src/Piston.cpp index 5eb14451d..b21d576f3 100644 --- a/src/Piston.cpp +++ b/src/Piston.cpp @@ -242,7 +242,7 @@ bool cPiston::CanPush(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) bool cPiston::CanBreakPush(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { UNUSED(a_BlockMeta); - return g_BlockPistonBreakable[a_BlockType]; + return cBlockInfo::IsPistonBreakable(a_BlockType); } diff --git a/src/Root.cpp b/src/Root.cpp index af2cb9e4b..78c94888d 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -245,7 +245,6 @@ void cRoot::Start(void) delete m_PluginManager; m_PluginManager = NULL; cItemHandler::Deinit(); - cBlockHandler::Deinit(); LOG("Cleaning up..."); delete m_Server; m_Server = NULL; diff --git a/src/Scoreboard.cpp b/src/Scoreboard.cpp index 61ecac5b7..c1da27086 100644 --- a/src/Scoreboard.cpp +++ b/src/Scoreboard.cpp @@ -17,19 +17,19 @@ AString cObjective::TypeToString(eType a_Type) { switch (a_Type) { - case E_TYPE_DUMMY: return "dummy"; - case E_TYPE_DEATH_COUNT: return "deathCount"; - case E_TYPE_PLAYER_KILL_COUNT: return "playerKillCount"; - case E_TYPE_TOTAL_KILL_COUNT: return "totalKillCount"; - case E_TYPE_HEALTH: return "health"; - case E_TYPE_ACHIEVEMENT: return "achievement"; - case E_TYPE_STAT: return "stat"; - case E_TYPE_STAT_ITEM_CRAFT: return "stat.craftItem"; - case E_TYPE_STAT_ITEM_USE: return "stat.useItem"; - case E_TYPE_STAT_ITEM_BREAK: return "stat.breakItem"; - case E_TYPE_STAT_BLOCK_MINE: return "stat.mineBlock"; - case E_TYPE_STAT_ENTITY_KILL: return "stat.killEntity"; - case E_TYPE_STAT_ENTITY_KILLED_BY: return "stat.entityKilledBy"; + case otDummy: return "dummy"; + case otDeathCount: return "deathCount"; + case otPlayerKillCount: return "playerKillCount"; + case otTotalKillCount: return "totalKillCount"; + case otHealth: return "health"; + case otAchievement: return "achievement"; + case otStat: return "stat"; + case otStatItemCraft: return "stat.craftItem"; + case otStatItemUse: return "stat.useItem"; + case otStatItemBreak: return "stat.breakItem"; + case otStatBlockMine: return "stat.mineBlock"; + case otStatEntityKill: return "stat.killEntity"; + case otStatEntityKilledBy: return "stat.entityKilledBy"; default: return ""; } @@ -46,19 +46,19 @@ cObjective::eType cObjective::StringToType(const AString & a_Name) const char * m_String; } TypeMap [] = { - {E_TYPE_DUMMY, "dummy"}, - {E_TYPE_DEATH_COUNT, "deathCount"}, - {E_TYPE_PLAYER_KILL_COUNT, "playerKillCount"}, - {E_TYPE_TOTAL_KILL_COUNT, "totalKillCount"}, - {E_TYPE_HEALTH, "health"}, - {E_TYPE_ACHIEVEMENT, "achievement"}, - {E_TYPE_STAT, "stat"}, - {E_TYPE_STAT_ITEM_CRAFT, "stat.craftItem"}, - {E_TYPE_STAT_ITEM_USE, "stat.useItem"}, - {E_TYPE_STAT_ITEM_BREAK, "stat.breakItem"}, - {E_TYPE_STAT_BLOCK_MINE, "stat.mineBlock"}, - {E_TYPE_STAT_ENTITY_KILL, "stat.killEntity"}, - {E_TYPE_STAT_ENTITY_KILLED_BY, "stat.entityKilledBy"} + {otDummy, "dummy" }, + {otDeathCount, "deathCount" }, + {otPlayerKillCount, "playerKillCount" }, + {otTotalKillCount, "totalKillCount" }, + {otHealth, "health" }, + {otAchievement, "achievement" }, + {otStat, "stat" }, + {otStatItemCraft, "stat.craftItem" }, + {otStatItemUse, "stat.useItem" }, + {otStatItemBreak, "stat.breakItem" }, + {otStatBlockMine, "stat.mineBlock" }, + {otStatEntityKill, "stat.killEntity" }, + {otStatEntityKilledBy, "stat.entityKilledBy"} }; for (size_t i = 0; i < ARRAYCOUNT(TypeMap); i++) { @@ -67,7 +67,7 @@ cObjective::eType cObjective::StringToType(const AString & a_Name) return TypeMap[i].m_Type; } } // for i - TypeMap[] - return E_TYPE_DUMMY; + return otDummy; } @@ -246,6 +246,17 @@ void cTeam::Reset(void) +void cTeam::SetDisplayName(const AString & a_Name) +{ + m_DisplayName = a_Name; + + // TODO 2014-03-01 xdot: Update clients +} + + + + + unsigned int cTeam::GetNumPlayers(void) const { return m_Players.size(); @@ -257,7 +268,7 @@ unsigned int cTeam::GetNumPlayers(void) const cScoreboard::cScoreboard(cWorld * a_World) : m_World(a_World) { - for (int i = 0; i < (int) E_DISPLAY_SLOT_COUNT; ++i) + for (int i = 0; i < (int) dsCount; ++i) { m_Display[i] = NULL; } @@ -301,11 +312,19 @@ bool cScoreboard::RemoveObjective(const AString & a_Name) return false; } - m_Objectives.erase(it); - ASSERT(m_World != NULL); m_World->BroadcastScoreboardObjective(it->second.GetName(), it->second.GetDisplayName(), 1); + for (unsigned int i = 0; i < (unsigned int) dsCount; ++i) + { + if (m_Display[i] == &it->second) + { + SetDisplay(NULL, (eDisplaySlot) i); + } + } + + m_Objectives.erase(it); + return true; } @@ -410,7 +429,7 @@ cTeam * cScoreboard::QueryPlayerTeam(const AString & a_Name) void cScoreboard::SetDisplay(const AString & a_Objective, eDisplaySlot a_Slot) { - ASSERT(a_Slot < E_DISPLAY_SLOT_COUNT); + ASSERT(a_Slot < dsCount); cObjective * Objective = GetObjective(a_Objective); @@ -435,7 +454,7 @@ void cScoreboard::SetDisplay(cObjective * a_Objective, eDisplaySlot a_Slot) cObjective * cScoreboard::GetObjectiveIn(eDisplaySlot a_Slot) { - ASSERT(a_Slot < E_DISPLAY_SLOT_COUNT); + ASSERT(a_Slot < dsCount); return m_Display[a_Slot]; } @@ -444,7 +463,7 @@ cObjective * cScoreboard::GetObjectiveIn(eDisplaySlot a_Slot) -void cScoreboard::ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback& a_Callback) +bool cScoreboard::ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback& a_Callback) { cCSLock Lock(m_CSObjectives); @@ -455,10 +474,66 @@ void cScoreboard::ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallb // Call callback if (a_Callback.Item(&it->second)) { - return; + return false; } } } + return true; +} + + + + + +bool cScoreboard::ForEachObjective(cObjectiveCallback& a_Callback) +{ + cCSLock Lock(m_CSObjectives); + + for (cObjectiveMap::iterator it = m_Objectives.begin(); it != m_Objectives.end(); ++it) + { + // Call callback + if (a_Callback.Item(&it->second)) + { + return false; + } + } + return true; +} + + + + + +bool cScoreboard::ForEachTeam(cTeamCallback& a_Callback) +{ + cCSLock Lock(m_CSObjectives); + + for (cTeamMap::iterator it = m_Teams.begin(); it != m_Teams.end(); ++it) + { + // Call callback + if (a_Callback.Item(&it->second)) + { + return false; + } + } + return true; +} + + + + + +void cScoreboard::AddPlayerScore(const AString & a_Name, cObjective::eType a_Type, cObjective::Score a_Value) +{ + cCSLock Lock(m_CSObjectives); + + for (cObjectiveMap::iterator it = m_Objectives.begin(); it != m_Objectives.end(); ++it) + { + if (it->second.GetType() == a_Type) + { + it->second.AddScore(a_Name, a_Value); + } + } } @@ -474,7 +549,7 @@ void cScoreboard::SendTo(cClientHandle & a_Client) it->second.SendTo(a_Client); } - for (int i = 0; i < (int) E_DISPLAY_SLOT_COUNT; ++i) + for (int i = 0; i < (int) dsCount; ++i) { // Avoid race conditions cObjective * Objective = m_Display[i]; diff --git a/src/Scoreboard.h b/src/Scoreboard.h index f64ba2bce..e22ecaeb1 100644 --- a/src/Scoreboard.h +++ b/src/Scoreboard.h @@ -14,9 +14,11 @@ class cObjective; +class cTeam; class cWorld; typedef cItemCallback<cObjective> cObjectiveCallback; +typedef cItemCallback<cTeam> cTeamCallback; @@ -31,23 +33,23 @@ public: enum eType { - E_TYPE_DUMMY, + otDummy, - E_TYPE_DEATH_COUNT, - E_TYPE_PLAYER_KILL_COUNT, - E_TYPE_TOTAL_KILL_COUNT, - E_TYPE_HEALTH, + otDeathCount, + otPlayerKillCount, + otTotalKillCount, + otHealth, - E_TYPE_ACHIEVEMENT, + otAchievement, - E_TYPE_STAT, - E_TYPE_STAT_ITEM_CRAFT, - E_TYPE_STAT_ITEM_USE, - E_TYPE_STAT_ITEM_BREAK, + otStat, + otStatItemCraft, + otStatItemUse, + otStatItemBreak, - E_TYPE_STAT_BLOCK_MINE, - E_TYPE_STAT_ENTITY_KILL, - E_TYPE_STAT_ENTITY_KILLED_BY + otStatBlockMine, + otStatEntityKill, + otStatEntityKilledBy }; // tolua_end @@ -67,31 +69,37 @@ public: const AString & GetName(void) const { return m_Name; } const AString & GetDisplayName(void) const { return m_DisplayName; } - /// Resets the objective + /** Resets the objective */ void Reset(void); - /// Returns the score of the specified player + /** Returns the score of the specified player */ Score GetScore(const AString & a_Name) const; - /// Sets the score of the specified player + /** Sets the score of the specified player */ void SetScore(const AString & a_Name, Score a_Score); - /// Resets the score of the specified player + /** Resets the score of the specified player */ void ResetScore(const AString & a_Name); - /// Adds a_Delta and returns the new score + /** Adds a_Delta and returns the new score */ Score AddScore(const AString & a_Name, Score a_Delta); - /// Subtracts a_Delta and returns the new score + /** Subtracts a_Delta and returns the new score */ Score SubScore(const AString & a_Name, Score a_Delta); void SetDisplayName(const AString & a_Name); // tolua_end - /// Send this objective to the specified client + /** Send this objective to the specified client */ void SendTo(cClientHandle & a_Client); + static const char * GetClassStatic(void) // Needed for ManualBindings's ForEach templates + { + return "cObjective"; + } + + private: typedef std::pair<AString, Score> cTrackedPlayer; @@ -109,7 +117,8 @@ private: friend class cScoreboardSerializer; -}; + +}; // tolua_export @@ -127,21 +136,21 @@ public: const AString & a_Prefix, const AString & a_Suffix ); - /// Adds a new player to the team + // tolua_begin + + /** Adds a new player to the team */ bool AddPlayer(const AString & a_Name); - /// Removes a player from the team + /** Removes a player from the team */ bool RemovePlayer(const AString & a_Name); - /// Returns whether the specified player is in this team + /** Returns whether the specified player is in this team */ bool HasPlayer(const AString & a_Name) const; - /// Removes all registered players + /** Removes all registered players */ void Reset(void); - // tolua_begin - - /// Returns the number of registered players + /** Returns the number of registered players */ unsigned int GetNumPlayers(void) const; bool AllowsFriendlyFire(void) const { return m_AllowsFriendlyFire; } @@ -163,6 +172,11 @@ public: // tolua_end + static const char * GetClassStatic(void) // Needed for ManualBindings's ForEach templates + { + return "cTeam"; + } + private: typedef std::set<AString> cPlayerNameSet; @@ -180,7 +194,8 @@ private: friend class cScoreboardSerializer; -}; + +}; // tolua_export @@ -193,11 +208,11 @@ public: enum eDisplaySlot { - E_DISPLAY_SLOT_LIST = 0, - E_DISPLAY_SLOT_SIDEBAR, - E_DISPLAY_SLOT_NAME, + dsList = 0, + dsSidebar, + dsName, - E_DISPLAY_SLOT_COUNT + dsCount }; // tolua_end @@ -209,44 +224,61 @@ public: // tolua_begin - /// Registers a new scoreboard objective, returns the cObjective instance, NULL on name collision + /** Registers a new scoreboard objective, returns the cObjective instance, NULL on name collision */ cObjective * RegisterObjective(const AString & a_Name, const AString & a_DisplayName, cObjective::eType a_Type); - /// Removes a registered objective, returns true if operation was successful + /** Removes a registered objective, returns true if operation was successful */ bool RemoveObjective(const AString & a_Name); - /// Retrieves the objective with the specified name, NULL if not found + /** Retrieves the objective with the specified name, NULL if not found */ cObjective * GetObjective(const AString & a_Name); - /// Registers a new team, returns the cTeam instance, NULL on name collision + /** Registers a new team, returns the cTeam instance, NULL on name collision */ cTeam * RegisterTeam(const AString & a_Name, const AString & a_DisplayName, const AString & a_Prefix, const AString & a_Suffix); - /// Removes a registered team, returns true if operation was successful + /** Removes a registered team, returns true if operation was successful */ bool RemoveTeam(const AString & a_Name); - /// Retrieves the team with the specified name, NULL if not found + /** Retrieves the team with the specified name, NULL if not found */ cTeam * GetTeam(const AString & a_Name); - cTeam * QueryPlayerTeam(const AString & a_Name); // WARNING: O(n logn) - void SetDisplay(const AString & a_Objective, eDisplaySlot a_Slot); - void SetDisplay(cObjective * a_Objective, eDisplaySlot a_Slot); - cObjective * GetObjectiveIn(eDisplaySlot a_Slot); - /// Execute callback for each objective with the specified type - void ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback& a_Callback); - unsigned int GetNumObjectives(void) const; unsigned int GetNumTeams(void) const; + void AddPlayerScore(const AString & a_Name, cObjective::eType a_Type, cObjective::Score a_Value = 1); + // tolua_end - /// Send this scoreboard to the specified client + /** Send this scoreboard to the specified client */ void SendTo(cClientHandle & a_Client); + cTeam * QueryPlayerTeam(const AString & a_Name); // WARNING: O(n logn) + + /** Execute callback for each objective with the specified type + * + * Returns true if all objectives processed, false if the callback aborted by returning true. + */ + bool ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback& a_Callback); + + /** Execute callback for each objective. + * + * Returns true if all objectives have been processed, false if the callback aborted by returning true. + */ + bool ForEachObjective(cObjectiveCallback& a_Callback); // Exported in ManualBindings.cpp + + /** Execute callback for each team. + * + * Returns true if all teams have been processed, false if the callback aborted by returning true. + */ + bool ForEachTeam(cTeamCallback& a_Callback); // Exported in ManualBindings.cpp + + void SetDisplay(cObjective * a_Objective, eDisplaySlot a_Slot); + private: @@ -265,11 +297,12 @@ private: cWorld * m_World; - cObjective* m_Display[E_DISPLAY_SLOT_COUNT]; + cObjective * m_Display[dsCount]; friend class cScoreboardSerializer; -} ; + +}; // tolua_export diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index 85190c82b..4967c83f9 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -252,7 +252,7 @@ int cFireSimulator::GetBurnStepTime(cChunk * a_Chunk, int a_RelX, int a_RelY, in { return m_BurnStepTimeFuel; } - IsBlockBelowSolid = g_BlockIsSolid[BlockBelow]; + IsBlockBelowSolid = cBlockInfo::IsSolid(BlockBelow); } for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 74b30f920..f377b0aa7 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -566,14 +566,14 @@ void cIncrementalRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_Block { 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)... + if (cBlockInfo::IsSolid(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)]) + if (cBlockInfo::IsSolid(m_World.GetBlock(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y + 1, a_BlockZ + gCrossCoords[i].z))) { continue; } diff --git a/src/Simulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator.h index e6bc28621..8b7363366 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.h +++ b/src/Simulator/IncrementalRedstoneSimulator.h @@ -170,7 +170,7 @@ private: /* ====== Misc Functions ====== */ /** Returns if a block is viable to be the MiddleBlock of a SetLinkedPowered operation */ - inline static bool IsViableMiddleBlock(BLOCKTYPE Block) { return g_BlockFullyOccupiesVoxel[Block]; } + inline static bool IsViableMiddleBlock(BLOCKTYPE Block) { return cBlockInfo::FullyOccupiesVoxel(Block); } /** Returns if a block is a mechanism (something that accepts power and does something) */ inline static bool IsMechanism(BLOCKTYPE Block) diff --git a/src/Tracer.cpp b/src/Tracer.cpp index ef136302f..968a64439 100644 --- a/src/Tracer.cpp +++ b/src/Tracer.cpp @@ -226,7 +226,7 @@ bool cTracer::Trace( const Vector3f & a_Start, const Vector3f & a_Direction, int BLOCKTYPE BlockID = m_World->GetBlock(pos.x, pos.y, pos.z); // Block is counted as a collision if we are not doing a line of sight and it is solid, // or if the block is not air and not water. That way mobs can still see underwater. - if ((!a_LineOfSight && g_BlockIsSolid[BlockID]) || (a_LineOfSight && (BlockID != E_BLOCK_AIR) && !IsBlockWater(BlockID))) + if ((!a_LineOfSight && cBlockInfo::IsSolid(BlockID)) || (a_LineOfSight && (BlockID != E_BLOCK_AIR) && !IsBlockWater(BlockID))) { BlockHitPosition = pos; int Normal = GetHitNormal(a_Start, End, pos ); diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index bfcad3d92..88977e005 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -224,6 +224,24 @@ void cSlotArea::DblClicked(cPlayer & a_Player, int a_SlotNum) +void cSlotArea::OnPlayerAdded(cPlayer & a_Player) +{ + UNUSED(a_Player); +} + + + + + +void cSlotArea::OnPlayerRemoved(cPlayer & a_Player) +{ + UNUSED(a_Player); +} + + + + + void cSlotArea::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_Apply, bool a_KeepEmptySlots) { for (int i = 0; i < m_NumSlots; i++) @@ -447,6 +465,18 @@ void cSlotAreaCrafting::OnPlayerRemoved(cPlayer & a_Player) + +void cSlotAreaCrafting::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots) +{ + UNUSED(a_ItemStack); + UNUSED(a_Player); + UNUSED(a_ShouldApply); + UNUSED(a_KeepEmptySlots); +} + + + + void cSlotAreaCrafting::ClickedResult(cPlayer & a_Player) { cItem & DraggingItem = a_Player.GetDraggingItem(); diff --git a/src/UI/SlotArea.h b/src/UI/SlotArea.h index d31c87e0c..25b367cff 100644 --- a/src/UI/SlotArea.h +++ b/src/UI/SlotArea.h @@ -48,10 +48,10 @@ public: virtual void DblClicked(cPlayer & a_Player, int a_SlotNum); /// Called when a new player opens the same parent window. The window already tracks the player. CS-locked. - virtual void OnPlayerAdded(cPlayer & a_Player) {} ; + virtual void OnPlayerAdded(cPlayer & a_Player); /// Called when one of the players closes the parent window. The window already doesn't track the player. CS-locked. - virtual void OnPlayerRemoved(cPlayer & a_Player) {} ; + virtual void OnPlayerRemoved(cPlayer & a_Player); /** Called to store as much of a_ItemStack in the area as possible. a_ItemStack is modified to reflect the change. The default implementation searches each slot for available space and distributes the stack there. @@ -226,7 +226,7 @@ public: virtual void OnPlayerRemoved(cPlayer & a_Player) override; // Distributing items into this area is completely disabled - virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots) override {} + virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots) override; protected: /// Maps player's EntityID -> current recipe; not a std::map because cCraftingGrid needs proper constructor params diff --git a/src/World.cpp b/src/World.cpp index 88cc19559..58d50d3a8 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1750,7 +1750,7 @@ bool cWorld::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure) bool cWorld::DigBlock(int a_X, int a_Y, int a_Z) { - cBlockHandler *Handler = cBlockHandler::GetBlockHandler(GetBlock(a_X, a_Y, a_Z)); + cBlockHandler * Handler = cBlockInfo::GetHandler(GetBlock(a_X, a_Y, a_Z)); cChunkInterface ChunkInterface(GetChunkMap()); Handler->OnDestroyed(ChunkInterface, *this, a_X, a_Y, a_Z); return m_ChunkMap->DigBlock(a_X, a_Y, a_Z); diff --git a/src/WorldStorage/FastNBT.h b/src/WorldStorage/FastNBT.h index 49f97c458..01a9ad274 100644 --- a/src/WorldStorage/FastNBT.h +++ b/src/WorldStorage/FastNBT.h @@ -106,6 +106,10 @@ public: /** Parses and contains the parsed data Also implements data accessor functions for tree traversal and value getters The data pointer passed in the constructor is assumed to be valid throughout the object's life. Care must be taken not to initialize from a temporary. +The parser decomposes the input data into a tree of tags that is stored as an array of cFastNBTTag items, +and accessing the tree is done by using the array indices for tags. Each tag stores the indices for its parent, +first child, last child, prev sibling and next sibling, a value of -1 indicates that the indice is not valid. +Each primitive tag also stores the length of the contained data, in bytes. */ class cParsedNBT { @@ -114,13 +118,32 @@ public: bool IsValid(void) const {return m_IsValid; } + /** Returns the root tag of the hierarchy. */ int GetRoot(void) const {return 0; } + + /** Returns the first child of the specified tag, or -1 if none / not applicable. */ int GetFirstChild (int a_Tag) const { return m_Tags[a_Tag].m_FirstChild; } + + /** Returns the last child of the specified tag, or -1 if none / not applicable. */ int GetLastChild (int a_Tag) const { return m_Tags[a_Tag].m_LastChild; } + + /** Returns the next sibling of the specified tag, or -1 if none. */ int GetNextSibling(int a_Tag) const { return m_Tags[a_Tag].m_NextSibling; } + + /** Returns the previous sibling of the specified tag, or -1 if none. */ int GetPrevSibling(int a_Tag) const { return m_Tags[a_Tag].m_PrevSibling; } - int GetDataLength (int a_Tag) const { return m_Tags[a_Tag].m_DataLength; } + + /** Returns the length of the tag's data, in bytes. + Not valid for Compound or List tags! */ + int GetDataLength (int a_Tag) const + { + ASSERT(m_Tags[a_Tag].m_Type != TAG_List); + ASSERT(m_Tags[a_Tag].m_Type != TAG_Compound); + return m_Tags[a_Tag].m_DataLength; + } + /** Returns the data stored in this tag. + Not valid for Compound or List tags! */ const char * GetData(int a_Tag) const { ASSERT(m_Tags[a_Tag].m_Type != TAG_List); @@ -128,55 +151,64 @@ public: return m_Data + m_Tags[a_Tag].m_DataStart; } + /** Returns the direct child tag of the specified name, or -1 if no such tag. */ int FindChildByName(int a_Tag, const AString & a_Name) const { return FindChildByName(a_Tag, a_Name.c_str(), a_Name.length()); } + /** Returns the direct child tag of the specified name, or -1 if no such tag. */ int FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLength = 0) const; - int FindTagByPath (int a_Tag, const AString & a_Path) const; + + /** Returns the child tag of the specified path (Name1\Name2\Name3...), or -1 if no such tag. */ + int FindTagByPath(int a_Tag, const AString & a_Path) const; eTagType GetType(int a_Tag) const { return m_Tags[a_Tag].m_Type; } - /// Returns the children type for a list tag; undefined on other tags. If list empty, returns TAG_End + /** Returns the children type for a List tag; undefined on other tags. If list empty, returns TAG_End. */ eTagType GetChildrenType(int a_Tag) const { ASSERT(m_Tags[a_Tag].m_Type == TAG_List); return (m_Tags[a_Tag].m_FirstChild < 0) ? TAG_End : m_Tags[m_Tags[a_Tag].m_FirstChild].m_Type; } + /** Returns the value stored in a Byte tag. Not valid for any other tag type. */ inline unsigned char GetByte(int a_Tag) const { ASSERT(m_Tags[a_Tag].m_Type == TAG_Byte); return (unsigned char)(m_Data[m_Tags[a_Tag].m_DataStart]); } + /** Returns the value stored in a Short tag. Not valid for any other tag type. */ inline Int16 GetShort(int a_Tag) const { ASSERT(m_Tags[a_Tag].m_Type == TAG_Short); return GetBEShort(m_Data + m_Tags[a_Tag].m_DataStart); } + /** Returns the value stored in an Int tag. Not valid for any other tag type. */ inline Int32 GetInt(int a_Tag) const { ASSERT(m_Tags[a_Tag].m_Type == TAG_Int); return GetBEInt(m_Data + m_Tags[a_Tag].m_DataStart); } + /** Returns the value stored in a Long tag. Not valid for any other tag type. */ inline Int64 GetLong(int a_Tag) const { ASSERT(m_Tags[a_Tag].m_Type == TAG_Long); return NetworkToHostLong8(m_Data + m_Tags[a_Tag].m_DataStart); } + /** Returns the value stored in a Float tag. Not valid for any other tag type. */ inline float GetFloat(int a_Tag) const { ASSERT(m_Tags[a_Tag].m_Type == TAG_Float); // Cause a compile-time error if sizeof(float) != 4 // If your platform produces a compiler error here, you'll need to add code that manually decodes 32-bit floats - char Check1[5 - sizeof(float)]; // sizeof(float) <= 4 - char Check2[sizeof(float) - 3]; // sizeof(float) >= 4 + char Check1[5 - sizeof(float)]; // Fails if sizeof(float) > 4 + char Check2[sizeof(float) - 3]; // Fails if sizeof(float) < 4 UNUSED(Check1); UNUSED(Check2); @@ -186,12 +218,21 @@ public: return f; } + /** Returns the value stored in a Double tag. Not valid for any other tag type. */ inline double GetDouble(int a_Tag) const { + // Cause a compile-time error if sizeof(double) != 8 + // If your platform produces a compiler error here, you'll need to add code that manually decodes 64-bit doubles + char Check1[9 - sizeof(double)]; // Fails if sizeof(double) > 8 + char Check2[sizeof(double) - 7]; // Fails if sizeof(double) < 8 + UNUSED(Check1); + UNUSED(Check2); + ASSERT(m_Tags[a_Tag].m_Type == TAG_Double); return NetworkToHostDouble8(m_Data + m_Tags[a_Tag].m_DataStart); } + /** Returns the value stored in a String tag. Not valid for any other tag type. */ inline AString GetString(int a_Tag) const { ASSERT(m_Tags[a_Tag].m_Type == TAG_String); @@ -200,6 +241,7 @@ public: return res; } + /** Returns the tag's name. For tags that are not named, returns an empty string. */ inline AString GetName(int a_Tag) const { AString res; diff --git a/src/WorldStorage/ScoreboardSerializer.cpp b/src/WorldStorage/ScoreboardSerializer.cpp index 9b8b661c4..6c885bb45 100644 --- a/src/WorldStorage/ScoreboardSerializer.cpp +++ b/src/WorldStorage/ScoreboardSerializer.cpp @@ -173,13 +173,13 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer) a_Writer.BeginCompound("DisplaySlots"); - cObjective * Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::E_DISPLAY_SLOT_LIST); + cObjective * Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::dsList); a_Writer.AddString("slot_0", (Objective == NULL) ? "" : Objective->GetName()); - Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::E_DISPLAY_SLOT_SIDEBAR); + Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::dsSidebar); a_Writer.AddString("slot_1", (Objective == NULL) ? "" : Objective->GetName()); - Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::E_DISPLAY_SLOT_NAME); + Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::dsName); a_Writer.AddString("slot_2", (Objective == NULL) ? "" : Objective->GetName()); a_Writer.EndCompound(); // DisplaySlots @@ -280,7 +280,7 @@ bool cScoreboardSerializer::LoadScoreboardFromNBT(const cParsedNBT & a_NBT) { AString Name, DisplayName, Prefix, Suffix; - bool AllowsFriendlyFire = false, CanSeeFriendlyInvisible = false; + bool AllowsFriendlyFire = true, CanSeeFriendlyInvisible = false; int CurrLine = a_NBT.FindChildByName(Child, "Name"); if (CurrLine >= 0) @@ -346,7 +346,7 @@ bool cScoreboardSerializer::LoadScoreboardFromNBT(const cParsedNBT & a_NBT) { AString Name = a_NBT.GetString(CurrLine); - m_ScoreBoard->SetDisplay(Name, cScoreboard::E_DISPLAY_SLOT_LIST); + m_ScoreBoard->SetDisplay(Name, cScoreboard::dsList); } CurrLine = a_NBT.FindChildByName(DisplaySlots, "slot_1"); @@ -354,7 +354,7 @@ bool cScoreboardSerializer::LoadScoreboardFromNBT(const cParsedNBT & a_NBT) { AString Name = a_NBT.GetString(CurrLine); - m_ScoreBoard->SetDisplay(Name, cScoreboard::E_DISPLAY_SLOT_SIDEBAR); + m_ScoreBoard->SetDisplay(Name, cScoreboard::dsSidebar); } CurrLine = a_NBT.FindChildByName(DisplaySlots, "slot_2"); @@ -362,7 +362,7 @@ bool cScoreboardSerializer::LoadScoreboardFromNBT(const cParsedNBT & a_NBT) { AString Name = a_NBT.GetString(CurrLine); - m_ScoreBoard->SetDisplay(Name, cScoreboard::E_DISPLAY_SLOT_NAME); + m_ScoreBoard->SetDisplay(Name, cScoreboard::dsName); } return true; |