Merge branch 'master' into ballisticmissiles
Conflicts: src/ClientHandle.cpp
This commit is contained in:
commit
c2978a3457
@ -22,8 +22,10 @@ Code Stuff
|
||||
- This helps prevent mistakes such as `if (a & 1 == 0)`
|
||||
* White space is free, so use it freely
|
||||
- "freely" as in "plentifully", not "arbitrarily"
|
||||
* All `case` statements inside a `switch` need an extra indent.
|
||||
* Each and every control statement deserves its braces. This helps maintainability later on when the file is edited, lines added or removed - the control logic doesn't break so easily.
|
||||
- The only exception: a `switch` statement with all `case` statements being a single short statement is allowed to use the short brace-less form.
|
||||
- These two rules really mean that indent is governed by braces
|
||||
* Add an empty last line in all source files (GCC and GIT can complain otherwise)
|
||||
* Use doxy-comments for functions in the header file, format as `/** Description */`
|
||||
* Use spaces after the comment markers: `// Comment` instead of `//Comment`
|
||||
|
4
Doxyfile
4
Doxyfile
@ -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
|
||||
|
1
MCServer/Plugins/.gitignore
vendored
1
MCServer/Plugins/.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
*.txt
|
||||
*.md
|
||||
*/
|
||||
|
29
MCServer/Plugins/@EnableMobDebug.lua
Normal file
29
MCServer/Plugins/@EnableMobDebug.lua
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
-- @EnableMobDebug.lua
|
||||
|
||||
-- Enables the MobDebug debugger, used by ZeroBrane Studio, for a plugin
|
||||
-- Needs to be named with a @ at the start so that it's loaded as the first file of the plugin
|
||||
|
||||
--[[
|
||||
Usage:
|
||||
Copy this file to your plugin's folder when you want to debug that plugin
|
||||
You should neither check this file into the plugin's version control system,
|
||||
nor distribute it in the final release.
|
||||
--]]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- Try to load the debugger, be silent about failures:
|
||||
local IsSuccess, MobDebug = pcall(require, "mobdebug")
|
||||
if (IsSuccess) then
|
||||
MobDebug.start()
|
||||
|
||||
-- The debugger will automatically put a breakpoint on this line, use this opportunity to set more breakpoints in your code
|
||||
LOG(cPluginManager:GetCurrentPlugin():GetName() .. ": MobDebug enabled")
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
@ -134,6 +134,7 @@ g_APIDesc =
|
||||
HasBlockSkyLights = { Params = "", Return = "bool", Notes = "Returns true if current datatypes include skylight" },
|
||||
HasBlockTypes = { Params = "", Return = "bool", Notes = "Returns true if current datatypes include block types" },
|
||||
LoadFromSchematicFile = { Params = "FileName", Return = "", Notes = "Clears current content and loads new content from the specified schematic file. Returns true if successful. Returns false and logs error if unsuccessful, old content is preserved in such a case." },
|
||||
LoadFromSchematicString = { Params = "SchematicData", Return = "", Notes = "Clears current content and loads new content from the specified string (assumed to contain .schematic data). Returns true if successful. Returns false and logs error if unsuccessful, old content is preserved in such a case." },
|
||||
Merge =
|
||||
{
|
||||
{ Params = "BlockAreaSrc, {{Vector3i|RelMinCoords}}, Strategy", Return = "", Notes = "Merges BlockAreaSrc into this object at the specified relative coords, using the specified strategy" },
|
||||
@ -161,6 +162,7 @@ g_APIDesc =
|
||||
RotateCW = { Params = "", Return = "", Notes = "Rotates the block area around the Y axis, clockwise (north -> east). Modifies blocks' metas (if present) to match." },
|
||||
RotateCWNoMeta = { Params = "", Return = "", Notes = "Rotates the block area around the Y axis, clockwise (north -> east). Doesn't modify blocks' metas." },
|
||||
SaveToSchematicFile = { Params = "FileName", Return = "", Notes = "Saves the current contents to a schematic file. Returns true if successful." },
|
||||
SaveToSchematicString = { Params = "", Return = "string", Notes = "Saves the current contents to a string (in a .schematic file format). Returns the data if successful, nil if failed." },
|
||||
SetBlockLight = { Params = "BlockX, BlockY, BlockZ, BlockLight", Return = "", Notes = "Sets the blocklight at the specified absolute coords" },
|
||||
SetBlockMeta = { Params = "BlockX, BlockY, BlockZ, BlockMeta", Return = "", Notes = "Sets the block meta at the specified absolute coords" },
|
||||
SetBlockSkyLight = { Params = "BlockX, BlockY, BlockZ, SkyLight", Return = "", Notes = "Sets the skylight at the specified absolute coords" },
|
||||
@ -290,6 +292,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 = [[
|
||||
@ -451,6 +485,58 @@ end
|
||||
},
|
||||
}, -- cClientHandle
|
||||
|
||||
cCompositeChat =
|
||||
{
|
||||
Desc = [[
|
||||
Encapsulates a chat message that can contain various formatting, URLs, commands executed on click
|
||||
and commands suggested on click. The chat message can be sent by the regular chat-sending functions,
|
||||
{{cPlayer}}:SendMessage(), {{cWorld}}:BroadcastChat() and {{cRoot}}:BroadcastChat().</p>
|
||||
<p>
|
||||
Note that most of the functions in this class are so-called modifiers - they modify the object and
|
||||
then return the object itself, so that they can be chained one after another.
|
||||
]],
|
||||
Functions =
|
||||
{
|
||||
constructor =
|
||||
{
|
||||
{ Params = "", Return = "", Notes = "Creates an empty chat message" },
|
||||
{ Params = "Text", Return = "", Notes = "Creates a chat message containing the specified text, parsed by the ParseText() function. This allows easy migration from old chat messages." },
|
||||
},
|
||||
AddRunCommandPart = { Params = "Text, Command, [Style]", Return = "self", Notes = "Adds a text which, when clicked, runs the specified command. Chaining." },
|
||||
AddSuggestCommandPart = { Params = "Text, Command, [Style]", Return = "self", Notes = "Adds a text which, when clicked, puts the specified command into the player's chat input area. Chaining." },
|
||||
AddTextPart = { Params = "Text, [Style]", Return = "self", Notes = "Adds a regular text. Chaining." },
|
||||
AddUrlPart = { Params = "Text, Url, [Style]", Return = "self", Notes = "Adds a text which, when clicked, opens up a browser at the specified URL. Chaining." },
|
||||
Clear = { Params = "", Return = "", Notes = "Removes all parts from this object" },
|
||||
GetMessageType = { Params = "", Return = "MessageType", Notes = "Returns the MessageType (mtXXX constant) that is associated with this message. When sent to a player, the message will be formatted according to this message type and the player's settings (adding \"[INFO]\" prefix etc.)" },
|
||||
ParseText = { Params = "Text", Return = "self", Notes = "Adds text, while recognizing http and https URLs and old-style formatting codes (\"@2\"). Chaining." },
|
||||
SetMessageType = { Params = "MessageType", Return = "self", Notes = "Sets the MessageType (mtXXX constant) that is associated with this message. When sent to a player, the message will be formatted according to this message type and the player's settings (adding \"[INFO]\" prefix etc.) Chaining." },
|
||||
UnderlineUrls = { Params = "", Return = "self", Notes = "Makes all URL parts contained in the message underlined. Doesn't affect parts added in the future. Chaining." },
|
||||
},
|
||||
|
||||
AdditionalInfo =
|
||||
{
|
||||
{
|
||||
Header = "Chaining example",
|
||||
Contents = [[
|
||||
Sending a chat message that is composed of multiple different parts has been made easy thanks to
|
||||
chaining. Consider the following example that shows how a message containing all kinds of parts
|
||||
is sent (adapted from the Debuggers plugin):
|
||||
<pre class="prettyprint lang-lua">
|
||||
function OnPlayerJoined(a_Player)
|
||||
-- Send an example composite chat message to the player:
|
||||
a_Player:SendMessage(cCompositeChat()
|
||||
:AddTextPart("Hello, ")
|
||||
:AddUrlPart(a_Player:GetName(), "www.mc-server.org", "u@2") -- Colored underlined link
|
||||
:AddSuggestCommandPart(", and welcome.", "/help", "u") -- Underlined suggest-command
|
||||
:AddRunCommandPart(" SetDay", "/time set 0") -- Regular text that will execute command when clicked
|
||||
:SetMessageType(mtJoin) -- It is a join-message
|
||||
)
|
||||
end</pre>
|
||||
]],
|
||||
},
|
||||
}, -- AdditionalInfo
|
||||
}, -- cCompositeChat
|
||||
|
||||
cCraftingGrid =
|
||||
{
|
||||
Desc = [[
|
||||
@ -1115,6 +1201,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 +1895,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 +1944,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 +1994,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.",
|
||||
@ -1973,7 +2152,9 @@ end
|
||||
DoWithDropSpenserAt = { Params = "X, Y, Z, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a dropper or a dispenser at the specified coords, calls the CallbackFunction with the {{cDropSpenserEntity}} parameter representing the dropper or dispenser. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cDropSpenserEntity|DropSpenserEntity}}, [CallbackData])</pre> Note that this can be used to access both dispensers and droppers in a similar way. The function returns false if there is neither dispenser nor dropper, or if there is, it returns the bool value that the callback has returned." },
|
||||
DoWithDropperAt = { Params = "X, Y, Z, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a dropper at the specified coords, calls the CallbackFunction with the {{cDropperEntity}} parameter representing the dropper. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cDropperEntity|DropperEntity}}, [CallbackData])</pre> The function returns false if there is no dropper, or if there is, it returns the bool value that the callback has returned." },
|
||||
DoWithEntityByID = { Params = "EntityID, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If an entity with the specified ID exists, calls the callback with the {{cEntity}} parameter representing the entity. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cEntity|Entity}}, [CallbackData])</pre> The function returns false if the entity was not found, and it returns the same bool value that the callback has returned if the entity was found." },
|
||||
DoWithFlowerPotAt = { Params = "X, Y, Z, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a flower pot at the specified coords, calls the CallbackFunction with the {{cFlowerPotEntity}} parameter representing the flower pot. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cFlowerPotEntity|FlowerPotEntity}}, [CallbackData])</pre> The function returns false if there is no flower pot, or if there is, it returns the bool value that the callback has returned." },
|
||||
DoWithFurnaceAt = { Params = "X, Y, Z, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a furnace at the specified coords, calls the CallbackFunction with the {{cFurnaceEntity}} parameter representing the furnace. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cFurnaceEntity|FurnaceEntity}}, [CallbackData])</pre> The function returns false if there is no furnace, or if there is, it returns the bool value that the callback has returned." },
|
||||
DoWithMobHeadAt = { Params = "X, Y, Z, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a mob head at the specified coords, calls the CallbackFunction with the {{cMobHeadEntity}} parameter representing the furnace. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cMobHeadEntity|MobHeadEntity}}, [CallbackData])</pre> The function returns false if there is no mob head, or if there is, it returns the bool value that the callback has returned." },
|
||||
DoWithNoteBlockAt = { Params = "BlockX, BlockY, BlockZ, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a note block at the specified coords, calls the CallbackFunction with the {{cNoteEntity}} parameter representing the note block. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cNoteEntity|NoteEntity}}, [CallbackData])</pre> The function returns false if there is no note block, or if there is, it returns the bool value that the callback has returned." },
|
||||
DoWithPlayer = { Params = "PlayerName, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a player of the specified name (exact match), calls the CallbackFunction with the {{cPlayer}} parameter representing the player. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cPlayer|Player}}, [CallbackData])</pre> The function returns false if the player was not found, or whatever bool value the callback returned if the player was found." },
|
||||
FastSetBlock =
|
||||
@ -2576,16 +2757,16 @@ end
|
||||
|
||||
IgnoreClasses =
|
||||
{
|
||||
"coroutine",
|
||||
"debug",
|
||||
"io",
|
||||
"math",
|
||||
"package",
|
||||
"os",
|
||||
"string",
|
||||
"table",
|
||||
"g_Stats",
|
||||
"g_TrackedPages",
|
||||
"^coroutine$",
|
||||
"^debug$",
|
||||
"^io$",
|
||||
"^math$",
|
||||
"^package$",
|
||||
"^os$",
|
||||
"^string$",
|
||||
"^table$",
|
||||
"^g_Stats$",
|
||||
"^g_TrackedPages$",
|
||||
},
|
||||
|
||||
IgnoreFunctions =
|
||||
|
@ -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
|
||||
@ -236,6 +238,20 @@ World:ForEachChestInChunk(Player:GetChunkX(), Player:GetChunkZ(),
|
||||
},
|
||||
Inherits = "cBlockEntity";
|
||||
}, -- cSignEntity
|
||||
|
||||
cFlowerPotEntity =
|
||||
{
|
||||
Desc = [[
|
||||
This class represents a flower pot entity in the world.
|
||||
]],
|
||||
Functions =
|
||||
{
|
||||
IsItemInPot = { Params = "", Return = "bool", Notes = "Is a flower in the pot?" },
|
||||
GetItem = { Params = "", Return = "{{cItem|Item}}", Notes = "Returns the item in the flower pot." },
|
||||
SetItem = { Params = "{{cItem|Item}}", Return = "", Notes = "Set the item in the flower pot" },
|
||||
},
|
||||
Inherits = "cBlockEntity";
|
||||
}, -- cFlowerPotEntity
|
||||
}
|
||||
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 3b416b07a339b3abcbc127070d56eea05b05373d
|
||||
Subproject commit 013a32a7fb3c8a6cfe0aef892d4c7394d4e1be59
|
@ -30,6 +30,7 @@ function Initialize(Plugin)
|
||||
PM:AddHook(cPluginManager.HOOK_CHUNK_GENERATED, OnChunkGenerated);
|
||||
PM:AddHook(cPluginManager.HOOK_PLUGINS_LOADED, OnPluginsLoaded);
|
||||
PM:AddHook(cPluginManager.HOOK_PLUGIN_MESSAGE, OnPluginMessage);
|
||||
PM:AddHook(cPluginManager.HOOK_PLAYER_JOINED, OnPlayerJoined)
|
||||
|
||||
PM:BindCommand("/le", "debuggers", HandleListEntitiesCmd, "- Shows a list of all the loaded entities");
|
||||
PM:BindCommand("/ke", "debuggers", HandleKillEntitiesCmd, "- Kills all the loaded entities");
|
||||
@ -70,6 +71,8 @@ function Initialize(Plugin)
|
||||
-- TestExpatBindings();
|
||||
-- TestPluginCalls();
|
||||
|
||||
TestBlockAreasString()
|
||||
|
||||
return true
|
||||
end;
|
||||
|
||||
@ -201,6 +204,42 @@ end
|
||||
|
||||
|
||||
|
||||
function TestBlockAreasString()
|
||||
-- Write one area to string, then to file:
|
||||
local BA1 = cBlockArea()
|
||||
BA1:Create(5, 5, 5, cBlockArea.baTypes + cBlockArea.baMetas)
|
||||
BA1:Fill(cBlockArea.baTypes, E_BLOCK_DIAMOND_BLOCK)
|
||||
BA1:FillRelCuboid(1, 3, 1, 3, 1, 3, cBlockArea.baTypes, E_BLOCK_GOLD_BLOCK)
|
||||
local Data = BA1:SaveToSchematicString()
|
||||
if ((type(Data) ~= "string") or (Data == "")) then
|
||||
LOG("Cannot save schematic to string")
|
||||
return
|
||||
end
|
||||
cFile:CreateFolder("schematics")
|
||||
local f = io.open("schematics/StringTest.schematic", "w")
|
||||
f:write(Data)
|
||||
f:close()
|
||||
|
||||
-- Load a second area from that file:
|
||||
local BA2 = cBlockArea()
|
||||
if not(BA2:LoadFromSchematicFile("schematics/StringTest.schematic")) then
|
||||
LOG("Cannot read schematic from string test file")
|
||||
return
|
||||
end
|
||||
BA2:Clear()
|
||||
|
||||
-- Load another area from a string in that file:
|
||||
f = io.open("schematics/StringTest.schematic", "r")
|
||||
Data = f:read("*all")
|
||||
if not(BA2:LoadFromSchematicString(Data)) then
|
||||
LOG("Cannot load schematic from string")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function TestSQLiteBindings()
|
||||
LOG("Testing SQLite bindings...");
|
||||
|
||||
@ -1258,3 +1297,17 @@ end
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerJoined(a_Player)
|
||||
-- Test composite chat chaining:
|
||||
a_Player:SendMessage(cCompositeChat()
|
||||
:AddTextPart("Hello, ")
|
||||
:AddUrlPart(a_Player:GetName(), "www.mc-server.org", "u@2")
|
||||
:AddSuggestCommandPart(", and welcome.", "/help", "u")
|
||||
:AddRunCommandPart(" SetDay", "/time set 0")
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -317,26 +317,19 @@ local function WriteCommandsCategoryGithub(a_Category, f)
|
||||
if (CategoryName == "") then
|
||||
CategoryName = "General";
|
||||
end
|
||||
f:write("\n## ", GithubizeString(a_Category.DisplayName or CategoryName), "\n");
|
||||
f:write("\n### ", GithubizeString(a_Category.DisplayName or CategoryName), "\n");
|
||||
|
||||
-- Write description:
|
||||
if (a_Category.Description ~= "") then
|
||||
f:write(GithubizeString(a_Category.Description), "\n");
|
||||
f:write(GithubizeString(a_Category.Description), "\n\n");
|
||||
end
|
||||
|
||||
f:write("| Command | Permission | Description | \n")
|
||||
f:write("| ------- | ---------- | ----------- | \n")
|
||||
|
||||
-- Write commands:
|
||||
f:write("\n");
|
||||
for idx2, cmd in ipairs(a_Category.Commands) do
|
||||
f:write("\n### ", cmd.CommandString, "\n", GithubizeString(cmd.Info.HelpString or "UNDOCUMENTED"), "\n\n");
|
||||
if (cmd.Info.Permission ~= nil) then
|
||||
f:write("Permission required: **", cmd.Info.Permission, "**\n\n");
|
||||
end
|
||||
if (cmd.Info.DetailedDescription ~= nil) then
|
||||
f:write(GithubizeString(cmd.Info.DetailedDescription));
|
||||
end
|
||||
if (cmd.Info.ParameterCombinations ~= nil) then
|
||||
WriteCommandParameterCombinationsGithub(cmd.CommandString, cmd.Info.ParameterCombinations, f);
|
||||
end
|
||||
f:write("|", cmd.CommandString, " | ", cmd.Info.Permission or "", " | ", GithubizeString(cmd.Info.HelpString or "UNDOCUMENTED"), "| \n")
|
||||
end
|
||||
f:write("\n\n")
|
||||
end
|
||||
@ -537,12 +530,13 @@ local function DumpPermissionsGithub(a_PluginInfo, f)
|
||||
|
||||
-- Dump the permissions:
|
||||
f:write("\n# Permissions\n");
|
||||
f:write("| Permissions | Description | Commands | Recommended groups |\n")
|
||||
f:write("| ----------- | ----------- | -------- | ------------------ |\n")
|
||||
for idx, perm in ipairs(Permissions) do
|
||||
f:write("### ", perm.Name, "\n");
|
||||
f:write(GithubizeString(perm.Info.Description or ""));
|
||||
f:write(perm.Name, " | ");
|
||||
f:write(GithubizeString(perm.Info.Description or ""), " | ");
|
||||
local CommandsAffected = perm.Info.CommandsAffected or {};
|
||||
if (#CommandsAffected > 0) then
|
||||
f:write("\n\nCommands affected:\n - ");
|
||||
local Affects = {};
|
||||
for idx2, cmd in ipairs(CommandsAffected) do
|
||||
if (type(cmd) == "string") then
|
||||
@ -551,11 +545,10 @@ local function DumpPermissionsGithub(a_PluginInfo, f)
|
||||
table.insert(Affects, GetCommandRefGithub(cmd.Name, cmd));
|
||||
end
|
||||
end
|
||||
f:write(table.concat(Affects, "\n - "));
|
||||
f:write("\n");
|
||||
f:write(table.concat(Affects, ", "), " | ");
|
||||
end
|
||||
if (perm.Info.RecommendedGroups ~= nil) then
|
||||
f:write("\n\nRecommended groups: ", perm.Info.RecommendedGroups, "\n");
|
||||
f:write(perm.Info.RecommendedGroups, " |");
|
||||
end
|
||||
f:write("\n");
|
||||
end
|
||||
@ -578,7 +571,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
|
||||
|
||||
|
BIN
MCServer/lua5.1.dll
Normal file
BIN
MCServer/lua5.1.dll
Normal file
Binary file not shown.
@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
macro (add_flags_lnk FLAGS)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAGS}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${FLAGS}")
|
||||
@ -62,6 +60,7 @@ macro(set_flags)
|
||||
|
||||
# We use a signed char (fixes #640 on RasPi)
|
||||
add_flags_cxx("-fsigned-char")
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
@ -184,6 +183,14 @@ macro(set_exe_flags)
|
||||
string(REPLACE "-w" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
string(REPLACE "-w" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
|
||||
add_flags_cxx("-Wall -Wextra")
|
||||
|
||||
# we support non-IEEE 754 fpus so can make no guarentees about error
|
||||
add_flags_cxx("-ffast-math")
|
||||
|
||||
# clang does not provide the __extern_always_inline macro and a part of libm depends on this when using fast-math
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
add_flags_cxx("-D__extern_always_inline=inline")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
|
@ -47,8 +47,12 @@ if (WIN32)
|
||||
)
|
||||
endif()
|
||||
|
||||
set_target_properties(lua PROPERTIES OUTPUT_NAME "lua51")
|
||||
|
||||
# NOTE: The DLL for each configuration is stored at the same place, thus overwriting each other.
|
||||
# This is known, however such behavior is needed for LuaRocks - they always load "lua.dll"
|
||||
# This is known, however such behavior is needed for LuaRocks - they always load "lua5.1.dll" or "lua51.dll"
|
||||
# We make it work by compiling to "lua51.dll" and providing a proxy-DLL "lua5.1.dll"
|
||||
# See http://lua-users.org/wiki/LuaProxyDllFour for details
|
||||
else()
|
||||
add_library(lua ${SOURCE})
|
||||
endif()
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 2ceda579893ceb23c5eb0d56df47dc235644e0f4
|
||||
Subproject commit 2cb1a0c4009ecf368ecc74eb428394e10f9e6d00
|
@ -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"
|
||||
@ -57,6 +58,8 @@ $cfile "../BlockEntities/HopperEntity.h"
|
||||
$cfile "../BlockEntities/JukeboxEntity.h"
|
||||
$cfile "../BlockEntities/NoteEntity.h"
|
||||
$cfile "../BlockEntities/SignEntity.h"
|
||||
$cfile "../BlockEntities/MobHeadEntity.h"
|
||||
$cfile "../BlockEntities/FlowerPotEntity.h"
|
||||
$cfile "../WebAdmin.h"
|
||||
$cfile "../Root.h"
|
||||
$cfile "../Vector3f.h"
|
||||
@ -75,6 +78,7 @@ $cfile "../Mobs/Monster.h"
|
||||
$cfile "../CompositeChat.h"
|
||||
$cfile "../Map.h"
|
||||
$cfile "../MapManager.h"
|
||||
$cfile "../Scoreboard.h"
|
||||
|
||||
|
||||
|
||||
|
506
src/Bindings/DeprecatedBindings.cpp
Normal file
506
src/Bindings/DeprecatedBindings.cpp
Normal file
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
8
src/Bindings/DeprecatedBindings.h
Normal file
8
src/Bindings/DeprecatedBindings.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
struct lua_State;
|
||||
class DeprecatedBindings
|
||||
{
|
||||
public:
|
||||
static void Bind( lua_State* tolua_S );
|
||||
};
|
@ -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;
|
||||
@ -714,7 +716,7 @@ void cLuaState::Push(cBlockEntity * a_BlockEntity)
|
||||
|
||||
|
||||
|
||||
void cLuaState::GetReturn(int a_StackPos, bool & a_ReturnedVal)
|
||||
void cLuaState::GetStackValue(int a_StackPos, bool & a_ReturnedVal)
|
||||
{
|
||||
a_ReturnedVal = (tolua_toboolean(m_LuaState, a_StackPos, a_ReturnedVal ? 1 : 0) > 0);
|
||||
}
|
||||
@ -723,11 +725,17 @@ void cLuaState::GetReturn(int a_StackPos, bool & a_ReturnedVal)
|
||||
|
||||
|
||||
|
||||
void cLuaState::GetReturn(int a_StackPos, AString & a_ReturnedVal)
|
||||
void cLuaState::GetStackValue(int a_StackPos, AString & a_Value)
|
||||
{
|
||||
if (lua_isstring(m_LuaState, a_StackPos))
|
||||
size_t len = 0;
|
||||
const char * data = lua_tolstring(m_LuaState, a_StackPos, &len);
|
||||
if (data != NULL)
|
||||
{
|
||||
a_ReturnedVal = tolua_tocppstring(m_LuaState, a_StackPos, a_ReturnedVal.c_str());
|
||||
a_Value.assign(data, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
a_Value.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -735,7 +743,7 @@ void cLuaState::GetReturn(int a_StackPos, AString & a_ReturnedVal)
|
||||
|
||||
|
||||
|
||||
void cLuaState::GetReturn(int a_StackPos, int & a_ReturnedVal)
|
||||
void cLuaState::GetStackValue(int a_StackPos, int & a_ReturnedVal)
|
||||
{
|
||||
if (lua_isnumber(m_LuaState, a_StackPos))
|
||||
{
|
||||
@ -747,7 +755,7 @@ void cLuaState::GetReturn(int a_StackPos, int & a_ReturnedVal)
|
||||
|
||||
|
||||
|
||||
void cLuaState::GetReturn(int a_StackPos, double & a_ReturnedVal)
|
||||
void cLuaState::GetStackValue(int a_StackPos, double & a_ReturnedVal)
|
||||
{
|
||||
if (lua_isnumber(m_LuaState, a_StackPos))
|
||||
{
|
||||
|
@ -197,6 +197,19 @@ public:
|
||||
void Push(void * a_Ptr);
|
||||
void Push(cHopperEntity * a_Hopper);
|
||||
void Push(cBlockEntity * a_BlockEntity);
|
||||
|
||||
/** Retrieve value at a_StackPos, if it is a valid bool. If not, a_Value is unchanged */
|
||||
void GetStackValue(int a_StackPos, bool & a_Value);
|
||||
|
||||
/** Retrieve value at a_StackPos, if it is a valid string. If not, a_Value is unchanged */
|
||||
void GetStackValue(int a_StackPos, AString & a_Value);
|
||||
|
||||
/** Retrieve value at a_StackPos, if it is a valid number. If not, a_Value is unchanged */
|
||||
void GetStackValue(int a_StackPos, int & a_Value);
|
||||
|
||||
/** Retrieve value at a_StackPos, if it is a valid number. If not, a_Value is unchanged */
|
||||
void GetStackValue(int a_StackPos, double & a_Value);
|
||||
|
||||
|
||||
/** Call any 0-param 0-return Lua function in a single line: */
|
||||
template <typename FnT>
|
||||
@ -270,7 +283,7 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetReturn(-1, a_Ret1);
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
return true;
|
||||
}
|
||||
@ -292,7 +305,7 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetReturn(-1, a_Ret1);
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
ASSERT(InitialTop == lua_gettop(m_LuaState));
|
||||
return true;
|
||||
@ -315,7 +328,7 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetReturn(-1, a_Ret1);
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
return true;
|
||||
}
|
||||
@ -338,7 +351,7 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetReturn(-1, a_Ret1);
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
return true;
|
||||
}
|
||||
@ -362,7 +375,7 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetReturn(-1, a_Ret1);
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
return true;
|
||||
}
|
||||
@ -387,7 +400,7 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetReturn(-1, a_Ret1);
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
return true;
|
||||
}
|
||||
@ -414,7 +427,7 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetReturn(-1, a_Ret1);
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
return true;
|
||||
}
|
||||
@ -442,7 +455,7 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetReturn(-1, a_Ret1);
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
return true;
|
||||
}
|
||||
@ -471,7 +484,7 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetReturn(-1, a_Ret1);
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
return true;
|
||||
}
|
||||
@ -501,7 +514,7 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetReturn(-1, a_Ret1);
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
return true;
|
||||
}
|
||||
@ -532,7 +545,7 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetReturn(-1, a_Ret1);
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
return true;
|
||||
}
|
||||
@ -553,8 +566,8 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetReturn(-2, a_Ret1);
|
||||
GetReturn(-1, a_Ret2);
|
||||
GetStackValue(-2, a_Ret1);
|
||||
GetStackValue(-1, a_Ret2);
|
||||
lua_pop(m_LuaState, 2);
|
||||
return true;
|
||||
}
|
||||
@ -576,8 +589,8 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetReturn(-2, a_Ret1);
|
||||
GetReturn(-1, a_Ret2);
|
||||
GetStackValue(-2, a_Ret1);
|
||||
GetStackValue(-1, a_Ret2);
|
||||
lua_pop(m_LuaState, 2);
|
||||
return true;
|
||||
}
|
||||
@ -601,8 +614,8 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetReturn(-2, a_Ret1);
|
||||
GetReturn(-1, a_Ret2);
|
||||
GetStackValue(-2, a_Ret1);
|
||||
GetStackValue(-1, a_Ret2);
|
||||
lua_pop(m_LuaState, 2);
|
||||
return true;
|
||||
}
|
||||
@ -627,8 +640,8 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetReturn(-2, a_Ret1);
|
||||
GetReturn(-1, a_Ret2);
|
||||
GetStackValue(-2, a_Ret1);
|
||||
GetStackValue(-1, a_Ret2);
|
||||
lua_pop(m_LuaState, 2);
|
||||
return true;
|
||||
}
|
||||
@ -654,8 +667,8 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetReturn(-2, a_Ret1);
|
||||
GetReturn(-1, a_Ret2);
|
||||
GetStackValue(-2, a_Ret1);
|
||||
GetStackValue(-1, a_Ret2);
|
||||
lua_pop(m_LuaState, 2);
|
||||
return true;
|
||||
}
|
||||
@ -683,8 +696,8 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetReturn(-2, a_Ret1);
|
||||
GetReturn(-1, a_Ret2);
|
||||
GetStackValue(-2, a_Ret1);
|
||||
GetStackValue(-1, a_Ret2);
|
||||
lua_pop(m_LuaState, 2);
|
||||
return true;
|
||||
}
|
||||
@ -713,8 +726,8 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetReturn(-2, a_Ret1);
|
||||
GetReturn(-1, a_Ret2);
|
||||
GetStackValue(-2, a_Ret1);
|
||||
GetStackValue(-1, a_Ret2);
|
||||
lua_pop(m_LuaState, 2);
|
||||
return true;
|
||||
}
|
||||
@ -743,9 +756,9 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetReturn(-3, a_Ret1);
|
||||
GetReturn(-2, a_Ret2);
|
||||
GetReturn(-1, a_Ret3);
|
||||
GetStackValue(-3, a_Ret1);
|
||||
GetStackValue(-2, a_Ret2);
|
||||
GetStackValue(-1, a_Ret3);
|
||||
lua_pop(m_LuaState, 3);
|
||||
return true;
|
||||
}
|
||||
@ -775,9 +788,9 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetReturn(-3, a_Ret1);
|
||||
GetReturn(-2, a_Ret2);
|
||||
GetReturn(-1, a_Ret3);
|
||||
GetStackValue(-3, a_Ret1);
|
||||
GetStackValue(-2, a_Ret2);
|
||||
GetStackValue(-1, a_Ret3);
|
||||
lua_pop(m_LuaState, 3);
|
||||
return true;
|
||||
}
|
||||
@ -808,11 +821,11 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetReturn(-5, a_Ret1);
|
||||
GetReturn(-4, a_Ret2);
|
||||
GetReturn(-3, a_Ret3);
|
||||
GetReturn(-2, a_Ret4);
|
||||
GetReturn(-1, a_Ret5);
|
||||
GetStackValue(-5, a_Ret1);
|
||||
GetStackValue(-4, a_Ret2);
|
||||
GetStackValue(-3, a_Ret3);
|
||||
GetStackValue(-2, a_Ret4);
|
||||
GetStackValue(-1, a_Ret5);
|
||||
lua_pop(m_LuaState, 5);
|
||||
return true;
|
||||
}
|
||||
@ -918,18 +931,6 @@ protected:
|
||||
/** Pushes a usertype of the specified class type onto the stack */
|
||||
void PushUserType(void * a_Object, const char * a_Type);
|
||||
|
||||
/** Retrieve value returned at a_StackPos, if it is a valid bool. If not, a_ReturnedVal is unchanged */
|
||||
void GetReturn(int a_StackPos, bool & a_ReturnedVal);
|
||||
|
||||
/** Retrieve value returned at a_StackPos, if it is a valid string. If not, a_ReturnedVal is unchanged */
|
||||
void GetReturn(int a_StackPos, AString & a_ReturnedVal);
|
||||
|
||||
/** Retrieve value returned at a_StackPos, if it is a valid number. If not, a_ReturnedVal is unchanged */
|
||||
void GetReturn(int a_StackPos, int & a_ReturnedVal);
|
||||
|
||||
/** Retrieve value returned at a_StackPos, if it is a valid number. If not, a_ReturnedVal is unchanged */
|
||||
void GetReturn(int a_StackPos, double & a_ReturnedVal);
|
||||
|
||||
/**
|
||||
Calls the function that has been pushed onto the stack by PushFunction(),
|
||||
with arguments pushed by PushXXX().
|
||||
|
@ -23,9 +23,11 @@
|
||||
#include "../BlockEntities/HopperEntity.h"
|
||||
#include "../BlockEntities/NoteEntity.h"
|
||||
#include "../BlockEntities/MobHeadEntity.h"
|
||||
#include "../BlockEntities/FlowerPotEntity.h"
|
||||
#include "md5/md5.h"
|
||||
#include "../LineBlockTracer.h"
|
||||
#include "../WorldStorage/SchematicFileSerializer.h"
|
||||
#include "../CompositeChat.h"
|
||||
|
||||
|
||||
|
||||
@ -2455,7 +2457,7 @@ static int tolua_cBlockArea_GetSize(lua_State * tolua_S)
|
||||
static int tolua_cBlockArea_LoadFromSchematicFile(lua_State * tolua_S)
|
||||
{
|
||||
// function cBlockArea::LoadFromSchematicFile
|
||||
// Exported manually because function has been moved to SchematicFileSerilizer.cpp
|
||||
// Exported manually because function has been moved to SchematicFileSerializer.cpp
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamUserType(1, "cBlockArea") ||
|
||||
@ -2482,10 +2484,41 @@ static int tolua_cBlockArea_LoadFromSchematicFile(lua_State * tolua_S)
|
||||
|
||||
|
||||
|
||||
static int tolua_cBlockArea_LoadFromSchematicString(lua_State * tolua_S)
|
||||
{
|
||||
// function cBlockArea::LoadFromSchematicString
|
||||
// Exported manually because function has been moved to SchematicFileSerializer.cpp
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamUserType(1, "cBlockArea") ||
|
||||
!L.CheckParamString (2) ||
|
||||
!L.CheckParamEnd (3)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, NULL);
|
||||
if (self == NULL)
|
||||
{
|
||||
tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea::LoadFromSchematicFile'", NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AString Data;
|
||||
L.GetStackValue(2, Data);
|
||||
bool res = cSchematicFileSerializer::LoadFromSchematicString(*self, Data);
|
||||
tolua_pushboolean(tolua_S, res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cBlockArea_SaveToSchematicFile(lua_State * tolua_S)
|
||||
{
|
||||
// function cBlockArea::SaveToSchematicFile
|
||||
// Exported manually because function has been moved to SchematicFileSerilizer.cpp
|
||||
// Exported manually because function has been moved to SchematicFileSerializer.cpp
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamUserType(1, "cBlockArea") ||
|
||||
@ -2511,6 +2544,285 @@ static int tolua_cBlockArea_SaveToSchematicFile(lua_State * tolua_S)
|
||||
|
||||
|
||||
|
||||
static int tolua_cBlockArea_SaveToSchematicString(lua_State * tolua_S)
|
||||
{
|
||||
// function cBlockArea::SaveToSchematicString
|
||||
// Exported manually because function has been moved to SchematicFileSerializer.cpp
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamUserType(1, "cBlockArea") ||
|
||||
!L.CheckParamEnd (2)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, NULL);
|
||||
if (self == NULL)
|
||||
{
|
||||
tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea::SaveToSchematicFile'", NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AString Data;
|
||||
if (cSchematicFileSerializer::SaveToSchematicString(*self, Data))
|
||||
{
|
||||
L.Push(Data);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cCompositeChat_AddRunCommandPart(lua_State * tolua_S)
|
||||
{
|
||||
// function cCompositeChat:AddRunCommandPart(Message, Command, [Style])
|
||||
// Exported manually to support call-chaining (return *this)
|
||||
|
||||
// Check params:
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamUserType(1, "cCompositeChat") ||
|
||||
!L.CheckParamString(2, 3)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL);
|
||||
if (self == NULL)
|
||||
{
|
||||
tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:AddRunCommandPart'", NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Add the part:
|
||||
AString Text, Command, Style;
|
||||
L.GetStackValue(2, Text);
|
||||
L.GetStackValue(3, Command);
|
||||
L.GetStackValue(4, Style);
|
||||
self->AddRunCommandPart(Text, Command, Style);
|
||||
|
||||
// Cut away everything from the stack except for the cCompositeChat instance; return that:
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cCompositeChat_AddSuggestCommandPart(lua_State * tolua_S)
|
||||
{
|
||||
// function cCompositeChat:AddSuggestCommandPart(Message, Command, [Style])
|
||||
// Exported manually to support call-chaining (return *this)
|
||||
|
||||
// Check params:
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamUserType(1, "cCompositeChat") ||
|
||||
!L.CheckParamString(2, 3)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL);
|
||||
if (self == NULL)
|
||||
{
|
||||
tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:AddSuggestCommandPart'", NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Add the part:
|
||||
AString Text, Command, Style;
|
||||
L.GetStackValue(2, Text);
|
||||
L.GetStackValue(3, Command);
|
||||
L.GetStackValue(4, Style);
|
||||
self->AddSuggestCommandPart(Text, Command, Style);
|
||||
|
||||
// Cut away everything from the stack except for the cCompositeChat instance; return that:
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cCompositeChat_AddTextPart(lua_State * tolua_S)
|
||||
{
|
||||
// function cCompositeChat:AddTextPart(Message, [Style])
|
||||
// Exported manually to support call-chaining (return *this)
|
||||
|
||||
// Check params:
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamUserType(1, "cCompositeChat") ||
|
||||
!L.CheckParamString(2)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL);
|
||||
if (self == NULL)
|
||||
{
|
||||
tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:AddTextPart'", NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Add the part:
|
||||
AString Text, Style;
|
||||
L.GetStackValue(2, Text);
|
||||
L.GetStackValue(3, Style);
|
||||
self->AddTextPart(Text, Style);
|
||||
|
||||
// Cut away everything from the stack except for the cCompositeChat instance; return that:
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cCompositeChat_AddUrlPart(lua_State * tolua_S)
|
||||
{
|
||||
// function cCompositeChat:AddTextPart(Message, Url, [Style])
|
||||
// Exported manually to support call-chaining (return *this)
|
||||
|
||||
// Check params:
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamUserType(1, "cCompositeChat") ||
|
||||
!L.CheckParamString(2, 3)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL);
|
||||
if (self == NULL)
|
||||
{
|
||||
tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:AddUrlPart'", NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Add the part:
|
||||
AString Text, Url, Style;
|
||||
L.GetStackValue(2, Text);
|
||||
L.GetStackValue(3, Url);
|
||||
L.GetStackValue(4, Style);
|
||||
self->AddUrlPart(Text, Url, Style);
|
||||
|
||||
// Cut away everything from the stack except for the cCompositeChat instance; return that:
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cCompositeChat_ParseText(lua_State * tolua_S)
|
||||
{
|
||||
// function cCompositeChat:ParseText(TextMessage)
|
||||
// Exported manually to support call-chaining (return *this)
|
||||
|
||||
// Check params:
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamUserType(1, "cCompositeChat") ||
|
||||
!L.CheckParamString(2)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL);
|
||||
if (self == NULL)
|
||||
{
|
||||
tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:ParseText'", NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Parse the text:
|
||||
AString Text;
|
||||
L.GetStackValue(2, Text);
|
||||
self->ParseText(Text);
|
||||
|
||||
// Cut away everything from the stack except for the cCompositeChat instance; return that:
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cCompositeChat_SetMessageType(lua_State * tolua_S)
|
||||
{
|
||||
// function cCompositeChat:SetMessageType(MessageType)
|
||||
// Exported manually to support call-chaining (return *this)
|
||||
|
||||
// Check params:
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamUserType(1, "cCompositeChat") ||
|
||||
!L.CheckParamNumber(2)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL);
|
||||
if (self == NULL)
|
||||
{
|
||||
tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:SetMessageType'", NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set the type:
|
||||
int MessageType;
|
||||
L.GetStackValue(1, MessageType);
|
||||
self->SetMessageType((eMessageType)MessageType);
|
||||
|
||||
// Cut away everything from the stack except for the cCompositeChat instance; return that:
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cCompositeChat_UnderlineUrls(lua_State * tolua_S)
|
||||
{
|
||||
// function cCompositeChat:UnderlineUrls()
|
||||
// Exported manually to support call-chaining (return *this)
|
||||
|
||||
// Check params:
|
||||
cLuaState L(tolua_S);
|
||||
if (!L.CheckParamUserType(1, "cCompositeChat"))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL);
|
||||
if (self == NULL)
|
||||
{
|
||||
tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:UnderlineUrls'", NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Call the processing
|
||||
self->UnderlineUrls();
|
||||
|
||||
// Cut away everything from the stack except for the cCompositeChat instance; return that:
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ManualBindings::Bind(lua_State * tolua_S)
|
||||
{
|
||||
tolua_beginmodule(tolua_S, NULL);
|
||||
@ -2527,12 +2839,24 @@ void ManualBindings::Bind(lua_State * tolua_S)
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cBlockArea");
|
||||
tolua_function(tolua_S, "GetBlockTypeMeta", tolua_cBlockArea_GetBlockTypeMeta);
|
||||
tolua_function(tolua_S, "GetOrigin", tolua_cBlockArea_GetOrigin);
|
||||
tolua_function(tolua_S, "GetRelBlockTypeMeta", tolua_cBlockArea_GetRelBlockTypeMeta);
|
||||
tolua_function(tolua_S, "GetSize", tolua_cBlockArea_GetSize);
|
||||
tolua_function(tolua_S, "LoadFromSchematicFile", tolua_cBlockArea_LoadFromSchematicFile);
|
||||
tolua_function(tolua_S, "SaveToSchematicFile", tolua_cBlockArea_SaveToSchematicFile);
|
||||
tolua_function(tolua_S, "GetBlockTypeMeta", tolua_cBlockArea_GetBlockTypeMeta);
|
||||
tolua_function(tolua_S, "GetOrigin", tolua_cBlockArea_GetOrigin);
|
||||
tolua_function(tolua_S, "GetRelBlockTypeMeta", tolua_cBlockArea_GetRelBlockTypeMeta);
|
||||
tolua_function(tolua_S, "GetSize", tolua_cBlockArea_GetSize);
|
||||
tolua_function(tolua_S, "LoadFromSchematicFile", tolua_cBlockArea_LoadFromSchematicFile);
|
||||
tolua_function(tolua_S, "LoadFromSchematicString", tolua_cBlockArea_LoadFromSchematicString);
|
||||
tolua_function(tolua_S, "SaveToSchematicFile", tolua_cBlockArea_SaveToSchematicFile);
|
||||
tolua_function(tolua_S, "SaveToSchematicString", tolua_cBlockArea_SaveToSchematicString);
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cCompositeChat");
|
||||
tolua_function(tolua_S, "AddRunCommandPart", tolua_cCompositeChat_AddRunCommandPart);
|
||||
tolua_function(tolua_S, "AddSuggestCommandPart", tolua_cCompositeChat_AddSuggestCommandPart);
|
||||
tolua_function(tolua_S, "AddTextPart", tolua_cCompositeChat_AddTextPart);
|
||||
tolua_function(tolua_S, "AddUrlPart", tolua_cCompositeChat_AddUrlPart);
|
||||
tolua_function(tolua_S, "ParseText", tolua_cCompositeChat_ParseText);
|
||||
tolua_function(tolua_S, "SetMessageType", tolua_cCompositeChat_SetMessageType);
|
||||
tolua_function(tolua_S, "UnderlineUrls", tolua_cCompositeChat_UnderlineUrls);
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cHopperEntity");
|
||||
@ -2561,7 +2885,8 @@ void ManualBindings::Bind(lua_State * tolua_S)
|
||||
tolua_function(tolua_S, "DoWithFurnaceAt", tolua_DoWithXYZ<cWorld, cFurnaceEntity, &cWorld::DoWithFurnaceAt>);
|
||||
tolua_function(tolua_S, "DoWithNoteBlockAt", tolua_DoWithXYZ<cWorld, cNoteEntity, &cWorld::DoWithNoteBlockAt>);
|
||||
tolua_function(tolua_S, "DoWithCommandBlockAt", tolua_DoWithXYZ<cWorld, cCommandBlockEntity, &cWorld::DoWithCommandBlockAt>);
|
||||
tolua_function(tolua_S, "DoWithMobHeadBlockAt", tolua_DoWithXYZ<cWorld, cMobHeadEntity, &cWorld::DoWithMobHeadBlockAt>);
|
||||
tolua_function(tolua_S, "DoWithMobHeadAt", tolua_DoWithXYZ<cWorld, cMobHeadEntity, &cWorld::DoWithMobHeadAt>);
|
||||
tolua_function(tolua_S, "DoWithFlowerPotAt", tolua_DoWithXYZ<cWorld, cFlowerPotEntity, &cWorld::DoWithFlowerPotAt>);
|
||||
tolua_function(tolua_S, "DoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::DoWithPlayer>);
|
||||
tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::FindAndDoWithPlayer>);
|
||||
tolua_function(tolua_S, "ForEachBlockEntityInChunk", tolua_ForEachInChunk<cWorld, cBlockEntity, &cWorld::ForEachBlockEntityInChunk>);
|
||||
@ -2583,6 +2908,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);
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "DispenserEntity.h"
|
||||
#include "DropperEntity.h"
|
||||
#include "EnderChestEntity.h"
|
||||
#include "FlowerPotEntity.h"
|
||||
#include "FurnaceEntity.h"
|
||||
#include "HopperEntity.h"
|
||||
#include "JukeboxEntity.h"
|
||||
@ -30,6 +31,7 @@ cBlockEntity * cBlockEntity::CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE
|
||||
case E_BLOCK_DISPENSER: return new cDispenserEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||
case E_BLOCK_DROPPER: return new cDropperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||
case E_BLOCK_ENDER_CHEST: return new cEnderChestEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||
case E_BLOCK_FLOWER_POT: return new cFlowerPotEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||
case E_BLOCK_HEAD: return new cMobHeadEntity (a_BlockX, a_BlockY, a_BlockZ, a_World);
|
||||
case E_BLOCK_LIT_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
|
||||
case E_BLOCK_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World);
|
||||
|
134
src/BlockEntities/FlowerPotEntity.cpp
Normal file
134
src/BlockEntities/FlowerPotEntity.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
|
||||
// FlowerPotEntity.cpp
|
||||
|
||||
// Implements the cFlowerPotEntity class representing a single sign in the world
|
||||
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
#include "json/json.h"
|
||||
#include "FlowerPotEntity.h"
|
||||
#include "../Entities/Player.h"
|
||||
#include "../Item.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cFlowerPotEntity::cFlowerPotEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
|
||||
super(E_BLOCK_FLOWER_POT, a_BlockX, a_BlockY, a_BlockZ, a_World)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// It don't do anything when 'used'
|
||||
void cFlowerPotEntity::UsedBy(cPlayer * a_Player)
|
||||
{
|
||||
if (IsItemInPot())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cItem SelectedItem = a_Player->GetInventory().GetEquippedItem();
|
||||
if (IsFlower(SelectedItem.m_ItemType, SelectedItem.m_ItemDamage))
|
||||
{
|
||||
m_Item = SelectedItem.CopyOne();
|
||||
if (!a_Player->IsGameModeCreative())
|
||||
{
|
||||
a_Player->GetInventory().RemoveOneEquippedItem();
|
||||
}
|
||||
m_World->BroadcastBlockEntity(m_PosX, m_PosY, m_PosZ, a_Player->GetClientHandle());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cFlowerPotEntity::SendTo(cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendUpdateBlockEntity(*this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cFlowerPotEntity::Destroy(void)
|
||||
{
|
||||
// Drop the contents as pickups:
|
||||
if (!m_Item.IsEmpty())
|
||||
{
|
||||
ASSERT(m_World != NULL);
|
||||
cItems Pickups;
|
||||
Pickups.Add(m_Item);
|
||||
m_World->SpawnItemPickups(Pickups, m_PosX + 0.5, m_PosY + 0.5, m_PosZ + 0.5);
|
||||
|
||||
m_Item.Empty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cFlowerPotEntity::LoadFromJson(const Json::Value & a_Value)
|
||||
{
|
||||
m_PosX = a_Value.get("x", 0).asInt();
|
||||
m_PosY = a_Value.get("y", 0).asInt();
|
||||
m_PosZ = a_Value.get("z", 0).asInt();
|
||||
|
||||
m_Item = cItem();
|
||||
m_Item.FromJson(a_Value.get("Item", 0));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cFlowerPotEntity::SaveToJson(Json::Value & a_Value)
|
||||
{
|
||||
a_Value["x"] = m_PosX;
|
||||
a_Value["y"] = m_PosY;
|
||||
a_Value["z"] = m_PosZ;
|
||||
|
||||
Json::Value Item;
|
||||
m_Item.GetJson(Item);
|
||||
a_Value["Item"] = Item;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cFlowerPotEntity::IsFlower(short m_ItemType, short m_ItemData)
|
||||
{
|
||||
switch (m_ItemType)
|
||||
{
|
||||
case E_BLOCK_DANDELION:
|
||||
case E_BLOCK_FLOWER:
|
||||
case E_BLOCK_CACTUS:
|
||||
case E_BLOCK_BROWN_MUSHROOM:
|
||||
case E_BLOCK_RED_MUSHROOM:
|
||||
case E_BLOCK_SAPLING:
|
||||
case E_BLOCK_DEAD_BUSH:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
case E_BLOCK_TALL_GRASS:
|
||||
{
|
||||
return (m_ItemData == (short) 2);
|
||||
}
|
||||
default:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
74
src/BlockEntities/FlowerPotEntity.h
Normal file
74
src/BlockEntities/FlowerPotEntity.h
Normal file
@ -0,0 +1,74 @@
|
||||
// FlowerPotEntity.h
|
||||
|
||||
// Declares the cFlowerPotEntity class representing a single sign in the world
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BlockEntity.h"
|
||||
|
||||
class cItem;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace Json
|
||||
{
|
||||
class Value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// tolua_begin
|
||||
|
||||
class cFlowerPotEntity :
|
||||
public cBlockEntity
|
||||
{
|
||||
typedef cBlockEntity super;
|
||||
|
||||
public:
|
||||
|
||||
// tolua_end
|
||||
|
||||
/** Creates a new flowerpot entity at the specified block coords. a_World may be NULL */
|
||||
cFlowerPotEntity(int a_BlocX, int a_BlockY, int a_BlockZ, cWorld * a_World);
|
||||
|
||||
bool LoadFromJson( const Json::Value& a_Value );
|
||||
virtual void SaveToJson(Json::Value& a_Value ) override;
|
||||
|
||||
virtual void Destroy(void) override;
|
||||
|
||||
// tolua_begin
|
||||
|
||||
/** Is a flower in the pot? */
|
||||
bool IsItemInPot(void) { return !m_Item.IsEmpty(); }
|
||||
|
||||
/** Get the item in the flower pot */
|
||||
cItem GetItem(void) const { return m_Item; }
|
||||
|
||||
/** Set the item in the flower pot */
|
||||
void SetItem(const cItem a_Item) { m_Item = a_Item; }
|
||||
|
||||
// tolua_end
|
||||
|
||||
virtual void UsedBy(cPlayer * a_Player) override;
|
||||
virtual void SendTo(cClientHandle & a_Client) override;
|
||||
|
||||
static bool IsFlower(short m_ItemType, short m_ItemData);
|
||||
|
||||
static const char * GetClassStatic(void) { return "cFlowerPotEntity"; }
|
||||
|
||||
private:
|
||||
|
||||
cItem m_Item;
|
||||
} ; // tolua_export
|
||||
|
||||
|
||||
|
||||
|
@ -30,48 +30,70 @@ cJukeboxEntity::~cJukeboxEntity()
|
||||
|
||||
void cJukeboxEntity::UsedBy(cPlayer * a_Player)
|
||||
{
|
||||
if (m_Record == 0)
|
||||
{
|
||||
const cItem & HeldItem = a_Player->GetEquippedItem();
|
||||
if (HeldItem.m_ItemType >= 2256 && HeldItem.m_ItemType <= 2267)
|
||||
{
|
||||
m_Record = HeldItem.m_ItemType;
|
||||
a_Player->GetInventory().RemoveOneEquippedItem();
|
||||
PlayRecord();
|
||||
}
|
||||
}
|
||||
else
|
||||
if (IsPlayingRecord())
|
||||
{
|
||||
EjectRecord();
|
||||
}
|
||||
else
|
||||
{
|
||||
const cItem & HeldItem = a_Player->GetEquippedItem();
|
||||
if (PlayRecord(HeldItem.m_ItemType))
|
||||
{
|
||||
a_Player->GetInventory().RemoveOneEquippedItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cJukeboxEntity::PlayRecord(void)
|
||||
bool cJukeboxEntity::PlayRecord(int a_Record)
|
||||
{
|
||||
if (!IsRecordItem(a_Record))
|
||||
{
|
||||
// This isn't a Record Item
|
||||
return false;
|
||||
}
|
||||
if (IsPlayingRecord())
|
||||
{
|
||||
// A Record is already in the Jukebox.
|
||||
EjectRecord();
|
||||
}
|
||||
m_Record = a_Record;
|
||||
m_World->BroadcastSoundParticleEffect(1005, m_PosX, m_PosY, m_PosZ, m_Record);
|
||||
m_World->SetBlockMeta(m_PosX, m_PosY, m_PosZ, E_META_JUKEBOX_ON);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cJukeboxEntity::EjectRecord(void)
|
||||
bool cJukeboxEntity::EjectRecord(void)
|
||||
{
|
||||
if ((m_Record < E_ITEM_FIRST_DISC) || (m_Record > E_ITEM_LAST_DISC))
|
||||
if (!IsPlayingRecord())
|
||||
{
|
||||
// There's no record here
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
cItems Drops;
|
||||
Drops.push_back(cItem(m_Record, 1, 0));
|
||||
m_Record = 0;
|
||||
m_World->SpawnItemPickups(Drops, m_PosX + 0.5, m_PosY + 1, m_PosZ + 0.5, 8);
|
||||
m_World->BroadcastSoundParticleEffect(1005, m_PosX, m_PosY, m_PosZ, 0);
|
||||
m_Record = 0;
|
||||
m_World->SetBlockMeta(m_PosX, m_PosY, m_PosZ, E_META_JUKEBOX_OFF);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cJukeboxEntity::IsPlayingRecord(void)
|
||||
{
|
||||
return (m_Record != 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -37,10 +37,21 @@ public:
|
||||
|
||||
int GetRecord(void);
|
||||
void SetRecord(int a_Record);
|
||||
void PlayRecord(void);
|
||||
|
||||
/// Ejects the currently held record as a pickup. Does nothing when no record inserted.
|
||||
void EjectRecord(void);
|
||||
/** 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 had been inserted. */
|
||||
bool EjectRecord(void);
|
||||
|
||||
/** Is in the Jukebox a Record? */
|
||||
bool IsPlayingRecord(void);
|
||||
|
||||
static bool IsRecordItem(int a_Item)
|
||||
{
|
||||
return ((a_Item >= E_ITEM_FIRST_DISC) && (a_Item <= E_ITEM_LAST_DISC));
|
||||
}
|
||||
|
||||
// tolua_end
|
||||
|
||||
|
399
src/BlockID.cpp
399
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;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -466,6 +466,10 @@ enum
|
||||
E_META_FLOWER_PINK_TULIP = 7,
|
||||
E_META_FLOWER_OXEYE_DAISY = 8,
|
||||
|
||||
// E_BLOCK_JUKEBOX metas
|
||||
E_META_JUKEBOX_OFF = 0,
|
||||
E_META_JUKEBOX_ON = 1,
|
||||
|
||||
// E_BLOCK_HOPPER metas:
|
||||
E_META_HOPPER_FACING_YM = 0,
|
||||
E_META_HOPPER_UNATTACHED = 1, // Hopper doesn't move items up, there's no YP
|
||||
@ -905,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];
|
||||
|
||||
|
||||
|
||||
|
||||
|
451
src/BlockInfo.cpp
Normal file
451
src/BlockInfo.cpp
Normal file
@ -0,0 +1,451 @@
|
||||
|
||||
#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;
|
||||
ms_Info[E_BLOCK_RAIL ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_ACTIVATOR_RAIL ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_POWERED_RAIL ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_COBWEB ].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;
|
||||
ms_Info[E_BLOCK_FURNACE ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_LIT_FURNACE ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_ANVIL ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_ENCHANTMENT_TABLE ].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;
|
||||
|
||||
|
||||
|
||||
|
||||
|
103
src/BlockInfo.h
Normal file
103
src/BlockInfo.h
Normal file
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "BlockHandler.h"
|
||||
#include "ChunkInterface.h"
|
||||
#include "WorldInterface.h"
|
||||
#include "MetaRotater.h"
|
||||
#include "../Entities/Player.h"
|
||||
|
||||
|
||||
@ -11,11 +12,11 @@
|
||||
|
||||
|
||||
class cBlockBedHandler :
|
||||
public cBlockHandler
|
||||
public cMetaRotater<cBlockHandler, 0x3, 0x02, 0x03, 0x00, 0x01, true>
|
||||
{
|
||||
public:
|
||||
cBlockBedHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
: cMetaRotater<cBlockHandler, 0x3, 0x02, 0x03, 0x00, 0x01,true>(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -2,16 +2,17 @@
|
||||
|
||||
#include "BlockHandler.h"
|
||||
#include "Chunk.h"
|
||||
#include "MetaRotater.h"
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockButtonHandler :
|
||||
public cBlockHandler
|
||||
public cMetaRotater<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, true>
|
||||
{
|
||||
public:
|
||||
cBlockButtonHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
: cMetaRotater<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, true>(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
@ -101,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));
|
||||
}
|
||||
} ;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -4,17 +4,18 @@
|
||||
#include "BlockEntity.h"
|
||||
#include "../BlockArea.h"
|
||||
#include "../Entities/Player.h"
|
||||
#include "MetaRotater.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockChestHandler :
|
||||
public cBlockEntityHandler
|
||||
public cMetaRotater<cBlockEntityHandler, 0x07, 0x04, 0x01, 0x03, 0x02, true>
|
||||
{
|
||||
public:
|
||||
cBlockChestHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockEntityHandler(a_BlockType)
|
||||
: cMetaRotater<cBlockEntityHandler, 0x07, 0x04, 0x01, 0x03, 0x02, true>(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -3,17 +3,18 @@
|
||||
|
||||
#include "BlockHandler.h"
|
||||
#include "BlockRedstoneRepeater.h"
|
||||
#include "MetaRotater.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockComparatorHandler :
|
||||
public cBlockHandler
|
||||
public cMetaRotater<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03, true>
|
||||
{
|
||||
public:
|
||||
cBlockComparatorHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
: cMetaRotater<cBlockHandler, 0x03, 0x00, 0x01, 0x02, 0x03, true>(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
@ -26,6 +27,13 @@ public:
|
||||
}
|
||||
|
||||
|
||||
virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override
|
||||
{
|
||||
UNUSED(a_ChunkInterface);
|
||||
a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
|
||||
}
|
||||
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
// Reset meta to 0
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
|
||||
cBlockDoorHandler::cBlockDoorHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
: super(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
@ -55,6 +55,29 @@ void cBlockDoorHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterfac
|
||||
|
||||
|
||||
|
||||
void cBlockDoorHandler::OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace)
|
||||
{
|
||||
UNUSED(a_ChunkInterface);
|
||||
|
||||
a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
|
||||
NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
|
||||
|
||||
if (Meta & 8)
|
||||
{
|
||||
// Current block is top of the door
|
||||
a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY - 1, a_BlockZ, a_Player);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Current block is bottom of the door
|
||||
a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, a_Player);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBlockDoorHandler::OnPlacedByPlayer(
|
||||
cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player,
|
||||
int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
|
||||
|
@ -4,18 +4,21 @@
|
||||
#include "BlockHandler.h"
|
||||
#include "../Entities/Player.h"
|
||||
#include "Chunk.h"
|
||||
#include "MetaRotater.h"
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockDoorHandler :
|
||||
public cBlockHandler
|
||||
public cMetaRotater<cBlockHandler, 0x03, 0x01, 0x02, 0x03, 0x00, true>
|
||||
{
|
||||
typedef cMetaRotater<cBlockHandler, 0x03, 0x01, 0x02, 0x03, 0x00, true> super;
|
||||
public:
|
||||
cBlockDoorHandler(BLOCKTYPE a_BlockType);
|
||||
|
||||
virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override;
|
||||
virtual void OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override;
|
||||
virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override;
|
||||
virtual const char * GetStepSound(void) override;
|
||||
|
||||
|
||||
@ -167,6 +170,60 @@ public:
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
if (a_Meta & 0x08)
|
||||
{
|
||||
return a_Meta;
|
||||
}
|
||||
else
|
||||
{
|
||||
return super::MetaRotateCCW(a_Meta);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
if (a_Meta & 0x08)
|
||||
{
|
||||
return a_Meta;
|
||||
}
|
||||
else
|
||||
{
|
||||
return super::MetaRotateCW(a_Meta);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
if (a_Meta & 0x08)
|
||||
{
|
||||
return a_Meta;
|
||||
}
|
||||
else
|
||||
{
|
||||
return super::MetaMirrorXY(a_Meta);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
if (a_Meta & 0x08)
|
||||
{
|
||||
return a_Meta;
|
||||
}
|
||||
else
|
||||
{
|
||||
return super::MetaMirrorYZ(a_Meta);
|
||||
}
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -6,17 +6,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "../Piston.h"
|
||||
#include "MetaRotater.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockDropSpenserHandler :
|
||||
public cBlockEntityHandler
|
||||
public cMetaRotater<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>
|
||||
{
|
||||
public:
|
||||
cBlockDropSpenserHandler(BLOCKTYPE a_BlockType) :
|
||||
cBlockEntityHandler(a_BlockType)
|
||||
cMetaRotater<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
@ -34,6 +35,20 @@ public:
|
||||
a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetYaw(), a_Player->GetPitch());
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Bit 0x08 is a flag. Lowest three bits are position. 0x08 == 1000
|
||||
NIBBLETYPE OtherMeta = a_Meta & 0x08;
|
||||
// Mirrors defined by by a table. (Source, mincraft.gamepedia.com) 0x07 == 0111
|
||||
switch (a_Meta & 0x07)
|
||||
{
|
||||
case 0x00: return 0x01 + OtherMeta; // Down -> Up
|
||||
case 0x01: return 0x00 + OtherMeta; // Up -> Down
|
||||
}
|
||||
// Not Facing Up or Down; No change.
|
||||
return a_Meta;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -2,17 +2,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "BlockEntity.h"
|
||||
|
||||
#include "MetaRotater.h"
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockEnderchestHandler :
|
||||
public cBlockEntityHandler
|
||||
public cMetaRotater<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>
|
||||
{
|
||||
public:
|
||||
cBlockEnderchestHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockEntityHandler(a_BlockType)
|
||||
: cMetaRotater<cBlockEntityHandler, 0x07, 0x02, 0x05, 0x03, 0x04>(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -2,17 +2,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
|
||||
#include "MetaRotater.h"
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockFenceGateHandler :
|
||||
public cBlockHandler
|
||||
public cMetaRotater<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01, true>
|
||||
{
|
||||
public:
|
||||
cBlockFenceGateHandler(BLOCKTYPE a_BlockType) :
|
||||
cBlockHandler(a_BlockType)
|
||||
cMetaRotater<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01, true>(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
@ -48,6 +48,12 @@ public:
|
||||
}
|
||||
|
||||
|
||||
virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override
|
||||
{
|
||||
a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
|
||||
}
|
||||
|
||||
|
||||
virtual bool IsUseable(void) override
|
||||
{
|
||||
return true;
|
||||
|
@ -2,101 +2,24 @@
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
#include "BlockEntity.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockFlowerPotHandler :
|
||||
public cBlockHandler
|
||||
public cBlockEntityHandler
|
||||
{
|
||||
public:
|
||||
cBlockFlowerPotHandler(BLOCKTYPE a_BlockType) :
|
||||
cBlockHandler(a_BlockType)
|
||||
cBlockEntityHandler(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
a_Pickups.push_back(cItem(E_ITEM_FLOWER_POT, 1, 0));
|
||||
if (a_BlockMeta == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
cItem Plant;
|
||||
switch (a_BlockMeta)
|
||||
{
|
||||
case 1: Plant = cItem(E_BLOCK_RED_ROSE, 1, 0); break;
|
||||
case 2: Plant = cItem(E_BLOCK_YELLOW_FLOWER, 1, 0); break;
|
||||
case 3: Plant = cItem(E_BLOCK_SAPLING, 1, E_META_SAPLING_APPLE); break;
|
||||
case 4: Plant = cItem(E_BLOCK_SAPLING, 1, E_META_SAPLING_CONIFER); break;
|
||||
case 5: Plant = cItem(E_BLOCK_SAPLING, 1, E_META_SAPLING_BIRCH); break;
|
||||
case 6: Plant = cItem(E_BLOCK_SAPLING, 1, E_META_SAPLING_JUNGLE); break;
|
||||
case 7: Plant = cItem(E_BLOCK_RED_MUSHROOM, 1, 0); break;
|
||||
case 8: Plant = cItem(E_BLOCK_BROWN_MUSHROOM, 1, 0); break;
|
||||
case 9: Plant = cItem(E_BLOCK_CACTUS, 1, 0); break;
|
||||
case 10: Plant = cItem(E_BLOCK_DEAD_BUSH, 1, 0); break;
|
||||
case 11: Plant = cItem(E_BLOCK_TALL_GRASS, 1, E_META_TALL_GRASS_FERN); break;
|
||||
default: return;
|
||||
}
|
||||
a_Pickups.push_back(Plant);
|
||||
}
|
||||
|
||||
|
||||
void OnUse(cWorld * a_World, cWorldInterface * a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
NIBBLETYPE Meta = a_World->GetBlockMeta( a_BlockX, a_BlockY, a_BlockZ );
|
||||
if (Meta != 0)
|
||||
{
|
||||
// Already filled
|
||||
return;
|
||||
}
|
||||
|
||||
switch (a_Player->GetEquippedItem().m_ItemType)
|
||||
{
|
||||
case E_BLOCK_RED_ROSE: Meta = 1; break;
|
||||
case E_BLOCK_YELLOW_FLOWER: Meta = 2; break;
|
||||
case E_BLOCK_SAPLING:
|
||||
{
|
||||
switch (a_Player->GetEquippedItem().m_ItemDamage)
|
||||
{
|
||||
case E_META_SAPLING_APPLE: Meta = 3; break;
|
||||
case E_META_SAPLING_CONIFER: Meta = 4; break;
|
||||
case E_META_SAPLING_BIRCH: Meta = 5; break;
|
||||
case E_META_SAPLING_JUNGLE: Meta = 6; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_RED_MUSHROOM: Meta = 7; break;
|
||||
case E_BLOCK_BROWN_MUSHROOM: Meta = 8; break;
|
||||
case E_BLOCK_CACTUS: Meta = 9; break;
|
||||
case E_BLOCK_DEAD_BUSH: Meta = 10; break;
|
||||
case E_BLOCK_TALL_GRASS:
|
||||
{
|
||||
if (a_Player->GetEquippedItem().m_ItemDamage == E_META_TALL_GRASS_FERN)
|
||||
{
|
||||
Meta = 11;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (a_Player->GetGameMode() != gmCreative)
|
||||
{
|
||||
a_Player->GetInventory().RemoveOneEquippedItem();
|
||||
}
|
||||
a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
|
||||
}
|
||||
|
||||
|
||||
virtual bool IsUseable(void) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
@ -57,6 +57,7 @@
|
||||
#include "BlockRedstoneLamp.h"
|
||||
#include "BlockRedstoneRepeater.h"
|
||||
#include "BlockRedstoneTorch.h"
|
||||
#include "BlockTNT.h"
|
||||
#include "BlockSand.h"
|
||||
#include "BlockSapling.h"
|
||||
#include "BlockSideways.h"
|
||||
@ -77,33 +78,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)
|
||||
@ -172,6 +146,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
|
||||
case E_BLOCK_NETHER_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType);
|
||||
case E_BLOCK_NETHER_PORTAL: return new cBlockPortalHandler (a_BlockType);
|
||||
case E_BLOCK_NETHER_WART: return new cBlockNetherWartHandler (a_BlockType);
|
||||
case E_BLOCK_NETHER_QUARTZ_ORE: return new cBlockOreHandler (a_BlockType);
|
||||
case E_BLOCK_NEW_LEAVES: return new cBlockNewLeavesHandler (a_BlockType);
|
||||
case E_BLOCK_NEW_LOG: return new cBlockSidewaysHandler (a_BlockType);
|
||||
case E_BLOCK_NOTE_BLOCK: return new cBlockNoteHandler (a_BlockType);
|
||||
@ -192,7 +167,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);
|
||||
@ -212,6 +187,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
|
||||
case E_BLOCK_TALL_GRASS: return new cBlockTallGrassHandler (a_BlockType);
|
||||
case E_BLOCK_TORCH: return new cBlockTorchHandler (a_BlockType);
|
||||
case E_BLOCK_TRAPDOOR: return new cBlockTrapdoorHandler (a_BlockType);
|
||||
case E_BLOCK_TNT: return new cBlockTNTHandler (a_BlockType);
|
||||
case E_BLOCK_VINES: return new cBlockVineHandler (a_BlockType);
|
||||
case E_BLOCK_WALLSIGN: return new cBlockSignHandler (a_BlockType);
|
||||
case E_BLOCK_WATER: return new cBlockFluidHandler (a_BlockType);
|
||||
@ -231,20 +207,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 +291,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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -361,6 +323,14 @@ void cBlockHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface &
|
||||
|
||||
|
||||
|
||||
void cBlockHandler::OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBlockHandler::ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta)
|
||||
{
|
||||
// Setting the meta to a_BlockMeta keeps most textures. The few other blocks have to override this.
|
||||
|
@ -69,6 +69,9 @@ public:
|
||||
/// Called if the user right clicks the block and the block is useable
|
||||
virtual void OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ);
|
||||
|
||||
/** Called when a Right Click to this Block is cancelled */
|
||||
virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace);
|
||||
|
||||
/// <summary>Called when the item is mined to convert it into pickups. Pickups may specify multiple items. Appends items to a_Pickups, preserves its original contents</summary>
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta);
|
||||
|
||||
@ -136,31 +139,15 @@ 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);
|
||||
|
||||
friend class cBlockInfo;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Shortcut to get the blockhandler for a specific block
|
||||
inline cBlockHandler * BlockHandler(BLOCKTYPE a_BlockType)
|
||||
{
|
||||
return cBlockHandler::GetBlockHandler(a_BlockType);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
} ;
|
||||
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
|
||||
) override
|
||||
{
|
||||
class cCallback : public cMobHeadBlockCallback
|
||||
class cCallback : public cMobHeadCallback
|
||||
{
|
||||
cPlayer * m_Player;
|
||||
NIBBLETYPE m_OldBlockMeta;
|
||||
@ -45,6 +45,7 @@ public:
|
||||
|
||||
a_MobHeadEntity->SetType(static_cast<eMobHeadType>(m_OldBlockMeta));
|
||||
a_MobHeadEntity->SetRotation(static_cast<eMobHeadRotation>(Rotation));
|
||||
a_MobHeadEntity->GetWorld()->BroadcastBlockEntity(a_MobHeadEntity->GetPosX(), a_MobHeadEntity->GetPosY(), a_MobHeadEntity->GetPosZ(), m_Player->GetClientHandle());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -59,7 +60,7 @@ public:
|
||||
|
||||
a_BlockMeta = a_BlockFace;
|
||||
cWorld * World = (cWorld *) &a_WorldInterface;
|
||||
World->DoWithMobHeadBlockAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
|
||||
World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
|
||||
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta);
|
||||
}
|
||||
} ;
|
||||
|
@ -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;
|
||||
|
@ -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)));
|
||||
}
|
||||
|
||||
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
a_BlockMeta = RepeaterRotationToMetaData(a_Player->GetYaw());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual void OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override
|
||||
{
|
||||
@ -37,6 +37,13 @@ public:
|
||||
}
|
||||
|
||||
|
||||
virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override
|
||||
{
|
||||
UNUSED(a_ChunkInterface);
|
||||
a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
|
||||
}
|
||||
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
// Reset meta to 0
|
||||
|
@ -28,7 +28,7 @@ public:
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
a_Pickups.push_back(cItem(m_BlockType, 1, a_BlockMeta));
|
||||
a_Pickups.push_back(cItem(m_BlockType, 1, a_BlockMeta & 0x7));
|
||||
}
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ public:
|
||||
{
|
||||
a_BlockType = m_BlockType;
|
||||
BLOCKTYPE Type = (BLOCKTYPE) (a_Player->GetEquippedItem().m_ItemType);
|
||||
NIBBLETYPE Meta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage & 0x07);
|
||||
NIBBLETYPE Meta = (NIBBLETYPE) a_Player->GetEquippedItem().m_ItemDamage;
|
||||
|
||||
// HandlePlaceBlock wants a cItemHandler pointer thing, so let's give it one
|
||||
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(GetDoubleSlabType(Type));
|
||||
@ -159,21 +159,30 @@ public:
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
if (m_BlockType == E_BLOCK_DOUBLE_STONE_SLAB)
|
||||
{
|
||||
m_BlockType = E_BLOCK_STONE_SLAB;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_BlockType = E_BLOCK_WOODEN_SLAB;
|
||||
}
|
||||
a_Pickups.push_back(cItem(m_BlockType, 2, a_BlockMeta));
|
||||
BLOCKTYPE Block = GetSingleSlabType(m_BlockType);
|
||||
a_Pickups.push_back(cItem(Block, 2, a_BlockMeta & 0x7));
|
||||
}
|
||||
|
||||
inline static BLOCKTYPE GetSingleSlabType(BLOCKTYPE a_BlockType)
|
||||
{
|
||||
switch (a_BlockType)
|
||||
{
|
||||
case E_BLOCK_DOUBLE_STONE_SLAB: return E_BLOCK_STONE_SLAB;
|
||||
case E_BLOCK_DOUBLE_WOODEN_SLAB: return E_BLOCK_WOODEN_SLAB;
|
||||
}
|
||||
ASSERT(!"Unhandled double slab type!");
|
||||
return a_BlockType;
|
||||
}
|
||||
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
return ((m_BlockType == E_BLOCK_DOUBLE_WOODEN_SLAB) || (m_BlockType == E_BLOCK_DOUBLE_WOODEN_SLAB)) ? "step.wood" : "step.stone";
|
||||
{
|
||||
switch (m_BlockType)
|
||||
{
|
||||
case E_BLOCK_DOUBLE_STONE_SLAB: return "step.stone";
|
||||
case E_BLOCK_DOUBLE_WOODEN_SLAB: return "step.wood";
|
||||
}
|
||||
ASSERT(!"Unhandled double slab type!");
|
||||
return "";
|
||||
}
|
||||
} ;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -2,17 +2,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
|
||||
#include "MetaRotater.h"
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockStairsHandler :
|
||||
public cBlockHandler
|
||||
public cMetaRotater<cBlockHandler, 0x03, 0x03, 0x00, 0x02, 0x01, true>
|
||||
{
|
||||
public:
|
||||
cBlockStairsHandler(BLOCKTYPE a_BlockType) :
|
||||
cBlockHandler(a_BlockType)
|
||||
cMetaRotater<cBlockHandler, 0x03, 0x03, 0x00, 0x02, 0x01, true>(a_BlockType)
|
||||
{
|
||||
|
||||
}
|
||||
@ -96,54 +96,6 @@ public:
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Bits 3 and 4 stay, the rest is swapped around according to a table:
|
||||
NIBBLETYPE TopBits = (a_Meta & 0x0c);
|
||||
switch (a_Meta & 0x03)
|
||||
{
|
||||
case 0x00: return TopBits | 0x03; // East -> North
|
||||
case 0x01: return TopBits | 0x02; // West -> South
|
||||
case 0x02: return TopBits | 0x00; // South -> East
|
||||
case 0x03: return TopBits | 0x01; // North -> West
|
||||
}
|
||||
// Not reachable, but to avoid a compiler warning:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Bits 3 and 4 stay, the rest is swapped around according to a table:
|
||||
NIBBLETYPE TopBits = (a_Meta & 0x0c);
|
||||
switch (a_Meta & 0x03)
|
||||
{
|
||||
case 0x00: return TopBits | 0x02; // East -> South
|
||||
case 0x01: return TopBits | 0x03; // West -> North
|
||||
case 0x02: return TopBits | 0x01; // South -> West
|
||||
case 0x03: return TopBits | 0x00; // North -> East
|
||||
}
|
||||
// Not reachable, but to avoid a compiler warning:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Bits 3 and 4 stay, the rest is swapped around according to a table:
|
||||
NIBBLETYPE TopBits = (a_Meta & 0x0c);
|
||||
switch (a_Meta & 0x03)
|
||||
{
|
||||
case 0x00: return TopBits | 0x00; // East -> East
|
||||
case 0x01: return TopBits | 0x01; // West -> West
|
||||
case 0x02: return TopBits | 0x03; // South -> North
|
||||
case 0x03: return TopBits | 0x02; // North -> South
|
||||
}
|
||||
// Not reachable, but to avoid a compiler warning:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Toggle bit 3:
|
||||
@ -151,20 +103,6 @@ public:
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Bits 3 and 4 stay, the rest is swapped around according to a table:
|
||||
NIBBLETYPE TopBits = (a_Meta & 0x0c);
|
||||
switch (a_Meta & 0x03)
|
||||
{
|
||||
case 0x00: return TopBits | 0x01; // East -> West
|
||||
case 0x01: return TopBits | 0x00; // West -> East
|
||||
case 0x02: return TopBits | 0x02; // South -> South
|
||||
case 0x03: return TopBits | 0x03; // North -> North
|
||||
}
|
||||
// Not reachable, but to avoid a compiler warning:
|
||||
return 0;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
32
src/Blocks/BlockTNT.h
Normal file
32
src/Blocks/BlockTNT.h
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockTNTHandler :
|
||||
public cBlockHandler
|
||||
{
|
||||
public:
|
||||
cBlockTNTHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
return "step.grass";
|
||||
}
|
||||
|
||||
virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override
|
||||
{
|
||||
a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -2,17 +2,17 @@
|
||||
|
||||
#include "BlockHandler.h"
|
||||
#include "../Chunk.h"
|
||||
|
||||
#include "MetaRotater.h"
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockTorchHandler :
|
||||
public cBlockHandler
|
||||
public cMetaRotater<cBlockHandler, 0x7, 0x4, 0x1, 0x3, 0x2>
|
||||
{
|
||||
public:
|
||||
cBlockTorchHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
: cMetaRotater<cBlockHandler, 0x7, 0x4, 0x1, 0x3, 0x2>(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -185,67 +185,6 @@ public:
|
||||
{
|
||||
return "step.wood";
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Bit 4 stays, the rest is swapped around according to a table:
|
||||
NIBBLETYPE TopBits = (a_Meta & 0x08);
|
||||
switch (a_Meta & 0x07)
|
||||
{
|
||||
case 0x01: return TopBits | 0x04; // East -> North
|
||||
case 0x02: return TopBits | 0x03; // West -> South
|
||||
case 0x03: return TopBits | 0x01; // South -> East
|
||||
case 0x04: return TopBits | 0x02; // North -> West
|
||||
default: return a_Meta; // Floor -> Floor
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Bit 4 stays, the rest is swapped around according to a table:
|
||||
NIBBLETYPE TopBits = (a_Meta & 0x08);
|
||||
switch (a_Meta & 0x07)
|
||||
{
|
||||
case 0x01: return TopBits | 0x03; // East -> South
|
||||
case 0x02: return TopBits | 0x04; // West -> North
|
||||
case 0x03: return TopBits | 0x02; // South -> West
|
||||
case 0x04: return TopBits | 0x01; // North -> East
|
||||
default: return a_Meta; // Floor -> Floor
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Bit 4 stays, the rest is swapped around according to a table:
|
||||
NIBBLETYPE TopBits = (a_Meta & 0x08);
|
||||
switch (a_Meta & 0x07)
|
||||
{
|
||||
case 0x03: return TopBits | 0x04; // South -> North
|
||||
case 0x04: return TopBits | 0x03; // North -> South
|
||||
default: return a_Meta; // Keep the rest
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Mirroring around the XZ plane doesn't make sense for floor torches,
|
||||
// the others stay the same, so let's keep all the metas the same.
|
||||
// The base class does tht for us, no need to override MetaMirrorXZ()
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Bit 4 stays, the rest is swapped around according to a table:
|
||||
NIBBLETYPE TopBits = (a_Meta & 0x08);
|
||||
switch (a_Meta & 0x07)
|
||||
{
|
||||
case 0x01: return TopBits | 0x02; // East -> West
|
||||
case 0x02: return TopBits | 0x01; // West -> East
|
||||
default: return a_Meta; // Keep the rest
|
||||
}
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -36,8 +36,16 @@ public:
|
||||
{
|
||||
// Flip the ON bit on/off using the XOR bitwise operation
|
||||
NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x04);
|
||||
|
||||
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
|
||||
|
||||
cWorld * World = (cWorld *) &a_WorldInterface;
|
||||
World->BroadcastSoundParticleEffect(1003, a_BlockX, a_BlockY, a_BlockZ, 0, a_Player->GetClientHandle());
|
||||
}
|
||||
|
||||
virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override
|
||||
{
|
||||
UNUSED(a_ChunkInterface);
|
||||
a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
|
||||
}
|
||||
|
||||
virtual bool GetPlacementBlockTypeMeta(
|
||||
@ -97,7 +105,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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,8 +1,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
|
||||
#include "MetaRotater.h"
|
||||
|
||||
|
||||
|
||||
@ -70,7 +69,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);
|
||||
}
|
||||
|
||||
|
||||
@ -180,8 +179,8 @@ public:
|
||||
{
|
||||
return ((a_Meta << 1) | (a_Meta >> 3)) & 0x0f; // Rotate bits to the left
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Bits 2 and 4 stay, bits 1 and 3 swap
|
||||
@ -194,6 +193,7 @@ public:
|
||||
// Bits 1 and 3 stay, bits 2 and 4 swap
|
||||
return ((a_Meta & 0x05) | ((a_Meta & 0x02) << 2) | ((a_Meta & 0x08) >> 2));
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
99
src/Blocks/MetaRotater.h
Normal file
99
src/Blocks/MetaRotater.h
Normal file
@ -0,0 +1,99 @@
|
||||
// MetaRotater.h
|
||||
|
||||
// Provides a mixin for rotations and reflections
|
||||
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
Provides a mixin for rotations and reflections following the standard pattern of apply mask then use case.
|
||||
|
||||
Usage:
|
||||
Inherit from this class providing your base class as Base, the BitMask for the direction bits in bitmask and the masked value for the directions in North, East, South, West. There is also an aptional parameter AssertIfNotMatched. Set this if it is invalid for a block to exist in any other state.
|
||||
*/
|
||||
|
||||
template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched = false>
|
||||
class cMetaRotater : public Base
|
||||
{
|
||||
public:
|
||||
|
||||
cMetaRotater(BLOCKTYPE a_BlockType) :
|
||||
Base(a_BlockType)
|
||||
{}
|
||||
|
||||
virtual ~cMetaRotater() {}
|
||||
|
||||
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override;
|
||||
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override;
|
||||
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override;
|
||||
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override;
|
||||
};
|
||||
|
||||
|
||||
template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched>
|
||||
NIBBLETYPE cMetaRotater<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaRotateCW(NIBBLETYPE a_Meta)
|
||||
{
|
||||
NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
|
||||
switch (a_Meta & BitMask)
|
||||
{
|
||||
case South: return West | OtherMeta;
|
||||
case West: return North | OtherMeta;
|
||||
case North: return East | OtherMeta;
|
||||
case East: return South | OtherMeta;
|
||||
}
|
||||
if (AssertIfNotMatched)
|
||||
{
|
||||
ASSERT(!"Invalid Meta value");
|
||||
}
|
||||
return a_Meta;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched>
|
||||
NIBBLETYPE cMetaRotater<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaRotateCCW(NIBBLETYPE a_Meta)
|
||||
{
|
||||
NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
|
||||
switch (a_Meta & BitMask)
|
||||
{
|
||||
case South: return East | OtherMeta;
|
||||
case East: return North | OtherMeta;
|
||||
case North: return West | OtherMeta;
|
||||
case West: return South | OtherMeta;
|
||||
}
|
||||
if (AssertIfNotMatched)
|
||||
{
|
||||
ASSERT(!"Invalid Meta value");
|
||||
}
|
||||
return a_Meta;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched>
|
||||
NIBBLETYPE cMetaRotater<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaMirrorXY(NIBBLETYPE a_Meta)
|
||||
{
|
||||
NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
|
||||
switch (a_Meta & BitMask)
|
||||
{
|
||||
case South: return North | OtherMeta;
|
||||
case North: return South | OtherMeta;
|
||||
}
|
||||
// Not Facing North or South; No change.
|
||||
return a_Meta;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched>
|
||||
NIBBLETYPE cMetaRotater<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaMirrorYZ(NIBBLETYPE a_Meta)
|
||||
{
|
||||
NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
|
||||
switch (a_Meta & BitMask)
|
||||
{
|
||||
case West: return East | OtherMeta;
|
||||
case East: return West | OtherMeta;
|
||||
}
|
||||
// Not Facing East or West; No change.
|
||||
return a_Meta;
|
||||
}
|
@ -27,4 +27,7 @@ public:
|
||||
|
||||
/** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */
|
||||
virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) = 0;
|
||||
|
||||
/** Sends the block on those coords to the player */
|
||||
virtual void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, cPlayer * a_Player) = 0;
|
||||
};
|
||||
|
@ -40,6 +40,7 @@ if (NOT MSVC)
|
||||
BlockEntities/NoteEntity.h
|
||||
BlockEntities/SignEntity.h
|
||||
BlockEntities/MobHeadEntity.h
|
||||
BlockEntities/FlowerPotEntity.h
|
||||
BlockID.h
|
||||
BoundingBox.h
|
||||
ChatColor.h
|
||||
@ -95,6 +96,7 @@ if (NOT MSVC)
|
||||
#add cpp files here
|
||||
add_library(Bindings
|
||||
Bindings/Bindings
|
||||
Bindings/DeprecatedBindings
|
||||
Bindings/LuaChunkStay
|
||||
Bindings/LuaState
|
||||
Bindings/LuaWindow
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "BlockEntities/NoteEntity.h"
|
||||
#include "BlockEntities/SignEntity.h"
|
||||
#include "BlockEntities/MobHeadEntity.h"
|
||||
#include "BlockEntities/FlowerPotEntity.h"
|
||||
#include "Entities/Pickup.h"
|
||||
#include "Item.h"
|
||||
#include "Noise.h"
|
||||
@ -883,7 +884,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);
|
||||
}
|
||||
@ -1311,6 +1312,7 @@ void cChunk::CreateBlockEntities(void)
|
||||
case E_BLOCK_HEAD:
|
||||
case E_BLOCK_NOTE_BLOCK:
|
||||
case E_BLOCK_JUKEBOX:
|
||||
case E_BLOCK_FLOWER_POT:
|
||||
{
|
||||
if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width))
|
||||
{
|
||||
@ -1440,6 +1442,7 @@ void cChunk::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType,
|
||||
case E_BLOCK_HEAD:
|
||||
case E_BLOCK_NOTE_BLOCK:
|
||||
case E_BLOCK_JUKEBOX:
|
||||
case E_BLOCK_FLOWER_POT:
|
||||
{
|
||||
AddBlockEntity(cBlockEntity::CreateByBlockType(a_BlockType, a_BlockMeta, WorldPos.x, WorldPos.y, WorldPos.z, m_World));
|
||||
break;
|
||||
@ -1540,10 +1543,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;
|
||||
@ -2337,7 +2340,7 @@ bool cChunk::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCom
|
||||
|
||||
|
||||
|
||||
bool cChunk::DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadBlockCallback & a_Callback)
|
||||
bool cChunk::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback & a_Callback)
|
||||
{
|
||||
// The blockentity list is locked by the parent chunkmap's CS
|
||||
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(), itr2 = itr; itr != m_BlockEntities.end(); itr = itr2)
|
||||
@ -2369,6 +2372,38 @@ bool cChunk::DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMob
|
||||
|
||||
|
||||
|
||||
bool cChunk::DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback)
|
||||
{
|
||||
// The blockentity list is locked by the parent chunkmap's CS
|
||||
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(), itr2 = itr; itr != m_BlockEntities.end(); itr = itr2)
|
||||
{
|
||||
++itr2;
|
||||
if (((*itr)->GetPosX() != a_BlockX) || ((*itr)->GetPosY() != a_BlockY) || ((*itr)->GetPosZ() != a_BlockZ))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((*itr)->GetBlockType() != E_BLOCK_FLOWER_POT)
|
||||
{
|
||||
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
||||
return false;
|
||||
}
|
||||
|
||||
// The correct block entity is here,
|
||||
if (a_Callback.Item((cFlowerPotEntity *)*itr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // for itr - m_BlockEntitites[]
|
||||
|
||||
// Not found:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cChunk::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4)
|
||||
{
|
||||
// The blockentity list is locked by the parent chunkmap's CS
|
||||
|
11
src/Chunk.h
11
src/Chunk.h
@ -32,6 +32,7 @@ class cDispenserEntity;
|
||||
class cFurnaceEntity;
|
||||
class cNoteEntity;
|
||||
class cMobHeadEntity;
|
||||
class cFlowerPotEntity;
|
||||
class cBlockArea;
|
||||
class cPawn;
|
||||
class cPickup;
|
||||
@ -48,7 +49,8 @@ typedef cItemCallback<cDispenserEntity> cDispenserCallback;
|
||||
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
|
||||
typedef cItemCallback<cNoteEntity> cNoteBlockCallback;
|
||||
typedef cItemCallback<cCommandBlockEntity> cCommandBlockCallback;
|
||||
typedef cItemCallback<cMobHeadEntity> cMobHeadBlockCallback;
|
||||
typedef cItemCallback<cMobHeadEntity> cMobHeadCallback;
|
||||
typedef cItemCallback<cFlowerPotEntity> cFlowerPotCallback;
|
||||
|
||||
|
||||
|
||||
@ -253,8 +255,11 @@ public:
|
||||
/** Calls the callback for the command block at the specified coords; returns false if there's no command block at those coords or callback returns true, returns true if found */
|
||||
bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback);
|
||||
|
||||
/** Calls the callback for the mob head block at the specified coords; returns false if there's no mob header block at those coords or callback returns true, returns true if found */
|
||||
bool DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadBlockCallback & a_Callback);
|
||||
/** Calls the callback for the mob head block at the specified coords; returns false if there's no mob head block at those coords or callback returns true, returns true if found */
|
||||
bool DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback & a_Callback);
|
||||
|
||||
/** Calls the callback for the flower pot at the specified coords; returns false if there's no flower pot at those coords or callback returns true, returns true if found */
|
||||
bool DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback);
|
||||
|
||||
/** Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found */
|
||||
bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Lua-accessible
|
||||
|
@ -2182,7 +2182,7 @@ bool cChunkMap::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, c
|
||||
|
||||
|
||||
|
||||
bool cChunkMap::DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadBlockCallback & a_Callback)
|
||||
bool cChunkMap::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback & a_Callback)
|
||||
{
|
||||
int ChunkX, ChunkZ;
|
||||
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
||||
@ -2193,7 +2193,25 @@ bool cChunkMap::DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, c
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return Chunk->DoWithMobHeadBlockAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||
return Chunk->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cChunkMap::DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback)
|
||||
{
|
||||
int ChunkX, ChunkZ;
|
||||
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
||||
cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
|
||||
cCSLock Lock(m_CSLayers);
|
||||
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
|
||||
if ((Chunk == NULL) && !Chunk->IsValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return Chunk->DoWithFlowerPotAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,6 +26,7 @@ class cFurnaceEntity;
|
||||
class cNoteEntity;
|
||||
class cCommandBlockEntity;
|
||||
class cMobHeadEntity;
|
||||
class cFlowerPotEntity;
|
||||
class cPawn;
|
||||
class cPickup;
|
||||
class cChunkDataSerializer;
|
||||
@ -41,10 +42,11 @@ typedef cItemCallback<cChestEntity> cChestCallback;
|
||||
typedef cItemCallback<cDispenserEntity> cDispenserCallback;
|
||||
typedef cItemCallback<cDropperEntity> cDropperCallback;
|
||||
typedef cItemCallback<cDropSpenserEntity> cDropSpenserCallback;
|
||||
typedef cItemCallback<cFlowerPotEntity> cFlowerPotCallback;
|
||||
typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
|
||||
typedef cItemCallback<cNoteEntity> cNoteBlockCallback;
|
||||
typedef cItemCallback<cCommandBlockEntity> cCommandBlockCallback;
|
||||
typedef cItemCallback<cMobHeadEntity> cMobHeadBlockCallback;
|
||||
typedef cItemCallback<cMobHeadEntity> cMobHeadCallback;
|
||||
typedef cItemCallback<cChunk> cChunkCallback;
|
||||
|
||||
|
||||
@ -257,7 +259,10 @@ public:
|
||||
bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/** Calls the callback for the mob head block at the specified coords; returns false if there's no mob head block at those coords or callback returns true, returns true if found */
|
||||
bool DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadBlockCallback & a_Callback); // Lua-accessible
|
||||
bool DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/** Calls the callback for the flower pot at the specified coords; returns false if there's no flower pot at those coords or callback returns true, returns true if found */
|
||||
bool DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/** Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found */
|
||||
bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Lua-accessible
|
||||
|
@ -558,12 +558,25 @@ void cClientHandle::HandlePluginMessage(const AString & a_Channel, const AString
|
||||
}
|
||||
else if (a_Channel == "REGISTER")
|
||||
{
|
||||
if (HasPluginChannel(a_Channel))
|
||||
{
|
||||
SendPluginMessage("UNREGISTER", a_Channel);
|
||||
return; // Can't register again if already taken - kinda defeats the point of plugin messaging!
|
||||
}
|
||||
|
||||
RegisterPluginChannels(BreakApartPluginChannels(a_Message));
|
||||
}
|
||||
else if (a_Channel == "UNREGISTER")
|
||||
{
|
||||
UnregisterPluginChannels(BreakApartPluginChannels(a_Message));
|
||||
}
|
||||
else if (!HasPluginChannel(a_Channel))
|
||||
{
|
||||
// Ignore if client sent something but didn't register the channel first
|
||||
LOGD("Player %s sent a plugin message on channel \"%s\", but didn't REGISTER it first", GetUsername().c_str(), a_Channel.c_str());
|
||||
SendPluginMessage("UNREGISTER", a_Channel);
|
||||
return;
|
||||
}
|
||||
|
||||
cPluginManager::Get()->CallHookPluginMessage(*this, a_Channel, a_Message);
|
||||
}
|
||||
@ -824,7 +837,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);
|
||||
@ -843,7 +856,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());
|
||||
@ -857,7 +870,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())
|
||||
{
|
||||
@ -925,14 +938,22 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
|
||||
a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, ItemToFullString(a_HeldItem).c_str()
|
||||
);
|
||||
|
||||
cWorld * World = m_Player->GetWorld();
|
||||
|
||||
cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager();
|
||||
if (PlgMgr->CallHookPlayerRightClick(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ))
|
||||
{
|
||||
// A plugin doesn't agree with the action, replace the block on the client and quit:
|
||||
cChunkInterface ChunkInterface(World->GetChunkMap());
|
||||
BLOCKTYPE BlockType = World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
|
||||
cBlockHandler * BlockHandler = cBlockInfo::GetHandler(BlockType);
|
||||
BlockHandler->OnCancelRightClick(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
|
||||
|
||||
if (a_BlockFace > BLOCK_FACE_NONE)
|
||||
{
|
||||
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
|
||||
m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
|
||||
World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
|
||||
World->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); //2 block high things
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -958,17 +979,15 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
|
||||
if (a_BlockFace > -1)
|
||||
{
|
||||
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
|
||||
m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
|
||||
World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
cWorld * World = m_Player->GetWorld();
|
||||
|
||||
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())
|
||||
{
|
||||
@ -1048,7 +1067,7 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e
|
||||
if (
|
||||
cBlockSlabHandler::IsAnySlabType(ClickedBlock) && // Is there a slab already?
|
||||
cBlockSlabHandler::IsAnySlabType(EquippedBlock) && // Is the player placing another slab?
|
||||
((ClickedBlockMeta & 0x07) == (EquippedBlockDamage & 0x07)) && // Is it the same slab type?
|
||||
((ClickedBlockMeta & 0x07) == EquippedBlockDamage) && // Is it the same slab type?
|
||||
(
|
||||
(a_BlockFace == BLOCK_FACE_TOP) || // Clicking the top of a bottom slab
|
||||
(a_BlockFace == BLOCK_FACE_BOTTOM) // Clicking the bottom of a top slab
|
||||
|
@ -124,14 +124,15 @@ public:
|
||||
/** Removes all parts from the object. */
|
||||
void Clear(void);
|
||||
|
||||
// tolua_end
|
||||
|
||||
// The following are exported in ManualBindings in order to support chaining - they return *this in Lua (#755)
|
||||
|
||||
/** Adds a plain text part, with optional style.
|
||||
The default style is plain white text. */
|
||||
void AddTextPart(const AString & a_Message, const AString & a_Style = "");
|
||||
|
||||
// tolua_end
|
||||
|
||||
/** Adds a part that is translated client-side, with the formatting parameters and optional style.
|
||||
Exported in ManualBindings due to AStringVector usage - Lua uses an array-table of strings. */
|
||||
/** Adds a part that is translated client-side, with the formatting parameters and optional style. */
|
||||
void AddClientTranslatedPart(const AString & a_TranslationID, const AStringVector & a_Parameters, const AString & a_Style = "");
|
||||
|
||||
// tolua_begin
|
||||
@ -155,12 +156,14 @@ public:
|
||||
/** Sets the message type, which is indicated by prefixes added to the message when serializing. */
|
||||
void SetMessageType(eMessageType a_MessageType);
|
||||
|
||||
/** Returns the message type set previously by SetMessageType(). */
|
||||
eMessageType GetMessageType(void) const { return m_MessageType; }
|
||||
|
||||
/** Adds the "underline" style to each part that is an URL. */
|
||||
void UnderlineUrls(void);
|
||||
|
||||
// tolua_begin
|
||||
|
||||
/** Returns the message type set previously by SetMessageType(). */
|
||||
eMessageType GetMessageType(void) const { return m_MessageType; }
|
||||
|
||||
// tolua_end
|
||||
|
||||
const cParts & GetParts(void) const { return m_Parts; }
|
||||
|
@ -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;
|
||||
default: 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;
|
||||
default: 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;
|
||||
default: 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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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())
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -847,6 +847,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
|
||||
{
|
||||
@ -856,24 +858,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);
|
||||
}
|
||||
|
||||
|
||||
@ -1497,10 +1482,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)
|
||||
{
|
||||
AddToGroup( Split[i].c_str() );
|
||||
if (!cRoot::Get()->GetGroupManager()->ExistsGroup(*itr))
|
||||
{
|
||||
LOGWARNING("The group %s for player %s was not found!", itr->c_str(), m_PlayerName.c_str());
|
||||
}
|
||||
AddToGroup(*itr);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1508,16 +1497,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
|
||||
{
|
||||
LOGWARN("Regenerating users.ini, player %s will be added to the \"Default\" group", m_PlayerName.c_str());
|
||||
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.SetValue(m_PlayerName, "Groups", "Default");
|
||||
IniFile.WriteFile("users.ini");
|
||||
cGroupManager::GenerateDefaultUsersIni(IniFile);
|
||||
AddToGroup("Default");
|
||||
}
|
||||
ResolvePermissions();
|
||||
@ -1884,7 +1872,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;
|
||||
|
@ -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:
|
||||
|
@ -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++)
|
||||
{
|
||||
|
@ -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;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,86 +276,26 @@ void cComposableGenerator::InitCompositionGen(cIniFile & a_IniFile)
|
||||
|
||||
|
||||
|
||||
void cComposableGenerator::InitStructureGens(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, ",");
|
||||
for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr)
|
||||
{
|
||||
if (NoCaseCompare(*itr, "DualRidgeCaves") == 0)
|
||||
{
|
||||
float Threshold = (float)a_IniFile.GetValueSetF("Generator", "DualRidgeCavesThreshold", 0.3);
|
||||
m_StructureGens.push_back(new cStructGenDualRidgeCaves(Seed, Threshold));
|
||||
}
|
||||
else if (NoCaseCompare(*itr, "DirectOverhangs") == 0)
|
||||
{
|
||||
m_StructureGens.push_back(new cStructGenDirectOverhangs(Seed));
|
||||
}
|
||||
else if (NoCaseCompare(*itr, "DistortedMembraneOverhangs") == 0)
|
||||
{
|
||||
m_StructureGens.push_back(new cStructGenDistortedMembraneOverhangs(Seed));
|
||||
}
|
||||
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));
|
||||
}
|
||||
else if (NoCaseCompare(*itr, "MarbleCaves") == 0)
|
||||
{
|
||||
m_StructureGens.push_back(new cStructGenMarbleCaves(Seed));
|
||||
}
|
||||
else if (NoCaseCompare(*itr, "MineShafts") == 0)
|
||||
{
|
||||
int GridSize = a_IniFile.GetValueSetI("Generator", "MineShaftsGridSize", 512);
|
||||
int MaxSystemSize = a_IniFile.GetValueSetI("Generator", "MineShaftsMaxSystemSize", 160);
|
||||
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(
|
||||
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");
|
||||
// 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)
|
||||
{
|
||||
@ -384,14 +310,48 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
|
||||
{
|
||||
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_FinishGens.push_back(new cStructGenDirectOverhangs(Seed));
|
||||
}
|
||||
else if (NoCaseCompare(*itr, "DistortedMembraneOverhangs") == 0)
|
||||
{
|
||||
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_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_FinishGens.push_back(new cStructGenMarbleCaves(Seed));
|
||||
}
|
||||
else if (NoCaseCompare(*itr, "MineShafts") == 0)
|
||||
{
|
||||
int GridSize = a_IniFile.GetValueSetI("Generator", "MineShaftsGridSize", 512);
|
||||
int MaxSystemSize = a_IniFile.GetValueSetI("Generator", "MineShaftsMaxSystemSize", 160);
|
||||
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_FinishGens.push_back(new cStructGenMineShafts(
|
||||
Seed, GridSize, MaxSystemSize,
|
||||
ChanceCorridor, ChanceCrossing, ChanceStaircase
|
||||
));
|
||||
}
|
||||
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[]
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
} ;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -46,6 +46,7 @@ cGroupManager::cGroupManager()
|
||||
LOGD("-- Loading Groups --");
|
||||
|
||||
LoadGroups();
|
||||
CheckUsers();
|
||||
|
||||
LOGD("-- Groups Successfully Loaded --");
|
||||
}
|
||||
@ -54,6 +55,53 @@ 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"))
|
||||
{
|
||||
GenerateDefaultUsersIni(IniFile);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int NumKeys = IniFile.GetNumKeys();
|
||||
for (size_t i = 0; i < NumKeys; i++)
|
||||
{
|
||||
AString Player = IniFile.GetKeyName( i );
|
||||
AString Groups = IniFile.GetValue(Player, "Groups", "");
|
||||
if (!Groups.empty())
|
||||
{
|
||||
AStringVector Split = StringSplit( Groups, "," );
|
||||
for( unsigned int i = 0; i < Split.size(); i++ )
|
||||
{
|
||||
if (!ExistsGroup(Split[i]))
|
||||
{
|
||||
LOGWARNING("The group %s for player %s was not found!", Split[i].c_str(), Player.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cGroupManager::LoadGroups()
|
||||
{
|
||||
cIniFile IniFile;
|
||||
@ -137,6 +185,16 @@ void cGroupManager::LoadGroups()
|
||||
|
||||
|
||||
|
||||
bool cGroupManager::ExistsGroup( const AString & a_Name )
|
||||
{
|
||||
GroupMap::iterator itr = m_pState->Groups.find( a_Name );
|
||||
return ( itr != m_pState->Groups.end() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cGroup* cGroupManager::GetGroup( const AString & a_Name )
|
||||
{
|
||||
GroupMap::iterator itr = m_pState->Groups.find( a_Name );
|
||||
|
@ -14,8 +14,13 @@ class cGroup;
|
||||
class cGroupManager
|
||||
{
|
||||
public:
|
||||
bool ExistsGroup(const AString & a_Name);
|
||||
cGroup * GetGroup(const AString & a_Name);
|
||||
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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -204,6 +204,12 @@ void cInventory::SetSlot(int a_SlotNum, const cItem & a_Item)
|
||||
return;
|
||||
}
|
||||
Grid->SetSlot(GridSlotNum, a_Item);
|
||||
|
||||
// Broadcast the Equipped Item, if the Slot is changed.
|
||||
if ((Grid == &m_HotbarSlots) && (m_EquippedSlotNum == (a_SlotNum - invHotbarOffset)))
|
||||
{
|
||||
m_Owner.GetWorld()->BroadcastEntityEquipment(m_Owner, 0, a_Item, m_Owner.GetClientHandle());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,10 +36,10 @@ public:
|
||||
|
||||
// The map center is fixed at the central point of the 8x8 block of chunks you are standing in when you right-click it.
|
||||
|
||||
const int RegionWidth = cChunkDef::Width * 8 * pow(2.0, (double) DEFAULT_SCALE);
|
||||
const int RegionWidth = cChunkDef::Width * 8;
|
||||
|
||||
int CenterX = floor(a_Player->GetPosX() / (float) RegionWidth) * RegionWidth;
|
||||
int CenterZ = floor(a_Player->GetPosZ() / (float) RegionWidth) * RegionWidth;
|
||||
int CenterX = (int)(floor(a_Player->GetPosX() / (float) RegionWidth) * RegionWidth);
|
||||
int CenterZ = (int)(floor(a_Player->GetPosZ() / (float) RegionWidth) * RegionWidth);
|
||||
|
||||
cMap * NewMap = a_World->GetMapManager().CreateMap(CenterX, CenterZ, DEFAULT_SCALE);
|
||||
|
||||
|
@ -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))
|
||||
|
@ -19,17 +19,13 @@ public:
|
||||
{
|
||||
switch(m_ItemType)
|
||||
{
|
||||
case E_ITEM_WOODEN_PICKAXE:
|
||||
case E_ITEM_GOLD_PICKAXE:
|
||||
return 1;
|
||||
case E_ITEM_STONE_PICKAXE:
|
||||
return 2;
|
||||
case E_ITEM_IRON_PICKAXE:
|
||||
return 3;
|
||||
case E_ITEM_DIAMOND_PICKAXE:
|
||||
return 4;
|
||||
default:
|
||||
return 0;
|
||||
case E_ITEM_WOODEN_PICKAXE: return 1;
|
||||
case E_ITEM_GOLD_PICKAXE: return 1;
|
||||
case E_ITEM_STONE_PICKAXE: return 2;
|
||||
case E_ITEM_IRON_PICKAXE: return 3;
|
||||
case E_ITEM_DIAMOND_PICKAXE: return 4;
|
||||
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,6 +57,10 @@ public:
|
||||
return PickaxeLevel() >= 2;
|
||||
}
|
||||
|
||||
case E_BLOCK_ANVIL:
|
||||
case E_BLOCK_ENCHANTMENT_TABLE:
|
||||
case E_BLOCK_FURNACE:
|
||||
case E_BLOCK_LIT_FURNACE:
|
||||
case E_BLOCK_COAL_ORE:
|
||||
case E_BLOCK_STONE:
|
||||
case E_BLOCK_COBBLESTONE:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -42,7 +42,7 @@ cLog::~cLog()
|
||||
|
||||
|
||||
|
||||
cLog* cLog::GetInstance()
|
||||
cLog * cLog::GetInstance()
|
||||
{
|
||||
if (s_Log != NULL)
|
||||
{
|
||||
@ -92,7 +92,7 @@ void cLog::ClearLog()
|
||||
if( m_File )
|
||||
fclose (m_File);
|
||||
#endif
|
||||
m_File = 0;
|
||||
m_File = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -357,6 +357,8 @@ void cMap::AddPlayer(cPlayer * a_Player, Int64 a_WorldAge)
|
||||
MapClient.m_LastUpdate = a_WorldAge;
|
||||
MapClient.m_SendInfo = true;
|
||||
MapClient.m_Handle = Handle;
|
||||
MapClient.m_DataUpdate = 0;
|
||||
MapClient.m_NextDecoratorUpdate = 0;
|
||||
|
||||
m_Clients.push_back(MapClient);
|
||||
|
||||
|
@ -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)
|
||||
);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user