Merge branch 'master' of https://github.com/mc-server/MCServer
Conflicts: src/Server.cpp
This commit is contained in:
commit
431b7ed0b7
@ -942,24 +942,6 @@ cFile:Delete("/usr/bin/virus.exe");
|
||||
Inherits = "cEntity",
|
||||
},
|
||||
|
||||
cGroup =
|
||||
{
|
||||
Desc = [[
|
||||
This class represents a group {{cPlayer|players}} can be in. Groups define the permissions players
|
||||
have, and optionally the color of their name in the chat.
|
||||
]],
|
||||
Functions =
|
||||
{
|
||||
SetName = { Return = "" },
|
||||
GetName = { Return = "string" },
|
||||
SetColor = { Return = "" },
|
||||
GetColor = { Return = "string" },
|
||||
AddCommand = { Return = "" },
|
||||
AddPermission = { Return = "" },
|
||||
InheritFrom = { Return = "" },
|
||||
},
|
||||
}, -- cGroup
|
||||
|
||||
cIniFile =
|
||||
{
|
||||
Desc = [[
|
||||
@ -1760,7 +1742,6 @@ a_Player:OpenWindow(Window);
|
||||
Functions =
|
||||
{
|
||||
AddFoodExhaustion = { Params = "Exhaustion", Return = "", Notes = "Adds the specified number to the food exhaustion. Only positive numbers expected." },
|
||||
AddToGroup = { Params = "GroupName", Return = "", Notes = "Temporarily adds the player to the specified group. The assignment is lost when the player disconnects." },
|
||||
CalcLevelFromXp = { Params = "XPAmount", Return = "number", Notes = "(STATIC) Returns the level which is reached with the specified amount of XP. Inverse of XpForLevel()." },
|
||||
CanFly = { Return = "bool", Notes = "Returns if the player is able to fly." },
|
||||
CloseWindow = { Params = "[CanRefuse]", Return = "", Notes = "Closes the currently open UI window. If CanRefuse is true (default), the window may refuse the closing." },
|
||||
@ -1770,7 +1751,7 @@ a_Player:OpenWindow(Window);
|
||||
FoodPoison = { Params = "NumTicks", Return = "", Notes = "Starts the food poisoning for the specified amount of ticks; if already foodpoisoned, sets FoodPoisonedTicksRemaining to the larger of the two" },
|
||||
ForceSetSpeed = { Params = "{{Vector3d|Direction}}", Notes = "Forces the player to move to the given direction." },
|
||||
GetClientHandle = { Params = "", Return = "{{cClientHandle}}", Notes = "Returns the client handle representing the player's connection. May be nil (AI players)." },
|
||||
GetColor = { Return = "string", Notes = "Returns the full color code to be used for this player (based on the first group). Prefix player messages with this code." },
|
||||
GetColor = { Return = "string", Notes = "Returns the full color code to be used for this player's messages (based on their rank). Prefix player messages with this code." },
|
||||
GetCurrentXp = { Params = "", Return = "number", Notes = "Returns the current amount of XP" },
|
||||
GetEffectiveGameMode = { Params = "", Return = "{{Globals#GameMode|GameMode}}", Notes = "(OBSOLETE) Returns the current resolved game mode of the player. If the player is set to inherit the world's gamemode, returns that instead. See also GetGameMode() and IsGameModeXXX() functions. Note that this function is the same as GetGameMode(), use that function instead." },
|
||||
GetEquippedItem = { Params = "", Return = "{{cItem}}", Notes = "Returns the item that the player is currently holding; empty item if holding nothing." },
|
||||
@ -1784,7 +1765,6 @@ a_Player:OpenWindow(Window);
|
||||
GetFoodSaturationLevel = { Params = "", Return = "number", Notes = "Returns the food saturation (overcharge of the food level, is depleted before food level)" },
|
||||
GetFoodTickTimer = { Params = "", Return = "", Notes = "Returns the number of ticks past the last food-based heal or damage action; when this timer reaches 80, a new heal / damage is applied." },
|
||||
GetGameMode = { Return = "{{Globals#GameMode|GameMode}}", Notes = "Returns the player's gamemode. The player may have their gamemode unassigned, in which case they inherit the gamemode from the current {{cWorld|world}}.<br /> <b>NOTE:</b> Instead of comparing the value returned by this function to the gmXXX constants, use the IsGameModeXXX() functions. These functions handle the gamemode inheritance automatically."},
|
||||
GetGroups = { Return = "array-table of {{cGroup}}", Notes = "Returns all the groups that this player is member of, as a table. The groups are stored in the array part of the table, beginning with index 1."},
|
||||
GetIP = { Return = "string", Notes = "Returns the IP address of the player, if available. Returns an empty string if there's no IP to report."},
|
||||
GetInventory = { Return = "{{cInventory|Inventory}}", Notes = "Returns the player's inventory"},
|
||||
GetMaxSpeed = { Params = "", Return = "number", Notes = "Returns the player's current maximum speed, relative to the game default speed. Takes into account the sprinting / flying status." },
|
||||
@ -1807,15 +1787,13 @@ a_Player:OpenWindow(Window);
|
||||
IsGameModeAdventure = { Params = "", Return = "bool", Notes = "Returns true if the player is in the gmAdventure gamemode, or has their gamemode unset and the world is a gmAdventure world." },
|
||||
IsGameModeCreative = { Params = "", Return = "bool", Notes = "Returns true if the player is in the gmCreative gamemode, or has their gamemode unset and the world is a gmCreative world." },
|
||||
IsGameModeSurvival = { Params = "", Return = "bool", Notes = "Returns true if the player is in the gmSurvival gamemode, or has their gamemode unset and the world is a gmSurvival world." },
|
||||
IsInGroup = { Params = "GroupNameString", Return = "bool", Notes = "Returns true if the player is a member of the specified group." },
|
||||
IsOnGround = { Params = "", Return = "bool", Notes = "Returns true if the player is on ground (not falling, not jumping, not flying)" },
|
||||
IsSatiated = { Params = "", Return = "bool", Notes = "Returns true if the player is satiated (cannot eat)." },
|
||||
IsVisible = { Params = "", Return = "bool", Notes = "Returns true if the player is visible to other players" },
|
||||
LoadPermissionsFromDisk = { Params = "", Return = "", Notes = "Reloads the player's permissions from the disk. This loses any temporary changes made to the player's groups." },
|
||||
LoadRank = { Params = "", Return = "", Notes = "Reloads the player's rank, message visuals and permissions from the {{cRankManager}}, based on the player's current rank." },
|
||||
MoveTo = { Params = "{{Vector3d|NewPosition}}", Return = "Tries to move the player into the specified position." },
|
||||
MoveToWorld = { Params = "WorldName", Return = "bool", Return = "Moves the player to the specified world. Returns true if successful." },
|
||||
OpenWindow = { Params = "{{cWindow|Window}}", Return = "", Notes = "Opens the specified UI window for the player." },
|
||||
RemoveFromGroup = { Params = "GroupName", Return = "", Notes = "Temporarily removes the player from the specified group. This change is lost when the player disconnects." },
|
||||
Respawn = { Params = "", Return = "", Notes = "Restores the health, extinguishes fire, makes visible and sends the Respawn packet." },
|
||||
SendMessage = { Params = "Message", Return = "", Notes = "Sends the specified message to the player." },
|
||||
SendMessageFailure = { Params = "Message", Return = "", Notes = "Prepends Rose [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and sends message to player. For a command that failed to run because of insufficient permissions, etc." },
|
||||
@ -2004,6 +1982,71 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
|
||||
},
|
||||
}, -- cPluginManager
|
||||
|
||||
cRankManager =
|
||||
{
|
||||
Desc = [[
|
||||
Manages the players' permissions. The players are assigned a single rank, which contains groups of
|
||||
permissions. The functions in this class query or modify these.</p>
|
||||
<p>
|
||||
All the functions are static, call them using the <code>cRankManager:Function()</code> convention.</p>
|
||||
<p>
|
||||
The players are identified by their UUID, to support player renaming.</p>
|
||||
<p>
|
||||
The rank also contains specific "mesage visuals" - bits that are used for formatting messages from the
|
||||
players. There's a message prefix, which is put in front of every message the player sends, and the
|
||||
message suffix that is appended to each message. There's also a PlayerNameColorCode, which holds the
|
||||
color that is used for the player's name in the messages.</p>
|
||||
<p>
|
||||
Each rank can contain any number of permission groups. These groups allow for an easier setup of the
|
||||
permissions - you can share groups among ranks, so the usual approach is to group similar permissions
|
||||
together and add that group to any rank that should use those permissions.</p>
|
||||
<p>
|
||||
Permissions are added to individual groups. Each group can support unlimited permissions. Note that
|
||||
adding a permission to a group will make the permission available to all the ranks that contain that
|
||||
permission group.</p>
|
||||
<p>
|
||||
One rank is reserved as the Default rank. All players that don't have an explicit rank assigned to them
|
||||
will behave as if assigned to this rank. The default rank can be changed to any other rank at any time.
|
||||
Note that the default rank cannot be removed from the RankManager - RemoveRank() will change the default
|
||||
rank to the replacement rank, if specified, and fail if no replacement rank is specified. Renaming the
|
||||
default rank using RenameRank() will change the default rank to the new name.
|
||||
]],
|
||||
Functions =
|
||||
{
|
||||
AddGroup = { Params = "GroupName", Return = "", Notes = "Adds the group of the specified name. Logs a warning and does nothing if the group already exists." },
|
||||
AddGroupToRank = { Params = "GroupName, RankName", Return = "bool", Notes = "Adds the specified group to the specified rank. Returns true on success, false on failure - if the group name or the rank name is not found." },
|
||||
AddPermissionToGroup = { Params = "Permission, GroupName", Return = "bool", Notes = "Adds the specified permission to the specified group. Returns true on success, false on failure - if the group name is not found." },
|
||||
AddRank = { Params = "RankName, MsgPrefix, MsgSuffix, MsgNameColorCode", Return = "", Notes = "Adds a new rank of the specified name and with the specified message visuals. Logs an info message and does nothing if the rank already exists." },
|
||||
GetAllGroups = { Params = "", Return = "array-table of groups' names", Notes = "Returns an array-table containing the names of all the groups that are known to the manager." },
|
||||
GetAllPermissions = { Params = "", Return = "array-table of permissions", Notes = "Returns an array-table containing all the permissions that are known to the manager." },
|
||||
GetAllRanks = { Params = "", Return = "array-table of ranks' names", Notes = "Returns an array-table containing the names of all the ranks that are known to the manager." },
|
||||
GetDefaultRank = { Params = "", Return = "string", Notes = "Returns the name of the default rank. " },
|
||||
GetGroupPermissions = { Params = "GroupName", Return = "array-table of permissions", Notes = "Returns an array-table containing the permissions that the specified group contains." },
|
||||
GetPlayerGroups = { Params = "PlayerUUID", Return = "array-table of groups' names", Notes = "Returns an array-table of the names of the groups that are assigned to the specified player through their rank. Returns an empty table if the player is not known or has no rank or groups assigned to them." },
|
||||
GetPlayerMsgVisuals = { Params = "PlayerUUID", Return = "MsgPrefix, MsgSuffix, MsgNameColorCode", Notes = "Returns the message visuals assigned to the player. If the player is not explicitly assigned a rank, the default rank's visuals are returned. If there is an error, no value is returned at all." },
|
||||
GetPlayerPermissions = { Params = "PlayerUUID", Return = "array-table of permissions", Notes = "Returns the permissions that the specified player is assigned through their rank. Returns the default rank's permissions if the player has no explicit rank assigned to them. Returns an empty array on error." },
|
||||
GetPlayerRankName = { Params = "PlayerUUID", Return = "RankName", Notes = "Returns the name of the rank that is assigned to the specified player. An empty string (NOT the default rank) is returned if the player has no rank assigned to them." },
|
||||
GetRankGroups = { Params = "RankName", Return = "array-table of groups' names", Notes = "Returns an array-table of the names of all the groups that are assigned to the specified rank. Returns an empty table if there is no such rank." },
|
||||
GetRankPermissions = { Params = "RankName", Return = "array-table of permissions", Notes = "Returns an array-table of all the permissions that are assigned to the specified rank through its groups. Returns an empty table if there is no such rank." },
|
||||
GetRankVisuals = { Params = "RankName", Return = "MsgPrefix, MsgSuffix, MsgNameColorCode", Notes = "Returns the message visuals for the specified rank. Returns no value if the specified rank does not exist." },
|
||||
GroupExists = { Params = "GroupName", Return = "bool", Notes = "Returns true iff the specified group exists." },
|
||||
IsGroupInRank = { Params = "GroupName, RankName", Return = "bool", Notes = "Returns true iff the specified group is assigned to the specified rank." },
|
||||
IsPermissionInGroup = { Params = "Permission, GroupName", Return = "bool", Notes = "Returns true iff the specified permission is assigned to the specified group." },
|
||||
IsPlayerRankSet = { Params = "PlayerUUID", Return = "bool", Notes = "Returns true iff the specified player has a rank assigned to them." },
|
||||
RankExists = { Params = "RankName", Return = "bool", Notes = "Returns true iff the specified rank exists." },
|
||||
RemoveGroup = { Params = "GroupName", Return = "", Notes = "Removes the specified group completely. The group will be removed from all the ranks using it and then erased from the manager. Logs an info message and does nothing if the group doesn't exist." },
|
||||
RemoveGroupFromRank = { Params = "GroupName, RankName", Return = "", Notes = "Removes the specified group from the specified rank. The group will still exist, even if it isn't assigned to any rank. Logs an info message and does nothing if the group or rank doesn't exist." },
|
||||
RemovePermissionFromGroup = { Params = "Permission, GroupName", Return = "", Notes = "Removes the specified permission from the specified group. Logs an info message and does nothing if the group doesn't exist." },
|
||||
RemovePlayerRank = { Params = "PlayerUUID", Return = "", Notes = "Removes the player's rank; the player's left without a rank. Note that this doesn't change the {{cPlayer}} instances for the already connected players, you need to update all the instances manually. No action if the player has no rank assigned to them already." },
|
||||
RemoveRank = { Params = "RankName, [ReplacementRankName]", Return = "", Notes = "Removes the specified rank. If ReplacementRankName is given, the players that have RankName will get their rank set to ReplacementRankName. If it isn't given, or is an invalid rank, the players will be removed from the manager, their ranks will be unset completely. Logs an info message and does nothing if the rank is not found." },
|
||||
RenameGroup = { Params = "OldName, NewName", Return = "", Notes = "Renames the specified group. Logs an info message and does nothing if the group is not found or the new name is already used." },
|
||||
RenameRank = { Params = "OldName, NewName", Return = "", Notes = "Renames the specified rank. Logs an info message and does nothing if the rank is not found or the new name is already used." },
|
||||
SetDefaultRank = { Params = "RankName", Return = "bool", Notes = "Sets the specified rank as the default rank. Returns true on success, false on failure (rank doesn't exist)." },
|
||||
SetPlayerRank = { Params = "PlayerUUID, PlayerName, RankName", Return = "", Notes = "Updates the rank for the specified player. The player name is provided for reference, the UUID is used for identification. Logs a warning and does nothing if the rank is not found." },
|
||||
SetRankVisuals = { Params = "RankName, MsgPrefix, MsgSuffix, MsgNameColorCode", Return = "", Notes = "Updates the rank's message visuals. Logs an info message and does nothing if rank not found." },
|
||||
},
|
||||
}, -- cRankManager
|
||||
|
||||
cRoot =
|
||||
{
|
||||
Desc = [[
|
||||
@ -2032,7 +2075,6 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
|
||||
GetDefaultWorld = { Params = "", Return = "{{cWorld|cWorld}}", Notes = "Returns the world object from the default world." },
|
||||
GetFurnaceFuelBurnTime = { Params = "{{cItem|Fuel}}", Return = "number", Notes = "(STATIC) Returns the number of ticks for how long the item would fuel a furnace. Returns zero if not a fuel." },
|
||||
GetFurnaceRecipe = { Params = "{{cItem|InItem}}", Return = "{{cItem|OutItem}}, NumTicks, {{cItem|InItem}}", Notes = "(STATIC) Returns the furnace recipe for smelting the specified input. If a recipe is found, returns the smelted result, the number of ticks required for the smelting operation, and the input consumed (note that MCServer supports smelting M items into N items and different smelting rates). If no recipe is found, returns no value." },
|
||||
GetGroupManager = { Params = "", Return = "{{cGroupManager|cGroupManager}}", Notes = "Returns the cGroupManager object." },
|
||||
GetPhysicalRAMUsage = { Params = "", Return = "number", Notes = "Returns the amount of physical RAM that the entire MCServer process is using, in KiB. Negative if the OS doesn't support this query." },
|
||||
GetPluginManager = { Params = "", Return = "{{cPluginManager|cPluginManager}}", Notes = "Returns the cPluginManager object." },
|
||||
GetPrimaryServerVersion = { Params = "", Return = "number", Notes = "Returns the servers primary server version." },
|
||||
@ -2116,10 +2158,11 @@ end
|
||||
{
|
||||
GetDescription = { Return = "string", Notes = "Returns the server description set in the settings.ini." },
|
||||
GetMaxPlayers = { Return = "number", Notes = "Returns the max amount of players who can join the server." },
|
||||
SetMaxPlayers = { Params = "number", Notes = "Sets the max amount of players who can join." },
|
||||
GetNumPlayers = { Return = "number", Notes = "Returns the amount of players online." },
|
||||
GetServerID = { Return = "string", Notes = "Returns the ID of the server?" },
|
||||
IsHardcore = { Params = "", Return = "bool", Notes = "Returns true if the server is hardcore (players get banned on death)." },
|
||||
SetMaxPlayers = { Params = "number", Notes = "Sets the max amount of players who can join." },
|
||||
ShouldAuthenticate = { Params = "", Return = "bool", Notes = "Returns true iff the server is set to authenticate players (\"online mode\")." },
|
||||
},
|
||||
}, -- cServer
|
||||
|
||||
@ -2527,8 +2570,8 @@ World:ForEachEntity(
|
||||
The following code snippet checks if the player holds a shovel.
|
||||
<pre class="prettyprint lang-lua">
|
||||
-- a_Player is a {{cPlayer}} object, possibly received as a hook param
|
||||
local HeldItem = a_Player:GetEquippedItem();
|
||||
if (cItemCategory:IsShovel(HeldItem.m_ItemType)) then
|
||||
local HeldItem = a_Player:GetEquippedItem()
|
||||
if (ItemCategory.IsShovel(HeldItem.m_ItemType)) then
|
||||
-- It's a shovel
|
||||
end
|
||||
</pre>
|
||||
@ -2760,15 +2803,16 @@ end
|
||||
Functions =
|
||||
{
|
||||
AddFaceDirection = {Params = "BlockX, BlockY, BlockZ, BlockFace, [IsInverse]", Return = "BlockX, BlockY, BlockZ", Notes = "Returns the coords of a block adjacent to the specified block through the specified {{Globals#BlockFaces|face}}"},
|
||||
BlockFaceToString = { Params = "{{Globals#BlockFaces|eBlockFace}}", Return = "string", Notes = "Returns the string representation of the {{Globals#BlockFaces|eBlockFace}} constant. Uses the axis-direction-based names, such as BLOCK_FACE_XP." },
|
||||
BlockFaceToString = {Params = "{{Globals#BlockFaces|eBlockFace}}", Return = "string", Notes = "Returns the string representation of the {{Globals#BlockFaces|eBlockFace}} constant. Uses the axis-direction-based names, such as BLOCK_FACE_XP." },
|
||||
BlockStringToType = {Params = "BlockTypeString", Return = "BLOCKTYPE", Notes = "Returns the block type parsed from the given string"},
|
||||
Clamp = {Params = "Number, Min, Max", Return = "number", Notes = "Clamp the number to the specified range."},
|
||||
ClickActionToString = {Params = "{{Globals#ClickAction|ClickAction}}", Return = "string", Notes = "Returns a string description of the ClickAction enumerated value"},
|
||||
DamageTypeToString = {Params = "{{Globals#DamageType|DamageType}}", Return = "string", Notes = "Converts the {{Globals#DamageType|DamageType}} enumerated value to a string representation "},
|
||||
EscapeString = {Params = "string", Return = "string", Notes = "Returns a copy of the string with all quotes and backslashes escaped by a backslash"},
|
||||
GetChar = {Params = "String, Pos", Return = "string", Notes = "Returns one character from the string, specified by position "},
|
||||
GetIniItemSet = { Params = "IniFile, SectionName, KeyName, DefaultValue", Return = "{{cItem}}", Notes = "Returns the item that has been read from the specified INI file value. If the value is not present in the INI file, the DefaultValue is stored in the file and parsed as the result. Returns empty item if the value cannot be parsed. " },
|
||||
GetTime = {Return = "number", Notes = "Returns the current OS time, as a unix time stamp (number of seconds since Jan 1, 1970)"},
|
||||
IsBiomeNoDownfall = { Params = "Biome", Return = "bool", Notes = "Returns true if the biome is 'dry', that is, there is no precipitation during rains and storms." },
|
||||
IsBiomeNoDownfall = {Params = "Biome", Return = "bool", Notes = "Returns true if the biome is 'dry', that is, there is no precipitation during rains and storms." },
|
||||
IsValidBlock = {Params = "BlockType", Return = "bool", Notes = "Returns true if BlockType is a known block type"},
|
||||
IsValidItem = {Params = "ItemType", Return = "bool", Notes = "Returns true if ItemType is a known item type"},
|
||||
ItemToFullString = {Params = "{{cItem|cItem}}", Return = "string", Notes = "Returns the string representation of the item, in the format 'ItemTypeText:ItemDamage * Count'"},
|
||||
|
@ -11,9 +11,11 @@ return
|
||||
Params =
|
||||
{
|
||||
{ Name = "Player", Type = "{{cPlayer}}", Notes = "The player who has moved. The object already has the new position stored in it." },
|
||||
{ Name = "OldPosition", Type = "{{Vector3d}}", Notes = "The old position." },
|
||||
{ Name = "NewPosition", Type = "{{Vector3d}}", Notes = "The new position." },
|
||||
},
|
||||
Returns = [[
|
||||
If the function returns true, movement is prohibited. FIXME: The player's client is not informed.</p>
|
||||
If the function returns true, movement is prohibited.</p>
|
||||
<p>
|
||||
If the function returns false or no value, other plugins' callbacks are called and finally the new
|
||||
position is permanently stored in the cPlayer object.</p>
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 1b16c23c216d359e9fe0334c63deeecc347e69bd
|
||||
Subproject commit 7cc99285ae5117418f657c3b295ca71f2b75b4f4
|
@ -33,6 +33,7 @@ function Initialize(Plugin)
|
||||
PM:AddHook(cPluginManager.HOOK_PROJECTILE_HIT_BLOCK, OnProjectileHitBlock);
|
||||
PM:AddHook(cPluginManager.HOOK_CHUNK_UNLOADING, OnChunkUnloading);
|
||||
PM:AddHook(cPluginManager.HOOK_WORLD_STARTED, OnWorldStarted);
|
||||
PM:AddHook(cPluginManager.HOOK_PROJECTILE_HIT_BLOCK, OnProjectileHitBlock);
|
||||
|
||||
-- _X: Disabled so that the normal operation doesn't interfere with anything
|
||||
-- PM:AddHook(cPluginManager.HOOK_CHUNK_GENERATED, OnChunkGenerated);
|
||||
@ -80,7 +81,8 @@ function Initialize(Plugin)
|
||||
|
||||
TestBlockAreasString()
|
||||
TestStringBase64()
|
||||
TestUUIDFromName()
|
||||
-- TestUUIDFromName()
|
||||
-- TestRankMgr()
|
||||
|
||||
--[[
|
||||
-- Test cCompositeChat usage in console-logging:
|
||||
@ -352,6 +354,18 @@ end
|
||||
|
||||
|
||||
|
||||
function TestRankMgr()
|
||||
LOG("Testing the rank manager")
|
||||
cRankManager:AddRank("LuaRank")
|
||||
cRankManager:AddGroup("LuaTestGroup")
|
||||
cRankManager:AddGroupToRank("LuaTestGroup", "LuaRank")
|
||||
cRankManager:AddPermissionToGroup("luaperm", "LuaTestGroup")
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function TestSQLiteBindings()
|
||||
LOG("Testing SQLite bindings...");
|
||||
|
||||
@ -1532,3 +1546,15 @@ end
|
||||
|
||||
|
||||
|
||||
|
||||
function OnProjectileHitBlock(a_ProjectileEntity, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_BlockHitPos)
|
||||
-- This simple test is for testing issue #1326 - simply declaring this hook would crash the server upon call
|
||||
LOG("Projectile hit block")
|
||||
LOG(" Projectile EntityID: " .. a_ProjectileEntity:GetUniqueID())
|
||||
LOG(" Block: {" .. a_BlockX .. ", " .. a_BlockY .. ", " .. a_BlockZ .. "}, face " .. a_BlockFace)
|
||||
LOG(" HitPos: {" .. a_BlockHitPos.x .. ", " .. a_BlockHitPos.y .. ", " .. a_BlockHitPos.z .. "}")
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -185,4 +185,10 @@ AttackDamage=6.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=100
|
||||
|
||||
[Bat]
|
||||
AttackRange=2.0
|
||||
AttackRate=1
|
||||
AttackDamage=0.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=6
|
||||
|
||||
|
@ -12,7 +12,8 @@
|
||||
:: It expects the MS Performance tools installed in C:\Program Files\Microsoft Visual Studio 9.0\Team Tools\Performance Tools
|
||||
:: You can override this path by setting the pt environment variable prior to launching this script
|
||||
::
|
||||
:: By default it will launch the release version of MCServer; set the app environment variable to another executable to run that instead.
|
||||
:: By default it will launch the 32-bit release version of MCServer; set the app environment variable to another executable to run that instead.
|
||||
:: Set the IsExecutablex64 env variable to \x64 to profile a 64-bit executable instead (available as the profile_run_x64.cmd script)
|
||||
:: Note that the app needs to be compiled with the "/PROFILE" flag in order for the profiling to work
|
||||
|
||||
|
||||
@ -45,7 +46,7 @@ if %outputdir%n == n (
|
||||
|
||||
|
||||
|
||||
::Create the output directory, if it didn't exist
|
||||
:: Create the output directory, if it didn't exist
|
||||
mkdir %outputdir%
|
||||
|
||||
|
||||
@ -55,15 +56,15 @@ mkdir %outputdir%
|
||||
:: Start the profiler
|
||||
set outputname=profile.vsp
|
||||
set output=%outputdir%\%outputname%
|
||||
%pt%\vsperfcmd /start:sample /output:%output%
|
||||
%pt%%IsExecutablex64%\vsperfcmd /start:sample /output:%output%
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
:: Launch the application via the profiler
|
||||
%pt%\vsperfcmd /launch:%app%
|
||||
if errorlevel 1 goto haderror
|
||||
%pt%%IsExecutablex64%\vsperfcmd /launch:%app%
|
||||
if errorlevel 1 goto haderrorshutdown
|
||||
|
||||
:: Shut down the profiler (this command waits, until the application is terminated)
|
||||
%pt%\vsperfcmd /shutdown
|
||||
%pt%%IsExecutablex64%\vsperfcmd /shutdown
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
@ -86,6 +87,10 @@ goto finished
|
||||
|
||||
|
||||
|
||||
:haderrorshutdown
|
||||
echo An error was encountered, shutting down the profiler
|
||||
%pt%%IsExecutablex64%\vsperfcmd /shutdown
|
||||
|
||||
:haderror
|
||||
echo An error was encountered
|
||||
pause
|
||||
|
5
MCServer/profile_run_x64.cmd
Normal file
5
MCServer/profile_run_x64.cmd
Normal file
@ -0,0 +1,5 @@
|
||||
@echo off
|
||||
:: This script uses the profile_run.cmd script to run profiling on a x64 release executable
|
||||
|
||||
set IsExecutablex64=\x64
|
||||
call profile_run.cmd
|
@ -1,3 +1,5 @@
|
||||
|
||||
|
||||
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}")
|
||||
|
5
Tools/AnvilStats/.gitignore
vendored
5
Tools/AnvilStats/.gitignore
vendored
@ -1,3 +1,7 @@
|
||||
*.vcproj
|
||||
*.vcxproj
|
||||
*.sln
|
||||
*.user
|
||||
.xls
|
||||
Statistics.txt
|
||||
*.bmp
|
||||
@ -7,3 +11,4 @@ Profiling
|
||||
*.png
|
||||
world/
|
||||
*.html
|
||||
*.xls
|
||||
|
@ -1,55 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Express 2013 for Windows Desktop
|
||||
VisualStudioVersion = 12.0.21005.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AnvilStats", "AnvilStats.vcxproj", "{CF996A5E-0A86-4004-9710-682B06B5AEBA}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821} = {B61007AC-B557-4B67-A765-E468C0C3A821}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\lib\zlib\zlib.vcxproj", "{B61007AC-B557-4B67-A765-E468C0C3A821}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
DebugProfile|Win32 = DebugProfile|Win32
|
||||
MinSizeRel|Win32 = MinSizeRel|Win32
|
||||
Release profiled|Win32 = Release profiled|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
ReleaseProfile|Win32 = ReleaseProfile|Win32
|
||||
RelWithDebInfo|Win32 = RelWithDebInfo|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.DebugProfile|Win32.ActiveCfg = Debug|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.DebugProfile|Win32.Build.0 = Debug|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.MinSizeRel|Win32.ActiveCfg = Release|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.MinSizeRel|Win32.Build.0 = Release|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release profiled|Win32.ActiveCfg = Release profiled|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release profiled|Win32.Build.0 = Release profiled|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release|Win32.Build.0 = Release|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.ReleaseProfile|Win32.ActiveCfg = Release|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.ReleaseProfile|Win32.Build.0 = Release|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.RelWithDebInfo|Win32.Build.0 = Release|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.DebugProfile|Win32.ActiveCfg = DebugProfile|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.DebugProfile|Win32.Build.0 = DebugProfile|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.Release profiled|Win32.ActiveCfg = Release|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.Release profiled|Win32.Build.0 = Release|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.Release|Win32.Build.0 = Release|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.ReleaseProfile|Win32.ActiveCfg = ReleaseProfile|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.ReleaseProfile|Win32.Build.0 = ReleaseProfile|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -1,468 +0,0 @@
|
||||
<?xml version="1.0" encoding="windows-1250"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="AnvilStats"
|
||||
ProjectGUID="{CF996A5E-0A86-4004-9710-682B06B5AEBA}"
|
||||
RootNamespace="AnvilStats"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""..\..\lib""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="Globals.h"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
StackReserveSize="16777216"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories=""..\..\lib""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="Globals.h"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
StackReserveSize="16777216"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release profiled|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories=""..\..\lib""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="Globals.h"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
StackReserveSize="16777216"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
Profile="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\AnvilStats.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeMap.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeMap.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Callback.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ChunkExtract.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ChunkExtract.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Globals.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release profiled|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Globals.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\HeightBiomeMap.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\HeightBiomeMap.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\HeightMap.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\HeightMap.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ImageComposingCallback.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ImageComposingCallback.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Processor.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Processor.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SpringStats.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SpringStats.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Statistics.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Statistics.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="shared"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\CriticalSection.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\CriticalSection.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Endianness.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\Event.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\Event.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\WorldStorage\FastNBT.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="NBT_RESERVE_SIZE=10000"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="NBT_RESERVE_SIZE=10000"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release profiled|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="NBT_RESERVE_SIZE=10000"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\WorldStorage\FastNBT.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\File.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\File.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\GZipFile.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\GZipFile.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\IsThread.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\IsThread.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\StringUtils.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\StringUtils.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\AnvilStats.txt"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
144
Tools/AnvilStats/CMakeLists.txt
Normal file
144
Tools/AnvilStats/CMakeLists.txt
Normal file
@ -0,0 +1,144 @@
|
||||
|
||||
cmake_minimum_required (VERSION 2.8.3)
|
||||
|
||||
project (AnvilStats)
|
||||
|
||||
include(../../SetFlags.cmake)
|
||||
|
||||
set_flags()
|
||||
set_lib_flags()
|
||||
|
||||
|
||||
# Set include paths to the used libraries:
|
||||
include_directories("../../lib")
|
||||
include_directories("../../src")
|
||||
|
||||
|
||||
|
||||
function(flatten_files arg1)
|
||||
set(res "")
|
||||
foreach(f ${${arg1}})
|
||||
get_filename_component(f ${f} ABSOLUTE)
|
||||
list(APPEND res ${f})
|
||||
endforeach()
|
||||
set(${arg1} "${res}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
add_subdirectory(../../lib/zlib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/lib/zlib)
|
||||
|
||||
set_exe_flags()
|
||||
|
||||
# Include the shared files:
|
||||
set(SHARED_SRC
|
||||
../../src/ByteBuffer.cpp
|
||||
../../src/StringUtils.cpp
|
||||
../../src/LoggerListeners.cpp
|
||||
../../src/Logger.cpp
|
||||
../../src/WorldStorage/FastNBT.cpp
|
||||
../BiomeVisualiser/BiomeColors.cpp
|
||||
)
|
||||
|
||||
set(SHARED_HDR
|
||||
../../src/ByteBuffer.h
|
||||
../../src/StringUtils.h
|
||||
../../src/LoggerListeners.h
|
||||
../../src/Logger.h
|
||||
../../src/WorldStorage/FastNBT.h
|
||||
../BiomeVisualiser/BiomeColors.h
|
||||
)
|
||||
|
||||
set(SHARED_OSS_SRC
|
||||
../../src/OSSupport/CriticalSection.cpp
|
||||
../../src/OSSupport/Event.cpp
|
||||
../../src/OSSupport/File.cpp
|
||||
../../src/OSSupport/GZipFile.cpp
|
||||
../../src/OSSupport/IsThread.cpp
|
||||
../../src/OSSupport/Timer.cpp
|
||||
)
|
||||
|
||||
set(SHARED_OSS_HDR
|
||||
../../src/OSSupport/CriticalSection.h
|
||||
../../src/OSSupport/Event.h
|
||||
../../src/OSSupport/File.h
|
||||
../../src/OSSupport/GZipFile.h
|
||||
../../src/OSSupport/IsThread.h
|
||||
../../src/OSSupport/Timer.h
|
||||
)
|
||||
|
||||
flatten_files(SHARED_SRC)
|
||||
flatten_files(SHARED_HDR)
|
||||
flatten_files(SHARED_OSS_SRC)
|
||||
flatten_files(SHARED_OSS_HDR)
|
||||
source_group("Shared" FILES ${SHARED_SRC} ${SHARED_HDR})
|
||||
source_group("Shared\\OSSupport" FILES ${SHARED_OSS_SRC} ${SHARED_OSS_HDR})
|
||||
|
||||
|
||||
|
||||
# Include the main source files:
|
||||
set(SOURCES
|
||||
AnvilStats.cpp
|
||||
BiomeMap.cpp
|
||||
ChunkExtract.cpp
|
||||
Globals.cpp
|
||||
HeightBiomeMap.cpp
|
||||
HeightMap.cpp
|
||||
ImageComposingCallback.cpp
|
||||
Processor.cpp
|
||||
SpringStats.cpp
|
||||
Statistics.cpp
|
||||
Utils.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
BiomeMap.h
|
||||
Callback.h
|
||||
ChunkExtract.h
|
||||
Globals.h
|
||||
HeightBiomeMap.h
|
||||
HeightMap.h
|
||||
ImageComposingCallback.h
|
||||
Processor.h
|
||||
SpringStats.h
|
||||
Statistics.h
|
||||
Utils.h
|
||||
|
||||
AnvilStats.txt
|
||||
)
|
||||
|
||||
source_group("" FILES ${SOURCES} ${HEADERS})
|
||||
|
||||
add_definitions(-DNBT_RESERVE_SIZE=10000)
|
||||
|
||||
add_executable(AnvilStats
|
||||
${SOURCES}
|
||||
${HEADERS}
|
||||
${SHARED_SRC}
|
||||
${SHARED_HDR}
|
||||
${SHARED_OSS_SRC}
|
||||
${SHARED_OSS_HDR}
|
||||
)
|
||||
|
||||
|
||||
target_link_libraries(AnvilStats zlib)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Under MSVC we need to enlarge the default stack size for the executable:
|
||||
if (MSVC)
|
||||
get_target_property(TEMP AnvilStats LINK_FLAGS)
|
||||
if (TEMP STREQUAL "TEMP-NOTFOUND")
|
||||
SET(TEMP "") # set to empty string
|
||||
message("LINKER_FLAGS not found")
|
||||
else ()
|
||||
SET(TEMP "${TEMP} ") # a space to cleanly separate from existing content
|
||||
message("LINKER_FLAGS: ${LINKER_FLAGS}")
|
||||
endif ()
|
||||
# append our values
|
||||
SET(TEMP "${TEMP}/STACK:16777216")
|
||||
set_target_properties(AnvilStats PROPERTIES LINK_FLAGS ${TEMP})
|
||||
endif ()
|
||||
|
||||
|
||||
|
@ -241,6 +241,17 @@ public:
|
||||
|
||||
|
||||
|
||||
/** Clamp value to the specified range. */
|
||||
template <typename T>
|
||||
T Clamp(T a_Value, T a_Min, T a_Max)
|
||||
{
|
||||
return (a_Value < a_Min) ? a_Min : ((a_Value > a_Max) ? a_Max : a_Value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Common headers (part 2, with macros):
|
||||
#include "../../src/ChunkDef.h"
|
||||
#include "../../src/BlockID.h"
|
||||
|
@ -28,6 +28,7 @@ cProcessor::cThread::cThread(cCallback & a_Callback, cProcessor & a_ParentProces
|
||||
m_Callback(a_Callback),
|
||||
m_ParentProcessor(a_ParentProcessor)
|
||||
{
|
||||
LOG("Created a new thread: %p", this);
|
||||
super::Start();
|
||||
}
|
||||
|
||||
@ -35,11 +36,20 @@ cProcessor::cThread::cThread(cCallback & a_Callback, cProcessor & a_ParentProces
|
||||
|
||||
|
||||
|
||||
void cProcessor::cThread::WaitForStart(void)
|
||||
{
|
||||
m_HasStarted.Wait();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProcessor::cThread::Execute(void)
|
||||
{
|
||||
LOG("Started a new thread: %d", cIsThread::GetCurrentID());
|
||||
LOG("Started a new thread: %p, ID %d", this, cIsThread::GetCurrentID());
|
||||
|
||||
m_ParentProcessor.m_ThreadsHaveStarted.Set();
|
||||
m_HasStarted.Set();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
@ -52,7 +62,7 @@ void cProcessor::cThread::Execute(void)
|
||||
ProcessFile(FileName);
|
||||
} // for-ever
|
||||
|
||||
LOG("Thread %d terminated", cIsThread::GetCurrentID());
|
||||
LOG("Thread %p (ID %d) terminated", this, cIsThread::GetCurrentID());
|
||||
}
|
||||
|
||||
|
||||
@ -522,20 +532,18 @@ void cProcessor::ProcessWorld(const AString & a_WorldFolder, cCallbackFactory &
|
||||
#endif // _DEBUG
|
||||
//*/
|
||||
|
||||
// Start all the threads:
|
||||
for (int i = 0; i < NumThreads; i++)
|
||||
{
|
||||
cCallback * Callback = a_CallbackFactory.GetNewCallback();
|
||||
m_Threads.push_back(new cThread(*Callback, *this));
|
||||
}
|
||||
|
||||
// Wait for the first thread to start processing:
|
||||
m_ThreadsHaveStarted.Wait();
|
||||
|
||||
// Wait for all threads to finish
|
||||
// simply by calling each thread's destructor sequentially
|
||||
// Wait for all threads to finish:
|
||||
LOG("Waiting for threads to finish");
|
||||
for (cThreads::iterator itr = m_Threads.begin(), end = m_Threads.end(); itr != end; ++itr)
|
||||
{
|
||||
(*itr)->WaitForStart();
|
||||
delete *itr;
|
||||
} // for itr - m_Threads[]
|
||||
LOG("Processor finished");
|
||||
|
@ -30,6 +30,7 @@ class cProcessor
|
||||
|
||||
cCallback & m_Callback;
|
||||
cProcessor & m_ParentProcessor;
|
||||
cEvent m_HasStarted;
|
||||
|
||||
// cIsThread override:
|
||||
virtual void Execute(void) override;
|
||||
@ -48,6 +49,9 @@ class cProcessor
|
||||
|
||||
public:
|
||||
cThread(cCallback & a_Callback, cProcessor & a_ParentProcessor);
|
||||
|
||||
/** Waits until the thread starts processing the callback code. */
|
||||
void WaitForStart(void);
|
||||
} ;
|
||||
|
||||
typedef std::vector<cThread *> cThreads;
|
||||
@ -65,10 +69,12 @@ protected:
|
||||
AStringList m_FileQueue;
|
||||
|
||||
cThreads m_Threads;
|
||||
cEvent m_ThreadsHaveStarted; // This is signalled by each thread to notify the parent thread that it can start waiting for those threads
|
||||
|
||||
|
||||
/** Populates m_FileQueue with Anvil files from the specified folder. */
|
||||
void PopulateFileQueue(const AString & a_WorldFolder);
|
||||
|
||||
/** Returns one filename from m_FileQueue, and removes the name from the queue. */
|
||||
AString GetOneFileName(void);
|
||||
} ;
|
||||
|
||||
|
@ -28,6 +28,8 @@ cStatistics::cStats::cStats(void) :
|
||||
{
|
||||
memset(m_BiomeCounts, 0, sizeof(m_BiomeCounts));
|
||||
memset(m_BlockCounts, 0, sizeof(m_BlockCounts));
|
||||
memset(m_PerHeightBlockCounts, 0, sizeof(m_PerHeightBlockCounts));
|
||||
memset(m_PerHeightSpawners, 0, sizeof(m_PerHeightSpawners));
|
||||
memset(m_SpawnerEntity, 0, sizeof(m_SpawnerEntity));
|
||||
}
|
||||
|
||||
@ -46,6 +48,11 @@ void cStatistics::cStats::Add(const cStatistics::cStats & a_Stats)
|
||||
for (int j = 0; j <= 255; j++)
|
||||
{
|
||||
m_BlockCounts[i][j] += a_Stats.m_BlockCounts[i][j];
|
||||
m_PerHeightBlockCounts[i][j] += a_Stats.m_PerHeightBlockCounts[i][j];
|
||||
}
|
||||
for (int j = 0; j < ARRAYCOUNT(m_PerHeightSpawners[0]); j++)
|
||||
{
|
||||
m_PerHeightSpawners[i][j] += a_Stats.m_PerHeightSpawners[i][j];
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < ARRAYCOUNT(m_SpawnerEntity); i++)
|
||||
@ -149,6 +156,7 @@ bool cStatistics::OnSection
|
||||
|
||||
for (int y = 0; y < 16; y++)
|
||||
{
|
||||
int Height = (int)a_Y * 16 + y;
|
||||
for (int z = 0; z < 16; z++)
|
||||
{
|
||||
for (int x = 0; x < 16; x++)
|
||||
@ -156,6 +164,7 @@ bool cStatistics::OnSection
|
||||
unsigned char Biome = m_BiomeData[x + 16 * z]; // Cannot use cChunkDef, different datatype
|
||||
unsigned char BlockType = cChunkDef::GetBlock(a_BlockTypes, x, y, z);
|
||||
m_Stats.m_BlockCounts[Biome][BlockType] += 1;
|
||||
m_Stats.m_PerHeightBlockCounts[Height][BlockType] += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -259,16 +268,27 @@ bool cStatistics::OnTileTick(
|
||||
|
||||
void cStatistics::OnSpawner(cParsedNBT & a_NBT, int a_TileEntityTag)
|
||||
{
|
||||
// Get the spawned entity type:
|
||||
int EntityIDTag = a_NBT.FindChildByName(a_TileEntityTag, "EntityId");
|
||||
if ((EntityIDTag < 0) || (a_NBT.GetType(EntityIDTag) != TAG_String))
|
||||
{
|
||||
return;
|
||||
}
|
||||
eEntityType Ent = GetEntityType(a_NBT.GetString(EntityIDTag));
|
||||
if (Ent < ARRAYCOUNT(m_Stats.m_SpawnerEntity))
|
||||
if (Ent >= ARRAYCOUNT(m_Stats.m_SpawnerEntity))
|
||||
{
|
||||
m_Stats.m_SpawnerEntity[Ent] += 1;
|
||||
return;
|
||||
}
|
||||
m_Stats.m_SpawnerEntity[Ent] += 1;
|
||||
|
||||
// Get the spawner pos:
|
||||
int PosYTag = a_NBT.FindChildByName(a_TileEntityTag, "y");
|
||||
if ((PosYTag < 0) || (a_NBT.GetType(PosYTag) != TAG_Int))
|
||||
{
|
||||
return;
|
||||
}
|
||||
int BlockY = Clamp(a_NBT.GetInt(PosYTag), 0, 255);
|
||||
m_Stats.m_PerHeightSpawners[BlockY][Ent] += 1;
|
||||
}
|
||||
|
||||
|
||||
@ -316,10 +336,14 @@ cStatisticsFactory::~cStatisticsFactory()
|
||||
SaveBiomes();
|
||||
LOG(" BlockTypes.xls");
|
||||
SaveBlockTypes();
|
||||
LOG(" PerHeightBlockTypes.xls");
|
||||
SavePerHeightBlockTypes();
|
||||
LOG(" BiomeBlockTypes.xls");
|
||||
SaveBiomeBlockTypes();
|
||||
LOG(" Spawners.xls");
|
||||
SaveSpawners();
|
||||
LOG(" PerHeightSpawners.xls");
|
||||
SavePerHeightSpawners();
|
||||
}
|
||||
|
||||
|
||||
@ -395,6 +419,61 @@ void cStatisticsFactory::SaveBlockTypes(void)
|
||||
|
||||
|
||||
|
||||
void cStatisticsFactory::SavePerHeightBlockTypes(void)
|
||||
{
|
||||
// Export as two tables: biomes 0-127 and 128-255, because OpenOffice doesn't support more than 256 columns
|
||||
|
||||
cFile f;
|
||||
if (!f.Open("PerHeightBlockTypes.xls", cFile::fmWrite))
|
||||
{
|
||||
LOG("Cannot write to file PerHeightBlockTypes.xls. Statistics not written.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Write header:
|
||||
f.Printf("Blocks 0 - 127:\nHeight");
|
||||
for (int i = 0; i < 128; i++)
|
||||
{
|
||||
f.Printf("\t%s(%d)", GetBlockTypeString(i), i);
|
||||
}
|
||||
f.Printf("\n");
|
||||
|
||||
// Write first half:
|
||||
for (int y = 0; y < 256; y++)
|
||||
{
|
||||
f.Printf("%d", y);
|
||||
for (int BlockType = 0; BlockType < 128; BlockType++)
|
||||
{
|
||||
f.Printf("\t%llu", m_CombinedStats.m_PerHeightBlockCounts[y][BlockType]);
|
||||
} // for BlockType
|
||||
f.Printf("\n");
|
||||
} // for y - height (0 - 127)
|
||||
f.Printf("\n");
|
||||
|
||||
// Write second header:
|
||||
f.Printf("Blocks 128 - 255:\nHeight");
|
||||
for (int i = 128; i < 256; i++)
|
||||
{
|
||||
f.Printf("\t%s(%d)", GetBlockTypeString(i), i);
|
||||
}
|
||||
f.Printf("\n");
|
||||
|
||||
// Write second half:
|
||||
for (int y = 0; y < 256; y++)
|
||||
{
|
||||
f.Printf("%d", y);
|
||||
for (int BlockType = 128; BlockType < 256; BlockType++)
|
||||
{
|
||||
f.Printf("\t%llu", m_CombinedStats.m_PerHeightBlockCounts[y][BlockType]);
|
||||
} // for BlockType
|
||||
f.Printf("\n");
|
||||
} // for y - height (0 - 127)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cStatisticsFactory::SaveBiomeBlockTypes(void)
|
||||
{
|
||||
// Export as two tables: biomes 0-127 and 128-255, because OpenOffice doesn't support more than 256 columns
|
||||
@ -521,3 +600,41 @@ void cStatisticsFactory::SaveSpawners(void)
|
||||
|
||||
|
||||
|
||||
|
||||
void cStatisticsFactory::SavePerHeightSpawners(void)
|
||||
{
|
||||
cFile f;
|
||||
if (!f.Open("PerHeightSpawners.xls", cFile::fmWrite))
|
||||
{
|
||||
LOG("Cannot write to file PerHeightSpawners.xls. Statistics not written.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Write header:
|
||||
f.Printf("Height\tTotal");
|
||||
for (int i = 0; i < entMax; i++)
|
||||
{
|
||||
f.Printf("\t%s", GetEntityTypeString((eEntityType)i));
|
||||
}
|
||||
f.Printf("\n");
|
||||
|
||||
// Write individual lines:
|
||||
for (int y = 0; y < 256; y++)
|
||||
{
|
||||
UInt64 Total = 0;
|
||||
for (int i = 0; i < entMax; i++)
|
||||
{
|
||||
Total += m_CombinedStats.m_PerHeightSpawners[y][i];
|
||||
}
|
||||
f.Printf("%d\t%llu", y, Total);
|
||||
for (int i = 0; i < entMax; i++)
|
||||
{
|
||||
f.Printf("\t%llu", m_CombinedStats.m_PerHeightSpawners[y][i]);
|
||||
}
|
||||
f.Printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -31,6 +31,8 @@ public:
|
||||
UInt64 m_NumEntities;
|
||||
UInt64 m_NumTileEntities;
|
||||
UInt64 m_NumTileTicks;
|
||||
UInt64 m_PerHeightBlockCounts[256][256]; // First dimension is the height, second dimension is BlockType
|
||||
UInt64 m_PerHeightSpawners[256][entMax + 1]; // First dimension is the height, second dimension is spawned entity type
|
||||
int m_MinChunkX, m_MaxChunkX; // X coords range
|
||||
int m_MinChunkZ, m_MaxChunkZ; // Z coords range
|
||||
|
||||
@ -74,6 +76,8 @@ protected:
|
||||
|
||||
virtual bool OnEmptySection(unsigned char a_Y) override;
|
||||
|
||||
virtual bool OnSectionsFinished(void) override { return false; } // continue processing
|
||||
|
||||
virtual bool OnEntity(
|
||||
const AString & a_EntityType,
|
||||
double a_PosX, double a_PosY, double a_PosZ,
|
||||
@ -128,9 +132,11 @@ protected:
|
||||
void JoinResults(void);
|
||||
void SaveBiomes(void);
|
||||
void SaveBlockTypes(void);
|
||||
void SavePerHeightBlockTypes(void);
|
||||
void SaveBiomeBlockTypes(void);
|
||||
void SaveStatistics(void);
|
||||
void SaveSpawners(void);
|
||||
void SavePerHeightSpawners(void);
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -272,7 +272,7 @@ extern const char * GetEntityTypeString(eEntityType a_EntityType)
|
||||
int GetNumCores(void)
|
||||
{
|
||||
// Get number of cores by querying the system process affinity mask (Windows-specific)
|
||||
DWORD Affinity, ProcAffinity;
|
||||
DWORD_PTR Affinity, ProcAffinity;
|
||||
GetProcessAffinityMask(GetCurrentProcess(), &ProcAffinity, &Affinity);
|
||||
int NumCores = 0;
|
||||
while (Affinity > 0)
|
||||
|
@ -39,14 +39,12 @@ set_exe_flags()
|
||||
set(SHARED_SRC
|
||||
../../src/StringCompression.cpp
|
||||
../../src/StringUtils.cpp
|
||||
../../src/Log.cpp
|
||||
../../src/MCLogger.cpp
|
||||
../../src/LoggerListeners.cpp
|
||||
../../src/Logger.cpp
|
||||
)
|
||||
set(SHARED_HDR
|
||||
../../src/ByteBuffer.h
|
||||
../../src/StringUtils.h
|
||||
../../src/Log.h
|
||||
../../src/MCLogger.h
|
||||
)
|
||||
flatten_files(SHARED_SRC)
|
||||
flatten_files(SHARED_HDR)
|
||||
|
@ -5,7 +5,8 @@
|
||||
|
||||
#include "Globals.h"
|
||||
#include "MCADefrag.h"
|
||||
#include "MCLogger.h"
|
||||
#include "Logger.h"
|
||||
#include "LoggerListeners.h"
|
||||
#include "zlib/zlib.h"
|
||||
|
||||
|
||||
@ -21,7 +22,13 @@ static const Byte g_Zeroes[4096] = {0};
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
new cMCLogger(Printf("Defrag_%08x.log", time(NULL)));
|
||||
cLogger::cListener * consoleLogListener = MakeConsoleListener();
|
||||
cLogger::cListener * fileLogListener = new cFileListener();
|
||||
cLogger::GetInstance().AttachListener(consoleLogListener);
|
||||
cLogger::GetInstance().AttachListener(fileLogListener);
|
||||
|
||||
cLogger::InitiateMultithreading();
|
||||
|
||||
cMCADefrag Defrag;
|
||||
if (!Defrag.Init(argc, argv))
|
||||
{
|
||||
@ -30,6 +37,11 @@ int main(int argc, char ** argv)
|
||||
|
||||
Defrag.Run();
|
||||
|
||||
cLogger::GetInstance().DetachListener(consoleLogListener);
|
||||
delete consoleLogListener;
|
||||
cLogger::GetInstance().DetachListener(fileLogListener);
|
||||
delete fileLogListener;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -34,20 +34,18 @@ set_exe_flags()
|
||||
set(SHARED_SRC
|
||||
../../src/ByteBuffer.cpp
|
||||
../../src/StringUtils.cpp
|
||||
../../src/Log.cpp
|
||||
../../src/MCLogger.cpp
|
||||
../../src/PolarSSL++/AesCfb128Decryptor.cpp
|
||||
../../src/PolarSSL++/AesCfb128Encryptor.cpp
|
||||
../../src/PolarSSL++/CryptoKey.cpp
|
||||
../../src/PolarSSL++/CtrDrbgContext.cpp
|
||||
../../src/PolarSSL++/EntropyContext.cpp
|
||||
../../src/PolarSSL++/RsaPrivateKey.cpp
|
||||
../../src/LoggerListeners.cpp
|
||||
../../src/Logger.cpp
|
||||
)
|
||||
set(SHARED_HDR
|
||||
../../src/ByteBuffer.h
|
||||
../../src/StringUtils.h
|
||||
../../src/Log.h
|
||||
../../src/MCLogger.h
|
||||
../../src/PolarSSL++/AesCfb128Decryptor.h
|
||||
../../src/PolarSSL++/AesCfb128Encryptor.h
|
||||
../../src/PolarSSL++/CryptoKey.h
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "../../../lua/src/lauxlib.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
TOLUA_API void tolua_pushvalue (lua_State* L, int lo)
|
||||
{
|
||||
@ -55,9 +56,11 @@ TOLUA_API void tolua_pushusertype (lua_State* L, void* value, const char* type)
|
||||
else
|
||||
{
|
||||
luaL_getmetatable(L, type);
|
||||
assert(!lua_isnil(L, -1)); /* Failure here means that the usertype is unknown to ToLua. Check what type you're pushing. */
|
||||
lua_pushstring(L,"tolua_ubox");
|
||||
lua_rawget(L,-2); /* stack: mt ubox */
|
||||
if (lua_isnil(L, -1)) {
|
||||
if (lua_isnil(L, -1))
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
lua_pushstring(L, "tolua_ubox");
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
template<class T>
|
||||
template <class T>
|
||||
class cAllocationPool
|
||||
{
|
||||
public:
|
||||
@ -34,7 +34,7 @@ public:
|
||||
|
||||
/** Allocates memory storing unused elements in a linked list. Keeps at least NumElementsInReserve
|
||||
elements in the list unless malloc fails so that the program has a reserve to handle OOM.**/
|
||||
template<class T, size_t NumElementsInReserve>
|
||||
template <class T, size_t NumElementsInReserve>
|
||||
class cListAllocationPool : public cAllocationPool<T>
|
||||
{
|
||||
public:
|
||||
|
@ -67,7 +67,6 @@ $cfile "../Root.h"
|
||||
$cfile "../Cuboid.h"
|
||||
$cfile "../BoundingBox.h"
|
||||
$cfile "../Tracer.h"
|
||||
$cfile "../Group.h"
|
||||
$cfile "../BlockArea.h"
|
||||
$cfile "../Generating/ChunkDesc.h"
|
||||
$cfile "../CraftingRecipes.h"
|
||||
|
@ -11,6 +11,7 @@ SET (SRCS
|
||||
LuaState.cpp
|
||||
LuaWindow.cpp
|
||||
ManualBindings.cpp
|
||||
ManualBindings_RankManager.cpp
|
||||
Plugin.cpp
|
||||
PluginLua.cpp
|
||||
PluginManager.cpp
|
||||
@ -45,7 +46,6 @@ set(BINDING_DEPENDENCIES
|
||||
../Bindings/AllToLua.pkg
|
||||
../Bindings/gen_LuaState_Call.lua
|
||||
../Bindings/LuaFunctions.h
|
||||
../Bindings/LuaState_Call.inc
|
||||
../Bindings/LuaWindow.h
|
||||
../Bindings/Plugin.h
|
||||
../Bindings/PluginLua.h
|
||||
@ -97,7 +97,6 @@ set(BINDING_DEPENDENCIES
|
||||
../Entities/HangingEntity.h
|
||||
../Entities/ItemFrame.h
|
||||
../Generating/ChunkDesc.h
|
||||
../Group.h
|
||||
../Inventory.h
|
||||
../Item.h
|
||||
../ItemGrid.h
|
||||
@ -128,6 +127,7 @@ if (NOT MSVC)
|
||||
endif ()
|
||||
set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.cpp PROPERTIES GENERATED TRUE)
|
||||
set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/Bindings.h PROPERTIES GENERATED TRUE)
|
||||
set_source_files_properties(${CMAKE_SOURCE_DIR}/src/Bindings/LuaState_Call.inc PROPERTIES GENERATED TRUE)
|
||||
|
||||
if(NOT MSVC)
|
||||
add_library(Bindings ${SRCS} ${HDRS})
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "../MCLogger.h"
|
||||
#include "Logger.h"
|
||||
#include <time.h>
|
||||
// tolua_begin
|
||||
|
||||
|
@ -460,7 +460,43 @@ void cLuaState::Push(const Vector3d & a_Vector)
|
||||
{
|
||||
ASSERT(IsValid());
|
||||
|
||||
tolua_pushusertype(m_LuaState, (void *)&a_Vector, "Vector3d");
|
||||
tolua_pushusertype(m_LuaState, (void *)&a_Vector, "Vector3<double>");
|
||||
m_NumCurrentFunctionArgs += 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cLuaState::Push(const Vector3d * a_Vector)
|
||||
{
|
||||
ASSERT(IsValid());
|
||||
|
||||
tolua_pushusertype(m_LuaState, (void *)a_Vector, "Vector3<double>");
|
||||
m_NumCurrentFunctionArgs += 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cLuaState::Push(const Vector3i & a_Vector)
|
||||
{
|
||||
ASSERT(IsValid());
|
||||
|
||||
tolua_pushusertype(m_LuaState, (void *)&a_Vector, "Vector3<int>");
|
||||
m_NumCurrentFunctionArgs += 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cLuaState::Push(const Vector3i * a_Vector)
|
||||
{
|
||||
ASSERT(IsValid());
|
||||
|
||||
tolua_pushusertype(m_LuaState, (void *)a_Vector, "Vector3<int>");
|
||||
m_NumCurrentFunctionArgs += 1;
|
||||
}
|
||||
|
||||
@ -708,11 +744,11 @@ void cLuaState::Push(TakeDamageInfo * a_TDI)
|
||||
|
||||
|
||||
|
||||
void cLuaState::Push(Vector3i * a_Vector)
|
||||
void cLuaState::Push(Vector3d * a_Vector)
|
||||
{
|
||||
ASSERT(IsValid());
|
||||
|
||||
tolua_pushusertype(m_LuaState, a_Vector, "Vector3i");
|
||||
tolua_pushusertype(m_LuaState, a_Vector, "Vector3<double>");
|
||||
m_NumCurrentFunctionArgs += 1;
|
||||
}
|
||||
|
||||
@ -720,11 +756,11 @@ void cLuaState::Push(Vector3i * a_Vector)
|
||||
|
||||
|
||||
|
||||
void cLuaState::Push(Vector3d * a_Vector)
|
||||
void cLuaState::Push(Vector3i * a_Vector)
|
||||
{
|
||||
ASSERT(IsValid());
|
||||
|
||||
tolua_pushusertype(m_LuaState, a_Vector, "Vector3d");
|
||||
tolua_pushusertype(m_LuaState, a_Vector, "Vector3<int>");
|
||||
m_NumCurrentFunctionArgs += 1;
|
||||
}
|
||||
|
||||
|
@ -186,6 +186,9 @@ public:
|
||||
void Push(const HTTPRequest * a_Request);
|
||||
void Push(const HTTPTemplateRequest * a_Request);
|
||||
void Push(const Vector3d & a_Vector);
|
||||
void Push(const Vector3d * a_Vector);
|
||||
void Push(const Vector3i & a_Vector);
|
||||
void Push(const Vector3i * a_Vector);
|
||||
|
||||
// Push a value onto the stack (keep alpha-sorted):
|
||||
void Push(bool a_Value);
|
||||
|
@ -82,6 +82,33 @@ static int lua_do_error(lua_State* L, const char * a_pFormat, ...)
|
||||
|
||||
|
||||
// Lua bound functions with special return types
|
||||
static int tolua_Clamp(lua_State * tolua_S)
|
||||
{
|
||||
cLuaState LuaState(tolua_S);
|
||||
int NumArgs = lua_gettop(LuaState);
|
||||
if (NumArgs != 3)
|
||||
{
|
||||
return lua_do_error(LuaState, "Error in function call '#funcname#': Requires 3 arguments, got %i", NumArgs);
|
||||
}
|
||||
|
||||
if (!lua_isnumber(LuaState, 1) || !lua_isnumber(LuaState, 2) || !lua_isnumber(LuaState, 3))
|
||||
{
|
||||
return lua_do_error(LuaState, "Error in function call '#funcname#': Expected a number for parameters #1, #2 and #3");
|
||||
}
|
||||
|
||||
lua_Number Number = tolua_tonumber(LuaState, 1, 0);
|
||||
lua_Number Min = tolua_tonumber(LuaState, 2, 0);
|
||||
lua_Number Max = tolua_tonumber(LuaState, 3, 0);
|
||||
|
||||
lua_Number Result = Clamp(Number, Min, Max);
|
||||
LuaState.Push(Result);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_StringSplit(lua_State * tolua_S)
|
||||
{
|
||||
cLuaState LuaState(tolua_S);
|
||||
@ -141,7 +168,7 @@ static AString GetLogMessage(lua_State * tolua_S)
|
||||
static int tolua_LOG(lua_State * tolua_S)
|
||||
{
|
||||
// If the param is a cCompositeChat, read the log level from it:
|
||||
cMCLogger::eLogLevel LogLevel = cMCLogger::llRegular;
|
||||
cLogger::eLogLevel LogLevel = cLogger::llRegular;
|
||||
tolua_Error err;
|
||||
if (tolua_isusertype(tolua_S, 1, "cCompositeChat", false, &err))
|
||||
{
|
||||
@ -149,7 +176,7 @@ static int tolua_LOG(lua_State * tolua_S)
|
||||
}
|
||||
|
||||
// Log the message:
|
||||
cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), LogLevel);
|
||||
cLogger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), LogLevel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -159,7 +186,7 @@ static int tolua_LOG(lua_State * tolua_S)
|
||||
|
||||
static int tolua_LOGINFO(lua_State * tolua_S)
|
||||
{
|
||||
cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), cMCLogger::llInfo);
|
||||
cLogger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), cLogger::llInfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -169,7 +196,7 @@ static int tolua_LOGINFO(lua_State * tolua_S)
|
||||
|
||||
static int tolua_LOGWARN(lua_State * tolua_S)
|
||||
{
|
||||
cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), cMCLogger::llWarning);
|
||||
cLogger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), cLogger::llWarning);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -179,7 +206,7 @@ static int tolua_LOGWARN(lua_State * tolua_S)
|
||||
|
||||
static int tolua_LOGERROR(lua_State * tolua_S)
|
||||
{
|
||||
cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), cMCLogger::llError);
|
||||
cLogger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), cLogger::llError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -274,11 +301,11 @@ static int tolua_cFile_GetFolderContents(lua_State * tolua_S)
|
||||
|
||||
|
||||
|
||||
template<
|
||||
template <
|
||||
class Ty1,
|
||||
class Ty2,
|
||||
bool (Ty1::*Func1)(const AString &, cItemCallback<Ty2> &)
|
||||
>
|
||||
>
|
||||
static int tolua_DoWith(lua_State* tolua_S)
|
||||
{
|
||||
int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */
|
||||
@ -368,7 +395,7 @@ static int tolua_DoWith(lua_State* tolua_S)
|
||||
|
||||
|
||||
|
||||
template<
|
||||
template <
|
||||
class Ty1,
|
||||
class Ty2,
|
||||
bool (Ty1::*Func1)(int, cItemCallback<Ty2> &)
|
||||
@ -458,7 +485,7 @@ static int tolua_DoWithID(lua_State* tolua_S)
|
||||
|
||||
|
||||
|
||||
template<
|
||||
template <
|
||||
class Ty1,
|
||||
class Ty2,
|
||||
bool (Ty1::*Func1)(int, int, int, cItemCallback<Ty2> &)
|
||||
@ -480,7 +507,6 @@ static int tolua_DoWithXYZ(lua_State* tolua_S)
|
||||
int ItemX = ((int)tolua_tonumber(tolua_S, 2, 0));
|
||||
int ItemY = ((int)tolua_tonumber(tolua_S, 3, 0));
|
||||
int ItemZ = ((int)tolua_tonumber(tolua_S, 4, 0));
|
||||
LOG("x %i y %i z %i", ItemX, ItemY, ItemZ);
|
||||
if (!lua_isfunction( tolua_S, 5))
|
||||
{
|
||||
return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a function for parameter #4");
|
||||
@ -554,7 +580,7 @@ static int tolua_DoWithXYZ(lua_State* tolua_S)
|
||||
|
||||
|
||||
|
||||
template<
|
||||
template <
|
||||
class Ty1,
|
||||
class Ty2,
|
||||
bool (Ty1::*Func1)(int, int, cItemCallback<Ty2> &)
|
||||
@ -650,7 +676,7 @@ static int tolua_ForEachInChunk(lua_State * tolua_S)
|
||||
|
||||
|
||||
|
||||
template<
|
||||
template <
|
||||
class Ty1,
|
||||
class Ty2,
|
||||
bool (Ty1::*Func1)(cItemCallback<Ty2> &)
|
||||
@ -1777,49 +1803,30 @@ static int tolua_cWorld_ChunkStay(lua_State * tolua_S)
|
||||
|
||||
|
||||
|
||||
static int tolua_cPlayer_GetGroups(lua_State * tolua_S)
|
||||
static int tolua_cPlayer_GetPermissions(lua_State * tolua_S)
|
||||
{
|
||||
// Function signature: cPlayer:GetPermissions() -> {permissions-array}
|
||||
|
||||
// Check the params:
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamUserType(1, "cPlayer") ||
|
||||
!L.CheckParamEnd (2)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
cPlayer * self = (cPlayer *)tolua_tousertype(tolua_S, 1, NULL);
|
||||
|
||||
const cPlayer::GroupList & AllGroups = self->GetGroups();
|
||||
|
||||
lua_createtable(tolua_S, (int)AllGroups.size(), 0);
|
||||
int newTable = lua_gettop(tolua_S);
|
||||
int index = 1;
|
||||
cPlayer::GroupList::const_iterator iter = AllGroups.begin();
|
||||
while (iter != AllGroups.end())
|
||||
if (self == NULL)
|
||||
{
|
||||
const cGroup * Group = *iter;
|
||||
tolua_pushusertype(tolua_S, (void *)Group, "const cGroup");
|
||||
lua_rawseti(tolua_S, newTable, index);
|
||||
++iter;
|
||||
++index;
|
||||
LOGWARNING("%s: invalid self (%p)", __FUNCTION__, self);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cPlayer_GetResolvedPermissions(lua_State * tolua_S)
|
||||
{
|
||||
cPlayer * self = (cPlayer*) tolua_tousertype(tolua_S, 1, NULL);
|
||||
|
||||
cPlayer::StringList AllPermissions = self->GetResolvedPermissions();
|
||||
|
||||
lua_createtable(tolua_S, (int)AllPermissions.size(), 0);
|
||||
int newTable = lua_gettop(tolua_S);
|
||||
int index = 1;
|
||||
cPlayer::StringList::iterator iter = AllPermissions.begin();
|
||||
while (iter != AllPermissions.end())
|
||||
{
|
||||
std::string & Permission = *iter;
|
||||
lua_pushlstring(tolua_S, Permission.c_str(), Permission.length());
|
||||
lua_rawseti(tolua_S, newTable, index);
|
||||
++iter;
|
||||
++index;
|
||||
}
|
||||
// Push the permissions:
|
||||
L.Push(self->GetPermissions());
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1876,6 +1883,40 @@ static int tolua_cPlayer_OpenWindow(lua_State * tolua_S)
|
||||
|
||||
|
||||
|
||||
static int tolua_cPlayer_PermissionMatches(lua_State * tolua_S)
|
||||
{
|
||||
// Function signature: cPlayer:PermissionMatches(PermissionStr, TemplateStr) -> bool
|
||||
|
||||
// Check the params:
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamUserType(1, "cPlayer") ||
|
||||
!L.CheckParamString (2, 3) ||
|
||||
!L.CheckParamEnd (4)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
cPlayer * self = (cPlayer *)tolua_tousertype(tolua_S, 1, NULL);
|
||||
if (self == NULL)
|
||||
{
|
||||
LOGWARNING("%s: invalid self (%p)", __FUNCTION__, self);
|
||||
return 0;
|
||||
}
|
||||
AString Permission, Template;
|
||||
L.GetStackValues(2, Permission, Template);
|
||||
|
||||
// Push the result of the match:
|
||||
L.Push(self->PermissionMatches(StringSplit(Permission, "."), StringSplit(Template, ".")));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <
|
||||
class OBJTYPE,
|
||||
void (OBJTYPE::*SetCallback)(cPluginLua * a_Plugin, int a_FnRef)
|
||||
@ -2102,6 +2143,62 @@ static int tolua_cWebAdmin_GetPlugins(lua_State * tolua_S)
|
||||
|
||||
|
||||
|
||||
/** Binding for cWebAdmin::GetHTMLEscapedString.
|
||||
Manual code required because ToLua generates an extra return value */
|
||||
static int tolua_AllToLua_cWebAdmin_GetHTMLEscapedString(lua_State * tolua_S)
|
||||
{
|
||||
// Check the param types:
|
||||
cLuaState S(tolua_S);
|
||||
if (
|
||||
!S.CheckParamUserTable(1, "cWebAdmin") ||
|
||||
!S.CheckParamString(2) ||
|
||||
!S.CheckParamEnd(3)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the parameters:
|
||||
AString Input;
|
||||
S.GetStackValue(2, Input);
|
||||
|
||||
// Convert and return:
|
||||
S.Push(cWebAdmin::GetHTMLEscapedString(Input));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Binding for cWebAdmin::GetURLEncodedString.
|
||||
Manual code required because ToLua generates an extra return value */
|
||||
static int tolua_AllToLua_cWebAdmin_GetURLEncodedString(lua_State * tolua_S)
|
||||
{
|
||||
// Check the param types:
|
||||
cLuaState S(tolua_S);
|
||||
if (
|
||||
!S.CheckParamUserTable(1, "cWebAdmin") ||
|
||||
!S.CheckParamString(2) ||
|
||||
!S.CheckParamEnd(3)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the parameters:
|
||||
AString Input;
|
||||
S.GetStackValue(2, Input);
|
||||
|
||||
// Convert and return:
|
||||
S.Push(cWebAdmin::GetURLEncodedString(Input));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cWebPlugin_GetTabNames(lua_State * tolua_S)
|
||||
{
|
||||
cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S, 1, NULL);
|
||||
@ -2317,6 +2414,62 @@ static int tolua_cMojangAPI_GetUUIDsFromPlayerNames(lua_State * L)
|
||||
|
||||
|
||||
|
||||
static int tolua_cMojangAPI_MakeUUIDDashed(lua_State * L)
|
||||
{
|
||||
// Function signature: cMojangAPI:MakeUUIDDashed(UUID) -> string
|
||||
|
||||
// Check params:
|
||||
cLuaState S(L);
|
||||
if (
|
||||
!S.CheckParamUserTable(1, "cMojangAPI") ||
|
||||
!S.CheckParamString(2) ||
|
||||
!S.CheckParamEnd(3)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
AString UUID;
|
||||
S.GetStackValue(2, UUID);
|
||||
|
||||
// Push the result:
|
||||
S.Push(cRoot::Get()->GetMojangAPI().MakeUUIDDashed(UUID));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cMojangAPI_MakeUUIDShort(lua_State * L)
|
||||
{
|
||||
// Function signature: cMojangAPI:MakeUUIDShort(UUID) -> string
|
||||
|
||||
// Check params:
|
||||
cLuaState S(L);
|
||||
if (
|
||||
!S.CheckParamUserTable(1, "cMojangAPI") ||
|
||||
!S.CheckParamString(2) ||
|
||||
!S.CheckParamEnd(3)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
AString UUID;
|
||||
S.GetStackValue(2, UUID);
|
||||
|
||||
// Push the result:
|
||||
S.Push(cRoot::Get()->GetMojangAPI().MakeUUIDShort(UUID));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int Lua_ItemGrid_GetSlotCoords(lua_State * L)
|
||||
{
|
||||
tolua_Error tolua_err;
|
||||
@ -3103,6 +3256,7 @@ static int tolua_cCompositeChat_UnderlineUrls(lua_State * tolua_S)
|
||||
void ManualBindings::Bind(lua_State * tolua_S)
|
||||
{
|
||||
tolua_beginmodule(tolua_S, NULL);
|
||||
tolua_function(tolua_S, "Clamp", tolua_Clamp);
|
||||
tolua_function(tolua_S, "StringSplit", tolua_StringSplit);
|
||||
tolua_function(tolua_S, "StringSplitAndTrim", tolua_StringSplitAndTrim);
|
||||
tolua_function(tolua_S, "LOG", tolua_LOG);
|
||||
@ -3212,9 +3366,9 @@ void ManualBindings::Bind(lua_State * tolua_S)
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cPlayer");
|
||||
tolua_function(tolua_S, "GetGroups", tolua_cPlayer_GetGroups);
|
||||
tolua_function(tolua_S, "GetResolvedPermissions", tolua_cPlayer_GetResolvedPermissions);
|
||||
tolua_function(tolua_S, "GetPermissions", tolua_cPlayer_GetPermissions);
|
||||
tolua_function(tolua_S, "OpenWindow", tolua_cPlayer_OpenWindow);
|
||||
tolua_function(tolua_S, "PermissionMatches", tolua_cPlayer_PermissionMatches);
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cLuaWindow");
|
||||
@ -3237,7 +3391,9 @@ void ManualBindings::Bind(lua_State * tolua_S)
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cWebAdmin");
|
||||
tolua_function(tolua_S, "GetHTMLEscapedString", tolua_AllToLua_cWebAdmin_GetHTMLEscapedString);
|
||||
tolua_function(tolua_S, "GetPlugins", tolua_cWebAdmin_GetPlugins);
|
||||
tolua_function(tolua_S, "GetURLEncodedString", tolua_AllToLua_cWebAdmin_GetURLEncodedString);
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cWebPlugin");
|
||||
@ -3255,6 +3411,8 @@ void ManualBindings::Bind(lua_State * tolua_S)
|
||||
tolua_function(tolua_S, "GetPlayerNameFromUUID", tolua_cMojangAPI_GetPlayerNameFromUUID);
|
||||
tolua_function(tolua_S, "GetUUIDFromPlayerName", tolua_cMojangAPI_GetUUIDFromPlayerName);
|
||||
tolua_function(tolua_S, "GetUUIDsFromPlayerNames", tolua_cMojangAPI_GetUUIDsFromPlayerNames);
|
||||
tolua_function(tolua_S, "MakeUUIDDashed", tolua_cMojangAPI_MakeUUIDDashed);
|
||||
tolua_function(tolua_S, "MakeUUIDShort", tolua_cMojangAPI_MakeUUIDShort);
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cItemGrid");
|
||||
@ -3263,6 +3421,8 @@ void ManualBindings::Bind(lua_State * tolua_S)
|
||||
|
||||
tolua_function(tolua_S, "md5", tolua_md5);
|
||||
|
||||
BindRankManager(tolua_S);
|
||||
|
||||
tolua_endmodule(tolua_S);
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
struct lua_State;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Provides namespace for the bindings. */
|
||||
class ManualBindings
|
||||
{
|
||||
public:
|
||||
static void Bind( lua_State* tolua_S);
|
||||
/** Binds all the manually implemented functions to tolua_S. */
|
||||
static void Bind(lua_State * tolua_S);
|
||||
|
||||
protected:
|
||||
/** Binds the manually implemented cRankManager glue code to tolua_S.
|
||||
Implemented in ManualBindings_RankManager.cpp. */
|
||||
static void BindRankManager(lua_State * tolua_S);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
1007
src/Bindings/ManualBindings_RankManager.cpp
Normal file
1007
src/Bindings/ManualBindings_RankManager.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -73,7 +73,7 @@ public:
|
||||
virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) = 0;
|
||||
virtual bool OnPlayerJoined (cPlayer & a_Player) = 0;
|
||||
virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) = 0;
|
||||
virtual bool OnPlayerMoved (cPlayer & a_Player) = 0;
|
||||
virtual bool OnPlayerMoving (cPlayer & a_Player, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition) = 0;
|
||||
virtual bool OnPlayerPlacedBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0;
|
||||
virtual bool OnPlayerPlacingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0;
|
||||
virtual bool OnPlayerRightClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) = 0;
|
||||
@ -91,6 +91,7 @@ public:
|
||||
virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0;
|
||||
virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) = 0;
|
||||
virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) = 0;
|
||||
virtual bool OnServerPing (cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) = 0;
|
||||
virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) = 0;
|
||||
virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) = 0;
|
||||
virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) = 0;
|
||||
|
@ -835,14 +835,14 @@ bool cPluginLua::OnPlayerLeftClick(cPlayer & a_Player, int a_BlockX, int a_Block
|
||||
|
||||
|
||||
|
||||
bool cPluginLua::OnPlayerMoved(cPlayer & a_Player)
|
||||
bool cPluginLua::OnPlayerMoving(cPlayer & a_Player, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition)
|
||||
{
|
||||
cCSLock Lock(m_CriticalSection);
|
||||
bool res = false;
|
||||
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLAYER_MOVING];
|
||||
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
|
||||
{
|
||||
m_LuaState.Call((int)(**itr), &a_Player, cLuaState::Return, res);
|
||||
m_LuaState.Call((int)(**itr), &a_Player, a_OldPosition, a_NewPosition, cLuaState::Return, res);
|
||||
if (res)
|
||||
{
|
||||
return true;
|
||||
@ -1193,6 +1193,26 @@ bool cPluginLua::OnProjectileHitEntity(cProjectileEntity & a_Projectile, cEntity
|
||||
|
||||
|
||||
|
||||
bool cPluginLua::OnServerPing(cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon)
|
||||
{
|
||||
cCSLock Lock(m_CriticalSection);
|
||||
bool res = false;
|
||||
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_SERVER_PING];
|
||||
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
|
||||
{
|
||||
m_LuaState.Call((int)(**itr), &a_ClientHandle, a_ServerDescription, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon, cLuaState::Return, res, a_ServerDescription, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon);
|
||||
if (res)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPluginLua::OnSpawnedEntity(cWorld & a_World, cEntity & a_Entity)
|
||||
{
|
||||
cCSLock Lock(m_CriticalSection);
|
||||
@ -1570,6 +1590,7 @@ const char * cPluginLua::GetHookFnName(int a_HookType)
|
||||
case cPluginManager::HOOK_PLUGINS_LOADED: return "OnPluginsLoaded";
|
||||
case cPluginManager::HOOK_POST_CRAFTING: return "OnPostCrafting";
|
||||
case cPluginManager::HOOK_PRE_CRAFTING: return "OnPreCrafting";
|
||||
case cPluginManager::HOOK_SERVER_PING: return "OnServerPing";
|
||||
case cPluginManager::HOOK_SPAWNED_ENTITY: return "OnSpawnedEntity";
|
||||
case cPluginManager::HOOK_SPAWNED_MONSTER: return "OnSpawnedMonster";
|
||||
case cPluginManager::HOOK_SPAWNING_ENTITY: return "OnSpawningEntity";
|
||||
|
@ -98,8 +98,8 @@ public:
|
||||
virtual bool OnPlayerFishing (cPlayer & a_Player, cItems & a_Reward) override;
|
||||
virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) override;
|
||||
virtual bool OnPlayerJoined (cPlayer & a_Player) override;
|
||||
virtual bool OnPlayerMoved (cPlayer & a_Player) override;
|
||||
virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) override;
|
||||
virtual bool OnPlayerMoving (cPlayer & a_Player, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition) override;
|
||||
virtual bool OnPlayerPlacedBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
|
||||
virtual bool OnPlayerPlacingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
|
||||
virtual bool OnPlayerRightClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override;
|
||||
@ -117,6 +117,7 @@ public:
|
||||
virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override;
|
||||
virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) override;
|
||||
virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) override;
|
||||
virtual bool OnServerPing (cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) override;
|
||||
virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) override;
|
||||
virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) override;
|
||||
virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) override;
|
||||
|
@ -849,14 +849,14 @@ bool cPluginManager::CallHookPlayerLeftClick(cPlayer & a_Player, int a_BlockX, i
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::CallHookPlayerMoving(cPlayer & a_Player)
|
||||
bool cPluginManager::CallHookPlayerMoving(cPlayer & a_Player, const Vector3d a_OldPosition, const Vector3d a_NewPosition)
|
||||
{
|
||||
FIND_HOOK(HOOK_PLAYER_MOVING);
|
||||
VERIFY_HOOK;
|
||||
|
||||
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->OnPlayerMoved(a_Player))
|
||||
if ((*itr)->OnPlayerMoving(a_Player, a_OldPosition, a_NewPosition))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -1189,6 +1189,25 @@ bool cPluginManager::CallHookProjectileHitEntity(cProjectileEntity & a_Projectil
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::CallHookServerPing(cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon)
|
||||
{
|
||||
FIND_HOOK(HOOK_SERVER_PING);
|
||||
VERIFY_HOOK;
|
||||
|
||||
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->OnServerPing(a_ClientHandle, a_ServerDescription, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::CallHookSpawnedEntity(cWorld & a_World, cEntity & a_Entity)
|
||||
{
|
||||
FIND_HOOK(HOOK_SPAWNED_ENTITY);
|
||||
|
@ -120,6 +120,7 @@ public:
|
||||
HOOK_PRE_CRAFTING,
|
||||
HOOK_PROJECTILE_HIT_BLOCK,
|
||||
HOOK_PROJECTILE_HIT_ENTITY,
|
||||
HOOK_SERVER_PING,
|
||||
HOOK_SPAWNED_ENTITY,
|
||||
HOOK_SPAWNED_MONSTER,
|
||||
HOOK_SPAWNING_ENTITY,
|
||||
@ -206,7 +207,7 @@ public:
|
||||
bool CallHookPlayerFishing (cPlayer & a_Player, cItems a_Reward);
|
||||
bool CallHookPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel);
|
||||
bool CallHookPlayerJoined (cPlayer & a_Player);
|
||||
bool CallHookPlayerMoving (cPlayer & a_Player);
|
||||
bool CallHookPlayerMoving (cPlayer & a_Player, const Vector3d a_OldPosition, const Vector3d a_NewPosition);
|
||||
bool CallHookPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status);
|
||||
bool CallHookPlayerPlacedBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
|
||||
bool CallHookPlayerPlacingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
|
||||
@ -225,6 +226,7 @@ public:
|
||||
bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
|
||||
bool CallHookProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos);
|
||||
bool CallHookProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity);
|
||||
bool CallHookServerPing (cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon);
|
||||
bool CallHookSpawnedEntity (cWorld & a_World, cEntity & a_Entity);
|
||||
bool CallHookSpawnedMonster (cWorld & a_World, cMonster & a_Monster);
|
||||
bool CallHookSpawningEntity (cWorld & a_World, cEntity & a_Entity);
|
||||
|
@ -54,6 +54,7 @@ local Combinations =
|
||||
{9, 2},
|
||||
|
||||
-- Special combinations:
|
||||
{5, 5},
|
||||
{7, 3},
|
||||
{8, 3},
|
||||
{9, 5},
|
||||
@ -182,6 +183,33 @@ for _, combination in ipairs(Combinations) do
|
||||
WriteOverload(f, combination[1], combination[2])
|
||||
end
|
||||
|
||||
-- Generate the cLuaState::GetStackValues() multi-param templates:
|
||||
for i = 2, 6 do
|
||||
f:write("/** Reads ", i, " consecutive values off the stack */\ntemplate <\n")
|
||||
|
||||
-- Write the template function header:
|
||||
local txt = {}
|
||||
for idx = 1, i do
|
||||
table.insert(txt, "\ttypename ArgT" .. idx)
|
||||
end
|
||||
f:write(table.concat(txt, ",\n"))
|
||||
|
||||
-- Write the argument declarations:
|
||||
txt = {}
|
||||
f:write("\n>\nvoid GetStackValues(\n\tint a_BeginPos,\n")
|
||||
for idx = 1, i do
|
||||
table.insert(txt, "\tArgT" .. idx .. " & Arg" .. idx)
|
||||
end
|
||||
f:write(table.concat(txt, ",\n"))
|
||||
|
||||
-- Write the function body:
|
||||
f:write("\n)\n{\n")
|
||||
for idx = 1, i do
|
||||
f:write("\tGetStackValue(a_BeginPos + ", idx - 1, ", Arg", idx, ");\n")
|
||||
end
|
||||
f:write("}\n\n\n\n\n\n")
|
||||
end
|
||||
|
||||
-- Close the generated file
|
||||
f:close()
|
||||
|
||||
|
@ -28,7 +28,7 @@ typedef void (CombinatorFunc)(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLE
|
||||
|
||||
// This wild construct allows us to pass a function argument and still have it inlined by the compiler :)
|
||||
/// Merges two blocktypes and blockmetas of the specified sizes and offsets using the specified combinator function
|
||||
template<bool MetasValid, CombinatorFunc Combinator>
|
||||
template <bool MetasValid, CombinatorFunc Combinator>
|
||||
void InternalMergeBlocks(
|
||||
BLOCKTYPE * a_DstTypes, const BLOCKTYPE * a_SrcTypes,
|
||||
NIBBLETYPE * a_DstMetas, const NIBBLETYPE * a_SrcMetas,
|
||||
@ -74,7 +74,7 @@ void InternalMergeBlocks(
|
||||
|
||||
|
||||
/// Combinator used for cBlockArea::msOverwrite merging
|
||||
template<bool MetaValid>
|
||||
template <bool MetaValid>
|
||||
void MergeCombinatorOverwrite(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
||||
{
|
||||
a_DstType = a_SrcType;
|
||||
@ -89,7 +89,7 @@ void MergeCombinatorOverwrite(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLE
|
||||
|
||||
|
||||
/// Combinator used for cBlockArea::msFillAir merging
|
||||
template<bool MetaValid>
|
||||
template <bool MetaValid>
|
||||
void MergeCombinatorFillAir(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
||||
{
|
||||
if (a_DstType == E_BLOCK_AIR)
|
||||
@ -108,7 +108,7 @@ void MergeCombinatorFillAir(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETY
|
||||
|
||||
|
||||
/// Combinator used for cBlockArea::msImprint merging
|
||||
template<bool MetaValid>
|
||||
template <bool MetaValid>
|
||||
void MergeCombinatorImprint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
||||
{
|
||||
if (a_SrcType != E_BLOCK_AIR)
|
||||
@ -127,7 +127,7 @@ void MergeCombinatorImprint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETY
|
||||
|
||||
|
||||
/// Combinator used for cBlockArea::msLake merging
|
||||
template<bool MetaValid>
|
||||
template <bool MetaValid>
|
||||
void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
||||
{
|
||||
// Sponge is the NOP block
|
||||
@ -201,7 +201,7 @@ void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE
|
||||
|
||||
|
||||
/** Combinator used for cBlockArea::msSpongePrint merging */
|
||||
template<bool MetaValid>
|
||||
template <bool MetaValid>
|
||||
void MergeCombinatorSpongePrint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
||||
{
|
||||
// Sponge overwrites nothing, everything else overwrites anything
|
||||
@ -220,7 +220,7 @@ void MergeCombinatorSpongePrint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBB
|
||||
|
||||
|
||||
/** Combinator used for cBlockArea::msDifference merging */
|
||||
template<bool MetaValid>
|
||||
template <bool MetaValid>
|
||||
void MergeCombinatorDifference(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
||||
{
|
||||
if ((a_DstType == a_SrcType) && (!MetaValid || (a_DstMeta == a_SrcMeta)))
|
||||
@ -246,7 +246,7 @@ void MergeCombinatorDifference(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBL
|
||||
|
||||
|
||||
/** Combinator used for cBlockArea::msMask merging */
|
||||
template<bool MetaValid>
|
||||
template <bool MetaValid>
|
||||
void MergeCombinatorMask(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
||||
{
|
||||
// If the blocks are the same, keep the dest; otherwise replace with air
|
||||
@ -1764,7 +1764,9 @@ NIBBLETYPE cBlockArea::GetNibble(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBL
|
||||
|
||||
cBlockArea::cChunkReader::cChunkReader(cBlockArea & a_Area) :
|
||||
m_Area(a_Area),
|
||||
m_Origin(a_Area.m_Origin.x, a_Area.m_Origin.y, a_Area.m_Origin.z)
|
||||
m_Origin(a_Area.m_Origin.x, a_Area.m_Origin.y, a_Area.m_Origin.z),
|
||||
m_CurrentChunkX(0),
|
||||
m_CurrentChunkZ(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -2119,7 +2121,7 @@ void cBlockArea::RelSetData(
|
||||
|
||||
|
||||
|
||||
template<bool MetasValid>
|
||||
template <bool MetasValid>
|
||||
void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy, const NIBBLETYPE * SrcMetas, NIBBLETYPE * DstMetas)
|
||||
{
|
||||
// Block types are compulsory, block metas are voluntary
|
||||
|
@ -362,7 +362,7 @@ protected:
|
||||
NIBBLETYPE a_BlockLight, NIBBLETYPE a_BlockSkyLight
|
||||
);
|
||||
|
||||
template<bool MetasValid>
|
||||
template <bool MetasValid>
|
||||
void MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy, const NIBBLETYPE * SrcMetas, NIBBLETYPE * DstMetas);
|
||||
// tolua_begin
|
||||
} ;
|
||||
|
@ -11,7 +11,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "BlockEntityWithItems.h"
|
||||
|
||||
#include "RedstonePoweredEntity.h"
|
||||
|
||||
|
||||
|
||||
@ -31,6 +31,9 @@ class cServer;
|
||||
// tolua_begin
|
||||
class cDropSpenserEntity :
|
||||
public cBlockEntityWithItems
|
||||
// tolua_end
|
||||
, public cRedstonePoweredEntity
|
||||
// tolua_begin
|
||||
{
|
||||
typedef cBlockEntityWithItems super;
|
||||
|
||||
@ -64,11 +67,11 @@ public:
|
||||
/// Sets the dropspenser to dropspense an item in the next tick
|
||||
void Activate(void);
|
||||
|
||||
/// Sets the internal redstone power flag to "on" or "off", depending on the parameter. Calls Activate() if appropriate
|
||||
void SetRedstonePower(bool a_IsPowered);
|
||||
|
||||
// tolua_end
|
||||
|
||||
/// Sets the internal redstone power flag to "on" or "off", depending on the parameter. Calls Activate() if appropriate
|
||||
virtual void SetRedstonePower(bool a_IsPowered) override;
|
||||
|
||||
protected:
|
||||
bool m_ShouldDropSpense; ///< If true, the dropspenser will dropspense an item in the next tick
|
||||
bool m_IsPowered; ///< Set to true when the dropspenser receives redstone power.
|
||||
|
@ -549,13 +549,13 @@ bool cHopperEntity::MoveItemsFromSlot(cBlockEntityWithItems & a_Entity, int a_Sl
|
||||
bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Try the chest directly connected to the hopper:
|
||||
cChestEntity * Chest = (cChestEntity *)a_Chunk.GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ);
|
||||
if (Chest == NULL)
|
||||
cChestEntity * ConnectedChest = (cChestEntity *)a_Chunk.GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ);
|
||||
if (ConnectedChest == NULL)
|
||||
{
|
||||
LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, a_BlockX, a_BlockY, a_BlockZ);
|
||||
return false;
|
||||
}
|
||||
if (MoveItemsToGrid(*Chest))
|
||||
if (MoveItemsToGrid(*ConnectedChest))
|
||||
{
|
||||
// Chest block directly connected was not full
|
||||
return true;
|
||||
@ -586,13 +586,13 @@ bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_Block
|
||||
}
|
||||
|
||||
BLOCKTYPE Block = Neighbor->GetBlock(x, a_BlockY, z);
|
||||
if (Block != Chest->GetBlockType())
|
||||
if (Block != ConnectedChest->GetBlockType())
|
||||
{
|
||||
// Not the same kind of chest
|
||||
continue;
|
||||
}
|
||||
|
||||
Chest = (cChestEntity *)Neighbor->GetBlockEntity(a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z);
|
||||
cChestEntity * Chest = (cChestEntity *)Neighbor->GetBlockEntity(a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z);
|
||||
if (Chest == NULL)
|
||||
{
|
||||
LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d} (%d, %d)", __FUNCTION__, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z, x, z);
|
||||
|
@ -2,6 +2,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "BlockEntity.h"
|
||||
#include "RedstonePoweredEntity.h"
|
||||
|
||||
|
||||
namespace Json
|
||||
@ -30,6 +31,9 @@ enum ENUM_NOTE_INSTRUMENTS
|
||||
|
||||
class cNoteEntity :
|
||||
public cBlockEntity
|
||||
// tolua_end
|
||||
, public cRedstonePoweredEntity
|
||||
// tolua_begin
|
||||
{
|
||||
typedef cBlockEntity super;
|
||||
public:
|
||||
@ -38,6 +42,7 @@ public:
|
||||
|
||||
/// Creates a new note entity. a_World may be NULL
|
||||
cNoteEntity(int a_X, int a_Y, int a_Z, cWorld * a_World);
|
||||
virtual ~cNoteEntity() {}
|
||||
|
||||
bool LoadFromJson(const Json::Value & a_Value);
|
||||
virtual void SaveToJson(Json::Value & a_Value) override;
|
||||
@ -54,6 +59,14 @@ public:
|
||||
virtual void UsedBy(cPlayer * a_Player) override;
|
||||
virtual void SendTo(cClientHandle &) override {}
|
||||
|
||||
virtual void SetRedstonePower(bool a_Value)
|
||||
{
|
||||
if (a_Value)
|
||||
{
|
||||
MakeSound();
|
||||
}
|
||||
}
|
||||
|
||||
static const char * GetClassStatic(void) { return "cNoteEntity"; }
|
||||
|
||||
private:
|
||||
|
13
src/BlockEntities/RedstonePoweredEntity.h
Normal file
13
src/BlockEntities/RedstonePoweredEntity.h
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
// Interface class representing a blockEntity that responds to redstone
|
||||
class cRedstonePoweredEntity
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~cRedstonePoweredEntity() {};
|
||||
|
||||
/// Sets the internal redstone power flag to "on" or "off", depending on the parameter. Calls Activate() if appropriate
|
||||
virtual void SetRedstonePower(bool a_IsPowered) = 0;
|
||||
};
|
@ -294,6 +294,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
|
||||
a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_LILY_PAD ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_MELON_STEM ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_NETHER_WART ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_POTATOES ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_PUMPKIN_STEM ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_OneHitDig = true;
|
||||
|
@ -40,14 +40,15 @@ public:
|
||||
) override
|
||||
{
|
||||
a_BlockType = m_BlockType;
|
||||
NIBBLETYPE HighBits = a_BlockMeta & 0x0c; // Only highest two bits are preserved
|
||||
NIBBLETYPE Meta = (NIBBLETYPE)a_Player->GetEquippedItem().m_ItemDamage;
|
||||
int Direction = (int)floor(a_Player->GetYaw() * 4.0 / 360.0 + 1.5) & 0x3;
|
||||
|
||||
switch (Direction)
|
||||
{
|
||||
case 0: a_BlockMeta = 0x2 | HighBits; break;
|
||||
case 1: a_BlockMeta = 0x3 | HighBits; break;
|
||||
case 2: a_BlockMeta = 0x0 | HighBits; break;
|
||||
case 3: a_BlockMeta = 0x1 | HighBits; break;
|
||||
case 0: a_BlockMeta = 0x2 | Meta << 2; break;
|
||||
case 1: a_BlockMeta = 0x3 | Meta << 2; break;
|
||||
case 2: a_BlockMeta = 0x0 | Meta << 2; break;
|
||||
case 3: a_BlockMeta = 0x1 | Meta << 2; break;
|
||||
default:
|
||||
{
|
||||
return false;
|
||||
|
@ -37,7 +37,7 @@ public:
|
||||
{
|
||||
NIBBLETYPE Meta = a_BlockMeta & 0x7;
|
||||
|
||||
if ((Meta == 2) || (Meta == 3))
|
||||
if ((Meta == E_META_BIG_FLOWER_DOUBLE_TALL_GRASS) || (Meta == E_META_BIG_FLOWER_LARGE_FERN))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -63,11 +63,11 @@ public:
|
||||
if (r1.randInt(10) == 5)
|
||||
{
|
||||
cItems Pickups;
|
||||
if (FlowerMeta == 2)
|
||||
if (FlowerMeta == E_META_BIG_FLOWER_DOUBLE_TALL_GRASS)
|
||||
{
|
||||
Pickups.Add(E_BLOCK_TALL_GRASS, 2, 1);
|
||||
}
|
||||
else if (FlowerMeta == 3)
|
||||
else if (FlowerMeta == E_META_BIG_FLOWER_LARGE_FERN)
|
||||
{
|
||||
Pickups.Add(E_BLOCK_TALL_GRASS, 2, 2);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ public:
|
||||
{
|
||||
NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
|
||||
|
||||
if (!a_Player->Feed(2, 0.1))
|
||||
if (!a_Player->Feed(2, 0.4))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ public:
|
||||
Chunk->GetBlockTypeMeta(BlockX, BlockY + 1, BlockZ, AboveDest, AboveMeta);
|
||||
if (cBlockInfo::GetHandler(AboveDest)->CanDirtGrowGrass(AboveMeta))
|
||||
{
|
||||
if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, BlockX * cChunkDef::Width, BlockY, BlockZ * cChunkDef::Width, ssGrassSpread))
|
||||
if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread(Chunk->GetWorld(), Chunk->GetPosX() * cChunkDef::Width + BlockX, BlockY, Chunk->GetPosZ() * cChunkDef::Width + BlockZ, ssGrassSpread))
|
||||
{
|
||||
Chunk->FastSetBlock(BlockX, BlockY, BlockZ, E_BLOCK_GRASS, 0);
|
||||
}
|
||||
|
@ -54,10 +54,7 @@ public:
|
||||
BLOCKTYPE * BlockTypes = Area.GetBlockTypes();
|
||||
for (size_t i = 0; i < NumBlocks; i++)
|
||||
{
|
||||
if (
|
||||
(BlockTypes[i] == E_BLOCK_WATER) ||
|
||||
(BlockTypes[i] == E_BLOCK_STATIONARY_WATER)
|
||||
)
|
||||
if (IsBlockWater(BlockTypes[i]))
|
||||
{
|
||||
Found = true;
|
||||
break;
|
||||
|
@ -35,6 +35,7 @@ public:
|
||||
NIBBLETYPE OldMetaData = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
|
||||
NIBBLETYPE NewMetaData = PlayerYawToMetaData(a_Player->GetYaw());
|
||||
OldMetaData ^= 4; // Toggle the gate
|
||||
|
||||
if ((OldMetaData & 1) == (NewMetaData & 1))
|
||||
{
|
||||
// Standing in front of the gate - apply new direction
|
||||
|
@ -40,11 +40,6 @@ public:
|
||||
FindAndSetPortalFrame(a_BlockX, a_BlockY - 1, a_BlockZ, a_ChunkInterface, a_WorldInterface);
|
||||
}
|
||||
|
||||
virtual void OnDigging(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override
|
||||
{
|
||||
a_ChunkInterface.DigBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ);
|
||||
}
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
// No pickups from this block
|
||||
@ -60,8 +55,8 @@ public:
|
||||
return "step.wood";
|
||||
}
|
||||
|
||||
/// Traces along YP until it finds an obsidian block, returns Y difference or 0 if no portal, and -1 for border
|
||||
/// Takes the X, Y, and Z of the base block; with an optional MaxY for portal border finding
|
||||
/** Traces along YP until it finds an obsidian block, returns Y difference or 0 if no portal, and -1 for border
|
||||
Takes the X, Y, and Z of the base block; with an optional MaxY for portal border finding */
|
||||
int FindObsidianCeiling(int X, int Y, int Z, cChunkInterface & a_ChunkInterface, int MaxY = 0)
|
||||
{
|
||||
if (a_ChunkInterface.GetBlock(X, Y, Z) != E_BLOCK_OBSIDIAN)
|
||||
@ -91,13 +86,12 @@ public:
|
||||
return newY;
|
||||
}
|
||||
}
|
||||
else { return 0; }
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Evaluates if coords have a valid border on top, based on MaxY
|
||||
/** Evaluates if coords have a valid border on top, based on MaxY */
|
||||
bool EvaluatePortalBorder(int X, int FoundObsidianY, int Z, int MaxY, cChunkInterface & a_ChunkInterface)
|
||||
{
|
||||
for (int checkBorder = FoundObsidianY + 1; checkBorder <= MaxY - 1; checkBorder++) // FoundObsidianY + 1: FoundObsidianY has already been checked in FindObsidianCeiling; MaxY - 1: portal doesn't need corners
|
||||
@ -149,8 +143,8 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
/// Evaluates if coordinates are a portal going XP/XM; returns true if so, and writes boundaries to variable
|
||||
/// Takes coordinates of base block and Y coord of target obsidian ceiling
|
||||
/** Evaluates if coordinates are a portal going XP/XM; returns true if so, and writes boundaries to variable
|
||||
Takes coordinates of base block and Y coord of target obsidian ceiling */
|
||||
bool FindPortalSliceX(int X1, int X2, int Y, int Z, int MaxY, cChunkInterface & a_ChunkInterface)
|
||||
{
|
||||
Dir = 1; // Set assumed direction (will change if portal turns out to be facing the other direction)
|
||||
@ -168,7 +162,8 @@ public:
|
||||
{
|
||||
return false; // Not valid slice, no portal can be formed
|
||||
}
|
||||
} XZP = X1 - 1; // Set boundary of frame interior
|
||||
}
|
||||
XZP = X1 - 1; // Set boundary of frame interior
|
||||
for (; ((a_ChunkInterface.GetBlock(X2, Y, Z) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock(X2, Y + 1, Z) == E_BLOCK_OBSIDIAN)); X2--) // Go the other direction (XM)
|
||||
{
|
||||
int Value = FindObsidianCeiling(X2, Y, Z, a_ChunkInterface, MaxY);
|
||||
@ -182,7 +177,9 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} XZM = X2 + 1; // Set boundary, see previous
|
||||
}
|
||||
XZM = X2 + 1; // Set boundary, see previous
|
||||
|
||||
return (FoundFrameXP && FoundFrameXM);
|
||||
}
|
||||
|
||||
@ -204,7 +201,8 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} XZP = Z1 - 1;
|
||||
}
|
||||
XZP = Z1 - 1;
|
||||
for (; ((a_ChunkInterface.GetBlock(X, Y, Z2) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock(X, Y + 1, Z2) == E_BLOCK_OBSIDIAN)); Z2--)
|
||||
{
|
||||
int Value = FindObsidianCeiling(X, Y, Z2, a_ChunkInterface, MaxY);
|
||||
@ -218,7 +216,9 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} XZM = Z2 + 1;
|
||||
}
|
||||
XZM = Z2 + 1;
|
||||
|
||||
return (FoundFrameZP && FoundFrameZM);
|
||||
}
|
||||
};
|
||||
|
@ -19,7 +19,7 @@ public:
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
// Reset meta to 0
|
||||
// Reset meta to zero
|
||||
a_Pickups.push_back(cItem(m_BlockType, 1, 0));
|
||||
}
|
||||
|
||||
|
@ -20,8 +20,8 @@ public:
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
// Reset meta to 0
|
||||
MTRand r1;
|
||||
a_Pickups.push_back(cItem(E_ITEM_GLOWSTONE_DUST, (char)(2 + r1.randInt(2)), 0));
|
||||
cFastRandom Random;
|
||||
a_Pickups.push_back(cItem(E_ITEM_GLOWSTONE_DUST, (char)(2 + Random.NextInt(3)), 0));
|
||||
}
|
||||
} ;
|
||||
|
||||
|
@ -45,13 +45,11 @@
|
||||
#include "BlockLadder.h"
|
||||
#include "BlockLeaves.h"
|
||||
#include "BlockLilypad.h"
|
||||
#include "BlockNewLeaves.h"
|
||||
#include "BlockLever.h"
|
||||
#include "BlockMelon.h"
|
||||
#include "BlockMushroom.h"
|
||||
#include "BlockMycelium.h"
|
||||
#include "BlockNetherWart.h"
|
||||
#include "BlockNote.h"
|
||||
#include "BlockOre.h"
|
||||
#include "BlockPiston.h"
|
||||
#include "BlockPlanks.h"
|
||||
@ -251,9 +249,9 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE 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_LEAVES: return new cBlockLeavesHandler (a_BlockType);
|
||||
case E_BLOCK_NEW_LOG: return new cBlockSidewaysHandler (a_BlockType);
|
||||
case E_BLOCK_NOTE_BLOCK: return new cBlockNoteHandler (a_BlockType);
|
||||
case E_BLOCK_NOTE_BLOCK: return new cBlockEntityHandler (a_BlockType);
|
||||
case E_BLOCK_PISTON: return new cBlockPistonHandler (a_BlockType);
|
||||
case E_BLOCK_PISTON_EXTENSION: return new cBlockPistonHeadHandler;
|
||||
case E_BLOCK_PLANKS: return new cBlockPlanksHandler (a_BlockType);
|
||||
|
@ -19,8 +19,8 @@ public:
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
MTRand r1;
|
||||
a_Pickups.push_back(cItem(E_ITEM_MELON_SLICE, (char)(3 + r1.randInt(4)), 0));
|
||||
cFastRandom Random;
|
||||
a_Pickups.push_back(cItem(E_ITEM_MELON_SLICE, (char)(3 + Random.NextInt(5)), 0));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,42 +0,0 @@
|
||||
#pragma once
|
||||
#include "BlockHandler.h"
|
||||
#include "BlockLeaves.h"
|
||||
#include "../World.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockNewLeavesHandler :
|
||||
public cBlockLeavesHandler
|
||||
{
|
||||
public:
|
||||
cBlockNewLeavesHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockLeavesHandler(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
MTRand rand;
|
||||
|
||||
// Only the first 2 bits contain the display information, the others are for growing
|
||||
if (rand.randInt(5) == 0)
|
||||
{
|
||||
a_Pickups.push_back(cItem(E_BLOCK_SAPLING, 1, (a_BlockMeta & 3) + 4));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override
|
||||
{
|
||||
cBlockHandler::OnDestroyed(a_ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ);
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,13 +0,0 @@
|
||||
#pragma once
|
||||
#include "BlockHandler.h"
|
||||
#include "BlockEntity.h"
|
||||
|
||||
class cBlockNoteHandler : public cBlockEntityHandler
|
||||
{
|
||||
public:
|
||||
cBlockNoteHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockEntityHandler(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
};
|
@ -2,7 +2,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
#include "../MersenneTwister.h"
|
||||
#include "../World.h"
|
||||
|
||||
|
||||
@ -20,58 +19,41 @@ public:
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
short ItemType = m_BlockType;
|
||||
char Count = 1;
|
||||
short Meta = 0;
|
||||
cFastRandom Random;
|
||||
|
||||
MTRand r1;
|
||||
switch (m_BlockType)
|
||||
{
|
||||
case E_BLOCK_LAPIS_ORE:
|
||||
{
|
||||
ItemType = E_ITEM_DYE;
|
||||
Count = 4 + (char)r1.randInt(4);
|
||||
Meta = 4;
|
||||
a_Pickups.push_back(cItem(E_ITEM_DYE, (char)(4 + Random.NextInt(5)), 4));
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_REDSTONE_ORE:
|
||||
case E_BLOCK_REDSTONE_ORE_GLOWING:
|
||||
{
|
||||
Count = 4 + (char)r1.randInt(1);
|
||||
a_Pickups.push_back(cItem(E_ITEM_REDSTONE_DUST, (char)(4 + Random.NextInt(2)), 0));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Count = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (m_BlockType)
|
||||
{
|
||||
case E_BLOCK_DIAMOND_ORE:
|
||||
{
|
||||
ItemType = E_ITEM_DIAMOND;
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_REDSTONE_ORE:
|
||||
case E_BLOCK_REDSTONE_ORE_GLOWING:
|
||||
{
|
||||
ItemType = E_ITEM_REDSTONE_DUST;
|
||||
a_Pickups.push_back(cItem(E_ITEM_DIAMOND));
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_EMERALD_ORE:
|
||||
{
|
||||
ItemType = E_ITEM_EMERALD;
|
||||
a_Pickups.push_back(cItem(E_ITEM_EMERALD));
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_COAL_ORE:
|
||||
{
|
||||
ItemType = E_ITEM_COAL;
|
||||
a_Pickups.push_back(cItem(E_ITEM_COAL));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ASSERT(!"Unhandled ore!");
|
||||
}
|
||||
}
|
||||
a_Pickups.push_back(cItem(ItemType, Count, Meta));
|
||||
}
|
||||
} ;
|
||||
|
||||
|
@ -24,8 +24,7 @@ public:
|
||||
) override
|
||||
{
|
||||
a_BlockType = m_BlockType;
|
||||
NIBBLETYPE Meta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage);
|
||||
a_BlockMeta = Meta;
|
||||
a_BlockMeta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
return; // No pickups
|
||||
// No pickups
|
||||
}
|
||||
|
||||
virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
|
||||
@ -47,15 +47,15 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
int PosX = a_Chunk.GetPosX() * 16 + a_RelX;
|
||||
int PosZ = a_Chunk.GetPosZ() * 16 + a_RelZ;
|
||||
int PosX = a_Chunk.GetPosX() * cChunkDef::Width + a_RelX;
|
||||
int PosZ = a_Chunk.GetPosZ() * cChunkDef::Width + a_RelZ;
|
||||
|
||||
a_WorldInterface.SpawnMob(PosX, a_RelY, PosZ, cMonster::mtZombiePigman);
|
||||
}
|
||||
|
||||
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
|
||||
{
|
||||
if ((a_RelY - 1 < 0) || (a_RelY + 1 > cChunkDef::Height))
|
||||
if ((a_RelY <= 0) || (a_RelY >= cChunkDef::Height))
|
||||
{
|
||||
return false; // In case someone places a portal with meta 1 or 2 at boundaries, and server tries to get invalid coords at Y - 1 or Y + 1
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
// Reset meta to 0
|
||||
// Reset meta to zero
|
||||
a_Pickups.push_back(cItem(m_BlockType, 1, 0));
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ public:
|
||||
}
|
||||
|
||||
BLOCKTYPE BlockBelow = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ);
|
||||
return ((BlockBelow == E_BLOCK_FENCE_GATE) || (BlockBelow == E_BLOCK_FENCE) || cBlockInfo::IsSolid(BlockBelow));
|
||||
return (cBlockInfo::IsSolid(BlockBelow));
|
||||
}
|
||||
} ;
|
||||
|
||||
|
@ -25,6 +25,7 @@ public:
|
||||
{
|
||||
a_BlockType = m_BlockType;
|
||||
NIBBLETYPE Meta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage);
|
||||
|
||||
if (Meta != E_META_QUARTZ_PILLAR) // Check if the block is a pillar block.
|
||||
{
|
||||
a_BlockMeta = Meta;
|
||||
|
@ -26,8 +26,8 @@ public:
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
// Reset meta to 0
|
||||
a_Pickups.push_back(cItem(E_ITEM_REDSTONE_DUST, 1));
|
||||
// Reset meta to zero
|
||||
a_Pickups.push_back(cItem(E_ITEM_REDSTONE_DUST, 1, 0));
|
||||
}
|
||||
} ;
|
||||
|
||||
|
@ -46,7 +46,7 @@ public:
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
// Reset meta to 0
|
||||
// Reset meta to zero
|
||||
a_Pickups.push_back(cItem(E_ITEM_REDSTONE_REPEATER, 1, 0));
|
||||
}
|
||||
|
||||
@ -59,7 +59,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) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR));
|
||||
return ((a_RelY > 0) && cBlockInfo::IsSolid(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)));
|
||||
}
|
||||
|
||||
|
||||
|
@ -112,6 +112,18 @@ 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
|
||||
{
|
||||
if ((a_BlockFace == BLOCK_FACE_NONE) || (a_Player->GetEquippedItem().m_ItemType != (short)m_BlockType))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Sends the slab back to the client. It's to refuse a doubleslab placement.
|
||||
a_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
|
||||
}
|
||||
|
||||
|
||||
/// Converts the single-slab blocktype to its equivalent double-slab blocktype
|
||||
static BLOCKTYPE GetDoubleSlabType(BLOCKTYPE a_SingleSlabBlockType)
|
||||
{
|
||||
|
@ -72,17 +72,20 @@ public:
|
||||
return "step.stone";
|
||||
}
|
||||
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
// Reset meta to 0
|
||||
// Reset meta to zero
|
||||
a_Pickups.push_back(cItem(m_BlockType, 1, 0));
|
||||
}
|
||||
|
||||
|
||||
virtual bool CanDirtGrowGrass(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static NIBBLETYPE RotationToMetaData(double a_Rotation)
|
||||
{
|
||||
a_Rotation += 90 + 45; // So its not aligned with axis
|
||||
@ -108,14 +111,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Toggle bit 3:
|
||||
return (a_Meta & 0x0b) | ((~a_Meta) & 0x04);
|
||||
}
|
||||
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -29,6 +29,7 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ))
|
||||
{
|
||||
case E_BLOCK_DIRT:
|
||||
|
@ -23,7 +23,7 @@ public:
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
// Reset meta to 0
|
||||
// Reset meta to zero
|
||||
a_Pickups.push_back(cItem(m_BlockType, 1, 0));
|
||||
}
|
||||
|
||||
@ -103,9 +103,10 @@ public:
|
||||
a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta);
|
||||
|
||||
AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true);
|
||||
BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn);
|
||||
BLOCKTYPE BlockIsOn;
|
||||
a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn);
|
||||
|
||||
return (a_RelY > 0) && cBlockInfo::IsSolid(BlockIsOn);
|
||||
return ((a_RelY > 0) && cBlockInfo::IsSolid(BlockIsOn));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -24,7 +24,6 @@ public:
|
||||
) override
|
||||
{
|
||||
a_BlockType = m_BlockType;
|
||||
|
||||
a_BlockMeta = DirectionToMetadata(a_BlockFace);
|
||||
|
||||
return true;
|
||||
@ -56,7 +55,7 @@ public:
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
// Reset meta to 0
|
||||
// Reset meta to zero
|
||||
a_Pickups.push_back(cItem(E_BLOCK_TRIPWIRE_HOOK, 1, 0));
|
||||
}
|
||||
|
||||
@ -66,9 +65,10 @@ public:
|
||||
a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta);
|
||||
|
||||
AddFaceDirection(a_RelX, a_RelY, a_RelZ, MetadataToDirection(Meta), true);
|
||||
BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn);
|
||||
BLOCKTYPE BlockIsOn;
|
||||
a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn);
|
||||
|
||||
return (a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(BlockIsOn);
|
||||
return ((a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(BlockIsOn));
|
||||
}
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
|
@ -46,7 +46,7 @@ public:
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
// Reset meta to 0
|
||||
// Reset meta to zero
|
||||
a_Pickups.push_back(cItem(E_BLOCK_VINES, 1, 0));
|
||||
}
|
||||
|
||||
@ -80,7 +80,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) || (a_BlockType == E_BLOCK_NEW_LEAVES) || cBlockInfo::IsSolid(a_BlockType);
|
||||
return ((a_BlockType == E_BLOCK_LEAVES) || (a_BlockType == E_BLOCK_NEW_LEAVES) || cBlockInfo::IsSolid(a_BlockType));
|
||||
}
|
||||
|
||||
|
||||
@ -182,7 +182,7 @@ public:
|
||||
a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY - 1, a_RelZ, Block);
|
||||
if (Block == E_BLOCK_AIR)
|
||||
{
|
||||
if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, a_RelX * cChunkDef::Width, a_RelY - 1, a_RelZ * cChunkDef::Width, ssVineSpread))
|
||||
if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY - 1, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width, ssVineSpread))
|
||||
{
|
||||
a_Chunk.UnboundedRelSetBlock(a_RelX, a_RelY - 1, a_RelZ, E_BLOCK_VINES, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ));
|
||||
}
|
||||
|
@ -57,8 +57,6 @@ SET (HDRS
|
||||
BlockMushroom.h
|
||||
BlockMycelium.h
|
||||
BlockNetherWart.h
|
||||
BlockNewLeaves.h
|
||||
BlockNote.h
|
||||
BlockOre.h
|
||||
BlockPiston.h
|
||||
BlockPlanks.h
|
||||
|
@ -7,7 +7,7 @@
|
||||
// For example to use in class Foo which should inherit Bar use
|
||||
// class Foo : public cClearMetaOnDrop<Bar>;
|
||||
|
||||
template<class Base>
|
||||
template <class Base>
|
||||
class cClearMetaOnDrop : public Base
|
||||
{
|
||||
public:
|
||||
|
@ -20,7 +20,7 @@ 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>
|
||||
template <class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched = false>
|
||||
class cMetaRotator : public Base
|
||||
{
|
||||
public:
|
||||
@ -41,7 +41,7 @@ public:
|
||||
|
||||
|
||||
|
||||
template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched>
|
||||
template <class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched>
|
||||
NIBBLETYPE cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaRotateCW(NIBBLETYPE a_Meta)
|
||||
{
|
||||
NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
|
||||
@ -63,7 +63,7 @@ NIBBLETYPE cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatc
|
||||
|
||||
|
||||
|
||||
template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched>
|
||||
template <class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched>
|
||||
NIBBLETYPE cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaRotateCCW(NIBBLETYPE a_Meta)
|
||||
{
|
||||
NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
|
||||
@ -85,7 +85,7 @@ NIBBLETYPE cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatc
|
||||
|
||||
|
||||
|
||||
template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched>
|
||||
template <class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched>
|
||||
NIBBLETYPE cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaMirrorXY(NIBBLETYPE a_Meta)
|
||||
{
|
||||
NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
|
||||
@ -102,7 +102,7 @@ NIBBLETYPE cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatc
|
||||
|
||||
|
||||
|
||||
template<class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched>
|
||||
template <class Base, NIBBLETYPE BitMask, NIBBLETYPE North, NIBBLETYPE East, NIBBLETYPE South, NIBBLETYPE West, bool AssertIfNotMatched>
|
||||
NIBBLETYPE cMetaRotator<Base, BitMask, North, East, South, West, AssertIfNotMatched>::MetaMirrorYZ(NIBBLETYPE a_Meta)
|
||||
{
|
||||
NIBBLETYPE OtherMeta = a_Meta & (~BitMask);
|
||||
|
@ -27,7 +27,7 @@
|
||||
)
|
||||
#define IS_LITTLE_ENDIAN
|
||||
#elif ( \
|
||||
defined (__ARMEB__) || defined(__sparc) \
|
||||
defined (__ARMEB__) || defined(__sparc) || defined(__powerpc__) || defined(__POWERPC__) \
|
||||
)
|
||||
#define IS_BIG_ENDIAN
|
||||
#else
|
||||
|
@ -1,6 +1,7 @@
|
||||
cmake_minimum_required (VERSION 2.8.2)
|
||||
project (MCServer)
|
||||
|
||||
|
||||
include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/")
|
||||
include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/jsoncpp/include")
|
||||
include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/polarssl/include")
|
||||
@ -33,16 +34,14 @@ SET (SRCS
|
||||
FastRandom.cpp
|
||||
FurnaceRecipe.cpp
|
||||
Globals.cpp
|
||||
Group.cpp
|
||||
GroupManager.cpp
|
||||
Inventory.cpp
|
||||
Item.cpp
|
||||
ItemGrid.cpp
|
||||
LightingThread.cpp
|
||||
LineBlockTracer.cpp
|
||||
LinearInterpolation.cpp
|
||||
Log.cpp
|
||||
MCLogger.cpp
|
||||
LoggerListeners.cpp
|
||||
Logger.cpp
|
||||
Map.cpp
|
||||
MapManager.cpp
|
||||
MobCensus.cpp
|
||||
@ -52,6 +51,7 @@ SET (SRCS
|
||||
MonsterConfig.cpp
|
||||
Noise.cpp
|
||||
ProbabDistrib.cpp
|
||||
RankManager.cpp
|
||||
RCONServer.cpp
|
||||
Root.cpp
|
||||
Scoreboard.cpp
|
||||
@ -97,8 +97,6 @@ SET (HDRS
|
||||
ForEachChunkProvider.h
|
||||
FurnaceRecipe.h
|
||||
Globals.h
|
||||
Group.h
|
||||
GroupManager.h
|
||||
Inventory.h
|
||||
Item.h
|
||||
ItemGrid.h
|
||||
@ -107,8 +105,8 @@ SET (HDRS
|
||||
LineBlockTracer.h
|
||||
LinearInterpolation.h
|
||||
LinearUpscale.h
|
||||
Log.h
|
||||
MCLogger.h
|
||||
Logger.h
|
||||
LoggerListeners.h
|
||||
Map.h
|
||||
MapManager.h
|
||||
Matrix4.h
|
||||
@ -121,6 +119,7 @@ SET (HDRS
|
||||
MonsterConfig.h
|
||||
Noise.h
|
||||
ProbabDistrib.h
|
||||
RankManager.h
|
||||
RCONServer.h
|
||||
Root.h
|
||||
Scoreboard.h
|
||||
@ -234,7 +233,7 @@ endif()
|
||||
|
||||
|
||||
# Generate a list of all source files:
|
||||
set(ALLFILES "")
|
||||
set(ALLFILES "${SRCS}" "${HDRS}")
|
||||
foreach(folder ${FOLDERS})
|
||||
get_directory_property(FOLDER_SRCS DIRECTORY ${folder} DEFINITION SRCS)
|
||||
foreach (src ${FOLDER_SRCS})
|
||||
|
@ -108,7 +108,7 @@ local g_ViolationPatterns =
|
||||
|
||||
-- Check that all commas have spaces after them and not in front of them:
|
||||
{" ,", "Extra space before a \",\""},
|
||||
{",[^%s\"%%]", "Needs a space after a \",\""}, -- Report all except >> "," << needed for splitting and >>,%s<< needed for formatting
|
||||
{",[^%s\"%%\']", "Needs a space after a \",\""}, -- Report all except >> "," << needed for splitting and >>,%s<< needed for formatting
|
||||
|
||||
-- Check that opening braces are not at the end of a code line:
|
||||
{"[^%s].-{\n?$", "Brace should be on a separate line"},
|
||||
@ -119,6 +119,7 @@ local g_ViolationPatterns =
|
||||
{"while%(", "Needs a space after \"while\""},
|
||||
{"switch%(", "Needs a space after \"switch\""},
|
||||
{"catch%(", "Needs a space after \"catch\""},
|
||||
{"template<", "Needs a space after \"template\""},
|
||||
|
||||
-- No space after keyword's parenthesis:
|
||||
{"[^%a#]if %( ", "Remove the space after \"(\""},
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#ifndef _WIN32
|
||||
@ -594,17 +595,19 @@ void cChunk::Tick(float a_Dt)
|
||||
itr = m_Entities.erase(itr);
|
||||
delete ToDelete;
|
||||
}
|
||||
else if ((*itr)->IsWorldTravellingFrom(m_World)) // Remove all entities that are travelling to another world:
|
||||
else if ((*itr)->IsWorldTravellingFrom(m_World))
|
||||
{
|
||||
// Remove all entities that are travelling to another world
|
||||
MarkDirty();
|
||||
(*itr)->SetWorldTravellingFrom(NULL);
|
||||
itr = m_Entities.erase(itr);
|
||||
}
|
||||
else if ( // If any entity moved out of the chunk, move it to the neighbor:
|
||||
else if (
|
||||
((*itr)->GetChunkX() != m_PosX) ||
|
||||
((*itr)->GetChunkZ() != m_PosZ)
|
||||
)
|
||||
{
|
||||
// The entity moved out of the chunk, move it to the neighbor
|
||||
MarkDirty();
|
||||
MoveEntityToNewChunk(*itr);
|
||||
itr = m_Entities.erase(itr);
|
||||
@ -2127,6 +2130,45 @@ bool cChunk::DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBloc
|
||||
|
||||
|
||||
|
||||
bool cChunk::DoWithRedstonePoweredEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cRedstonePoweredCallback & 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;
|
||||
}
|
||||
switch ((*itr)->GetBlockType())
|
||||
{
|
||||
case E_BLOCK_DROPPER:
|
||||
case E_BLOCK_DISPENSER:
|
||||
case E_BLOCK_NOTE_BLOCK:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
if (a_Callback.Item((cRedstonePoweredEntity *)*itr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // for itr - m_BlockEntitites[]
|
||||
|
||||
// Not found:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool cChunk::DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback)
|
||||
{
|
||||
// The blockentity list is locked by the parent chunkmap's CS
|
||||
|
@ -43,6 +43,7 @@ class cBlockArea;
|
||||
class cFluidSimulatorData;
|
||||
class cMobCensus;
|
||||
class cMobSpawner;
|
||||
class cRedstonePoweredEntity;
|
||||
|
||||
typedef std::list<cClientHandle *> cClientHandleList;
|
||||
typedef cItemCallback<cEntity> cEntityCallback;
|
||||
@ -54,6 +55,7 @@ typedef cItemCallback<cNoteEntity> cNoteBlockCallback;
|
||||
typedef cItemCallback<cCommandBlockEntity> cCommandBlockCallback;
|
||||
typedef cItemCallback<cMobHeadEntity> cMobHeadCallback;
|
||||
typedef cItemCallback<cFlowerPotEntity> cFlowerPotCallback;
|
||||
typedef cItemCallback<cRedstonePoweredEntity> cRedstonePoweredCallback;
|
||||
|
||||
|
||||
|
||||
@ -238,6 +240,8 @@ public:
|
||||
/** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */
|
||||
bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback); // Lua-acessible
|
||||
|
||||
/** Calls the callback for the redstone powered entity at the specified coords; returns false if there's no redstone powered entity at those coords, true if found */
|
||||
bool DoWithRedstonePoweredEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cRedstonePoweredCallback & a_Callback);
|
||||
/** Calls the callback for the beacon at the specified coords; returns false if there's no beacon at those coords, true if found */
|
||||
bool DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback); // Lua-acessible
|
||||
|
||||
|
@ -419,7 +419,7 @@ public:
|
||||
X Data;
|
||||
|
||||
cCoordWithData(int a_X, int a_Y, int a_Z) :
|
||||
x(a_X), y(a_Y), z(a_Z)
|
||||
x(a_X), y(a_Y), z(a_Z), Data()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -75,11 +75,21 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) :
|
||||
m_TimeSinceLastPacket(0),
|
||||
m_Ping(1000),
|
||||
m_PingID(1),
|
||||
m_PingStartTime(0),
|
||||
m_LastPingTime(1000),
|
||||
m_BlockDigAnimStage(-1),
|
||||
m_BlockDigAnimSpeed(0),
|
||||
m_BlockDigAnimX(0),
|
||||
m_BlockDigAnimY(256), // Invalid Y, so that the coords don't get picked up
|
||||
m_BlockDigAnimZ(0),
|
||||
m_HasStartedDigging(false),
|
||||
m_LastDigBlockX(0),
|
||||
m_LastDigBlockY(256), // Invalid Y, so that the coords don't get picked up
|
||||
m_LastDigBlockZ(0),
|
||||
m_State(csConnected),
|
||||
m_ShouldCheckDownloaded(false),
|
||||
m_NumExplosionsThisTick(0),
|
||||
m_NumBlockChangeInteractionsThisTick(0),
|
||||
m_UniqueID(0),
|
||||
m_HasSentPlayerChunk(false),
|
||||
m_Locale("en_GB")
|
||||
@ -341,8 +351,8 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID,
|
||||
m_Protocol->SendWeather(World->GetWeather());
|
||||
}
|
||||
|
||||
// Send time
|
||||
m_Protocol->SendTimeUpdate(World->GetWorldAge(), World->GetTimeOfDay());
|
||||
// Send time:
|
||||
m_Protocol->SendTimeUpdate(World->GetWorldAge(), World->GetTimeOfDay(), World->IsDaylightCycleEnabled());
|
||||
|
||||
// Send contents of the inventory window
|
||||
m_Protocol->SendWholeInventory(*m_Player->GetWindow());
|
||||
@ -912,8 +922,28 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB
|
||||
return;
|
||||
}
|
||||
|
||||
if ((a_Status == DIG_STATUS_STARTED) || (a_Status == DIG_STATUS_FINISHED))
|
||||
{
|
||||
if (a_BlockFace == BLOCK_FACE_NONE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check for clickthrough-blocks:
|
||||
When the user breaks a fire block, the client send the wrong block location.
|
||||
We must find the right block with the face direction. */
|
||||
int BlockX = a_BlockX;
|
||||
int BlockY = a_BlockY;
|
||||
int BlockZ = a_BlockZ;
|
||||
AddFaceDirection(BlockX, BlockY, BlockZ, a_BlockFace);
|
||||
if (cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(BlockX, BlockY, BlockZ))->IsClickedThrough())
|
||||
{
|
||||
a_BlockX = BlockX;
|
||||
a_BlockY = BlockY;
|
||||
a_BlockZ = BlockZ;
|
||||
}
|
||||
|
||||
if (
|
||||
((a_Status == DIG_STATUS_STARTED) || (a_Status == DIG_STATUS_FINISHED)) && // Only do a radius check for block destruction - things like pickup tossing send coordinates that are to be ignored
|
||||
((Diff(m_Player->GetPosX(), (double)a_BlockX) > 6) ||
|
||||
(Diff(m_Player->GetPosY(), (double)a_BlockY) > 6) ||
|
||||
(Diff(m_Player->GetPosZ(), (double)a_BlockZ) > 6))
|
||||
@ -922,6 +952,7 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB
|
||||
m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager();
|
||||
if (PlgMgr->CallHookPlayerLeftClick(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status))
|
||||
@ -1028,7 +1059,8 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc
|
||||
|
||||
if (
|
||||
m_Player->IsGameModeCreative() &&
|
||||
ItemCategory::IsSword(m_Player->GetInventory().GetEquippedItem().m_ItemType)
|
||||
ItemCategory::IsSword(m_Player->GetInventory().GetEquippedItem().m_ItemType) &&
|
||||
(m_Player->GetWorld()->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_FIRE)
|
||||
)
|
||||
{
|
||||
// Players can't destroy blocks with a Sword in the hand.
|
||||
@ -1051,26 +1083,6 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc
|
||||
m_LastDigBlockY = a_BlockY;
|
||||
m_LastDigBlockZ = a_BlockZ;
|
||||
|
||||
// Check for clickthrough-blocks:
|
||||
/* When the user breaks a fire block, the client send the wrong block location.
|
||||
We must find the right block with the face direction. */
|
||||
if (a_BlockFace != BLOCK_FACE_NONE)
|
||||
{
|
||||
int pX = a_BlockX;
|
||||
int pY = a_BlockY;
|
||||
int pZ = a_BlockZ;
|
||||
|
||||
AddFaceDirection(pX, pY, pZ, a_BlockFace); // Get the block in front of the clicked coordinates (m_bInverse defaulted to false)
|
||||
cBlockHandler * Handler = cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(pX, pY, pZ));
|
||||
|
||||
if (Handler->IsClickedThrough())
|
||||
{
|
||||
cChunkInterface ChunkInterface(m_Player->GetWorld()->GetChunkMap());
|
||||
Handler->OnDigging(ChunkInterface, *m_Player->GetWorld(), m_Player, pX, pY, pZ);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(m_Player->IsGameModeCreative()) || // In creative mode, digging is done immediately
|
||||
cBlockInfo::IsOneHitDig(a_OldBlock) // One-hit blocks get destroyed immediately, too
|
||||
@ -2581,9 +2593,9 @@ void cClientHandle::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
|
||||
|
||||
|
||||
void cClientHandle::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay)
|
||||
void cClientHandle::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle)
|
||||
{
|
||||
m_Protocol->SendTimeUpdate(a_WorldAge, a_TimeOfDay);
|
||||
m_Protocol->SendTimeUpdate(a_WorldAge, a_TimeOfDay, a_DoDaylightCycle);
|
||||
}
|
||||
|
||||
|
||||
|
@ -179,7 +179,7 @@ public:
|
||||
void SendTabCompletionResults(const AStringVector & a_Results);
|
||||
void SendTeleportEntity (const cEntity & a_Entity);
|
||||
void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay);
|
||||
void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle); // tolua_export
|
||||
void SendUnloadChunk (int a_ChunkX, int a_ChunkZ);
|
||||
void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity);
|
||||
void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4);
|
||||
|
@ -353,23 +353,23 @@ AString cCompositeChat::ExtractText(void) const
|
||||
|
||||
|
||||
|
||||
cMCLogger::eLogLevel cCompositeChat::MessageTypeToLogLevel(eMessageType a_MessageType)
|
||||
cLogger::eLogLevel cCompositeChat::MessageTypeToLogLevel(eMessageType a_MessageType)
|
||||
{
|
||||
switch (a_MessageType)
|
||||
{
|
||||
case mtCustom: return cMCLogger::llRegular;
|
||||
case mtFailure: return cMCLogger::llWarning;
|
||||
case mtInformation: return cMCLogger::llInfo;
|
||||
case mtSuccess: return cMCLogger::llRegular;
|
||||
case mtWarning: return cMCLogger::llWarning;
|
||||
case mtFatal: return cMCLogger::llError;
|
||||
case mtDeath: return cMCLogger::llRegular;
|
||||
case mtPrivateMessage: return cMCLogger::llRegular;
|
||||
case mtJoin: return cMCLogger::llRegular;
|
||||
case mtLeave: return cMCLogger::llRegular;
|
||||
case mtCustom: return cLogger::llRegular;
|
||||
case mtFailure: return cLogger::llWarning;
|
||||
case mtInformation: return cLogger::llInfo;
|
||||
case mtSuccess: return cLogger::llRegular;
|
||||
case mtWarning: return cLogger::llWarning;
|
||||
case mtFatal: return cLogger::llError;
|
||||
case mtDeath: return cLogger::llRegular;
|
||||
case mtPrivateMessage: return cLogger::llRegular;
|
||||
case mtJoin: return cLogger::llRegular;
|
||||
case mtLeave: return cLogger::llRegular;
|
||||
}
|
||||
ASSERT(!"Unhandled MessageType");
|
||||
return cMCLogger::llError;
|
||||
return cLogger::llError;
|
||||
}
|
||||
|
||||
|
||||
|
@ -196,7 +196,7 @@ public:
|
||||
|
||||
/** Converts the MessageType to a LogLevel value.
|
||||
Used by the logging bindings when logging a cCompositeChat object. */
|
||||
static cMCLogger::eLogLevel MessageTypeToLogLevel(eMessageType a_MessageType);
|
||||
static cLogger::eLogLevel MessageTypeToLogLevel(eMessageType a_MessageType);
|
||||
|
||||
protected:
|
||||
/** All the parts that */
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// CraftingRecipes.cpp
|
||||
|
||||
// Interfaces to the cCraftingRecipes class representing the storage of crafting recipes
|
||||
@ -83,7 +83,7 @@ cItem & cCraftingGrid::GetItem(int x, int y) const
|
||||
|
||||
|
||||
|
||||
void cCraftingGrid::SetItem(int x, int y, ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth)
|
||||
void cCraftingGrid::SetItem(int x, int y, ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth)
|
||||
{
|
||||
// Accessible through scripting, must verify parameters:
|
||||
if ((x < 0) || (x >= m_Width) || (y < 0) || (y >= m_Height))
|
||||
@ -228,7 +228,7 @@ void cCraftingRecipe::Clear(void)
|
||||
|
||||
|
||||
|
||||
void cCraftingRecipe::SetResult(ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth)
|
||||
void cCraftingRecipe::SetResult(ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth)
|
||||
{
|
||||
m_Result = cItem(a_ItemType, a_ItemCount, a_ItemHealth);
|
||||
}
|
||||
@ -324,7 +324,11 @@ void cCraftingRecipes::LoadRecipes(void)
|
||||
return;
|
||||
}
|
||||
AString Everything;
|
||||
f.ReadRestOfFile(Everything);
|
||||
if (!f.ReadRestOfFile(Everything))
|
||||
{
|
||||
LOGWARNING("Cannot read file \"crafting.txt\", no crafting recipes will be available!");
|
||||
return;
|
||||
}
|
||||
f.Close();
|
||||
|
||||
// Split it into lines, then process each line as a single recipe:
|
||||
@ -362,7 +366,10 @@ void cCraftingRecipes::ClearRecipes(void)
|
||||
|
||||
void cCraftingRecipes::AddRecipeLine(int a_LineNum, const AString & a_RecipeLine)
|
||||
{
|
||||
AStringVector Sides = StringSplit(a_RecipeLine, "=");
|
||||
AString RecipeLine(a_RecipeLine);
|
||||
RecipeLine.erase(std::remove(RecipeLine.begin(), RecipeLine.end(), ' '), RecipeLine.end());
|
||||
|
||||
AStringVector Sides = StringSplit(RecipeLine, "=");
|
||||
if (Sides.size() != 2)
|
||||
{
|
||||
LOGWARNING("crafting.txt: line %d: A single '=' was expected, got %d", a_LineNum, (int)Sides.size() - 1);
|
||||
@ -388,8 +395,7 @@ void cCraftingRecipes::AddRecipeLine(int a_LineNum, const AString & a_RecipeLine
|
||||
}
|
||||
if (ResultSplit.size() > 1)
|
||||
{
|
||||
Recipe->m_Result.m_ItemCount = atoi(ResultSplit[1].c_str());
|
||||
if (Recipe->m_Result.m_ItemCount == 0)
|
||||
if (!StringToInteger<char>(ResultSplit[1].c_str(), Recipe->m_Result.m_ItemCount))
|
||||
{
|
||||
LOGWARNING("crafting.txt: line %d: Cannot parse result count, ignoring the recipe.", a_LineNum);
|
||||
LOGINFO("Offending line: \"%s\"", a_RecipeLine.c_str());
|
||||
@ -441,8 +447,7 @@ bool cCraftingRecipes::ParseItem(const AString & a_String, cItem & a_Item)
|
||||
if (Split.size() > 1)
|
||||
{
|
||||
AString Damage = TrimString(Split[1]);
|
||||
a_Item.m_ItemDamage = atoi(Damage.c_str());
|
||||
if ((a_Item.m_ItemDamage == 0) && (Damage.compare("0") != 0))
|
||||
if (!StringToInteger<short>(Damage.c_str(), a_Item.m_ItemDamage))
|
||||
{
|
||||
// Parsing the number failed
|
||||
return false;
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
int GetWidth (void) const {return m_Width; }
|
||||
int GetHeight(void) const {return m_Height; }
|
||||
cItem & GetItem (int x, int y) const;
|
||||
void SetItem (int x, int y, ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth);
|
||||
void SetItem (int x, int y, ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth);
|
||||
void SetItem (int x, int y, const cItem & a_Item);
|
||||
void Clear (void);
|
||||
|
||||
@ -72,13 +72,13 @@ public:
|
||||
int GetIngredientsHeight(void) const {return m_Ingredients.GetHeight(); }
|
||||
cItem & GetIngredient (int x, int y) const {return m_Ingredients.GetItem(x, y); }
|
||||
const cItem & GetResult (void) const {return m_Result; }
|
||||
void SetResult (ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth);
|
||||
void SetResult (ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth);
|
||||
void SetResult (const cItem & a_Item)
|
||||
{
|
||||
m_Result = a_Item;
|
||||
}
|
||||
|
||||
void SetIngredient (int x, int y, ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth)
|
||||
void SetIngredient (int x, int y, ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth)
|
||||
{
|
||||
m_Ingredients.SetItem(x, y, a_ItemType, a_ItemCount, a_ItemHealth);
|
||||
}
|
||||
|
@ -21,7 +21,8 @@ const int CYCLE_MILLISECONDS = 100;
|
||||
|
||||
|
||||
cDeadlockDetect::cDeadlockDetect(void) :
|
||||
super("DeadlockDetect")
|
||||
super("DeadlockDetect"),
|
||||
m_IntervalSec(1000)
|
||||
{
|
||||
}
|
||||
|
||||
@ -136,6 +137,7 @@ void cDeadlockDetect::CheckWorldAge(const AString & a_WorldName, Int64 a_Age)
|
||||
|
||||
void cDeadlockDetect::DeadlockDetected(void)
|
||||
{
|
||||
LOGERROR("Deadlock detected, aborting the server");
|
||||
ASSERT(!"Deadlock detected");
|
||||
abort();
|
||||
}
|
||||
|
@ -528,7 +528,7 @@ inline float GetSpecialSignf( float a_Val)
|
||||
|
||||
|
||||
|
||||
template<class T> inline T Diff(T a_Val1, T a_Val2)
|
||||
template <class T> inline T Diff(T a_Val1, T a_Val2)
|
||||
{
|
||||
return std::abs(a_Val1 - a_Val2);
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
/** Individual enchantment IDs, corresponding to their NBT IDs: http://www.minecraftwiki.net/wiki/Data_Values#Enchantment_IDs
|
||||
*/
|
||||
|
||||
enum
|
||||
enum eEnchantment
|
||||
{
|
||||
enchProtection = 0,
|
||||
enchFireProtection = 1,
|
||||
|
@ -32,9 +32,6 @@ void cEnderCrystal::SpawnOn(cClientHandle & a_ClientHandle)
|
||||
void cEnderCrystal::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
{
|
||||
UNUSED(a_Dt);
|
||||
|
||||
a_Chunk.SetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT, E_BLOCK_FIRE, 0);
|
||||
|
||||
// No further processing (physics e.t.c.) is needed
|
||||
}
|
||||
|
||||
@ -49,6 +46,9 @@ void cEnderCrystal::KilledBy(TakeDamageInfo & a_TDI)
|
||||
m_World->DoExplosionAt(6.0, GetPosX(), GetPosY(), GetPosZ(), true, esEnderCrystal, this);
|
||||
|
||||
Destroy();
|
||||
|
||||
m_World->SetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT, E_BLOCK_BEDROCK, 0);
|
||||
m_World->SetBlock(POSX_TOINT, POSY_TOINT + 1, POSZ_TOINT, E_BLOCK_FIRE, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -871,11 +871,101 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta)
|
||||
return true;
|
||||
}
|
||||
case E_META_RAIL_CURVED_ZM_XM:
|
||||
case E_META_RAIL_CURVED_ZM_XP:
|
||||
case E_META_RAIL_CURVED_ZP_XM:
|
||||
case E_META_RAIL_CURVED_ZP_XP:
|
||||
{
|
||||
// TODO - simply can't be bothered right now
|
||||
Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ());
|
||||
|
||||
// Prevent division by small numbers
|
||||
if (abs(Distance.z) < 0.001)
|
||||
{
|
||||
Distance.z = 0.001;
|
||||
}
|
||||
|
||||
/* Check to which side the minecart is to be pushed.
|
||||
Let's consider a z-x-coordinate system where the minecart is the center (0/0).
|
||||
The minecart moves along the line x = -z, the perpendicular line to this is x = z.
|
||||
In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. */
|
||||
if (
|
||||
((Distance.z > 0) && ((Distance.x / Distance.z) >= 1)) ||
|
||||
((Distance.z < 0) && ((Distance.x / Distance.z) <= 1))
|
||||
)
|
||||
{
|
||||
// Moving -X +Z
|
||||
if ((-GetSpeedX() * 0.4 / sqrt(2)) < 0.01)
|
||||
{
|
||||
// ~ SpeedX >= 0 Immobile or not moving in the "right" direction. Give it a bump!
|
||||
AddSpeedX(-4 / sqrt(2));
|
||||
AddSpeedZ(4 / sqrt(2));
|
||||
}
|
||||
else
|
||||
{
|
||||
// ~ SpeedX < 0 Moving in the "right" direction. Only accelerate it a bit.
|
||||
SetSpeedX(GetSpeedX() * 0.4 / sqrt(2));
|
||||
SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2));
|
||||
}
|
||||
}
|
||||
else if ((GetSpeedX() * 0.4 / sqrt(2)) < 0.01)
|
||||
{
|
||||
// Moving +X -Z
|
||||
// ~ SpeedX <= 0 Immobile or not moving in the "right" direction
|
||||
AddSpeedX(4 / sqrt(2));
|
||||
AddSpeedZ(-4 / sqrt(2));
|
||||
}
|
||||
else
|
||||
{
|
||||
// ~ SpeedX > 0 Moving in the "right" direction
|
||||
SetSpeedX(GetSpeedX() * 0.4 / sqrt(2));
|
||||
SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case E_META_RAIL_CURVED_ZM_XP:
|
||||
case E_META_RAIL_CURVED_ZP_XM:
|
||||
{
|
||||
Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ());
|
||||
|
||||
// Prevent division by small numbers
|
||||
if (abs(Distance.z) < 0.001)
|
||||
{
|
||||
Distance.z = 0.001;
|
||||
}
|
||||
|
||||
/* Check to which side the minecart is to be pushed.
|
||||
Let's consider a z-x-coordinate system where the minecart is the center (0/0).
|
||||
The minecart moves along the line x = z, the perpendicular line to this is x = -z.
|
||||
In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. */
|
||||
if (
|
||||
((Distance.z > 0) && ((Distance.x / Distance.z) <= -1)) ||
|
||||
((Distance.z < 0) && ((Distance.x / Distance.z) >= -1))
|
||||
)
|
||||
{
|
||||
// Moving +X +Z
|
||||
if ((GetSpeedX() * 0.4) < 0.01)
|
||||
{
|
||||
// ~ SpeedX <= 0 Immobile or not moving in the "right" direction
|
||||
AddSpeedX(4 / sqrt(2));
|
||||
AddSpeedZ(4 / sqrt(2));
|
||||
}
|
||||
else
|
||||
{
|
||||
// ~ SpeedX > 0 Moving in the "right" direction
|
||||
SetSpeedX(GetSpeedX() * 0.4 / sqrt(2));
|
||||
SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2));
|
||||
}
|
||||
}
|
||||
else if ((-GetSpeedX() * 0.4) < 0.01)
|
||||
{
|
||||
// Moving -X -Z
|
||||
// ~ SpeedX >= 0 Immobile or not moving in the "right" direction
|
||||
AddSpeedX(-4 / sqrt(2));
|
||||
AddSpeedZ(-4 / sqrt(2));
|
||||
}
|
||||
else
|
||||
{
|
||||
// ~ SpeedX < 0 Moving in the "right" direction
|
||||
SetSpeedX(GetSpeedX() * 0.4 / sqrt(2));
|
||||
SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
|
@ -10,8 +10,6 @@
|
||||
#include "../Bindings/PluginManager.h"
|
||||
#include "../BlockEntities/BlockEntity.h"
|
||||
#include "../BlockEntities/EnderChestEntity.h"
|
||||
#include "../GroupManager.h"
|
||||
#include "../Group.h"
|
||||
#include "../Root.h"
|
||||
#include "../OSSupport/Timer.h"
|
||||
#include "../Chunk.h"
|
||||
@ -33,6 +31,15 @@
|
||||
|
||||
|
||||
|
||||
const int cPlayer::MAX_HEALTH = 20;
|
||||
|
||||
const int cPlayer::MAX_FOOD_LEVEL = 20;
|
||||
|
||||
/** Number of ticks it takes to eat an item */
|
||||
const int cPlayer::EATING_TICKS = 30;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) :
|
||||
@ -50,7 +57,6 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) :
|
||||
m_EnderChestContents(9, 3),
|
||||
m_CurrentWindow(NULL),
|
||||
m_InventoryWindow(NULL),
|
||||
m_Color('-'),
|
||||
m_GameMode(eGameMode_NotSet),
|
||||
m_IP(""),
|
||||
m_ClientHandle(a_Client),
|
||||
@ -216,16 +222,24 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
SendExperience();
|
||||
}
|
||||
|
||||
bool CanMove = true;
|
||||
if (!GetPosition().EqualsEps(m_LastPos, 0.01)) // Non negligible change in position from last tick?
|
||||
{
|
||||
// Apply food exhaustion from movement:
|
||||
ApplyFoodExhaustionFromMovement();
|
||||
|
||||
cRoot::Get()->GetPluginManager()->CallHookPlayerMoving(*this);
|
||||
if (cRoot::Get()->GetPluginManager()->CallHookPlayerMoving(*this, m_LastPos, GetPosition()))
|
||||
{
|
||||
CanMove = false;
|
||||
TeleportToCoords(m_LastPos.x, m_LastPos.y, m_LastPos.z);
|
||||
}
|
||||
m_ClientHandle->StreamChunks();
|
||||
}
|
||||
|
||||
if (CanMove)
|
||||
{
|
||||
BroadcastMovementUpdate(m_ClientHandle);
|
||||
}
|
||||
|
||||
if (m_Health > 0) // make sure player is alive
|
||||
{
|
||||
@ -509,7 +523,7 @@ void cPlayer::Heal(int a_Health)
|
||||
|
||||
void cPlayer::SetFoodLevel(int a_FoodLevel)
|
||||
{
|
||||
int FoodLevel = std::max(0, std::min(a_FoodLevel, (int)MAX_FOOD_LEVEL));
|
||||
int FoodLevel = Clamp(a_FoodLevel, 0, MAX_FOOD_LEVEL);
|
||||
|
||||
if (cRoot::Get()->GetPluginManager()->CallHookPlayerFoodLevelChange(*this, FoodLevel))
|
||||
{
|
||||
@ -601,7 +615,6 @@ void cPlayer::FinishEating(void)
|
||||
|
||||
// Send the packets:
|
||||
m_ClientHandle->SendEntityStatus(*this, esPlayerEatingAccepted);
|
||||
m_World->BroadcastEntityAnimation(*this, 0);
|
||||
m_World->BroadcastEntityMetadata(*this);
|
||||
|
||||
// consume the item:
|
||||
@ -619,8 +632,8 @@ void cPlayer::FinishEating(void)
|
||||
// if the food is mushroom soup, return a bowl to the inventory
|
||||
if (Item.m_ItemType == E_ITEM_MUSHROOM_SOUP)
|
||||
{
|
||||
cItem emptyBowl(E_ITEM_BOWL, 1, 0, "");
|
||||
GetInventory().AddItem(emptyBowl, true, true);
|
||||
cItem EmptyBowl(E_ITEM_BOWL);
|
||||
GetInventory().AddItem(EmptyBowl, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -631,7 +644,6 @@ void cPlayer::FinishEating(void)
|
||||
void cPlayer::AbortEating(void)
|
||||
{
|
||||
m_EatingFinishTick = -1;
|
||||
m_World->BroadcastEntityAnimation(*this, 0);
|
||||
m_World->BroadcastEntityMetadata(*this);
|
||||
}
|
||||
|
||||
@ -877,7 +889,7 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI)
|
||||
Pickups.Add(cItem(E_ITEM_RED_APPLE));
|
||||
}
|
||||
|
||||
m_Stats.AddValue(statItemsDropped, Pickups.Size());
|
||||
m_Stats.AddValue(statItemsDropped, (StatValue)Pickups.Size());
|
||||
|
||||
m_World->SpawnItemPickups(Pickups, GetPosX(), GetPosY(), GetPosZ(), 10);
|
||||
SaveToDisk(); // Save it, yeah the world is a tough place !
|
||||
@ -908,6 +920,10 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI)
|
||||
}
|
||||
GetWorld()->BroadcastChatDeath(Printf("%s %s", GetName().c_str(), DamageText.c_str()));
|
||||
}
|
||||
else if (a_TDI.Attacker == NULL) // && !m_World->ShouldBroadcastDeathMessages() by fallthrough
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
else if (a_TDI.Attacker->IsPlayer())
|
||||
{
|
||||
cPlayer * Killer = (cPlayer *)a_TDI.Attacker;
|
||||
@ -1348,48 +1364,6 @@ void cPlayer::SetVisible(bool a_bVisible)
|
||||
|
||||
|
||||
|
||||
void cPlayer::AddToGroup( const AString & a_GroupName)
|
||||
{
|
||||
cGroup* Group = cRoot::Get()->GetGroupManager()->GetGroup( a_GroupName);
|
||||
m_Groups.push_back( Group);
|
||||
LOGD("Added %s to group %s", GetName().c_str(), a_GroupName.c_str());
|
||||
ResolveGroups();
|
||||
ResolvePermissions();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPlayer::RemoveFromGroup( const AString & a_GroupName)
|
||||
{
|
||||
bool bRemoved = false;
|
||||
for (GroupList::iterator itr = m_Groups.begin(); itr != m_Groups.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->GetName().compare(a_GroupName) == 0)
|
||||
{
|
||||
m_Groups.erase( itr);
|
||||
bRemoved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bRemoved)
|
||||
{
|
||||
LOGD("Removed %s from group %s", GetName().c_str(), a_GroupName.c_str());
|
||||
ResolveGroups();
|
||||
ResolvePermissions();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGWARN("Tried to remove %s from group %s but was not in that group", GetName().c_str(), a_GroupName.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPlayer::HasPermission(const AString & a_Permission)
|
||||
{
|
||||
if (a_Permission.empty())
|
||||
@ -1398,47 +1372,18 @@ bool cPlayer::HasPermission(const AString & a_Permission)
|
||||
return true;
|
||||
}
|
||||
|
||||
AStringVector Split = StringSplit( a_Permission, ".");
|
||||
PermissionMap Possibilities = m_ResolvedPermissions;
|
||||
// Now search the namespaces
|
||||
while (Possibilities.begin() != Possibilities.end())
|
||||
{
|
||||
PermissionMap::iterator itr = Possibilities.begin();
|
||||
if (itr->second)
|
||||
{
|
||||
AStringVector OtherSplit = StringSplit( itr->first, ".");
|
||||
if (OtherSplit.size() <= Split.size())
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < OtherSplit.size(); ++i)
|
||||
{
|
||||
if (OtherSplit[i].compare( Split[i]) != 0)
|
||||
{
|
||||
if (OtherSplit[i].compare("*") == 0) return true; // WildCard man!! WildCard!
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == Split.size()) return true;
|
||||
}
|
||||
}
|
||||
Possibilities.erase( itr);
|
||||
}
|
||||
AStringVector Split = StringSplit(a_Permission, ".");
|
||||
|
||||
// Nothing that matched :(
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPlayer::IsInGroup( const AString & a_Group)
|
||||
{
|
||||
for (GroupList::iterator itr = m_ResolvedGroups.begin(); itr != m_ResolvedGroups.end(); ++itr)
|
||||
// Iterate over all granted permissions; if any matches, then return success:
|
||||
for (AStringVectorVector::const_iterator itr = m_SplitPermissions.begin(), end = m_SplitPermissions.end(); itr != end; ++itr)
|
||||
{
|
||||
if (PermissionMatches(Split, *itr))
|
||||
{
|
||||
if (a_Group.compare( (*itr)->GetName().c_str()) == 0)
|
||||
return true;
|
||||
}
|
||||
} // for itr - m_SplitPermissions[]
|
||||
|
||||
// No granted permission matches
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1446,68 +1391,35 @@ bool cPlayer::IsInGroup( const AString & a_Group)
|
||||
|
||||
|
||||
|
||||
void cPlayer::ResolvePermissions()
|
||||
bool cPlayer::PermissionMatches(const AStringVector & a_Permission, const AStringVector & a_Template)
|
||||
{
|
||||
m_ResolvedPermissions.clear(); // Start with an empty map
|
||||
|
||||
// Copy all player specific permissions into the resolved permissions map
|
||||
for (PermissionMap::iterator itr = m_Permissions.begin(); itr != m_Permissions.end(); ++itr)
|
||||
// Check the sub-items if they are the same or there's a wildcard:
|
||||
size_t lenP = a_Permission.size();
|
||||
size_t lenT = a_Template.size();
|
||||
size_t minLen = std::min(lenP, lenT);
|
||||
for (size_t i = 0; i < minLen; i++)
|
||||
{
|
||||
m_ResolvedPermissions[ itr->first ] = itr->second;
|
||||
if (a_Template[i] == "*")
|
||||
{
|
||||
// Has matched so far and now there's a wildcard in the template, so the permission matches:
|
||||
return true;
|
||||
}
|
||||
if (a_Permission[i] != a_Template[i])
|
||||
{
|
||||
// Found a mismatch
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (GroupList::iterator GroupItr = m_ResolvedGroups.begin(); GroupItr != m_ResolvedGroups.end(); ++GroupItr)
|
||||
// So far all the sub-items have matched
|
||||
// If the sub-item count is the same, then the permission matches:
|
||||
if (lenP == lenT)
|
||||
{
|
||||
const cGroup::PermissionMap & Permissions = (*GroupItr)->GetPermissions();
|
||||
for (cGroup::PermissionMap::const_iterator itr = Permissions.begin(); itr != Permissions.end(); ++itr)
|
||||
{
|
||||
m_ResolvedPermissions[ itr->first ] = itr->second;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPlayer::ResolveGroups()
|
||||
{
|
||||
// Clear resolved groups first
|
||||
m_ResolvedGroups.clear();
|
||||
|
||||
// Get a complete resolved list of all groups the player is in
|
||||
std::map< cGroup*, bool > AllGroups; // Use a map, because it's faster than iterating through a list to find duplicates
|
||||
GroupList ToIterate;
|
||||
for (GroupList::iterator GroupItr = m_Groups.begin(); GroupItr != m_Groups.end(); ++GroupItr)
|
||||
{
|
||||
ToIterate.push_back( *GroupItr);
|
||||
}
|
||||
while (ToIterate.begin() != ToIterate.end())
|
||||
{
|
||||
cGroup* CurrentGroup = *ToIterate.begin();
|
||||
if (AllGroups.find( CurrentGroup) != AllGroups.end())
|
||||
{
|
||||
LOGWARNING("ERROR: Player \"%s\" is in the group multiple times (\"%s\"). Please fix your settings in users.ini!",
|
||||
GetName().c_str(), CurrentGroup->GetName().c_str()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
AllGroups[ CurrentGroup ] = true;
|
||||
m_ResolvedGroups.push_back( CurrentGroup); // Add group to resolved list
|
||||
const cGroup::GroupList & Inherits = CurrentGroup->GetInherits();
|
||||
for (cGroup::GroupList::const_iterator itr = Inherits.begin(); itr != Inherits.end(); ++itr)
|
||||
{
|
||||
if (AllGroups.find( *itr) != AllGroups.end())
|
||||
{
|
||||
LOGERROR("ERROR: Player %s is in the same group multiple times due to inheritance (%s). FIX IT!", GetName().c_str(), (*itr)->GetName().c_str());
|
||||
continue;
|
||||
}
|
||||
ToIterate.push_back( *itr);
|
||||
}
|
||||
}
|
||||
ToIterate.erase( ToIterate.begin());
|
||||
}
|
||||
// There are more sub-items in either the permission or the template, not a match:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -1516,17 +1428,14 @@ void cPlayer::ResolveGroups()
|
||||
|
||||
AString cPlayer::GetColor(void) const
|
||||
{
|
||||
if (m_Color != '-')
|
||||
if (m_MsgNameColorCode.empty() || (m_MsgNameColorCode == "-"))
|
||||
{
|
||||
return cChatColor::Delimiter + m_Color;
|
||||
// Color has not been assigned, return an empty string:
|
||||
return AString();
|
||||
}
|
||||
|
||||
if (m_Groups.size() < 1)
|
||||
{
|
||||
return cChatColor::White;
|
||||
}
|
||||
|
||||
return (*m_Groups.begin())->GetColor();
|
||||
// Return the color, including the delimiter:
|
||||
return cChatColor::Delimiter + m_MsgNameColorCode;
|
||||
}
|
||||
|
||||
|
||||
@ -1599,7 +1508,7 @@ void cPlayer::TossPickup(const cItem & a_Item)
|
||||
|
||||
void cPlayer::TossItems(const cItems & a_Items)
|
||||
{
|
||||
m_Stats.AddValue(statItemsDropped, a_Items.Size());
|
||||
m_Stats.AddValue(statItemsDropped, (StatValue)a_Items.Size());
|
||||
|
||||
double vX = 0, vY = 0, vZ = 0;
|
||||
EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY);
|
||||
@ -1642,48 +1551,9 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn)
|
||||
|
||||
|
||||
|
||||
void cPlayer::LoadPermissionsFromDisk()
|
||||
{
|
||||
m_Groups.clear();
|
||||
m_Permissions.clear();
|
||||
|
||||
cIniFile IniFile;
|
||||
if (IniFile.ReadFile("users.ini"))
|
||||
{
|
||||
AString Groups = IniFile.GetValueSet(GetName(), "Groups", "Default");
|
||||
AStringVector Split = StringSplitAndTrim(Groups, ",");
|
||||
|
||||
for (AStringVector::const_iterator itr = Split.begin(), end = Split.end(); itr != end; ++itr)
|
||||
{
|
||||
if (!cRoot::Get()->GetGroupManager()->ExistsGroup(*itr))
|
||||
{
|
||||
LOGWARNING("The group %s for player %s was not found!", itr->c_str(), GetName().c_str());
|
||||
}
|
||||
AddToGroup(*itr);
|
||||
}
|
||||
|
||||
AString Color = IniFile.GetValue(GetName(), "Color", "-");
|
||||
if (!Color.empty())
|
||||
{
|
||||
m_Color = Color[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cGroupManager::GenerateDefaultUsersIni(IniFile);
|
||||
IniFile.AddValue("Groups", GetName(), "Default");
|
||||
AddToGroup("Default");
|
||||
}
|
||||
IniFile.WriteFile("users.ini");
|
||||
ResolvePermissions();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPlayer::LoadFromDisk(cWorldPtr & a_World)
|
||||
{
|
||||
LoadPermissionsFromDisk();
|
||||
LoadRank();
|
||||
|
||||
// Load from the UUID file:
|
||||
if (LoadFromFile(GetUUIDFileName(m_UUID), a_World))
|
||||
@ -1823,6 +1693,7 @@ bool cPlayer::LoadFromFile(const AString & a_FileName, cWorldPtr & a_World)
|
||||
|
||||
bool cPlayer::SaveToDisk()
|
||||
{
|
||||
cFile::CreateFolder(FILE_IO_PREFIX + AString("players/")); // Create the "players" folder, if it doesn't exist yet (#1268)
|
||||
cFile::CreateFolder(FILE_IO_PREFIX + AString("players/") + m_UUID.substr(0, 2));
|
||||
|
||||
// create the JSON data
|
||||
@ -1917,26 +1788,6 @@ bool cPlayer::SaveToDisk()
|
||||
|
||||
|
||||
|
||||
cPlayer::StringList cPlayer::GetResolvedPermissions()
|
||||
{
|
||||
StringList Permissions;
|
||||
|
||||
const PermissionMap& ResolvedPermissions = m_ResolvedPermissions;
|
||||
for (PermissionMap::const_iterator itr = ResolvedPermissions.begin(); itr != ResolvedPermissions.end(); ++itr)
|
||||
{
|
||||
if (itr->second)
|
||||
{
|
||||
Permissions.push_back( itr->first);
|
||||
}
|
||||
}
|
||||
|
||||
return Permissions;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPlayer::UseEquippedItem(int a_Amount)
|
||||
{
|
||||
if (IsGameModeCreative()) // No damage in creative
|
||||
@ -2195,6 +2046,31 @@ void cPlayer::ApplyFoodExhaustionFromMovement()
|
||||
|
||||
|
||||
|
||||
void cPlayer::LoadRank(void)
|
||||
{
|
||||
// Load the values from cRankManager:
|
||||
cRankManager & RankMgr = cRoot::Get()->GetRankManager();
|
||||
m_Rank = RankMgr.GetPlayerRankName(m_UUID);
|
||||
if (m_Rank.empty())
|
||||
{
|
||||
m_Rank = RankMgr.GetDefaultRank();
|
||||
}
|
||||
m_Permissions = RankMgr.GetPlayerPermissions(m_UUID);
|
||||
RankMgr.GetRankVisuals(m_Rank, m_MsgPrefix, m_MsgSuffix, m_MsgNameColorCode);
|
||||
|
||||
// Break up the individual permissions on each dot, into m_SplitPermissions:
|
||||
m_SplitPermissions.clear();
|
||||
m_SplitPermissions.reserve(m_Permissions.size());
|
||||
for (AStringVector::const_iterator itr = m_Permissions.begin(), end = m_Permissions.end(); itr != end; ++itr)
|
||||
{
|
||||
m_SplitPermissions.push_back(StringSplit(*itr, "."));
|
||||
} // for itr - m_Permissions[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPlayer::Detach()
|
||||
{
|
||||
super::Detach();
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
|
||||
|
||||
class cGroup;
|
||||
class cWindow;
|
||||
class cClientHandle;
|
||||
class cTeam;
|
||||
@ -29,12 +28,13 @@ class cPlayer :
|
||||
typedef cPawn super;
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
MAX_HEALTH = 20,
|
||||
MAX_FOOD_LEVEL = 20,
|
||||
EATING_TICKS = 30, ///< Number of ticks it takes to eat an item
|
||||
} ;
|
||||
static const int MAX_HEALTH;
|
||||
|
||||
static const int MAX_FOOD_LEVEL;
|
||||
|
||||
/** Number of ticks it takes to eat an item */
|
||||
static const int EATING_TICKS;
|
||||
|
||||
// tolua_end
|
||||
|
||||
CLASS_PROTODEF(cPlayer)
|
||||
@ -235,24 +235,20 @@ public:
|
||||
|
||||
// tolua_end
|
||||
|
||||
typedef std::list< cGroup* > GroupList;
|
||||
typedef std::list< std::string > StringList;
|
||||
bool HasPermission(const AString & a_Permission); // tolua_export
|
||||
|
||||
/** Adds a player to existing group or creates a new group when it doesn't exist */
|
||||
void AddToGroup( const AString & a_GroupName); // tolua_export
|
||||
/** Returns true iff a_Permission matches the a_Template.
|
||||
A match is defined by either being exactly the same, or each sub-item matches until there's a wildcard in a_Template.
|
||||
Ie. {"a", "b", "c"} matches {"a", "b", "*"} but doesn't match {"a", "b"} */
|
||||
static bool PermissionMatches(const AStringVector & a_Permission, const AStringVector & a_Template); // Exported in ManualBindings with AString params
|
||||
|
||||
/** Removes a player from the group, resolves permissions and group inheritance (case sensitive) */
|
||||
void RemoveFromGroup( const AString & a_GroupName); // tolua_export
|
||||
|
||||
bool HasPermission( const AString & a_Permission); // tolua_export
|
||||
const GroupList & GetGroups() { return m_Groups; } // >> EXPORTED IN MANUALBINDINGS <<
|
||||
StringList GetResolvedPermissions(); // >> EXPORTED IN MANUALBINDINGS <<
|
||||
bool IsInGroup( const AString & a_Group); // tolua_export
|
||||
/** Returns all the permissions that the player has assigned to them. */
|
||||
const AStringVector & GetPermissions(void) { return m_Permissions; } // Exported in ManualBindings.cpp
|
||||
|
||||
// tolua_begin
|
||||
|
||||
/** Returns the full color code to use for this player, based on their primary group or set in m_Color.
|
||||
The returned value includes the cChatColor::Delimiter. */
|
||||
/** Returns the full color code to use for this player, based on their rank.
|
||||
The returned value either is empty, or includes the cChatColor::Delimiter. */
|
||||
AString GetColor(void) const;
|
||||
|
||||
/** tosses the item in the selected hotbar slot */
|
||||
@ -346,8 +342,6 @@ public:
|
||||
*/
|
||||
bool LoadFromFile(const AString & a_FileName, cWorldPtr & a_World);
|
||||
|
||||
void LoadPermissionsFromDisk(void); // tolua_export
|
||||
|
||||
const AString & GetLoadedWorldName() { return m_LoadedWorldName; }
|
||||
|
||||
void UseEquippedItem(int a_Amount = 1);
|
||||
@ -421,6 +415,11 @@ public:
|
||||
/** Returns the UUID (short format) that has been read from the client, or empty string if not available. */
|
||||
const AString & GetUUID(void) const { return m_UUID; }
|
||||
|
||||
/** (Re)loads the rank and permissions from the cRankManager.
|
||||
Expects the m_UUID member to be valid.
|
||||
Loads the m_Rank, m_Permissions, m_MsgPrefix, m_MsgSuffix and m_MsgNameColorCode members. */
|
||||
void LoadRank(void);
|
||||
|
||||
// tolua_end
|
||||
|
||||
// cEntity overrides:
|
||||
@ -431,12 +430,22 @@ public:
|
||||
virtual void Detach(void);
|
||||
|
||||
protected:
|
||||
typedef std::map< std::string, bool > PermissionMap;
|
||||
PermissionMap m_ResolvedPermissions;
|
||||
PermissionMap m_Permissions;
|
||||
|
||||
GroupList m_ResolvedGroups;
|
||||
GroupList m_Groups;
|
||||
typedef std::vector<std::vector<AString> > AStringVectorVector;
|
||||
|
||||
/** The name of the rank assigned to this player. */
|
||||
AString m_Rank;
|
||||
|
||||
/** All the permissions that this player has, based on their rank. */
|
||||
AStringVector m_Permissions;
|
||||
|
||||
/** All the permissions that this player has, based on their rank, split into individual dot-delimited parts.
|
||||
This is used mainly by the HasPermission() function to optimize the lookup. */
|
||||
AStringVectorVector m_SplitPermissions;
|
||||
|
||||
// Message visuals:
|
||||
AString m_MsgPrefix, m_MsgSuffix;
|
||||
AString m_MsgNameColorCode;
|
||||
|
||||
AString m_PlayerName;
|
||||
AString m_LoadedWorldName;
|
||||
@ -481,8 +490,6 @@ protected:
|
||||
/** The player's last saved bed position */
|
||||
Vector3i m_LastBedPos;
|
||||
|
||||
char m_Color;
|
||||
|
||||
eGameMode m_GameMode;
|
||||
AString m_IP;
|
||||
|
||||
|
@ -45,7 +45,7 @@ public:
|
||||
float NextFloat(float a_Range, int a_Salt);
|
||||
|
||||
/** Returns a random float between 0 and 1. */
|
||||
float NextFloat(void) { return NextFloat(1); };
|
||||
float NextFloat(void) { return NextFloat(1); }
|
||||
|
||||
/** Returns a random int in the range [a_Begin .. a_End] */
|
||||
int GenerateRandomInteger(int a_Begin, int a_End);
|
||||
|
@ -12,6 +12,7 @@ SET (SRCS
|
||||
CompoGen.cpp
|
||||
ComposableGenerator.cpp
|
||||
DistortedHeightmap.cpp
|
||||
DungeonRoomsFinisher.cpp
|
||||
EndGen.cpp
|
||||
FinishGen.cpp
|
||||
GridStructGen.cpp
|
||||
@ -40,6 +41,7 @@ SET (HDRS
|
||||
CompoGen.h
|
||||
ComposableGenerator.h
|
||||
DistortedHeightmap.h
|
||||
DungeonRoomsFinisher.h
|
||||
EndGen.h
|
||||
FinishGen.h
|
||||
GridStructGen.h
|
||||
|
@ -166,6 +166,9 @@ cCaveTunnel::cCaveTunnel(
|
||||
if ((a_BlockStartY <= 0) && (a_BlockEndY <= 0))
|
||||
{
|
||||
// Don't bother detailing this cave, it's under the world anyway
|
||||
m_MinBlockX = m_MaxBlockX = 0;
|
||||
m_MinBlockY = m_MaxBlockY = -1;
|
||||
m_MinBlockZ = m_MaxBlockZ = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@ const unsigned int QUEUE_SKIP_LIMIT = 500;
|
||||
|
||||
cChunkGenerator::cChunkGenerator(void) :
|
||||
super("cChunkGenerator"),
|
||||
m_Seed(0), // Will be overwritten by the actual generator
|
||||
m_Generator(NULL),
|
||||
m_PluginInterface(NULL),
|
||||
m_ChunkSink(NULL)
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "Caves.h"
|
||||
#include "DistortedHeightmap.h"
|
||||
#include "DungeonRoomsFinisher.h"
|
||||
#include "EndGen.h"
|
||||
#include "MineShafts.h"
|
||||
#include "NetherFortGen.h"
|
||||
@ -343,6 +344,14 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
|
||||
float Threshold = (float)a_IniFile.GetValueSetF("Generator", "DualRidgeCavesThreshold", 0.3);
|
||||
m_FinishGens.push_back(new cStructGenDualRidgeCaves(Seed, Threshold));
|
||||
}
|
||||
else if (NoCaseCompare(*itr, "DungeonRooms") == 0)
|
||||
{
|
||||
int GridSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsGridSize", 48);
|
||||
int MaxSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMaxSize", 7);
|
||||
int MinSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMinSize", 5);
|
||||
AString HeightDistrib = a_IniFile.GetValueSet ("Generator", "DungeonRoomsHeightDistrib", "0, 0; 10, 10; 11, 500; 40, 500; 60, 40; 90, 1");
|
||||
m_FinishGens.push_back(new cDungeonRoomsFinisher(*m_HeightGen, Seed, GridSize, MaxSize, MinSize, HeightDistrib));
|
||||
}
|
||||
else if (NoCaseCompare(*itr, "Ice") == 0)
|
||||
{
|
||||
m_FinishGens.push_back(new cFinishGenIce);
|
||||
@ -387,6 +396,28 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
|
||||
|
||||
m_FinishGens.push_back(new cFinishGenSingleTopBlock(Seed, E_BLOCK_LILY_PAD, AllowedBiomes, 4, AllowedBlocks));
|
||||
}
|
||||
else if (NoCaseCompare(*itr, "NaturalPatches") == 0)
|
||||
{
|
||||
cStructGenOreNests::OreList Ores;
|
||||
|
||||
// Dirt vein
|
||||
cStructGenOreNests::OreInfo DirtVein;
|
||||
DirtVein.BlockType = E_BLOCK_DIRT;
|
||||
DirtVein.MaxHeight = 127;
|
||||
DirtVein.NumNests = 20;
|
||||
DirtVein.NestSize = 32;
|
||||
Ores.push_back(DirtVein);
|
||||
|
||||
// Gravel vein
|
||||
cStructGenOreNests::OreInfo GravelVein;
|
||||
GravelVein.BlockType = E_BLOCK_DIRT;
|
||||
GravelVein.MaxHeight = 127;
|
||||
GravelVein.NumNests = 20;
|
||||
GravelVein.NestSize = 32;
|
||||
Ores.push_back(GravelVein);
|
||||
|
||||
m_FinishGens.push_back(new cStructGenOreNests(Seed, Ores, E_BLOCK_STONE));
|
||||
}
|
||||
else if (NoCaseCompare(*itr, "NetherClumpFoliage") == 0)
|
||||
{
|
||||
m_FinishGens.push_back(new cFinishGenNetherClumpFoliage(Seed));
|
||||
@ -398,9 +429,74 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
|
||||
int MaxDepth = a_IniFile.GetValueSetI("Generator", "NetherFortsMaxDepth", 12);
|
||||
m_FinishGens.push_back(new cNetherFortGen(Seed, GridSize, MaxOffset, MaxDepth));
|
||||
}
|
||||
else if (NoCaseCompare(*itr, "NetherOreNests") == 0)
|
||||
{
|
||||
cStructGenOreNests::OreList Ores;
|
||||
|
||||
// Quartz vein
|
||||
cStructGenOreNests::OreInfo QuartzVein;
|
||||
QuartzVein.BlockType = E_BLOCK_NETHER_QUARTZ_ORE;
|
||||
QuartzVein.MaxHeight = 255;
|
||||
QuartzVein.NumNests = 80;
|
||||
QuartzVein.NestSize = 8;
|
||||
Ores.push_back(QuartzVein);
|
||||
|
||||
m_FinishGens.push_back(new cStructGenOreNests(Seed, Ores, E_BLOCK_NETHERRACK));
|
||||
|
||||
}
|
||||
else if (NoCaseCompare(*itr, "OreNests") == 0)
|
||||
{
|
||||
m_FinishGens.push_back(new cStructGenOreNests(Seed));
|
||||
cStructGenOreNests::OreList Ores;
|
||||
|
||||
// Coal vein
|
||||
cStructGenOreNests::OreInfo CoalVein;
|
||||
CoalVein.BlockType = E_BLOCK_COAL_ORE;
|
||||
CoalVein.MaxHeight = 127;
|
||||
CoalVein.NumNests = 50;
|
||||
CoalVein.NestSize = 10;
|
||||
Ores.push_back(CoalVein);
|
||||
|
||||
// Iron vein
|
||||
cStructGenOreNests::OreInfo IronVein;
|
||||
IronVein.BlockType = E_BLOCK_IRON_ORE;
|
||||
IronVein.MaxHeight = 64;
|
||||
IronVein.NumNests = 14;
|
||||
IronVein.NestSize = 6;
|
||||
Ores.push_back(IronVein);
|
||||
|
||||
// Gold vein
|
||||
cStructGenOreNests::OreInfo GoldVein;
|
||||
GoldVein.BlockType = E_BLOCK_GOLD_ORE;
|
||||
GoldVein.MaxHeight = 32;
|
||||
GoldVein.NumNests = 2;
|
||||
GoldVein.NestSize = 6;
|
||||
Ores.push_back(GoldVein);
|
||||
|
||||
// Redstone vein
|
||||
cStructGenOreNests::OreInfo RedstoneVein;
|
||||
RedstoneVein.BlockType = E_BLOCK_REDSTONE_ORE;
|
||||
RedstoneVein.MaxHeight = 16;
|
||||
RedstoneVein.NumNests = 4;
|
||||
RedstoneVein.NestSize = 6;
|
||||
Ores.push_back(RedstoneVein);
|
||||
|
||||
// Lapis vein
|
||||
cStructGenOreNests::OreInfo LapisVein;
|
||||
LapisVein.BlockType = E_BLOCK_LAPIS_ORE;
|
||||
LapisVein.MaxHeight = 30;
|
||||
LapisVein.NumNests = 2;
|
||||
LapisVein.NestSize = 5;
|
||||
Ores.push_back(LapisVein);
|
||||
|
||||
// Diamond vein
|
||||
cStructGenOreNests::OreInfo DiamondVein;
|
||||
DiamondVein.BlockType = E_BLOCK_DIAMOND_ORE;
|
||||
DiamondVein.MaxHeight = 15;
|
||||
DiamondVein.NumNests = 1;
|
||||
DiamondVein.NestSize = 4;
|
||||
Ores.push_back(DiamondVein);
|
||||
|
||||
m_FinishGens.push_back(new cStructGenOreNests(Seed, Ores, E_BLOCK_STONE));
|
||||
}
|
||||
else if (NoCaseCompare(*itr, "POCPieces") == 0)
|
||||
{
|
||||
|
279
src/Generating/DungeonRoomsFinisher.cpp
Normal file
279
src/Generating/DungeonRoomsFinisher.cpp
Normal file
@ -0,0 +1,279 @@
|
||||
|
||||
// DungeonRoomsFinisher.cpp
|
||||
|
||||
// Declares the cDungeonRoomsFinisher class representing the finisher that generates dungeon rooms
|
||||
|
||||
#include "Globals.h"
|
||||
#include "DungeonRoomsFinisher.h"
|
||||
#include "../FastRandom.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Height, in blocks, of the internal dungeon room open space. This many air blocks Y-wise. */
|
||||
static const int ROOM_HEIGHT = 4;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cDungeonRoom:
|
||||
|
||||
class cDungeonRoom :
|
||||
public cGridStructGen::cStructure
|
||||
{
|
||||
typedef cGridStructGen::cStructure super;
|
||||
|
||||
public:
|
||||
|
||||
cDungeonRoom(
|
||||
int a_GridX, int a_GridZ,
|
||||
int a_OriginX, int a_OriginZ,
|
||||
int a_HalfSizeX, int a_HalfSizeZ,
|
||||
int a_FloorHeight,
|
||||
cNoise & a_Noise
|
||||
) :
|
||||
super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
|
||||
m_StartX(a_OriginX - a_HalfSizeX),
|
||||
m_EndX(a_OriginX + a_HalfSizeX),
|
||||
m_StartZ(a_OriginZ - a_HalfSizeZ),
|
||||
m_EndZ(a_OriginZ + a_HalfSizeZ),
|
||||
m_FloorHeight(a_FloorHeight)
|
||||
{
|
||||
/*
|
||||
Pick coords next to the wall for the chests.
|
||||
This is done by indexing the possible coords, picking any one for the first chest
|
||||
and then picking another position for the second chest that is not adjacent to the first pos
|
||||
*/
|
||||
int rnd = a_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) / 7;
|
||||
int SizeX = m_EndX - m_StartX - 1;
|
||||
int SizeZ = m_EndZ - m_StartZ - 1;
|
||||
int NumPositions = 2 * SizeX + 2 * SizeZ;
|
||||
int FirstChestPos = rnd % NumPositions; // The corner positions are a bit more likely, but we don't mind
|
||||
rnd = rnd / 512;
|
||||
int SecondChestPos = (FirstChestPos + 2 + (rnd % (NumPositions - 3))) % NumPositions;
|
||||
m_Chest1 = DecodeChestCoords(FirstChestPos, SizeX, SizeZ);
|
||||
m_Chest2 = DecodeChestCoords(SecondChestPos, SizeX, SizeZ);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
// The X range of the room, start inclusive, end exclusive:
|
||||
int m_StartX, m_EndX;
|
||||
|
||||
// The Z range of the room, start inclusive, end exclusive:
|
||||
int m_StartZ, m_EndZ;
|
||||
|
||||
/** The Y coord of the floor of the room */
|
||||
int m_FloorHeight;
|
||||
|
||||
/** The (absolute) coords of the first chest. The Y coord represents the chest's Meta value (facing). */
|
||||
Vector3i m_Chest1;
|
||||
|
||||
/** The (absolute) coords of the second chest. The Y coord represents the chest's Meta value (facing). */
|
||||
Vector3i m_Chest2;
|
||||
|
||||
|
||||
|
||||
/** Decodes the position index along the room walls into a proper 2D position for a chest. */
|
||||
Vector3i DecodeChestCoords(int a_PosIdx, int a_SizeX, int a_SizeZ)
|
||||
{
|
||||
if (a_PosIdx < a_SizeX)
|
||||
{
|
||||
// Return a coord on the ZM side of the room:
|
||||
return Vector3i(m_StartX + a_PosIdx + 1, E_META_CHEST_FACING_ZP, m_StartZ + 1);
|
||||
}
|
||||
a_PosIdx -= a_SizeX;
|
||||
if (a_PosIdx < a_SizeZ)
|
||||
{
|
||||
// Return a coord on the XP side of the room:
|
||||
return Vector3i(m_EndX - 1, E_META_CHEST_FACING_XM, m_StartZ + a_PosIdx + 1);
|
||||
}
|
||||
a_PosIdx -= a_SizeZ;
|
||||
if (a_PosIdx < a_SizeX)
|
||||
{
|
||||
// Return a coord on the ZP side of the room:
|
||||
return Vector3i(m_StartX + a_PosIdx + 1, E_META_CHEST_FACING_ZM, m_StartZ + 1);
|
||||
}
|
||||
a_PosIdx -= a_SizeX;
|
||||
// Return a coord on the XM side of the room:
|
||||
return Vector3i(m_StartX + 1, E_META_CHEST_FACING_XP, m_StartZ + a_PosIdx + 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Fills the specified area of blocks in the chunk with the specified blocktype if they are one of the overwritten block types.
|
||||
The coords are absolute, start coords are inclusive, end coords are exclusive. */
|
||||
void ReplaceCuboid(cChunkDesc & a_ChunkDesc, int a_StartX, int a_StartY, int a_StartZ, int a_EndX, int a_EndY, int a_EndZ, BLOCKTYPE a_DstBlockType)
|
||||
{
|
||||
int BlockX = a_ChunkDesc.GetChunkX() * cChunkDef::Width;
|
||||
int BlockZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width;
|
||||
int RelStartX = Clamp(a_StartX - BlockX, 0, cChunkDef::Width - 1);
|
||||
int RelStartZ = Clamp(a_StartZ - BlockZ, 0, cChunkDef::Width - 1);
|
||||
int RelEndX = Clamp(a_EndX - BlockX, 0, cChunkDef::Width);
|
||||
int RelEndZ = Clamp(a_EndZ - BlockZ, 0, cChunkDef::Width);
|
||||
for (int y = a_StartY; y < a_EndY; y++)
|
||||
{
|
||||
for (int z = RelStartZ; z < RelEndZ; z++)
|
||||
{
|
||||
for (int x = RelStartX; x < RelEndX; x++)
|
||||
{
|
||||
if (cBlockInfo::CanBeTerraformed(a_ChunkDesc.GetBlockType(x, y, z)))
|
||||
{
|
||||
a_ChunkDesc.SetBlockType(x, y, z, a_DstBlockType);
|
||||
}
|
||||
} // for x
|
||||
} // for z
|
||||
} // for z
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Fills the specified area of blocks in the chunk with a random pattern of the specified blocktypes, if they are one of the overwritten block types.
|
||||
The coords are absolute, start coords are inclusive, end coords are exclusive. The first blocktype uses 75% chance, the second 25% chance. */
|
||||
void ReplaceCuboidRandom(cChunkDesc & a_ChunkDesc, int a_StartX, int a_StartY, int a_StartZ, int a_EndX, int a_EndY, int a_EndZ, BLOCKTYPE a_DstBlockType1, BLOCKTYPE a_DstBlockType2)
|
||||
{
|
||||
int BlockX = a_ChunkDesc.GetChunkX() * cChunkDef::Width;
|
||||
int BlockZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width;
|
||||
int RelStartX = Clamp(a_StartX - BlockX, 0, cChunkDef::Width - 1);
|
||||
int RelStartZ = Clamp(a_StartZ - BlockZ, 0, cChunkDef::Width - 1);
|
||||
int RelEndX = Clamp(a_EndX - BlockX, 0, cChunkDef::Width);
|
||||
int RelEndZ = Clamp(a_EndZ - BlockZ, 0, cChunkDef::Width);
|
||||
cFastRandom rnd;
|
||||
for (int y = a_StartY; y < a_EndY; y++)
|
||||
{
|
||||
for (int z = RelStartZ; z < RelEndZ; z++)
|
||||
{
|
||||
for (int x = RelStartX; x < RelEndX; x++)
|
||||
{
|
||||
if (cBlockInfo::CanBeTerraformed(a_ChunkDesc.GetBlockType(x, y, z)))
|
||||
{
|
||||
BLOCKTYPE BlockType = (rnd.NextInt(101) < 75) ? a_DstBlockType1 : a_DstBlockType2;
|
||||
a_ChunkDesc.SetBlockType(x, y, z, BlockType);
|
||||
}
|
||||
} // for x
|
||||
} // for z
|
||||
} // for z
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Tries to place a chest at the specified (absolute) coords.
|
||||
Does nothing if the coords are outside the chunk. */
|
||||
void TryPlaceChest(cChunkDesc & a_ChunkDesc, const Vector3i & a_Chest)
|
||||
{
|
||||
int RelX = a_Chest.x - a_ChunkDesc.GetChunkX() * cChunkDef::Width;
|
||||
int RelZ = a_Chest.z - a_ChunkDesc.GetChunkZ() * cChunkDef::Width;
|
||||
if (
|
||||
(RelX < 0) || (RelX >= cChunkDef::Width) || // The X coord is not in this chunk
|
||||
(RelZ < 0) || (RelZ >= cChunkDef::Width) // The Z coord is not in this chunk
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
a_ChunkDesc.SetBlockTypeMeta(RelX, m_FloorHeight + 1, RelZ, E_BLOCK_CHEST, (NIBBLETYPE)a_Chest.y);
|
||||
|
||||
// TODO: Fill the chest with random loot
|
||||
}
|
||||
|
||||
|
||||
|
||||
// cGridStructGen::cStructure override:
|
||||
virtual void DrawIntoChunk(cChunkDesc & a_ChunkDesc) override
|
||||
{
|
||||
if (
|
||||
(m_EndX < a_ChunkDesc.GetChunkX() * cChunkDef::Width) ||
|
||||
(m_StartX >= a_ChunkDesc.GetChunkX() * cChunkDef::Width + cChunkDef::Width) ||
|
||||
(m_EndZ < a_ChunkDesc.GetChunkZ() * cChunkDef::Width) ||
|
||||
(m_StartZ >= a_ChunkDesc.GetChunkZ() * cChunkDef::Width + cChunkDef::Width)
|
||||
)
|
||||
{
|
||||
// The chunk is not intersecting the room at all, bail out
|
||||
return;
|
||||
}
|
||||
int b = m_FloorHeight + 1; // Bottom
|
||||
int t = m_FloorHeight + 1 + ROOM_HEIGHT; // Top
|
||||
ReplaceCuboidRandom(a_ChunkDesc, m_StartX, m_FloorHeight, m_StartZ, m_EndX + 1, b, m_EndZ + 1, E_BLOCK_MOSSY_COBBLESTONE, E_BLOCK_COBBLESTONE); // Floor
|
||||
ReplaceCuboid(a_ChunkDesc, m_StartX + 1, b, m_StartZ + 1, m_EndX, t, m_EndZ, E_BLOCK_AIR); // Insides
|
||||
|
||||
// Walls:
|
||||
ReplaceCuboid(a_ChunkDesc, m_StartX, b, m_StartZ, m_StartX + 1, t, m_EndZ, E_BLOCK_COBBLESTONE); // XM wall
|
||||
ReplaceCuboid(a_ChunkDesc, m_EndX, b, m_StartZ, m_EndX + 1, t, m_EndZ, E_BLOCK_COBBLESTONE); // XP wall
|
||||
ReplaceCuboid(a_ChunkDesc, m_StartX, b, m_StartZ, m_EndX + 1, t, m_StartZ + 1, E_BLOCK_COBBLESTONE); // ZM wall
|
||||
ReplaceCuboid(a_ChunkDesc, m_StartX, b, m_EndZ, m_EndX + 1, t, m_EndZ + 1, E_BLOCK_COBBLESTONE); // ZP wall
|
||||
|
||||
// Place chests:
|
||||
TryPlaceChest(a_ChunkDesc, m_Chest1);
|
||||
TryPlaceChest(a_ChunkDesc, m_Chest2);
|
||||
|
||||
// Place the spawner:
|
||||
int CenterX = (m_StartX + m_EndX) / 2 - a_ChunkDesc.GetChunkX() * cChunkDef::Width;
|
||||
int CenterZ = (m_StartZ + m_EndZ) / 2 - a_ChunkDesc.GetChunkZ() * cChunkDef::Width;
|
||||
if (
|
||||
(CenterX >= 0) && (CenterX < cChunkDef::Width) &&
|
||||
(CenterZ >= 0) && (CenterZ < cChunkDef::Width)
|
||||
)
|
||||
{
|
||||
a_ChunkDesc.SetBlockTypeMeta(CenterX, b, CenterZ, E_BLOCK_MOB_SPAWNER, 0);
|
||||
// TODO: Set the spawned mob
|
||||
}
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cDungeonRoomsFinisher:
|
||||
|
||||
cDungeonRoomsFinisher::cDungeonRoomsFinisher(cTerrainHeightGen & a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib) :
|
||||
super(a_Seed + 100, a_GridSize, a_GridSize, a_GridSize, a_GridSize, a_MaxSize, a_MaxSize, 1024),
|
||||
m_HeightGen(a_HeightGen),
|
||||
m_MaxHalfSize((a_MaxSize + 1) / 2),
|
||||
m_MinHalfSize((a_MinSize + 1) / 2),
|
||||
m_HeightProbability(cChunkDef::Height)
|
||||
{
|
||||
// Initialize the height probability distribution:
|
||||
m_HeightProbability.SetDefString(a_HeightDistrib);
|
||||
|
||||
// Normalize the min and max size:
|
||||
if (m_MinHalfSize > m_MaxHalfSize)
|
||||
{
|
||||
std::swap(m_MinHalfSize, m_MaxHalfSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cDungeonRoomsFinisher::cStructurePtr cDungeonRoomsFinisher::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
|
||||
{
|
||||
// Select a random room size in each direction:
|
||||
int rnd = m_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) / 7;
|
||||
int HalfSizeX = m_MinHalfSize + (rnd % (m_MaxHalfSize - m_MinHalfSize + 1));
|
||||
rnd = rnd / 32;
|
||||
int HalfSizeZ = m_MinHalfSize + (rnd % (m_MaxHalfSize - m_MinHalfSize + 1));
|
||||
rnd = rnd / 32;
|
||||
|
||||
// Select a random floor height for the room, based on the height generator:
|
||||
int ChunkX, ChunkZ;
|
||||
int RelX = a_OriginX, RelY = 0, RelZ = a_OriginZ;
|
||||
cChunkDef::AbsoluteToRelative(RelX, RelY, RelZ, ChunkX, ChunkZ);
|
||||
cChunkDef::HeightMap HeightMap;
|
||||
m_HeightGen.GenHeightMap(ChunkX, ChunkZ, HeightMap);
|
||||
int Height = cChunkDef::GetHeight(HeightMap, RelX, RelZ); // Max room height at {a_OriginX, a_OriginZ}
|
||||
Height = Clamp(m_HeightProbability.MapValue(rnd % m_HeightProbability.GetSum()), 10, Height - 5);
|
||||
|
||||
// Create the dungeon room descriptor:
|
||||
return cStructurePtr(new cDungeonRoom(a_GridX, a_GridZ, a_OriginX, a_OriginZ, HalfSizeX, HalfSizeZ, Height, m_Noise));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
52
src/Generating/DungeonRoomsFinisher.h
Normal file
52
src/Generating/DungeonRoomsFinisher.h
Normal file
@ -0,0 +1,52 @@
|
||||
|
||||
// DungeonRoomsFinisher.h
|
||||
|
||||
// Declares the cDungeonRoomsFinisher class representing the finisher that generates dungeon rooms
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GridStructGen.h"
|
||||
#include "../ProbabDistrib.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cDungeonRoomsFinisher :
|
||||
public cGridStructGen
|
||||
{
|
||||
typedef cGridStructGen super;
|
||||
|
||||
public:
|
||||
/** Creates a new dungeon room finisher.
|
||||
a_HeightGen is the underlying height generator, so that the rooms can always be placed under the terrain.
|
||||
a_MaxSize and a_MinSize are the maximum and minimum sizes of the room's internal (air) area, in blocks across.
|
||||
a_HeightDistrib is the string defining the height distribution for the rooms (cProbabDistrib format). */
|
||||
cDungeonRoomsFinisher(cTerrainHeightGen & a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib);
|
||||
|
||||
protected:
|
||||
|
||||
/** The height gen that is used for limiting the rooms' Y coords */
|
||||
cTerrainHeightGen & m_HeightGen;
|
||||
|
||||
/** Maximum half-size (from center to wall) of the dungeon room's inner (air) area. Default is 3 (vanilla). */
|
||||
int m_MaxHalfSize;
|
||||
|
||||
/** Minimum half-size (from center to wall) of the dungeon room's inner (air) area. Default is 2 (vanilla). */
|
||||
int m_MinHalfSize;
|
||||
|
||||
/** The height probability distribution to make the spawners more common in layers 10 - 40, less common outside this range. */
|
||||
cProbabDistrib m_HeightProbability;
|
||||
|
||||
|
||||
// cGridStructGen overrides:
|
||||
virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -484,8 +484,6 @@ int cFinishGenSingleTopBlock::GetNumToGen(const cChunkDef::BiomeMap & a_BiomeMap
|
||||
|
||||
void cFinishGenSingleTopBlock::GenFinish(cChunkDesc & a_ChunkDesc)
|
||||
{
|
||||
// Add Lilypads on top of water surface in Swampland
|
||||
|
||||
int NumToGen = GetNumToGen(a_ChunkDesc.GetBiomeMap());
|
||||
int ChunkX = a_ChunkDesc.GetChunkX();
|
||||
int ChunkZ = a_ChunkDesc.GetChunkZ();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user