Merge branch 'master' into EntityCustomName
Conflicts: src/ClientHandle.cpp src/ClientHandle.h src/Protocol/Protocol.h src/Protocol/Protocol125.cpp src/Protocol/Protocol125.h src/Protocol/Protocol17x.cpp src/Protocol/Protocol17x.h src/Protocol/ProtocolRecognizer.cpp src/Protocol/ProtocolRecognizer.h src/World.cpp src/World.h
This commit is contained in:
commit
4b38e077cf
1
.gitignore
vendored
1
.gitignore
vendored
@ -56,6 +56,7 @@ Makefile
|
||||
*.a
|
||||
*.d
|
||||
*.so
|
||||
BuildInfo.h
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
Makefile
|
||||
|
@ -2,6 +2,10 @@
|
||||
|
||||
set -e
|
||||
|
||||
export MCSERVER_BUILD_SERIES_NAME="Travis $CC $TRAVIS_MCSERVER_BUILD_TYPE"
|
||||
export MCSERVER_BUILD_ID=$TRAVIS_JOB_NUMBER
|
||||
export MCSERVER_BUILD_DATETIME=`date`
|
||||
|
||||
cmake . -DBUILD_TOOLS=1 -DSELF_TEST=1;
|
||||
make -j 2;
|
||||
make -j 2 test;
|
||||
|
@ -1,4 +1,4 @@
|
||||
cmake_minimum_required (VERSION 2.8.2)
|
||||
cmake_minimum_required (VERSION 2.8.7)
|
||||
|
||||
# Without this, the MSVC variable isn't defined for MSVC builds ( http://www.cmake.org/pipermail/cmake/2011-November/047130.html )
|
||||
enable_language(CXX C)
|
||||
@ -18,6 +18,25 @@ if(DEFINED ENV{TRAVIS_BUILD_WITH_COVERAGE})
|
||||
set(BUILD_WITH_COVERAGE $ENV{TRAVIS_BUILD_WITH_COVERAGE})
|
||||
endif()
|
||||
|
||||
if(DEFINED ENV{MCSERVER_BUILD_ID})
|
||||
set(BUILD_ID $ENV{MCSERVER_BUILD_ID})
|
||||
set(BUILD_SERIES_NAME $ENV{MCSERVER_BUILD_SERIES_NAME})
|
||||
set(BUILD_DATETIME $ENV{MCSERVER_BUILD_DATETIME})
|
||||
if(DEFINED ENV{MCSERVER_BUILD_COMMIT_ID})
|
||||
set(BUILD_COMMIT_ID $ENV{MCSERVER_BUILD_COMMIT_ID})
|
||||
else()
|
||||
message("Commit id not set, attempting to determine id from git")
|
||||
execute_process(
|
||||
COMMAND git rev-parse HEAD
|
||||
RESULT_VARIABLE GIT_EXECUTED
|
||||
OUTPUT_VARIABLE BUILD_COMMIT_ID)
|
||||
string(STRIP ${BUILD_COMMIT_ID} BUILD_COMMIT_ID)
|
||||
if (NOT (GIT_EXECUTED EQUAL 0))
|
||||
message(FATAL_ERROR "Could not identifiy git commit id")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# This has to be done before any flags have been set up.
|
||||
if(${BUILD_TOOLS})
|
||||
add_subdirectory(Tools/MCADefrag/)
|
||||
|
@ -29,5 +29,6 @@ worktycho
|
||||
xoft
|
||||
Yeeeeezus (Donated AlchemistVillage prefabs)
|
||||
Howaner
|
||||
Masy98
|
||||
|
||||
Please add yourself to this list if you contribute to MCServer.
|
||||
|
@ -6,10 +6,7 @@
|
||||
..\MCServer\furnace.txt
|
||||
..\MCServer\items.ini
|
||||
..\MCServer\monsters.ini
|
||||
..\MCServer\buildinfo.txt
|
||||
MCServer*debug.cmd
|
||||
*.example.ini
|
||||
Lua-LICENSE.txt
|
||||
LuaExpat-license.html
|
||||
LuaSQLite3-LICENSE.txt
|
||||
SQLiteCpp-LICENSE.txt
|
||||
MersenneTwister-LICENSE.txt
|
||||
ThirdPartyLicenses
|
||||
|
@ -1,2 +1,3 @@
|
||||
MCServer\*.pdb
|
||||
src\Bindings\Bindings.*
|
||||
MCServer\buildinfo.txt
|
||||
src\Bindings\Bindings.*
|
||||
|
@ -524,6 +524,7 @@ end
|
||||
Functions =
|
||||
{
|
||||
GenerateOfflineUUID = { Params = "Username", Return = "string", Notes = "(STATIC) Generates an UUID based on the player name provided. This is used for the offline (non-auth) mode, when there's no UUID source. Each username generates a unique and constant UUID, so that when the player reconnects with the same name, their UUID is the same. Returns a 32-char UUID (no dashes)." },
|
||||
GetIPString = { Params = "", Return = "string", Notes = "Returns the IP address of the connection, as a string. Only the address part is returned, without the port number." },
|
||||
GetLocale = { Params = "", Return = "Locale", Notes = "Returns the locale string that the client sends as part of the protocol handshake. Can be used to provide localized strings." },
|
||||
GetPing = { Params = "", Return = "number", Notes = "Returns the ping time, in ms" },
|
||||
GetPlayer = { Params = "", Return = "{{cPlayer|cPlayer}}", Notes = "Returns the player object connected to this client. Note that this may be nil, for example if the player object is not yet spawned." },
|
||||
@ -1188,7 +1189,7 @@ These ItemGrids are available in the API and can be manipulated by the plugins,
|
||||
constructor =
|
||||
{
|
||||
{ Params = "", Return = "cItem", Notes = "Creates a new empty cItem object" },
|
||||
{ Params = "ItemType, Count, Damage, EnchantmentString", Return = "cItem", Notes = "Creates a new cItem object of the specified type, count (1 by default), damage (0 by default) and enchantments (non-enchanted by default)" },
|
||||
{ Params = "ItemType, Count, Damage, EnchantmentString, CustomName, Lore", Return = "cItem", Notes = "Creates a new cItem object of the specified type, count (1 by default), damage (0 by default), enchantments (non-enchanted by default), CustomName (empty by default) and Lore (string, empty by default)" },
|
||||
{ Params = "cItem", Return = "cItem", Notes = "Creates an exact copy of the cItem object in the parameter" },
|
||||
} ,
|
||||
AddCount = { Params = "AmountToAdd", Return = "cItem", Notes = "Adds the specified amount to the item count. Returns self (useful for chaining)." },
|
||||
@ -1201,12 +1202,14 @@ These ItemGrids are available in the API and can be manipulated by the plugins,
|
||||
IsDamageable = { Params = "", Return = "bool", Notes = "Returns true if this item does account for its damage" },
|
||||
IsEmpty = { Params = "", Return = "bool", Notes = "Returns true if this object represents an empty item (zero count or invalid ID)" },
|
||||
IsEqual = { Params = "cItem", Return = "bool", Notes = "Returns true if the item in the parameter is the same as the one stored in the object (type, damage, lore, name and enchantments)" },
|
||||
IsEnchantable = { Params = "", Return = "bool", Notes = "Returns true if the item is enchantable" },
|
||||
IsFullStack = { Params = "", Return = "bool", Notes = "Returns true if the item is stacked up to its maximum stacking" },
|
||||
IsSameType = { Params = "cItem", Return = "bool", Notes = "Returns true if the item in the parameter is of the same ItemType as the one stored in the object. This is true even if the two items have different enchantments" },
|
||||
IsBothNameAndLoreEmpty = { Params = "", Return = "bool", Notes = "Returns if both the custom name and lore are not set." },
|
||||
IsCustomNameEmpty = { Params = "", Return = "bool", Notes = "Returns if the custom name of the cItem is empty." },
|
||||
IsLoreEmpty = { Params = "", Return = "", Notes = "Returns if the lore of the cItem is empty." },
|
||||
GetEnchantability = { Params = "", Return = "number", Notes = "Returns the enchantability of the item. When the item hasn't a enchantability, it will returns 0" },
|
||||
EnchantByXPLevels = { Params = "NumXPLevels", Return = "bool", Notes = "Enchants the item using the specified number of XP levels. Returns true if item enchanted, false if not." },
|
||||
IsEnchantable = { Params = "ItemType, WithBook", Return = "bool", Notes = "(STATIC) Returns true if the specified item type is enchantable. If WithBook is true, the function is used in the anvil inventory with book enchantments. So it checks the \"only book enchantments\" too. Example: You can only enchant a hoe with a book." },
|
||||
},
|
||||
Variables =
|
||||
{
|
||||
@ -1214,8 +1217,10 @@ These ItemGrids are available in the API and can be manipulated by the plugins,
|
||||
m_ItemCount = { Type = "number", Notes = "Number of items in this stack" },
|
||||
m_ItemDamage = { Type = "number", Notes = "The damage of the item. Zero means no damage. Maximum damage can be queried with GetMaxDamage()" },
|
||||
m_ItemType = { Type = "number", Notes = "The item type. One of E_ITEM_ or E_BLOCK_ constants" },
|
||||
m_CustomName = { Type = "string", Notes = "The custom name for an item." },
|
||||
m_Lore = { Type = "string", Notes = "The lore for an item. Line breaks are represented by the ` character." },
|
||||
m_CustomName = { Type = "string", Notes = "The custom name for an item." },
|
||||
m_Lore = { Type = "string", Notes = "The lore for an item. Line breaks are represented by the ` character." },
|
||||
m_RepairCost = { Type = "number", Notes = "The repair cost of the item. The anvil need this value" },
|
||||
m_Enchantments = { Type = "{{cEnchantments|cEnchantments}}}", Notes = "The enchantments of the item." },
|
||||
},
|
||||
AdditionalInfo =
|
||||
{
|
||||
@ -1641,6 +1646,8 @@ a_Player:OpenWindow(Window);
|
||||
MobTypeToString = { Params = "{{cMonster#MobType|MobType}}", Return = "string", Notes = "(STATIC) Returns the string representing the given mob type ({{cMonster#MobType|mtXXX}} constant), or empty string if unknown type." },
|
||||
MoveToPosition = { Params = "Position", Return = "", Notes = "Moves mob to the specified position" },
|
||||
StringToMobType = { Params = "string", Return = "{{cMonster#MobType|MobType}}", Notes = "(STATIC) Returns the mob type ({{cMonster#MobType|mtXXX}} constant) parsed from the string type (\"creeper\"), or mtInvalidType if unrecognized." },
|
||||
GetRelativeWalkSpeed = { Params = "", Return = "number", Notes = "Returns the relative walk speed of this mob. Standard is 1.0" },
|
||||
SetRelativeWalkSpeed = { Params = "number", Return = "", Notes = "Sets the relative walk speed of this mob. Standard is 1.0" },
|
||||
},
|
||||
Constants =
|
||||
{
|
||||
@ -1757,7 +1764,7 @@ a_Player:OpenWindow(Window);
|
||||
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's messages (based on their rank). Prefix player messages with this code." },
|
||||
GetTabListName = { Return = "string", Notes = "Returns the name that is used in the tablist." },
|
||||
GetPlayerListName = { Return = "string", Notes = "Returns the name that is used in the playerlist." },
|
||||
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." },
|
||||
@ -1889,13 +1896,13 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
|
||||
},
|
||||
BindCommand =
|
||||
{
|
||||
{ Params = "Command, Permission, Callback, HelpString", Return = "[bool]", Notes = "(STATIC) Binds an in-game command with the specified callback function, permission and help string. By common convention, providing an empty string for HelpString will hide the command from the /help display. Returns true if successful, logs to console and returns no value on error." },
|
||||
{ Params = "Command, Permission, Callback, HelpString", Return = "[bool]", Notes = "Binds an in-game command with the specified callback function, permission and help string. By common convention, providing an empty string for HelpString will hide the command from the /help display. Returns true if successful, logs to console and returns no value on error." },
|
||||
{ Params = "Command, Permission, Callback, HelpString", Return = "[bool]", Notes = "(STATIC) Binds an in-game command with the specified callback function, permission and help string. By common convention, providing an empty string for HelpString will hide the command from the /help display. Returns true if successful, logs to console and returns no value on error. The callback uses the following signature: <pre class=\"prettyprint lang-lua\">function(Split, {{cPlayer|Player}})</pre> The Split parameter contains an array-table of the words that the player has sent, Player is the {{cPlayer}} object representing the player who sent the command. If the callback returns true, the command is assumed to have executed successfully; in all other cases the server sends a warning to the player that the command is unknown (this is so that subcommands can be implemented)." },
|
||||
{ Params = "Command, Permission, Callback, HelpString", Return = "[bool]", Notes = "Binds an in-game command with the specified callback function, permission and help string. By common convention, providing an empty string for HelpString will hide the command from the /help display. Returns true if successful, logs to console and returns no value on error. The callback uses the following signature: <pre class=\"prettyprint lang-lua\">function(Split, {{cPlayer|Player}})</pre> The Split parameter contains an array-table of the words that the player has sent, Player is the {{cPlayer}} object representing the player who sent the command. If the callback returns true, the command is assumed to have executed successfully; in all other cases the server sends a warning to the player that the command is unknown (this is so that subcommands can be implemented)." },
|
||||
},
|
||||
BindConsoleCommand =
|
||||
{
|
||||
{ Params = "Command, Callback, HelpString", Return = "[bool]", Notes = "(STATIC) Binds a console command with the specified callback function and help string. By common convention, providing an empty string for HelpString will hide the command from the \"help\" console command. Returns true if successful, logs to console and returns no value on error." },
|
||||
{ Params = "Command, Callback, HelpString", Return = "[bool]", Notes = "Binds a console command with the specified callback function and help string. By common convention, providing an empty string for HelpString will hide the command from the \"help\" console command. Returns true if successful, logs to console and returns no value on error." },
|
||||
{ Params = "Command, Callback, HelpString", Return = "[bool]", Notes = "(STATIC) Binds a console command with the specified callback function and help string. By common convention, providing an empty string for HelpString will hide the command from the \"help\" console command. Returns true if successful, logs to console and returns no value on error. The callback uses the following signature: <pre class=\"prettyprint lang-lua\">function(Split)</pre> The Split parameter contains an array-table of the words that the admin has typed. If the callback returns true, the command is assumed to have executed successfully; in all other cases the server issues a warning to the console that the command is unknown (this is so that subcommands can be implemented)." },
|
||||
{ Params = "Command, Callback, HelpString", Return = "[bool]", Notes = "Binds a console command with the specified callback function and help string. By common convention, providing an empty string for HelpString will hide the command from the \"help\" console command. Returns true if successful, logs to console and returns no value on error. The callback uses the following signature: <pre class=\"prettyprint lang-lua\">function(Split)</pre> The Split parameter contains an array-table of the words that the admin has typed. If the callback returns true, the command is assumed to have executed successfully; in all other cases the server issues a warning to the console that the command is unknown (this is so that subcommands can be implemented)." },
|
||||
},
|
||||
CallPlugin = { Params = "PluginName, FunctionName, [FunctionArgs...]", Return = "[FunctionRets]", Notes = "(STATIC) Calls the specified function in the specified plugin, passing all the given arguments to it. If it succeeds, it returns all the values returned by that function. If it fails, returns no value at all. Note that only strings, numbers, bools, nils and classes can be used for parameters and return values; tables and functions cannot be copied across plugins." },
|
||||
DisablePlugin = { Params = "PluginName", Return = "bool", Notes = "Disables a plugin specified by its name. Returns true if the plugin was disabled, false if it wasn't found or wasn't active." },
|
||||
@ -2349,6 +2356,7 @@ end
|
||||
ForEachBlockEntityInChunk = { Params = "ChunkX, ChunkZ, CallbackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each block entity in the chunk. Returns true if all block entities in the chunk have been processed (including when there are zero block entities), or false if the callback has aborted the enumeration by returning true. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cBlockEntity|BlockEntity}}, [CallbackData])</pre> The callback should return false or no value to continue with the next block entity, or true to abort the enumeration. Use {{tolua}}.cast() to cast the Callback's BlockEntity parameter to the correct {{cBlockEntity}} descendant." },
|
||||
ForEachChestInChunk = { Params = "ChunkX, ChunkZ, CallbackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each chest in the chunk. Returns true if all chests in the chunk have been processed (including when there are zero chests), or false if the callback has aborted the enumeration by returning true. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cChestEntity|ChestEntity}}, [CallbackData])</pre> The callback should return false or no value to continue with the next chest, or true to abort the enumeration." },
|
||||
ForEachEntity = { Params = "CallbackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each entity in the loaded world. Returns true if all the entities have been processed (including when there are zero entities), or false if the callback function has aborted the enumeration by returning true. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cEntity|Entity}}, [CallbackData])</pre> The callback should return false or no value to continue with the next entity, or true to abort the enumeration." },
|
||||
ForEachEntityInBox = { Params = "{{cBoundingBox|Box}}, CallbackFunction", Return = "bool", Notes = "Calls the specified callback for each entity in the specified bounding box. Returns true if all the entities have been processed (including when there are zero entities), or false if the callback function has aborted the enumeration by returning true. If any chunk within the bounding box is not valid, it is silently skipped without any notification. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cEntity|Entity}})</pre> The callback should return false or no value to continue with the next entity, or true to abort the enumeration." },
|
||||
ForEachEntityInChunk = { Params = "ChunkX, ChunkZ, CallbackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each entity in the specified chunk. Returns true if all the entities have been processed (including when there are zero entities), or false if the chunk is not loaded or the callback function has aborted the enumeration by returning true. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cEntity|Entity}}, [CallbackData])</pre> The callback should return false or no value to continue with the next entity, or true to abort the enumeration." },
|
||||
ForEachFurnaceInChunk = { Params = "ChunkX, ChunkZ, CallbackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each furnace in the chunk. Returns true if all furnaces in the chunk have been processed (including when there are zero furnaces), or false if the callback has aborted the enumeration by returning true. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cFurnaceEntity|FurnaceEntity}}, [CallbackData])</pre> The callback should return false or no value to continue with the next furnace, or true to abort the enumeration." },
|
||||
ForEachPlayer = { Params = "CallbackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each player in the loaded world. Returns true if all the players have been processed (including when there are zero players), or false if the callback function has aborted the enumeration by returning true. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cPlayer|Player}}, [CallbackData])</pre> The callback should return false or no value to continue with the next player, or true to abort the enumeration." },
|
||||
|
@ -6,8 +6,9 @@ return
|
||||
DefaultFnName = "OnSpawningEntity", -- also used as pagename
|
||||
Desc = [[
|
||||
This hook is called before the server spawns an {{cEntity|entity}}. The plugin can either modify the
|
||||
entity before it is spawned, or disable the spawning altogether. If the entity spawning is a
|
||||
monster, the {{OnSpawningMonster|HOOK_SPAWNING_MONSTER}} hook is called before this hook.</p>
|
||||
entity before it is spawned, or disable the spawning altogether. You can't disable the spawning if the
|
||||
entity is a player. If the entity spawning is a monster, the {{OnSpawningMonster|HOOK_SPAWNING_MONSTER}}
|
||||
hook is called before this hook.</p>
|
||||
<p>
|
||||
See also the {{OnSpawnedEntity|HOOK_SPAWNED_ENTITY}} hook for a similar hook called after the
|
||||
entity is spawned.
|
||||
|
@ -202,7 +202,7 @@ function Explode(Split, Player)
|
||||
if (#Split ~= 2) then
|
||||
-- There was more or less than one argument (excluding the "/explode" bit)
|
||||
-- Send the proper usage to the player and exit
|
||||
SendMessage(Player, "Usage: /explode [playername]")
|
||||
Player:SendMessage("Usage: /explode [playername]")
|
||||
return true
|
||||
end
|
||||
|
||||
@ -213,7 +213,7 @@ function Explode(Split, Player)
|
||||
if (Explodee:GetName() == Split[2]) then
|
||||
-- Create an explosion at the same position as they are; see <a href="cWorld.html">API docs</a> for further details of this function
|
||||
Player:GetWorld():DoExplosionAt(Explodee:GetPosX(), Explodee:GetPosY(), Explodee:GetPosZ(), false, esPlugin)
|
||||
SendMessageSuccess(Player, Split[2] .. " was successfully exploded")
|
||||
Player:SendMessageSuccess(Split[2] .. " was successfully exploded")
|
||||
HasExploded = true;
|
||||
return true -- Signalize to MCS that we do not need to call this callback for any more players
|
||||
end
|
||||
@ -224,7 +224,7 @@ function Explode(Split, Player)
|
||||
|
||||
if not(HasExploded) then
|
||||
-- We have not broken out so far, therefore, the player must not exist, send failure
|
||||
SendMessageFailure(Player, Split[2] .. " was not found")
|
||||
Player:SendMessageFailure(Split[2] .. " was not found")
|
||||
end
|
||||
|
||||
return true
|
||||
|
@ -38,7 +38,7 @@ function Initialize(Plugin)
|
||||
-- _X: Disabled so that the normal operation doesn't interfere with anything
|
||||
-- PM:AddHook(cPluginManager.HOOK_CHUNK_GENERATED, OnChunkGenerated);
|
||||
|
||||
PM:BindCommand("/cm", "debuggers", HandleCustomNameCmd, "- Gives you a custom name");
|
||||
PM:BindCommand("/nick", "debuggers", HandleNickCmd, "- Gives you a custom name");
|
||||
PM:BindCommand("/le", "debuggers", HandleListEntitiesCmd, "- Shows a list of all the loaded entities");
|
||||
PM:BindCommand("/ke", "debuggers", HandleKillEntitiesCmd, "- Kills all the loaded entities");
|
||||
PM:BindCommand("/wool", "debuggers", HandleWoolCmd, "- Sets all your armor to blue wool");
|
||||
@ -66,6 +66,8 @@ function Initialize(Plugin)
|
||||
PM:BindCommand("/sb", "debuggers", HandleSetBiome, "- Sets the biome around you to the specified one");
|
||||
PM:BindCommand("/wesel", "debuggers", HandleWESel, "- Expands the current WE selection by 1 block in X/Z");
|
||||
PM:BindCommand("/rmitem", "debuggers", HandleRMItem, "- Remove the specified item from the inventory.");
|
||||
PM:BindCommand("/pickups", "debuggers", HandlePickups, "- Spawns random pickups around you");
|
||||
PM:BindCommand("/poof", "debuggers", HandlePoof, "- Nudges pickups close to you away from you");
|
||||
|
||||
Plugin:AddWebTab("Debuggers", HandleRequest_Debuggers)
|
||||
Plugin:AddWebTab("StressTest", HandleRequest_StressTest)
|
||||
@ -769,14 +771,13 @@ end
|
||||
|
||||
|
||||
|
||||
function HandleCustomNameCmd(Split, Player)
|
||||
function HandleNickCmd(Split, Player)
|
||||
if (Split[2] == nil) then
|
||||
Player:SendMessage("Usage: /cm [CustomName]");
|
||||
Player:SendMessage("Usage: /nick [CustomName]");
|
||||
return true;
|
||||
end
|
||||
|
||||
local NewName = Split[2]
|
||||
Player:SetCustomName(NewName);
|
||||
Player:SetCustomName(Split[2]);
|
||||
Player:SendMessageSuccess("Custom name setted to " .. Player:GetCustomName() .. "!")
|
||||
return true
|
||||
end
|
||||
@ -1517,7 +1518,7 @@ function OnPlayerJoined(a_Player)
|
||||
-- Test composite chat chaining:
|
||||
a_Player:SendMessage(cCompositeChat()
|
||||
:AddTextPart("Hello, ")
|
||||
:AddUrlPart(a_Player:GetName(), "www.mc-server.org", "u@2")
|
||||
:AddUrlPart(a_Player:GetName(), "http://www.mc-server.org", "u@2")
|
||||
:AddSuggestCommandPart(", and welcome.", "/help", "u")
|
||||
:AddRunCommandPart(" SetDay", "/time set 0")
|
||||
)
|
||||
@ -1575,3 +1576,57 @@ end
|
||||
|
||||
|
||||
|
||||
|
||||
local PossibleItems =
|
||||
{
|
||||
cItem(E_ITEM_DIAMOND),
|
||||
cItem(E_ITEM_GOLD),
|
||||
cItem(E_ITEM_IRON),
|
||||
cItem(E_ITEM_DYE, 1, E_META_DYE_BLUE), -- Lapis lazuli
|
||||
cItem(E_ITEM_COAL),
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function HandlePickups(a_Split, a_Player)
|
||||
local PlayerX = a_Player:GetPosX()
|
||||
local PlayerY = a_Player:GetPosY()
|
||||
local PlayerZ = a_Player:GetPosZ()
|
||||
local World = a_Player:GetWorld()
|
||||
local Range = 12
|
||||
for x = 0, Range do for z = 0, Range do
|
||||
local px = PlayerX + x - Range / 2
|
||||
local pz = PlayerZ + z - Range / 2
|
||||
local Items = cItems()
|
||||
Items:Add(PossibleItems[math.random(#PossibleItems)])
|
||||
World:SpawnItemPickups(Items, px, PlayerY, pz, 0)
|
||||
end end -- for z, for x
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
function HandlePoof(a_Split, a_Player)
|
||||
local PlayerPos = Vector3d(a_Player:GetPosition()) -- Create a copy of the position
|
||||
PlayerPos.y = PlayerPos.y - 1
|
||||
local Box = cBoundingBox(PlayerPos, 4, 2)
|
||||
local NumEntities = 0
|
||||
a_Player:GetWorld():ForEachEntityInBox(Box,
|
||||
function (a_Entity)
|
||||
if not(a_Entity:IsPlayer()) then
|
||||
local AddSpeed = a_Entity:GetPosition() - PlayerPos -- Speed away from the player
|
||||
a_Entity:AddSpeed(AddSpeed * 32 / (AddSpeed:SqrLength() + 1)) -- The further away, the less speed to add
|
||||
NumEntities = NumEntities + 1
|
||||
end
|
||||
end
|
||||
)
|
||||
a_Player:SendMessage("Poof! (" .. NumEntities .. " entities)")
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -40,8 +40,8 @@
|
||||
|
||||
# Need to list each of the four log types, otherwise all logs would get converted into apple planks (^0)
|
||||
|
||||
ApplePlanks, 4 = AppleLog, *
|
||||
ConiferPlanks, 4 = ConiferLog, *
|
||||
OakPlanks, 4 = OakLog, *
|
||||
SprucePlanks, 4 = SpruceLog, *
|
||||
BirchPlanks, 4 = BirchLog, *
|
||||
JunglePlanks, 4 = JungleLog, *
|
||||
AcaciaPlanks, 4 = AcaciaLog, *
|
||||
@ -67,6 +67,7 @@ DiamondBlock = Diamond, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3
|
||||
LapisBlock = LapisLazuli, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
EmeraldBlock = Emerald, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
RedstoneBlock = RedstoneDust, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
CoalBlock = Coal, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
QuartzBlock = NetherQuartz, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
NetherBrick = netherbrickitem, 1:1, 1:2, 2:1, 2:2
|
||||
Glowstone = GlowstoneDust, 1:1, 1:2, 2:1, 2:2
|
||||
@ -147,9 +148,6 @@ StoneBrickStairs, 4 = StoneBrick, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
RedSandstoneStairs, 4 = RedSandstone, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
RedSandstoneStairs, 4 = RedSandstone, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
|
||||
# Other
|
||||
Carpet = Wool, 1:3, 2:3
|
||||
|
||||
|
||||
|
||||
#******************************************************#
|
||||
@ -353,7 +351,7 @@ Clay, 4 = ClayBlock, *
|
||||
|
||||
Painting = Stick, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3 | Wool, 2:2
|
||||
ItemFrame = Stick, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3 | Leather, 2:2
|
||||
Sign = Planks, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2 | Stick, 2:3
|
||||
Sign, 3 = Planks, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2 | Stick, 2:3
|
||||
Ladder, 3 = Stick, 1:1, 3:1, 1:2, 2:2, 3:2, 1:3, 3:3
|
||||
GlassPane, 16 = Glass, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
|
||||
IronBars, 16 = IronIngot, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
|
||||
@ -451,13 +449,30 @@ PinkWool = Wool, * | PinkDye, *
|
||||
GrayWool = Wool, * | GrayDye, *
|
||||
LightGrayWool = Wool, * | LightGrayDye, *
|
||||
CyanWool = Wool, * | CyanDye, *
|
||||
VioletWool = Wool, * | VioletDye, *
|
||||
PurpleWool = Wool, * | PurpleDye, *
|
||||
BlueWool = Wool, * | BlueDye, *
|
||||
BrownWool = Wool, * | BrownDye, *
|
||||
GreenWool = Wool, * | GreenDye, *
|
||||
RedWool = Wool, * | RedDye, *
|
||||
BlackWool = Wool, * | BlackDye, *
|
||||
|
||||
WhiteCarpet, 3 = WhiteWool, 1:1, 2:1
|
||||
OrangeCarpet, 3 = OrangeWool, 1:1, 2:1
|
||||
MagentaCarpet, 3 = MagentaWool, 1:1, 2:1
|
||||
LightBlueCarpet, 3 = LightBlueWool, 1:1, 2:1
|
||||
YellowCarpet, 3 = YellowWool, 1:1, 2:1
|
||||
LimeCarpet, 3 = LimeWool, 1:1, 2:1
|
||||
PinkCarpet, 3 = PinkWool, 1:1, 2:1
|
||||
GrayCarpet, 3 = GrayWool, 1:1, 2:1
|
||||
LightGrayCarpet, 3 = LightGrayWool, 1:1, 2:1
|
||||
CyanCarpet, 3 = CyanWool, 1:1, 2:1
|
||||
PurpleCarpet, 3 = PurpleWool, 1:1, 2:1
|
||||
BlueCarpet, 3 = BlueWool, 1:1, 2:1
|
||||
BrownCarpet, 3 = BrownWool, 1:1, 2:1
|
||||
GreenCarpet, 3 = GreenWool, 1:1, 2:1
|
||||
RedCarpet, 3 = RedWool, 1:1, 2:2
|
||||
BlackCarpet, 3 = BlackWool, 1:1, 2:1
|
||||
|
||||
#******************************************************#
|
||||
# Stained Glass:
|
||||
#
|
||||
|
@ -1,5 +1,6 @@
|
||||
[Items]
|
||||
air=0
|
||||
stone=1
|
||||
rock=1
|
||||
granite=1:1
|
||||
polishedgranite=1:2
|
||||
@ -7,7 +8,6 @@ diorite=1:3
|
||||
polisheddiorite=1:4
|
||||
andesite=1:5
|
||||
polishedandesite=1:6
|
||||
stone=1
|
||||
grass=2
|
||||
dirt=3
|
||||
coarseddirt=3:1
|
||||
@ -15,11 +15,11 @@ podzol=3:2
|
||||
cobblestone=4
|
||||
cobble=4
|
||||
planks=5
|
||||
appleplanks=5:0
|
||||
oakplanks=5:0
|
||||
appleplanks=5:0
|
||||
spruceplanks=5:1
|
||||
coniferplanks=5:1
|
||||
pineplanks=5:1
|
||||
spruceplanks=5:1
|
||||
darkplanks=5:1
|
||||
birchplanks=5:2
|
||||
lightplanks=5:2
|
||||
@ -29,53 +29,59 @@ acaciaplanks=5:4
|
||||
darkoakplanks=5:5
|
||||
bigoakplanks=5:5
|
||||
roofedoakplanks=5:5
|
||||
|
||||
|
||||
; Obsolete: do not use "wood", as its meaning is not clear - wiki uses log as wood, we use planks as wood.
|
||||
wood=5
|
||||
|
||||
sapling=6
|
||||
applesapling=6:0
|
||||
oaksapling=6:0
|
||||
applesapling=6:0
|
||||
sprucesapling=6:1
|
||||
conifersapling=6:1
|
||||
pinesapling=6:1
|
||||
sprucesapling=6:1
|
||||
darkplanks=6:1
|
||||
birchsapling=6:2
|
||||
whitesapling=6:2
|
||||
junglesapling=6:3
|
||||
adminium=7
|
||||
redsapling=6:3
|
||||
acaciasapling=6:4
|
||||
darkoaksapling=6:5
|
||||
bigoaksapling=6:5
|
||||
roofedoaksapling=6:5
|
||||
bedrock=7
|
||||
adminium=7
|
||||
water=8
|
||||
flowingwater=8
|
||||
stationarywater=9
|
||||
stillwater=9
|
||||
swater=9
|
||||
stationarywater=9
|
||||
lava=10
|
||||
flowinglava=10
|
||||
stationarylava=11
|
||||
stilllava=11
|
||||
slava=11
|
||||
stationarylava=11
|
||||
sand=12
|
||||
redsand=12:1
|
||||
gravel=13
|
||||
goldore=14
|
||||
ironore=15
|
||||
coalore=16
|
||||
tree=17
|
||||
log=17
|
||||
applelog=17:0
|
||||
tree=17
|
||||
oaklog=17:0
|
||||
applelog=17:0
|
||||
sprucelog=17:1
|
||||
coniferlog=17:1
|
||||
pinelog=17:1
|
||||
sprucelog=17:1
|
||||
darklog=17:1
|
||||
birchlog=17:2
|
||||
whitelog=17:2
|
||||
junglelog=17:3
|
||||
leaves=18
|
||||
appleleaves=18:0
|
||||
oakleaves=18:0
|
||||
appleleaves=18:0
|
||||
spruceleaves=18:1
|
||||
coniferleaves=18:1
|
||||
pineleaves=18:1
|
||||
spruceleaves=18:1
|
||||
darkleaves=18:1
|
||||
birchleaves=18:2
|
||||
whiteleaves=18:2
|
||||
jungleleaves=18:3
|
||||
sponge=19
|
||||
wetsponge=19:1
|
||||
@ -85,8 +91,9 @@ lapisblock=22
|
||||
dispenser=23
|
||||
sandstone=24
|
||||
normalsandstone=24:0
|
||||
ornamentsandstone=24:1
|
||||
chiseledsandstone=24:1
|
||||
decorativesandstone=24:1
|
||||
ornamentsandstone=24:1
|
||||
smoothsandstone=24:2
|
||||
noteblock=25
|
||||
bedblock=26
|
||||
@ -101,14 +108,16 @@ deadbush=32
|
||||
piston=33
|
||||
pistonextension=34
|
||||
pistonhead=34
|
||||
cloth=35
|
||||
wool=35
|
||||
cloth=35
|
||||
whitewool=35:0
|
||||
orangewool=35:1
|
||||
magentawool=35:2
|
||||
lightbluewool=35:3
|
||||
ltbluewool=35:3
|
||||
yellowwool=35:4
|
||||
limewool=35:5
|
||||
ltbluewool=35:3
|
||||
lightgreenwool=35:5
|
||||
ltgreenwool=35:5
|
||||
pinkwool=35:6
|
||||
@ -122,11 +131,13 @@ lightgraywool=35:8
|
||||
lightgreywool=35:8
|
||||
ltgraywool=35:8
|
||||
ltgreywool=35:8
|
||||
silverwool=35:8
|
||||
cyanwool=35:9
|
||||
purplewool=35:10
|
||||
violetwool=35:10
|
||||
bluewool=35:11
|
||||
darkbluewool=35:11
|
||||
dkbluewool=35:11
|
||||
brownwool=35:12
|
||||
greenwool=35:13
|
||||
darkgreenwool=35:13
|
||||
@ -134,14 +145,12 @@ dkgreenwool=35:13
|
||||
redwool=35:14
|
||||
blackwool=35:15
|
||||
dandelion=37
|
||||
|
||||
; Renamed in 1.7, use "poppy" instead; kept for compatibility reasons, will be removed later on.
|
||||
rose=38
|
||||
|
||||
flower=38
|
||||
poppy=38
|
||||
rose=38
|
||||
flower=38
|
||||
blueorchid=38:1
|
||||
allium=38:2
|
||||
azurebluet=38:3
|
||||
redtulip=38:4
|
||||
orangetulip=38:5
|
||||
whitetulip=38:6
|
||||
@ -149,11 +158,12 @@ pinktulip=38:7
|
||||
oxeyedaisy=38:8
|
||||
brownmushroom=39
|
||||
redmushroom=40
|
||||
gold=41
|
||||
goldblock=41
|
||||
iron=42
|
||||
gold=41
|
||||
ironblock=42
|
||||
iron=42
|
||||
doubleslab=43
|
||||
doublestep=43
|
||||
stonedoubleslab=43:0
|
||||
sandstonedoubleslab=43:1
|
||||
wooddoubleslab=43:2
|
||||
@ -183,19 +193,19 @@ obsidian=49
|
||||
torch=50
|
||||
fire=51
|
||||
mobspawner=52
|
||||
woodstairs=53
|
||||
oakwoodstairs=53
|
||||
woodstairs=53
|
||||
chest=54
|
||||
redstonedust=55
|
||||
redstonewire=55
|
||||
redstonedust=55
|
||||
diamondore=56
|
||||
diamondblock=57
|
||||
workbench=58
|
||||
crop=59
|
||||
crops=59
|
||||
soil=60
|
||||
farmland=60
|
||||
tilleddirt=60
|
||||
soil=60
|
||||
furnace=61
|
||||
litfurnace=62
|
||||
signblock=63
|
||||
@ -207,11 +217,11 @@ track=66
|
||||
tracks=66
|
||||
cobblestonestairs=67
|
||||
stairs=67
|
||||
signblocktop=68
|
||||
wallsign=68
|
||||
signblocktop=68
|
||||
lever=69
|
||||
rockplate=70
|
||||
stoneplate=70
|
||||
rockplate=70
|
||||
irondoorblock=71
|
||||
woodplate=72
|
||||
redstoneore=73
|
||||
@ -228,13 +238,13 @@ reedblock=83
|
||||
jukebox=84
|
||||
fence=85
|
||||
pumpkin=86
|
||||
netherstone=87
|
||||
netherrack=87
|
||||
hellrock=87
|
||||
slowsand=88
|
||||
netherstone=87
|
||||
soulsand=88
|
||||
lightstone=89
|
||||
slowsand=88
|
||||
glowstone=89
|
||||
lightstone=89
|
||||
portal=90
|
||||
jackolantern=91
|
||||
jacko=91
|
||||
@ -243,22 +253,39 @@ whitestainedglass=95
|
||||
orangestainedglass=95:1
|
||||
magentastainedglass=95:2
|
||||
lightbluestainedglass=95:3
|
||||
ltbluestainedglass=95:3
|
||||
yellowstainedglass=95:4
|
||||
limestainedglass=95:5
|
||||
lightgreenstainedglass=95:5
|
||||
ltgreenstainedglass=95:5
|
||||
pinkstainedglass=95:6
|
||||
graystainedglass=95:7
|
||||
greystainedglass=95:7
|
||||
darkgraystainedglass=95:7
|
||||
darkgreystainedglass=95:7
|
||||
dkgraystainedglass=95:7
|
||||
dkgreystainedglass=95:7
|
||||
lightgraystainedglass=95:8
|
||||
lightgreystainedglass=95:8
|
||||
ltgraystainedglass=95:8
|
||||
ltgreystainedglass=95:8
|
||||
silverstainedglass=95:8
|
||||
cyanstainedglass=95:9
|
||||
purplestainedglass=95:10
|
||||
violetstainedglass=95:10
|
||||
bluestainedglass=95:11
|
||||
darkbluestainedglass=95:11
|
||||
dkbluestainedglass=95:11
|
||||
brownstainedglass=95:12
|
||||
greenstainedglass=95:13
|
||||
darkgreenstainedglass=95:13
|
||||
dkgreenstainedglass=95:13
|
||||
redstainedglass=95:14
|
||||
blackstainedglass=95:15
|
||||
trapdoor=96
|
||||
silverfishblock=97
|
||||
stonebricks=98
|
||||
stonebrick=98
|
||||
stonebricks=98
|
||||
mossystonebrick=98:1
|
||||
crackedstonebrick=98:2
|
||||
chiseledstonebrick=98:3
|
||||
@ -288,35 +315,36 @@ endstone=121
|
||||
dragonegg=122
|
||||
redstonelamp=123
|
||||
redstonelampoff=123
|
||||
litredstonelamp=124
|
||||
redstonelampon=124
|
||||
woodendoubleslab=125
|
||||
appledoublewoodslab=125:0
|
||||
oakwooddoubleslab=125:0
|
||||
appledoublewoodslab=125:0
|
||||
sprucewooddoubleslab=125:1
|
||||
coniferwooddoubleslab=125:1
|
||||
pinewooddoubleslab=125:1
|
||||
sprucewooddoubleslab=125:1
|
||||
darkwooddoubleslab=125:1
|
||||
birchwooddoubleslab=125:2
|
||||
whitewooddoubleslab=125:2
|
||||
junglewooddoubleslab=125:3
|
||||
acaciawooddoubleslab=125:4
|
||||
bigoakwooddoubleslab=125:5
|
||||
darkoakwooddoubleslab=125:5
|
||||
bigoakwooddoubleslab=125:5
|
||||
roofedwooddoubleslab=125:5
|
||||
woodenslab=126
|
||||
applewoodslab=126:0
|
||||
oakwoodslab=126:0
|
||||
applewoodslab=126:0
|
||||
sprucewoodslab=126:1
|
||||
coniferwoodslab=126:1
|
||||
pinewoodslab=126:1
|
||||
sprucewoodslab=126:1
|
||||
darkwoodslab=126:1
|
||||
birchwoodslab=126:2
|
||||
whitewoodslab=126:2
|
||||
junglewoodslab=126:3
|
||||
acaciawoodslab=126:4
|
||||
bigoakwoodslab=126:5
|
||||
darkoakwoodslab=126:5
|
||||
roofedwoodslab=126:5
|
||||
bigoakwoodslab=126:5
|
||||
cocoabeans=127
|
||||
sandstonestairs=128
|
||||
emeraldore=129
|
||||
@ -324,9 +352,9 @@ enderchest=130
|
||||
tripwirehook=131
|
||||
tripwire=132
|
||||
emeraldblock=133
|
||||
sprucewoodstairs=134
|
||||
coniferwoodstairs=134
|
||||
pinewoodstairs=134
|
||||
sprucewoodstairs=134
|
||||
darkwoodstairs=134
|
||||
birchwoodstairs=135
|
||||
whitewoodstairs=135
|
||||
@ -342,6 +370,7 @@ woodenbutton=143
|
||||
skeletonhead=144
|
||||
witherhead=144:1
|
||||
zombiehead=144:2
|
||||
playerhead=144:3
|
||||
humanhead=144:3
|
||||
stevehead=144:3
|
||||
creeperhead=144:4
|
||||
@ -365,47 +394,84 @@ whitestainedclay=159
|
||||
orangestainedclay=159:1
|
||||
magentastainedclay=159:2
|
||||
lightbluestainedclay=159:3
|
||||
ltbluestainedclay=159:3
|
||||
yellowstainedclay=159:4
|
||||
limestainedclay=159:5
|
||||
lightgreenstainedclay=159:5
|
||||
ltgreenstainedclay=159:5
|
||||
pinkstainedclay=159:6
|
||||
graystainedclay=159:7
|
||||
greystainedclay=159:7
|
||||
darkgraystainedclay=159:7
|
||||
darkgreystainedclay=159:7
|
||||
dkgraystainedclay=159:7
|
||||
dkgreystainedclay=159:7
|
||||
lightgraystainedclay=159:8
|
||||
lightgreystainedclay=159:8
|
||||
ltgraystainedclay=159:8
|
||||
ltgreystainedclay=159:8
|
||||
silverstainedclay=159:8
|
||||
cyanstainedclay=159:9
|
||||
purplestainedclay=159:10
|
||||
violetstainedclay=159:10
|
||||
bluestainedclay=159:11
|
||||
darkbluestainedclay=159:11
|
||||
dkbluestainedclay=159:11
|
||||
brownstainedclay=159:12
|
||||
greenstainedclay=159:13
|
||||
darkgreenstainedclay=159:13
|
||||
dkgreenstainedclay=159:13
|
||||
redstainedclay=159:14
|
||||
blackstainedclay=159:15
|
||||
whitestainedglasspane=160
|
||||
orangestainedglasspane=160:1
|
||||
magentastainedglasspane=160:2
|
||||
lightbluestainedglasspane=160:3
|
||||
ltbluestainedglasspane=160:3
|
||||
yellowstainedglasspane=160:4
|
||||
limestainedglasspane=160:5
|
||||
lightgreenstainedglasspane=160:5
|
||||
ltgreenstainedglasspane=160:5
|
||||
pinkstainedglasspane=160:6
|
||||
graystainedglasspane=160:7
|
||||
greystainedglasspane=160:7
|
||||
darkgraystainedglasspane=160:7
|
||||
darkgreystainedglasspane=160:7
|
||||
dkgraystainedglasspane=160:7
|
||||
dkgreystainedglasspane=160:7
|
||||
lightgraystainedglasspane=160:8
|
||||
lightgreystainedglasspane=160:8
|
||||
ltgraystainedglasspane=160:8
|
||||
ltgreystainedglasspane=160:8
|
||||
silverstainedglasspane=160:8
|
||||
cyanstainedglasspane=160:9
|
||||
purplestainedglasspane=160:10
|
||||
violetstainedglasspane=160:10
|
||||
bluestainedglasspane=160:11
|
||||
darkbluestainedglasspane=160:11
|
||||
dkbluestainedglasspane=160:11
|
||||
brownstainedglasspane=160:12
|
||||
greenstainedglasspane=160:13
|
||||
darkgreenstainedglasspane=160:13
|
||||
dkgreenstainedglasspane=160:13
|
||||
redstainedglasspane=160:14
|
||||
blackstainedglasspane=160:15
|
||||
acacialeaves=161
|
||||
bigoakleaves=161:1
|
||||
newleaves=161
|
||||
acacialeaves=161:0
|
||||
darkoakleaves=161:1
|
||||
bigoakleaves=161:1
|
||||
roofedoakleaves=161:1
|
||||
acacialog=162
|
||||
bigoaklog=162:1
|
||||
newlog=162
|
||||
acacialog=162:0
|
||||
darkoaklog=162:1
|
||||
bigoaklog=162:1
|
||||
roofedoaklog=162:1
|
||||
acaciawoodstairs=163
|
||||
bigoakwoodstiars=164
|
||||
darkoakwoodstairs=164
|
||||
bigoakwoodstiars=164
|
||||
roofedoakwoodstairs=164
|
||||
slimeblock=165
|
||||
barrier=166
|
||||
irontrapdoor=167
|
||||
prismarine=168
|
||||
prismarinebricks=168:1
|
||||
@ -413,15 +479,58 @@ darkprismarine=168:2
|
||||
sealantern=169
|
||||
haybale=170
|
||||
carpet=171
|
||||
whitecarpet=171:0
|
||||
orangecarpet=171:1
|
||||
magentacarpet=171:2
|
||||
lightbluecarpet=171:3
|
||||
ltbluecarpet=171:3
|
||||
yellowcarpet=171:4
|
||||
limecarpet=171:5
|
||||
lightgreencarpet=171:5
|
||||
ltgreencarpet=171:5
|
||||
pinkcarpet=171:6
|
||||
graycarpet=171:7
|
||||
greycarpet=171:7
|
||||
darkgraycarpet=171:7
|
||||
darkgreycarpet=171:7
|
||||
dkgraycarpet=171:7
|
||||
dkgreycarpet=171:7
|
||||
lightgraycarpet=171:8
|
||||
lightgreycarpet=171:8
|
||||
ltgraycarpet=171:8
|
||||
ltgreycarpet=171:8
|
||||
silvercarpet=171:8
|
||||
cyancarpet=171:9
|
||||
purplecarpet=171:10
|
||||
violetcarpet=171:10
|
||||
bluecarpet=171:11
|
||||
darkbluecarpet=171:11
|
||||
dkbluecarpet=171:11
|
||||
browncarpet=171:12
|
||||
greencarpet=171:13
|
||||
darkgreencarpet=171:13
|
||||
dkgreencarpet=171:13
|
||||
redcarpet=171:14
|
||||
blackcarpet=171:15
|
||||
hardenedclay=172
|
||||
coalblock=173
|
||||
packedice=174
|
||||
doubleplant=175
|
||||
sunflower=175:0
|
||||
lilac=175:1
|
||||
doubletallgrass=175:2
|
||||
doubletallfern=175:3
|
||||
rosebush=175:4
|
||||
peony=175:5
|
||||
redsandstone=179
|
||||
chiseledredsandstone=179:1
|
||||
smoothredsandstone=179:2
|
||||
redsandstonestairs=180
|
||||
redsandstoneslab=182
|
||||
newstoneslab=182
|
||||
redsandstoneslab=182:0
|
||||
sprucefencegate=183
|
||||
coniferfencegate=183
|
||||
pinefencegate=183
|
||||
sprucefencegate=183
|
||||
darkfencegate=183
|
||||
birchfencegate=184
|
||||
whitefencegate=184
|
||||
@ -430,9 +539,9 @@ darkoakfencegate=186
|
||||
bigoakfencegate=186
|
||||
roofedoakfencegate=186
|
||||
acaciafencegate=187
|
||||
sprucefence=188
|
||||
coniferfence=188
|
||||
pinefence=188
|
||||
sprucefence=188
|
||||
darkfence=188
|
||||
birchfence=189
|
||||
whitefence=189
|
||||
@ -453,7 +562,6 @@ redapple=260
|
||||
bow=261
|
||||
arrow=262
|
||||
coal=263
|
||||
coalblock=173
|
||||
charcoal=263:1
|
||||
diamond=264
|
||||
ironingot=265
|
||||
@ -466,9 +574,9 @@ ironsword=267
|
||||
woodensword=268
|
||||
woodsword=268
|
||||
woodenshovel=269
|
||||
woodspade=269
|
||||
woodshovel=269
|
||||
woodenspade=269
|
||||
woodspade=269
|
||||
woodenpickaxe=270
|
||||
woodpickaxe=270
|
||||
woodenpick=270
|
||||
@ -496,8 +604,8 @@ soup=282
|
||||
goldensword=283
|
||||
goldsword=283
|
||||
goldenshovel=284
|
||||
goldshovel=284
|
||||
goldenspade=284
|
||||
goldshovel=284
|
||||
goldspade=284
|
||||
goldenpickaxe=285
|
||||
goldpickaxe=285
|
||||
@ -508,13 +616,13 @@ goldaxe=286
|
||||
string=287
|
||||
feather=288
|
||||
gunpowder=289
|
||||
woodhoe=290
|
||||
woodenhoe=290
|
||||
woodhoe=290
|
||||
stonehoe=291
|
||||
ironhoe=292
|
||||
diamondhoe=293
|
||||
goldhoe=294
|
||||
goldenhoe=294
|
||||
goldhoe=294
|
||||
seeds=295
|
||||
wheat=296
|
||||
bread=297
|
||||
@ -543,19 +651,24 @@ goldpants=316
|
||||
goldenboots=317
|
||||
goldboots=317
|
||||
flint=318
|
||||
porkchop=319
|
||||
meat=319
|
||||
pork=319
|
||||
cookedporkchop=320
|
||||
cookedmeat=320
|
||||
cookedpork=320
|
||||
painting=321
|
||||
paintings=321
|
||||
goldenapple=322
|
||||
goldapple=322
|
||||
notchapple=322:1
|
||||
enchantedgoldenapple=322:1
|
||||
enchantedgoldapple=322:1
|
||||
sign=323
|
||||
wooddoor=324
|
||||
oakdoor=324
|
||||
appledoor=324
|
||||
woodendoor=324
|
||||
wooddoor=324
|
||||
bucket=325
|
||||
waterbucket=326
|
||||
lavabucket=327
|
||||
@ -569,32 +682,38 @@ leather=334
|
||||
milkbucket=335
|
||||
brick=336
|
||||
clay=337
|
||||
reed=338
|
||||
sugarcane=338
|
||||
reed=338
|
||||
paper=339
|
||||
book=340
|
||||
slimeorb=341
|
||||
slimeball=341
|
||||
slimeorb=341
|
||||
storageminecart=342
|
||||
poweredminecart=343
|
||||
egg=344
|
||||
compass=345
|
||||
fishingrod=346
|
||||
watch=347
|
||||
glowstonedust=348
|
||||
lightstonedust=348
|
||||
lightdust=348
|
||||
glowstonedust=348
|
||||
glowdust=348
|
||||
rawfish=349
|
||||
fish=349
|
||||
rawfish=349
|
||||
rawsalmon=349:1
|
||||
clownfish=349:2
|
||||
pufferfish=349:3
|
||||
cookedfish=350
|
||||
cookedsalmon=350:1
|
||||
dye=351
|
||||
inksac=351:0
|
||||
blackdye=351:0
|
||||
reddye=351:1
|
||||
rosered=351:1
|
||||
greendye=351:2
|
||||
reddye=351:1
|
||||
cactusgreen=351:2
|
||||
greendye=351:2
|
||||
darkgreendye=351:2
|
||||
dkgreendye=351:2
|
||||
cocoabeans=351:3
|
||||
browndye=351:3
|
||||
lapislazuli=351:4
|
||||
@ -604,12 +723,13 @@ dkbluedye=351:4
|
||||
purpledye=351:5
|
||||
violetdye=351:5
|
||||
cyandye=351:6
|
||||
lightgreydye=351:7
|
||||
lightgraydye=351:7
|
||||
ltgreydye=351:7
|
||||
lightgreydye=351:7
|
||||
ltgraydye=351:7
|
||||
greydye=351:8
|
||||
ltgreydye=351:7
|
||||
silverdye=351:7
|
||||
graydye=351:8
|
||||
greydye=351:8
|
||||
darkgreydye=351:8
|
||||
darkgraydye=351:8
|
||||
dkgreydye=351:8
|
||||
@ -675,6 +795,7 @@ goldencarrot=396
|
||||
skeletonhead=397
|
||||
witherhead=397:1
|
||||
zombiehead=397:2
|
||||
playerhead=397:3
|
||||
stevehead=397:3
|
||||
creeperhead=397:4
|
||||
carrotonastick=398
|
||||
@ -709,30 +830,46 @@ banner=425
|
||||
blackbanner=415:0
|
||||
redbanner=415:1
|
||||
greenbanner=415:2
|
||||
darkgreenbanner=415:2
|
||||
dkgreenbanner=415:2
|
||||
brownbanner=415:3
|
||||
bluebanner=415:4
|
||||
darkbluebanner=415:4
|
||||
dkbluebanner=415:4
|
||||
purplebanner=415:5
|
||||
violetbanner=415:5
|
||||
cyanbanner=415:6
|
||||
silverbanner=415:7
|
||||
lightgraybanner=415:7
|
||||
lightgreybanner=415:7
|
||||
ltgraybanner=415:7
|
||||
ltgreybanner=415:7
|
||||
silverbanner=415:7
|
||||
graybanner=415:8
|
||||
greybanner=415:8
|
||||
darkgraybanner=415:8
|
||||
darkgreybanner=415:8
|
||||
dkgraybanner=415:8
|
||||
dkgreybanner=415:8
|
||||
pinkbanner=415:9
|
||||
limebanner=415:10
|
||||
lightgreenbanner=415:10
|
||||
ltgreenbanner=415:10
|
||||
yellowbanner=415:11
|
||||
lightbluebanner=415:12
|
||||
ltbluebanner=415:12
|
||||
magentabanner=415:13
|
||||
orangebanner=415:14
|
||||
whitebanner=415:15
|
||||
sprucedoor=427
|
||||
coniferdoor=427
|
||||
pinedoor=427
|
||||
sprucedoor=427
|
||||
darkdoor=427
|
||||
birchdoor=428
|
||||
whitedoor=428
|
||||
jungledoor=429
|
||||
acaciadoor=430
|
||||
bigoakdoor=431
|
||||
darkoakdoor=431
|
||||
bigoakdoor=431
|
||||
roofedoakdoor=431
|
||||
goldrecord=2256
|
||||
greenrecord=2257
|
||||
@ -748,4 +885,3 @@ wardrecord=2265
|
||||
|
||||
|
||||
|
||||
|
||||
|
603
MCServer/lang/items_de.ini
Normal file
603
MCServer/lang/items_de.ini
Normal file
@ -0,0 +1,603 @@
|
||||
[Items]
|
||||
luft=0
|
||||
stein=1
|
||||
granit=1:1
|
||||
poliertergranit=1:2
|
||||
diorit=1:3
|
||||
polierterdiorit=1:4
|
||||
andesit=1:5
|
||||
polierterandesit=1:6
|
||||
grasblock=2
|
||||
erde=3
|
||||
grobeerde=3:1
|
||||
podsol=3:2
|
||||
bruchstein=4
|
||||
holzbretter=5
|
||||
eichenholzbretter=5:0
|
||||
fichtenholzbretter=5:1
|
||||
birkenholzbretter=5:2
|
||||
tropenholzbretter=5:3
|
||||
akazienholzbretter=5:4
|
||||
schwarzeichenholzbretter=5:5
|
||||
setzling=6
|
||||
eichensetzling=6:0
|
||||
fichtensetzling=6:1
|
||||
birkensetzling=6:2
|
||||
tropensetzling=6:3
|
||||
akaziensetzling=6:4
|
||||
schwarzeichensetzling=6:5
|
||||
grundgestein=7
|
||||
wasser=8
|
||||
fliessendeswasser=8
|
||||
stehendeswasser=9
|
||||
stilleswasser=9
|
||||
swasser=9
|
||||
lava=10
|
||||
fliessendelava=10
|
||||
stehendelava=11
|
||||
stillelava=11
|
||||
slava=11
|
||||
sand=12
|
||||
rotersand=12:1
|
||||
kies=13
|
||||
golderz=14
|
||||
eisenerz=15
|
||||
kohleerz=16
|
||||
stamm=17
|
||||
eichenholz=17:0
|
||||
fichtenholz=17:1
|
||||
birkenholz=17:2
|
||||
tropenholz=17:3
|
||||
laub=18
|
||||
eichenlaub=18:0
|
||||
fichtenlaub=18:1
|
||||
birkenlaub=18:2
|
||||
tropenlaub=18:3
|
||||
schwamm=19
|
||||
nasserschwamm=19:1
|
||||
glas=20
|
||||
lapislazulierz=21
|
||||
lapislazuliblock=22
|
||||
werfer=23
|
||||
sandstein=24
|
||||
normalersandstein=24:0
|
||||
gemeisseltersandstein=24:1
|
||||
glattersandstein=24:2
|
||||
notenblock=25
|
||||
bettblock=26
|
||||
antriebsschiene=27
|
||||
sensorschiene=28
|
||||
klebrigerkolben=29
|
||||
spinnenweben=30
|
||||
gras=31
|
||||
gras=31:1
|
||||
farn=31:2
|
||||
toterbusch=32
|
||||
kolben=33
|
||||
kolbenkopf=34
|
||||
wolle=35
|
||||
weissewolle=35:0
|
||||
orangenewolle=35:1
|
||||
magentawolle=35:2
|
||||
hellblauewolle=35:3
|
||||
gelbewolle=35:4
|
||||
hellgruene=35:5
|
||||
rosawolle=35:6
|
||||
grauwool=35:7
|
||||
greywool=35:7
|
||||
grauewolle=35:7
|
||||
hellgrauewolle=35:8
|
||||
tuerkisewolle=35:9
|
||||
violettewolle=35:10
|
||||
blauewolle=35:11
|
||||
braunewolle=35:12
|
||||
gruenewolle=35:13
|
||||
rotewolle=35:14
|
||||
schwarzewolle=35:15
|
||||
loewenzahn=37
|
||||
blume=38
|
||||
mohn=38:0
|
||||
blaueorchidee=38:1
|
||||
sternlauch=38:2
|
||||
porzellansternchen=38:3
|
||||
rotetulpe=38:4
|
||||
orangenetulpe=38:5
|
||||
weissetulpe=38:6
|
||||
rosatulpe=38:7
|
||||
margerite=38:8
|
||||
braunerpilz=39
|
||||
roterpilz=40
|
||||
goldblock=41
|
||||
eisenblock=42
|
||||
doppelstufe=43
|
||||
doppelsteinstufe=43:0
|
||||
doppelsandsteinstufe=43:1
|
||||
doppelholzstufe=43:2
|
||||
doppelbruchsteinstufe=43:3
|
||||
doppelziegelstufe=43:4
|
||||
doppelsteinziegelstufe=43:5
|
||||
doppelnetherziegelstufe=43:6
|
||||
doppelquarzstufe=43:7
|
||||
stufe=44
|
||||
steinstufe=44:0
|
||||
sandsteinstufe=44:1
|
||||
holzstufe=44:2
|
||||
bruchsteinstufe=44:3
|
||||
ziegelstufe=44:4
|
||||
steinziegelstufe=44:5
|
||||
netherziegelstufe=44:6
|
||||
quarzstufe=44:7
|
||||
ziegelsteine=45
|
||||
tnt=46
|
||||
buecherregal=47
|
||||
bemoosterbruchstein=48
|
||||
obsidian=49
|
||||
fackel=50
|
||||
feuer=51
|
||||
monsterspawner=52
|
||||
eichenholztreppe=53
|
||||
kiste=54
|
||||
rotstonekabel=55
|
||||
diamanterz=56
|
||||
diamantblock=57
|
||||
werkbank=58
|
||||
ernte=59
|
||||
farmland=60
|
||||
ofen=61
|
||||
brennenderofen=62
|
||||
schildblock=63
|
||||
holztuerblock=64
|
||||
leiter=65
|
||||
schiene=66
|
||||
bruchsteintreppe=67
|
||||
wandschild=68
|
||||
schalter=69
|
||||
steindruckplatte=70
|
||||
eisentuerblock=71
|
||||
holzdruckplatte=72
|
||||
rotstoneerz=73
|
||||
leuchtendesrotstoneerz=74
|
||||
erloschenerotstonefackel=75
|
||||
rotstonefackel=76
|
||||
setinknopf=77
|
||||
schnee=78
|
||||
eis=79
|
||||
schneeblock=80
|
||||
kaktus=81
|
||||
ton=82
|
||||
zuckerrohrblock=83
|
||||
plattenspieler=84
|
||||
eichenholzzaun=85
|
||||
kuerbis=86
|
||||
netherstein=87
|
||||
selensand=88
|
||||
leuchtstein=89
|
||||
portal=90
|
||||
kürbislaterne=91
|
||||
kuchenlock=92
|
||||
weissesglas=95
|
||||
orangenesglas=95:1
|
||||
magentaglas=95:2
|
||||
hellblauesglas=95:3
|
||||
gelbesglas=95:4
|
||||
hellgruenesglas=95:5
|
||||
rosagerfaerbtglas=95:6
|
||||
grauesglas=95:7
|
||||
hellgrauesglas=95:8
|
||||
tuerkisesglas=95:9
|
||||
violettesglas=95:10
|
||||
blauesglas=95:11
|
||||
braunesglas=95:12
|
||||
gruenesglas=95:13
|
||||
rotesglas=95:14
|
||||
schwarzesglas=95:15
|
||||
falltuer=96
|
||||
silberfischblock=97
|
||||
steinziegel=98
|
||||
bemoostesteinziegel=98:1
|
||||
rissigesteinziegel=98:2
|
||||
gemeisseltesteinziegel=98:3
|
||||
braunerpilzblock=99
|
||||
roterpilzblock=100
|
||||
eisengitter=101
|
||||
glasscheibe=102
|
||||
melone=103
|
||||
kuerbispflanze=104
|
||||
melonenpflanze=105
|
||||
ranken=106
|
||||
eichenholzzauntor=107
|
||||
ziegeltreppe=108
|
||||
steinziegeltreppe=109
|
||||
myzel=110
|
||||
seerosenblatt=111
|
||||
netherziegel=112
|
||||
netherziegelzaun=113
|
||||
netherziegeltreppe=114
|
||||
netherwarzenblock=115
|
||||
zaubertisch=116
|
||||
braustandblock=117
|
||||
kesselblock=118
|
||||
endportal=119
|
||||
endportalrahmen=120
|
||||
endstein=121
|
||||
drachenei=122
|
||||
redstonelampe=123
|
||||
erlosscheneredstonelampe=124
|
||||
doppelholzstufe=125
|
||||
doppeleichenholzstufe=125:0
|
||||
doppelfichtenholzstufe=125:1
|
||||
doppelbirkenholzstufe=125:2
|
||||
doppeltropenholzstufe=125:3
|
||||
doppelakazienholzstufe=125:4
|
||||
doppelschwarzeichenstufe=125:5
|
||||
holzstufe=126
|
||||
eichenholzstufe=126:0
|
||||
fichtenholzstufe=126:1
|
||||
birkenholzstufe=126:2
|
||||
tropenholzstufe=126:3
|
||||
akazienholzstufe=126:4
|
||||
schwarzeichenholzstufe=126:5
|
||||
kakaobohnen=127
|
||||
sandsteintreppe=128
|
||||
smaragderz=129
|
||||
endertruhe=130
|
||||
haken=131
|
||||
stolperdraht=132
|
||||
smaragdblock=133
|
||||
fichtenholztreppe=134
|
||||
birkenholztreppe=135
|
||||
tropenholztreppe=136
|
||||
kommandoblock=137
|
||||
leuchtfeuer=138
|
||||
bruchsteinmauer=139
|
||||
bemoostebruchsteinmauer=139:1
|
||||
blumentopfblock=140
|
||||
karottenpflanze=141
|
||||
kartoffelpflanze=142
|
||||
knopf=143
|
||||
skelettschaedel=144
|
||||
witherskelettschaedel=144:1
|
||||
zombieschaedel=144:2
|
||||
schaedel=144:3
|
||||
creeperschaedel=144:4
|
||||
amboss=145
|
||||
redstonetruhe=146
|
||||
waegeplatteniedrigegewichte=147 # WTF, that names are so stupid...
|
||||
waegeplattehohegewichte=148
|
||||
inaktiverkomparator=149
|
||||
aktiverkomparator=150
|
||||
tageslichtsensor=151
|
||||
redstoneblock=152
|
||||
netherquarzerz=153
|
||||
trichter=154
|
||||
quarzblock=155
|
||||
gemeisselterquarzblock=155:1
|
||||
quarzsaeule=155:2
|
||||
quarztreppe=156
|
||||
aktivierungsschiene=157
|
||||
spender=158
|
||||
weissgerfaerbterton=159
|
||||
orangegerfaerbterton=159:1
|
||||
magentagerfaerbterton=159:2
|
||||
hellblaugerfaerbterton=159:3
|
||||
gelbgerfaerbterton=159:4
|
||||
hellgruengerfaerbterton=159:5
|
||||
rosagerfaerbterton=159:6
|
||||
graugerfaerbterton=159:7
|
||||
hellgraugefaerbterton=159:8
|
||||
tuerkisgerfaerbterton=159:9
|
||||
purplegerfaerbterton=159:10
|
||||
violettegerfaerbterton=159:10
|
||||
blaugerfaerbterton=159:11
|
||||
braungerfaerbterton=159:12
|
||||
gruengerfaerbterton=159:13
|
||||
rotgerfaerbterton=159:14
|
||||
schwarzgerfaerbterton=159:15
|
||||
weisseglasscheibe=160
|
||||
orangeneglasscheibe=160:1
|
||||
magentaglasscheibe=160:2
|
||||
hellblaueglasscheibe=160:3
|
||||
gelbeglasscheibe=160:4
|
||||
hellgrueneglasscheibe=160:5
|
||||
rosaglasscheibe=160:6
|
||||
graueglasscheibe=160:7
|
||||
hellgraueglasscheibe=160:8
|
||||
tuerkiseglasscheibe=160:9
|
||||
violetteglasscheibe=160:10
|
||||
blaueglasscheibe=160:11
|
||||
brauneglasscheibe=160:12
|
||||
grueneglasscheibe=160:13
|
||||
roteglasscheibe=160:14
|
||||
schwarzeglasscheibe=160:15
|
||||
neueslaub=161
|
||||
akazienlaub=161:0
|
||||
schwarzeichenlaub=161:1
|
||||
neuestaemme=162
|
||||
akazienholz=162:0
|
||||
schwarzeichenholz=162:1
|
||||
akazientreppe=163
|
||||
schwarzeichentreppe=164
|
||||
schleimblock=165
|
||||
bartriere=166
|
||||
eisenfalltür=167
|
||||
prismarin=168
|
||||
prismarinziegel=168:1
|
||||
dunklerprismarin=168:2
|
||||
seelaterne=169
|
||||
strohballen=170
|
||||
teppich=171
|
||||
weisserteppich=171:0
|
||||
orangenerteppich=171:1
|
||||
magentateppich=171:2
|
||||
hellblauerteppich=171:3
|
||||
gelberteppich=171:4
|
||||
hellgruenerteppich=171:5
|
||||
rosateppich=171:6
|
||||
grauerteppich=171:7
|
||||
hellgrauerteppich=171:8
|
||||
tuerkiserteppich=171:9
|
||||
violetterteppich=171:10
|
||||
blauerteppich=171:11
|
||||
braunerteppich=171:12
|
||||
gruenerteppich=171:13
|
||||
roterteppich=171:14
|
||||
schwarzerteppich=171:15
|
||||
gebrannterton=172
|
||||
kohleblock=173
|
||||
packeis=174
|
||||
doppelpflanze=175
|
||||
sonnenblume=175:0
|
||||
Flieder=175:1
|
||||
hohesgras=175:2
|
||||
grosserfarn=175:3
|
||||
rosenstrauch=175:4
|
||||
pfingstrose=175:5
|
||||
rotersandstein=179
|
||||
gemeisselterrotersandstein=179:1
|
||||
glatterrotersandstein=179:2
|
||||
rotesandsteintreppe=180
|
||||
neuesteinstufe=182
|
||||
rotesandsteinstufe=182:0
|
||||
fichtenzauntor=183
|
||||
birkenzauntor=184
|
||||
tropenzauntor=185
|
||||
schwarzeichenzauntor=186
|
||||
akazienzauntor=187
|
||||
fichtenzaun=188
|
||||
birkenzaun=189
|
||||
tropenzaun=190
|
||||
schwarzeichenzaun=191
|
||||
akazienzaun=192
|
||||
eisenschaufel=256
|
||||
eisenspitzhacke=257
|
||||
eisenaxt=258
|
||||
feuerzeug=259
|
||||
apfel=260
|
||||
bogen=261
|
||||
pfeil=262
|
||||
kohle=263
|
||||
holzkohle=263:1
|
||||
diamant=264
|
||||
eisenbarren=265
|
||||
goldbarren=266
|
||||
eisenschwert=267
|
||||
holzschwert=268
|
||||
holzschaufel=269
|
||||
holzspitzhacke=270
|
||||
holzaxt=271
|
||||
steinschwert=272
|
||||
steinschaufel=273
|
||||
steinspitzhacke=274
|
||||
steinaxt=275
|
||||
diamantschwert=276
|
||||
diamantschaufel=277
|
||||
diamantspitzhacke=278
|
||||
diamantaxt=279
|
||||
stock=280
|
||||
schuessel=281
|
||||
pilzsuppe=282
|
||||
goldschwert=283
|
||||
goldschaufel=284
|
||||
goldspitzhacke=285
|
||||
goldaxt=286
|
||||
faden=287
|
||||
feder=288
|
||||
schwarzpulver=289
|
||||
holzhacke=290
|
||||
steinhacke=291
|
||||
eisenhacke=292
|
||||
diamanthacke=293
|
||||
goldhacke=294
|
||||
samen=295
|
||||
weizen=296
|
||||
brot=297
|
||||
lederkappe=298
|
||||
lederjacke=299
|
||||
lederhose=300
|
||||
lederstiefel=301
|
||||
kettenhaube=302
|
||||
kettenhemd=303
|
||||
kettenhose=304
|
||||
kettenstiefel=305
|
||||
eisenhelm=306
|
||||
eisenbrustplatte=307
|
||||
eisenbeinschutz=308
|
||||
eisenstiefel=309
|
||||
diamanthelm=310
|
||||
diamantbrustplatte=311
|
||||
diamantbeinschutz=312
|
||||
diamantstiefel=313
|
||||
goldhelm=314
|
||||
goldharnisch=315
|
||||
goldbeinschutz=316
|
||||
goldstiefel=317
|
||||
goldboots=317
|
||||
feuerstein=318
|
||||
rohesschweinefleisch=319
|
||||
gebratenesschweinefleisch=320
|
||||
gemaelde=321
|
||||
goldenerapfel=322
|
||||
goldenerapfel=322:1
|
||||
schild=323
|
||||
eichenholztuer=324
|
||||
eimer=325
|
||||
wassereimer=326
|
||||
lavaeimer=327
|
||||
lore=328
|
||||
sattel=329
|
||||
eisentuer=330
|
||||
redstone=331
|
||||
schneeballl=332
|
||||
boot=333
|
||||
leder=334
|
||||
milcht=335
|
||||
ziegel=336
|
||||
ton=337
|
||||
zuckercane=338
|
||||
papier=339
|
||||
buch=340
|
||||
schleimball=341
|
||||
gueterlore=342
|
||||
angetriebenelore=343
|
||||
ei=344
|
||||
kompass=345
|
||||
angel=346
|
||||
uhr=347
|
||||
glowstonestaub=348
|
||||
fisch=349
|
||||
roherfisch=349
|
||||
roherlachs=349:1
|
||||
clownfisch=349:2
|
||||
kugelfisch=349:3
|
||||
gebratenerfisch=350
|
||||
gebratenerlachs=350:1
|
||||
farbe=351
|
||||
tintenbeutel=351:0
|
||||
rosenrot=351:1
|
||||
kaktusgruen=351:2
|
||||
kakaobohnen=351:3
|
||||
lapislazuli=351:4
|
||||
violetterfarbstoff=351:5
|
||||
tuerkiserfarbstoff=351:6
|
||||
hellgrauerfarbstoff=351:7
|
||||
grauerfarbstoff=351:8
|
||||
rosafarbstoff=351:9
|
||||
hellgruenerfarbstoff=351:10
|
||||
gelberfarbstoff=351:11
|
||||
hellblauerfarbstoff=351:12
|
||||
magentafarbstoff=351:13
|
||||
orangenerfarbstoff=351:14
|
||||
knochenmehl=351:15
|
||||
knochen=352
|
||||
zucker=353
|
||||
kuchen=354
|
||||
bett=355
|
||||
redstoneverstaerker=356
|
||||
keks=357
|
||||
karte=358
|
||||
schere=359
|
||||
melone=360
|
||||
kürbiskerne=361
|
||||
melonenkerne=362
|
||||
rohesrindfleisch=363
|
||||
steak=364
|
||||
roheshühnchen=365
|
||||
gebrateneshühnchen=366
|
||||
verrottetesfleisch=367
|
||||
enderperle=368
|
||||
lohenrute=369
|
||||
ghasttraene=370
|
||||
goldnugget=371
|
||||
netherwarze=372
|
||||
trank=373
|
||||
glasflasche=374
|
||||
spinnenauge=375
|
||||
fermentiertesspinnenauge=376
|
||||
lohenstaub=377
|
||||
magmacreme=378
|
||||
braustand=379
|
||||
kessel=380
|
||||
enderauge=381
|
||||
glitzerndemelone=382
|
||||
spawnei=383
|
||||
erfahrungsfläschchen=384
|
||||
feuerkugel=385
|
||||
buchundfeder=386
|
||||
beschriebenesbuch=387
|
||||
smaragd=388
|
||||
rahmen=389
|
||||
blumentopf=390
|
||||
karotte=391
|
||||
kartoffel=392
|
||||
ofenkartoffel=393
|
||||
giftigekartoffel=394
|
||||
leerekarte=395
|
||||
goldenekarotte=396
|
||||
skelettschaedel=397
|
||||
witherschaedel=397:1
|
||||
zombieschaedel=397:2
|
||||
kopf=397:3
|
||||
creeperschaedel=397:4
|
||||
karottenrute=398
|
||||
netherstern=399
|
||||
kuerbiskuchen=400
|
||||
feuerwerksrakete=401
|
||||
feuerwerksstern=402
|
||||
verzauberungsbuch=403
|
||||
redstonekomparator=404
|
||||
netherziegelitem=405
|
||||
netherquarz=406
|
||||
tntlore=407
|
||||
trichterlore=408
|
||||
prismarinscherbe=409
|
||||
prismarinkristalle=410
|
||||
roheskaninchen=411
|
||||
gebrateneskaninchen=412
|
||||
kaninchenragout=413
|
||||
hasenpfote=414
|
||||
kaninchenfell=415
|
||||
ruestungsstaender=416
|
||||
eisernepferderuestung=417
|
||||
goldenepferderuestung=418
|
||||
diamantenepferderuestung=419
|
||||
leine=420
|
||||
namensschild=421
|
||||
kommandoblocklore=422
|
||||
roheshammelfleisch=423
|
||||
gebrateneshammelfleisch=424
|
||||
banner=425
|
||||
schwarzesbanner=415:0
|
||||
rotesbanner=415:1
|
||||
gruenesbanner=415:2
|
||||
braunbanner=415:3
|
||||
blauesbanner=415:4
|
||||
violettesbanner=415:5
|
||||
tuerkisesbanner=415:6
|
||||
hellgrauesbanner=415:7
|
||||
grauesbanner=415:8
|
||||
rosabanner=415:9
|
||||
hellgruenesbanner=415:10
|
||||
gelbesbanner=415:11
|
||||
hellblauesbanner=415:12
|
||||
magentabanner=415:13
|
||||
orangenesbanner=415:14
|
||||
weissesbanner=415:15
|
||||
fichtenholztuer=427
|
||||
birkenholztuer=428
|
||||
tropentuer=429
|
||||
akazientuer=430
|
||||
schwarzeichentuer=431
|
||||
goldeneschallplatte=2256
|
||||
grueneschallplatte=2257
|
||||
blocksschallplatte=2258
|
||||
chirpschallplatte=2259
|
||||
farschallplatte=2260
|
||||
mallschallplatte=2261
|
||||
mellohischallplatte=2262
|
||||
stalschallplatte=2263
|
||||
stradschallplatte=2264
|
||||
wardschallplatte=2265
|
||||
11schallplatte=2266
|
||||
|
||||
|
||||
|
BIN
MCServer/webadmin/files/background.gif
Normal file
BIN
MCServer/webadmin/files/background.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 57 B |
BIN
MCServer/webadmin/files/favicon.ico
Normal file
BIN
MCServer/webadmin/files/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
BIN
MCServer/webadmin/files/logo.png
Normal file
BIN
MCServer/webadmin/files/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
BIN
MCServer/webadmin/files/mc-logo.png
Normal file
BIN
MCServer/webadmin/files/mc-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 65 KiB |
326
MCServer/webadmin/files/style.css
Normal file
326
MCServer/webadmin/files/style.css
Normal file
@ -0,0 +1,326 @@
|
||||
/* reset CSS */
|
||||
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, font, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
font-size: 100%;
|
||||
vertical-align: baseline;
|
||||
background: transparent;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
blockquote, q {
|
||||
quotes: none;
|
||||
}
|
||||
|
||||
/* remember to define focus styles! */
|
||||
:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
/* remove textarea resize at Safari */
|
||||
textarea {
|
||||
resize: none;
|
||||
}
|
||||
|
||||
/* remember to highlight inserts somehow! */
|
||||
ins {
|
||||
text-decoration: none;
|
||||
}
|
||||
del {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
/* tables still need 'cellspacing="0"' in the markup */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Origional from http://www.perspectived.com/
|
||||
Modified by Ben Phelps
|
||||
Made for FakeTruth - MCServer
|
||||
*/
|
||||
|
||||
/* Basic ---------------------------------------- */
|
||||
|
||||
.clear { clear: both; }
|
||||
|
||||
body {
|
||||
background: white;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 12px;
|
||||
color: #646464;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#wrapper {
|
||||
text-align: left;
|
||||
width: 930px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Logo ---------------------------------------- */
|
||||
|
||||
h1 {
|
||||
margin: 15px 0 10px 5px;
|
||||
width: 180px;
|
||||
height: 36px;
|
||||
background: url(logo.png) no-repeat left top;
|
||||
}
|
||||
|
||||
h1 a {
|
||||
display: block;
|
||||
width: 225px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
h1 span { display: none; }
|
||||
|
||||
a {
|
||||
color: #646464;
|
||||
}
|
||||
|
||||
/* Container ---------------------------------------- */
|
||||
|
||||
#containerHolder {
|
||||
background: #eee;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
|
||||
#container {
|
||||
background: #fff url(background.gif) repeat-y left top;
|
||||
border: 1px solid #ddd;
|
||||
width: 918px;
|
||||
|
||||
}
|
||||
|
||||
#connectHolder {
|
||||
background: #eee;
|
||||
padding: 5px;
|
||||
margin-bottom:8px;
|
||||
}
|
||||
|
||||
|
||||
#connect {
|
||||
border: 1px solid #ddd;
|
||||
background-color: #fff;
|
||||
padding:5px;
|
||||
width: 908px;
|
||||
}
|
||||
|
||||
.pics {
|
||||
height: 375px;
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
.pics img {
|
||||
padding: 5px;
|
||||
border: 1px solid #ddd;
|
||||
background-color: #eee;
|
||||
width: 600px;
|
||||
height: 375px;
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
/* Login -------------------------------------- */
|
||||
|
||||
#loginLogo {
|
||||
margin: 0 auto;
|
||||
margin-top:100px;
|
||||
width: 180px;
|
||||
height: 36px;
|
||||
background-image: url(logo.png);
|
||||
}
|
||||
|
||||
#loginHolder {
|
||||
background: #eee;
|
||||
padding: 5px;
|
||||
width: 310px;
|
||||
margin: 0 auto;
|
||||
height: 90px;
|
||||
margin-top:20px;
|
||||
}
|
||||
|
||||
#login {
|
||||
padding:10px;
|
||||
width: 288px;
|
||||
height: 68px;
|
||||
border: 1px solid #ddd;
|
||||
background:#fff;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
|
||||
/* Sidebar ---------------------------------------- */
|
||||
|
||||
#sidebar {
|
||||
width: 179px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#sidebar .sideNav { width: 179px; }
|
||||
|
||||
#sidebar .sideNav li { border-bottom: 1px solid #ddd; width: 179px; }
|
||||
|
||||
#sidebar .sideNav li a {
|
||||
display: block;
|
||||
color: #646464;
|
||||
background: #f6f6f6;
|
||||
text-decoration: none;
|
||||
height: 29px;
|
||||
line-height: 29px;
|
||||
padding: 0 19px;
|
||||
width: 141px;
|
||||
}
|
||||
|
||||
#sidebar .sideNav li a:hover { background: #fdfcf6; }
|
||||
|
||||
#sidebar .sideNav li a.active, #sidebar .sideNav li a.active:hover {
|
||||
background: #f0f7fa;
|
||||
color: #c66653;
|
||||
}
|
||||
|
||||
/* Breadcrumb ---------------------------------------- */
|
||||
|
||||
h2 {
|
||||
width: 718px;
|
||||
float: right;
|
||||
color: #646464;
|
||||
font-size: 16px;
|
||||
line-height: 16px;
|
||||
font-weight: bold;
|
||||
margin: 20px 0 0 0;
|
||||
padding: 0 0 10px 0;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
h2 a {
|
||||
color: #646464;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h2 a.active { color: #c66653; }
|
||||
|
||||
h2 a:hover { text-decoration: underline; }
|
||||
|
||||
/* Content ---------------------------------------- */
|
||||
|
||||
#main {
|
||||
width: 700px;
|
||||
float: right;
|
||||
padding: 0 19px 0 0;
|
||||
}
|
||||
|
||||
#main p {
|
||||
|
||||
padding: 10px;
|
||||
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 14px;
|
||||
line-height: 14px;
|
||||
font-weight: bold;
|
||||
color: #5494af;
|
||||
padding: 0 0 0 10px;
|
||||
margin: 20px 0 10px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
padding: 0 0 0 10px;
|
||||
margin: 20px 0 10px;
|
||||
}
|
||||
|
||||
#main ul {
|
||||
padding: 0 0 0 10px;
|
||||
list-style-type: circle;
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
#main table {
|
||||
border-top: 1px solid #ddd;
|
||||
width: 700px;
|
||||
}
|
||||
|
||||
#main table tr th {
|
||||
text-align: left;
|
||||
background: #f6f6f6;
|
||||
padding: 0px 20px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
#main table tr td {
|
||||
background: #f6f6f6;
|
||||
padding: 0px 20px;
|
||||
height: 29px;
|
||||
line-height: 29px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
#main table tr.odd td {
|
||||
background: #fbfbfb;
|
||||
}
|
||||
|
||||
#main table tr:hover td { background: #fdfcf6; }
|
||||
|
||||
#main table .action {
|
||||
text-align: right;
|
||||
padding: 0 20px 0 10px;
|
||||
}
|
||||
|
||||
#main table tr .action a { margin: 0 0 0 10px; text-decoration: none; color: #9b9b9b; }
|
||||
#main table tr:hover .action .edit { color: #c5a059; }
|
||||
#main table tr:hover .action .delete { color: #a02b2b; }
|
||||
#main table tr:hover .action .view { color: #55a34a; }
|
||||
|
||||
#main table tr:hover .action a:hover { text-decoration: underline; }
|
||||
|
||||
fieldset {
|
||||
border: 1px solid #ddd;
|
||||
padding: 19px;
|
||||
margin: 0 0 20px 0;
|
||||
background: #fbfbfb;
|
||||
}
|
||||
|
||||
form p { margin: 0 0 14px 0; float: left; width: 100%; }
|
||||
|
||||
label {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin: 0 0 7px 0;
|
||||
line-height: 12px;
|
||||
}
|
||||
|
||||
/* Footer ---------------------------------------- */
|
||||
|
||||
#footer {
|
||||
margin: 10px 0 30px 0;
|
||||
font-size: 11px;
|
||||
line-height: 11px;
|
||||
color: #9B9B9B;
|
||||
padding: 0 0 0 5px;
|
||||
}
|
||||
|
||||
#footer a { color: #9B9B9B; }
|
||||
|
||||
#footer a:hover { text-decoration: none; }
|
25
MCServer/webadmin/login_template.html
Normal file
25
MCServer/webadmin/login_template.html
Normal file
@ -0,0 +1,25 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>MCServer WebAdmin - Login</title>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="favicon.ico">
|
||||
<style type="text/css">
|
||||
header {
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header>
|
||||
<img src="mc-logo.png" alt="MCServer Logo" class="logo">
|
||||
<h1>MCServer - WebAdmin</h1>
|
||||
<form method="get" action="webadmin/">
|
||||
<input type="submit" value="Log in">
|
||||
</form>
|
||||
</header>
|
||||
</body>
|
||||
|
||||
</html>
|
File diff suppressed because one or more lines are too long
@ -1,209 +0,0 @@
|
||||
@echo off
|
||||
:: Nightbbuild2008.cmd
|
||||
:: This script is run every night to produce a new version of MCServer, backup its PDB files and upload the packages to web.
|
||||
:: When run without parameters, this script pauses at the end and waits for a keypress.
|
||||
:: To run in an automated scheduler, add any parameter to disable waiting for a keystroke
|
||||
::
|
||||
:: The sript creates a symbol store (a database of PDB files) that can be used as a single entry in MSVC's symbol path,
|
||||
:: then any executable / crashdump built by this script can be debugged and its symbols will be found automatically by MSVC,
|
||||
:: without the users needing to specify the build version or anything.
|
||||
:: In order to support pruning the symstore, a per-month store is created, so that old months can be removed when no longer needed.
|
||||
::
|
||||
:: This script expects a few tools on specific paths, you can pass the correct paths for your system as env vars "zip" and "vc"
|
||||
:: This script assumes that "git", "symstore" and "touch" are available on PATH.
|
||||
:: git comes from msysgit
|
||||
:: symstore comes from Microsoft's Debugging Tools for Windows
|
||||
:: touch comes from unxtools
|
||||
:: This script is locale-dependent, because it parses the output of "time" and "date" shell commands
|
||||
|
||||
|
||||
:: 7-zip executable (by default it should be on PATH):
|
||||
if %zip%a == a set zip=7z
|
||||
|
||||
:: Visual C++ compiler executable name:
|
||||
if %vc%a == a set vc="vcbuild.exe"
|
||||
|
||||
|
||||
|
||||
|
||||
:: Check that the required environment vars are available:
|
||||
if "a%ftppass%" == "a" (
|
||||
echo You need to set FTP password in the ftppass environment variable to upload the files
|
||||
goto haderror
|
||||
)
|
||||
if "a%ftpuser%" == "a" (
|
||||
echo You need to set FTP username in the ftpuser environment variable to upload the files
|
||||
goto haderror
|
||||
)
|
||||
if "a%ftpsite%" == "a" (
|
||||
echo You need to set FTP server in the ftpsite environment variable to upload the files
|
||||
goto haderror
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
:: Get the date and time into vars:
|
||||
:: This is locale-dependent!
|
||||
For /f "tokens=2-4 delims=/. " %%a in ('date /t') do (
|
||||
set MYYEAR=%%c
|
||||
set MYMONTH=%%b
|
||||
set MYDAY=%%a
|
||||
)
|
||||
For /f "tokens=1-2 delims=/:" %%a in ('time /t') do (set MYTIME=%%a_%%b)
|
||||
|
||||
echo Performing nightbuild of MC-Server
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
set DONOTPAUSE=y
|
||||
|
||||
:: Update the sources to the latest revision:
|
||||
git pull
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
:: Update the external plugins to the latest revision:
|
||||
git submodule update
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
|
||||
:: Get the Git commit ID into an environment var
|
||||
For /f "tokens=1 delims=/. " %%a in ('git log -1 --oneline --no-abbrev-commit') do (set COMMITID=%%a)
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
:: Test if the version is already present, using a "tagfile" that we create upon successful build
|
||||
set TAGFOLDER=Install\%MYYEAR%_%MYMONTH%\
|
||||
set TAGFILE=%TAGFOLDER%built_%COMMITID%.tag
|
||||
echo Tag file: %TAGFILE%
|
||||
if exist %TAGFILE% (
|
||||
echo Latest version already present, bailing out
|
||||
goto end
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:: Configure the sources to use the MSVC2008 compiler:
|
||||
cmake -G "Visual Studio 9 2008" .
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:: Update the Bindings:
|
||||
echo Updating Lua bindings
|
||||
del src\Bindings\Bindings.cpp
|
||||
del src\Bindings\Bindings.h
|
||||
set ALLTOLUA_WAIT=N
|
||||
cd src\Bindings
|
||||
call AllToLua.bat
|
||||
cd ..\..
|
||||
|
||||
|
||||
|
||||
|
||||
:: Compile using VC2008 Express. Do a full rebuild.
|
||||
echo Setting up VS environment...
|
||||
call "%VS90COMNTOOLS%\vsvars32.bat"
|
||||
echo Compiling MCServer...
|
||||
title MCS Nightbuild
|
||||
start "vc" /b /wait /low /min %vc% /r MCServer.sln "Release|Win32"
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
|
||||
:: Generate the .example.ini files by running the server without any ini files:
|
||||
cd MCServer
|
||||
del groups.ini
|
||||
del settings.ini
|
||||
del webadmin.ini
|
||||
echo stop | MCServer
|
||||
cd ..
|
||||
|
||||
|
||||
|
||||
:: Copy all the example ini files into the Install folder for zipping:
|
||||
copy MCServer\groups.ini Install\groups.example.ini
|
||||
copy MCServer\settings.ini Install\settings.example.ini
|
||||
copy MCServer\webadmin.ini Install\webadmin.example.ini
|
||||
|
||||
|
||||
|
||||
|
||||
:: Use 7-zip to compress the resulting files into a single file:
|
||||
set FILESUFFIX=%MYYEAR%_%MYMONTH%_%MYDAY%_%MYTIME%_%COMMITID%
|
||||
echo FILESUFFIX=%FILESUFFIX%
|
||||
copy MCServer\MCServer.exe Install\MCServer.exe
|
||||
cd Install
|
||||
%zip% a -mx9 -y MCServer_Win_%FILESUFFIX%.7z -scsWIN -i@Zip2008.list -xr!*.git*
|
||||
if errorlevel 1 goto haderror
|
||||
cd ..
|
||||
|
||||
:: Also pack PDBs into a separate archive:
|
||||
%zip% a -mx9 -y Install\PDBs_%FILESUFFIX%.7z -scsWIN @Install\Zip2008_PDBs.list
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:: upload to the FTP:
|
||||
:upload
|
||||
ncftpput -p %ftppass% -u %ftpuser% -T temp_ %ftpsite% / Install\MCServer_Win_%FILESUFFIX%.7z
|
||||
if errorlevel 1 goto haderror
|
||||
ncftpput -p %ftppass% -u %ftpuser% -T temp_ %ftpsite% /PDBs Install\PDBs_%FILESUFFIX%.7z
|
||||
if errorlevel 1 goto haderror
|
||||
echo Upload finished.
|
||||
|
||||
|
||||
|
||||
|
||||
:: Create the tagfile so that we know that this CommitID has been built already
|
||||
mkdir %TAGFOLDER%
|
||||
touch %TAGFILE%
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:: Add the symbols to a global symbol cache
|
||||
:: We want per-month symbol caches, so that the old ones can be easily deleted
|
||||
set SYMBOLS=Symbols\%MYYEAR%_%MYMONTH%\
|
||||
echo Storing symbols in %SYMBOLS%
|
||||
|
||||
symstore add /f MCServer\MCServer.* /s %SYMBOLS% /t MCServer
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
goto end
|
||||
|
||||
|
||||
|
||||
|
||||
:haderror
|
||||
echo an error was encountered, check command output above
|
||||
pause
|
||||
goto finished
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:end
|
||||
if "a%1" == "a" pause
|
||||
|
||||
|
||||
|
||||
:finished
|
@ -5,15 +5,15 @@ MCServer is a Minecraft server that is written in C++ and designed to be efficie
|
||||
|
||||
MCServer can run on PCs, Macs, and *nix. This includes android phones and tablets as well as Raspberry Pis.
|
||||
|
||||
We currently support the protocol from Minecraft 1.2 all the way up to Minecraft 1.7.10.
|
||||
We currently support the protocol from Minecraft 1.2 all the way up to Minecraft 1.8.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Normally, you will want to download a pre-compiled version of MCServer from one of the buildservers:
|
||||
|
||||
* [Linux and Raspberry Pi](http://ci.bearbin.net) (Bearbin's CI Server)
|
||||
* [Windows](http://mc-server.xoft.cz) (xoft's nightly build service)
|
||||
* [Windows and Linux](http://builds.mc-server.org)
|
||||
* [Raspberry Pi](http://ci.bearbin.net)
|
||||
|
||||
You simply need to download and extract these files before you can use the server.
|
||||
|
||||
@ -33,7 +33,7 @@ For other stuff, including plugins and discussion, check the [forums](http://for
|
||||
|
||||
Earn bitcoins for commits or donate to reward the MCServer developers: [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74)
|
||||
|
||||
Support Us on Gittip: [![Support via Gittip](http://img.shields.io/gittip/mcs_team.svg)](https://www.gittip.com/mcs_team)
|
||||
Support Us on Gratipay: [![Support via Gittip](http://img.shields.io/gittip/mcs_team.svg)](https://www.gittip.com/mcs_team)
|
||||
|
||||
Travis CI: [![Build Status](http://img.shields.io/travis/mc-server/MCServer.svg)](https://travis-ci.org/mc-server/MCServer)
|
||||
|
||||
|
@ -205,6 +205,15 @@ macro(enable_profile)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
#this is a hack because we can't use cmake 2.8.10 because of travis
|
||||
macro(get_clang_version)
|
||||
execute_process(
|
||||
COMMAND "${CMAKE_CXX_COMPILER}" "--version"
|
||||
OUTPUT_VARIABLE CLANG_VERSION_OUTPUT)
|
||||
string(REGEX MATCH "version ([0-9]\\.[0-9])" x ${CLANG_VERSION_OUTPUT})
|
||||
set(CLANG_VERSION ${CMAKE_MATCH_1})
|
||||
endmacro()
|
||||
|
||||
macro(set_exe_flags)
|
||||
# Remove disabling the maximum warning level:
|
||||
# clang does not like a command line that reads -Wall -Wextra -w -Wall -Wextra and does not output any warnings
|
||||
@ -223,17 +232,28 @@ macro(set_exe_flags)
|
||||
add_flags_cxx("-ffast-math")
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
get_clang_version()
|
||||
if ("${CLANG_VERSION}" VERSION_LESS 3.0)
|
||||
message(FATAL_ERROR "MCServer requires clang version 3.0 or higher, version is ${CLANG_VERSION}")
|
||||
endif()
|
||||
# clang does not provide the __extern_always_inline macro and a part of libm depends on this when using fast-math
|
||||
add_flags_cxx("-D__extern_always_inline=inline")
|
||||
add_flags_cxx("-Werror -Weverything -Wno-c++98-compat-pedantic -Wno-string-conversion")
|
||||
add_flags_cxx("-Wno-error=switch-enum -Wno-documentation -Wno-exit-time-destructors")
|
||||
add_flags_cxx("-Wno-error=sign-conversion -Wno-error=conversion -Wno-padded")
|
||||
add_flags_cxx("-Wno-error=deprecated -Wno-error=weak-vtables -Wno-error=float-equal")
|
||||
add_flags_cxx("-Wno-error=missing-prototypes -Wno-error=non-virtual-dtor")
|
||||
add_flags_cxx("-Wno-error=covered-switch-default -Wno-error=shadow -Wno-error=old-style-cast")
|
||||
add_flags_cxx("-Wno-error=exit-time-destructors -Wno-error=missing-variable-declarations")
|
||||
add_flags_cxx("-Wno-error=global-constructors -Wno-implicit-fallthrough")
|
||||
add_flags_cxx("-Wno-error=extra-semi -Wno-weak-vtables -Wno-switch-enum")
|
||||
add_flags_cxx("-Wno-exit-time-destructors -Wno-padded")
|
||||
add_flags_cxx("-Wno-error=sign-conversion -Wno-error=conversion -Wno-error=deprecated")
|
||||
add_flags_cxx("-Wno-error=missing-prototypes")
|
||||
add_flags_cxx("-Wno-error=shadow -Wno-error=old-style-cast -Wno-error=global-constructors")
|
||||
add_flags_cxx("-Wno-error=float-equal")
|
||||
add_flags_cxx("-Wno-weak-vtables -Wno-switch-enum")
|
||||
if ("${CLANG_VERSION}" VERSION_GREATER 3.0)
|
||||
# flags that are not present in 3.0
|
||||
add_flags_cxx("-Wno-error=covered-switch-default -Wno-error=missing-variable-declarations")
|
||||
add_flags_cxx("-Wno-implicit-fallthrough -Wno-error=extra-semi")
|
||||
endif()
|
||||
if ("${CLANG_VERSION}" VERSION_GREATER 3.1)
|
||||
# flags introduced in 3.2
|
||||
add_flags_cxx("-Wno-documentation")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
1
Tools/.gitignore
vendored
Normal file
1
Tools/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
Debug/
|
4
Tools/BiomeVisualiser/.gitignore
vendored
4
Tools/BiomeVisualiser/.gitignore
vendored
@ -1,4 +0,0 @@
|
||||
Debug/
|
||||
logs/
|
||||
Release/
|
||||
Release profiled/
|
@ -1,338 +0,0 @@
|
||||
|
||||
// BiomeCache.cpp
|
||||
|
||||
// Implements the cBiomeCache class representing a biome source that caches data from the underlying biome source
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BiomeCache.h"
|
||||
#include "Timer.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int GetNumCores(void)
|
||||
{
|
||||
// Get number of cores by querying the system process affinity mask
|
||||
DWORD Affinity, ProcAffinity;
|
||||
GetProcessAffinityMask(GetCurrentProcess(), &ProcAffinity, &Affinity);
|
||||
int NumCores = 0;
|
||||
while (Affinity > 0)
|
||||
{
|
||||
if ((Affinity & 1) == 1)
|
||||
{
|
||||
NumCores++;
|
||||
}
|
||||
Affinity >>= 1;
|
||||
} // while (Affinity > 0)
|
||||
return NumCores;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeCache::cBiomeCache(void) :
|
||||
m_Source(NULL),
|
||||
m_BaseX(-100000),
|
||||
m_BaseZ(-100000),
|
||||
m_Available(NULL),
|
||||
m_IsTerminatingThreads(false)
|
||||
{
|
||||
int NumThreads = GetNumCores();
|
||||
NumThreads--; // One core should be left for the system to run on ;)
|
||||
for (int i = NumThreads; i > 0; i--)
|
||||
{
|
||||
cThread * Thread = new cThread(*this);
|
||||
m_Threads.push_back(Thread);
|
||||
Thread->Start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeCache::~cBiomeCache()
|
||||
{
|
||||
m_IsTerminatingThreads = true;
|
||||
for (cThreads::iterator itr = m_Threads.begin(), end = m_Threads.end(); itr != end; ++itr)
|
||||
{
|
||||
m_evtQueued.Set();
|
||||
}
|
||||
for (cThreads::iterator itr = m_Threads.begin(), end = m_Threads.end(); itr != end; ++itr)
|
||||
{
|
||||
delete *itr;
|
||||
}
|
||||
m_Threads.clear();
|
||||
|
||||
SetSource(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeSource::eAvailability cBiomeCache::GetBiome(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_Biomes)
|
||||
{
|
||||
if (m_Source == NULL)
|
||||
{
|
||||
return baNever;
|
||||
}
|
||||
|
||||
// Look up using the cache:
|
||||
int x = a_ChunkX - m_BaseX;
|
||||
int z = a_ChunkZ - m_BaseZ;
|
||||
if ((x < 0) || (x >= m_Width) || (z < 0) || (z >= m_Height))
|
||||
{
|
||||
// Outside the cached region
|
||||
return baNever;
|
||||
}
|
||||
|
||||
cCSLock Lock(m_CS);
|
||||
cItem * Item = m_Available[x + m_Width * z];
|
||||
if (Item == NULL)
|
||||
{
|
||||
// Item hasn't been processed yet
|
||||
return baLater;
|
||||
}
|
||||
if (Item->m_IsValid)
|
||||
{
|
||||
memcpy(a_Biomes, Item->m_Biomes, sizeof(a_Biomes));
|
||||
return baNow;
|
||||
}
|
||||
|
||||
// Item has been processed, but the underlying source refused to give the data to us
|
||||
return baNever;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeCache::HintViewArea(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ)
|
||||
{
|
||||
cTimer Timer("Cache: HintViewArea");
|
||||
|
||||
if (
|
||||
(a_MinChunkX == m_BaseX) &&
|
||||
(a_MaxChunkX == m_BaseX + m_Width - 1) &&
|
||||
(a_MinChunkZ == m_BaseZ) &&
|
||||
(a_MaxChunkZ == m_BaseZ + m_Height - 1)
|
||||
)
|
||||
{
|
||||
// The same set of parameters, bail out
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Source != NULL)
|
||||
{
|
||||
m_Source->HintViewArea(a_MinChunkX, a_MaxChunkX, a_MinChunkZ, a_MaxChunkZ);
|
||||
}
|
||||
|
||||
int NewWidth = a_MaxChunkX - a_MinChunkX + 1;
|
||||
int NewHeight = a_MaxChunkZ - a_MinChunkZ + 1;
|
||||
|
||||
// Make a new empty cache table:
|
||||
pItem * NewAvailable = new pItem[NewWidth * NewHeight];
|
||||
for (int i = NewWidth * NewHeight - 1; i >= 0; --i)
|
||||
{
|
||||
NewAvailable[i] = NULL;
|
||||
}
|
||||
|
||||
// Move the common contents of the old table into the new table:
|
||||
cCSLock Lock(m_CS);
|
||||
for (int z = 0; z < NewHeight; z++)
|
||||
{
|
||||
int OldZ = z + a_MinChunkZ - m_BaseZ;
|
||||
if ((OldZ < 0) || (OldZ >= m_Height))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (int x = 0; x < NewWidth; x++)
|
||||
{
|
||||
int OldX = x + a_MinChunkX - m_BaseX;
|
||||
if ((OldX < 0) || (OldX >= m_Width))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
NewAvailable[x + NewWidth * z] = m_Available[OldX + m_Width * OldZ];
|
||||
m_Available[OldX + m_Width * OldZ] = NULL;
|
||||
} // for x
|
||||
} // for z
|
||||
|
||||
// All items that aren't common go into the pool:
|
||||
for (int idx = 0, z = 0; z < m_Height; z++)
|
||||
{
|
||||
for (int x = 0; x < m_Width; ++x, ++idx)
|
||||
{
|
||||
if (m_Available[idx] != NULL)
|
||||
{
|
||||
m_Pool.push_back(m_Available[idx]);
|
||||
m_Available[idx] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Replace the cache table:
|
||||
delete m_Available;
|
||||
m_Available = NewAvailable;
|
||||
m_Width = NewWidth;
|
||||
m_Height = NewHeight;
|
||||
m_BaseX = a_MinChunkX;
|
||||
m_BaseZ = a_MinChunkZ;
|
||||
|
||||
// Remove all items outside the coords:
|
||||
FilterOutItems(m_Queue, a_MinChunkX, a_MaxChunkX, a_MinChunkZ, a_MaxChunkZ);
|
||||
|
||||
// Queue all items from inside the coords into m_Queue:
|
||||
for (int z = 0; z < NewHeight; z++)
|
||||
{
|
||||
for (int x = 0; x < NewWidth; x++)
|
||||
{
|
||||
if (m_Available[x + m_Width * z] != NULL)
|
||||
{
|
||||
// Already calculated, skip
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m_Pool.empty())
|
||||
{
|
||||
m_Pool.push_back(new cItem(x + a_MinChunkX, z + a_MinChunkZ));
|
||||
}
|
||||
ASSERT(!m_Pool.empty());
|
||||
m_Pool.back()->m_ChunkX = x + a_MinChunkX;
|
||||
m_Pool.back()->m_ChunkZ = z + a_MinChunkZ;
|
||||
m_Queue.push_back(m_Pool.back());
|
||||
m_Pool.pop_back();
|
||||
m_evtQueued.Set();
|
||||
} // for x
|
||||
} // for z
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeCache::SetSource(cBiomeSource * a_Source)
|
||||
{
|
||||
// TODO: Stop all threads, so that they don't use the source anymore!
|
||||
|
||||
delete m_Source;
|
||||
m_Source = a_Source;
|
||||
|
||||
// Invalidate cache contents:
|
||||
cCSLock Lock(m_CS);
|
||||
m_BaseX = -10000;
|
||||
m_BaseZ = -10000;
|
||||
m_Pool.splice(m_Pool.end(), m_Queue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeCache::FilterOutItems(cItems & a_Items, int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ)
|
||||
{
|
||||
for (cItems::iterator itr = a_Items.begin(); itr != a_Items.end();)
|
||||
{
|
||||
if (
|
||||
((*itr)->m_ChunkX < a_MinChunkX) ||
|
||||
((*itr)->m_ChunkX > a_MaxChunkX) ||
|
||||
((*itr)->m_ChunkX < a_MinChunkX) ||
|
||||
((*itr)->m_ChunkX > a_MaxChunkX)
|
||||
)
|
||||
{
|
||||
m_Pool.push_back(*itr);
|
||||
itr = a_Items.erase(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeCache::thrProcessQueueItem(void)
|
||||
{
|
||||
if (m_Source == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cItem * Item = NULL;
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
if (m_Queue.empty())
|
||||
{
|
||||
cCSUnlock Unlock(Lock);
|
||||
m_evtQueued.Wait();
|
||||
}
|
||||
if (m_IsTerminatingThreads || m_Queue.empty())
|
||||
{
|
||||
// We've been woken up only to die / spurious wakeup
|
||||
return;
|
||||
}
|
||||
Item = m_Queue.back();
|
||||
m_Queue.pop_back();
|
||||
}
|
||||
|
||||
// Process the item:
|
||||
Item->m_IsValid = (m_Source->GetBiome(Item->m_ChunkX, Item->m_ChunkZ, Item->m_Biomes) == baNow);
|
||||
|
||||
// Store result:
|
||||
cCSLock Lock(m_CS);
|
||||
int x = Item->m_ChunkX - m_BaseX;
|
||||
int z = Item->m_ChunkZ - m_BaseZ;
|
||||
if ((x < 0) || (x >= m_Width) || (z < 0) || (z >= m_Height))
|
||||
{
|
||||
// The cache rectangle has changed under our fingers, drop this chunk
|
||||
return;
|
||||
}
|
||||
m_Available[x + m_Width * z] = Item;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cBiomeCache::cItem:
|
||||
|
||||
cBiomeCache::cItem::cItem(int a_ChunkX, int a_ChunkZ) :
|
||||
m_ChunkX(a_ChunkX),
|
||||
m_ChunkZ(a_ChunkZ)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cBiomeCache::cThread:
|
||||
|
||||
cBiomeCache::cThread::cThread(cBiomeCache & a_Parent) :
|
||||
super("Biome cache thread"),
|
||||
m_Parent(a_Parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeCache::cThread::Execute(void)
|
||||
{
|
||||
while (!m_ShouldTerminate && !m_Parent.m_IsTerminatingThreads)
|
||||
{
|
||||
m_Parent.thrProcessQueueItem();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,96 +0,0 @@
|
||||
|
||||
// BiomeCache.h
|
||||
|
||||
// Declares the cBiomeCache class representing a biome source that caches data from the underlying biome source
|
||||
|
||||
/*
|
||||
This cache works a bit differently than regular caches.
|
||||
It first receives the hint of area that it will need to provide.
|
||||
The Cache uses several threads to request biomes from the underlying source to fill that area.
|
||||
While the area is being filled, requests for biomes may already come, such requests are answered with baLater if no data yet.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "BiomeSource.h"
|
||||
#include "../src/OSSupport/IsThread.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeCache :
|
||||
public cBiomeSource
|
||||
{
|
||||
public:
|
||||
cBiomeCache(void);
|
||||
~cBiomeCache();
|
||||
|
||||
// cBiomeSource overrides:
|
||||
virtual eAvailability GetBiome(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_Biomes) override;
|
||||
virtual void HintViewArea(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ) override;
|
||||
|
||||
void SetSource(cBiomeSource * a_Source); // Takes ownership of the source ptr
|
||||
|
||||
protected:
|
||||
class cItem
|
||||
{
|
||||
public:
|
||||
cItem(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
int m_ChunkX;
|
||||
int m_ChunkZ;
|
||||
bool m_IsValid;
|
||||
cChunkDef::BiomeMap m_Biomes;
|
||||
} ;
|
||||
|
||||
typedef cItem * pItem;
|
||||
typedef std::list<pItem> cItems;
|
||||
|
||||
class cThread :
|
||||
public cIsThread
|
||||
{
|
||||
typedef cIsThread super;
|
||||
|
||||
public:
|
||||
cThread(cBiomeCache & a_Parent);
|
||||
|
||||
// cIsThread overrides:
|
||||
virtual void Execute(void) override;
|
||||
|
||||
protected:
|
||||
cBiomeCache & m_Parent;
|
||||
} ;
|
||||
|
||||
typedef std::list<cThread *> cThreads;
|
||||
|
||||
cBiomeSource * m_Source;
|
||||
|
||||
cCriticalSection m_CS;
|
||||
int m_BaseX; ///< MinChunkX for the m_Available rectangle
|
||||
int m_BaseZ; ///< MinChunkZ for the m_Available rectangle
|
||||
int m_Width; ///< Width of the m_Available rectangle
|
||||
int m_Height; ///< Height of the m_Available rectangle
|
||||
pItem * m_Available; ///< Items that have already been processed (baNow or baNever), [x + m_Width * z]
|
||||
cItems m_Queue; ///< Items that are queued for processing (baLater)
|
||||
cItems m_Pool; ///< Items that are not needed anymore, can be reused for other coords
|
||||
|
||||
cEvent m_evtQueued; // Triggerred when an item is added to m_Queue
|
||||
|
||||
cThreads m_Threads; // Threads that update the cache.
|
||||
bool m_IsTerminatingThreads; // Set to true to indicate to all threads that they should exit
|
||||
|
||||
/// Removes from a_Items all items that are outside of the given coords, moves those into m_Pool
|
||||
void FilterOutItems(cItems & a_Items, int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ);
|
||||
|
||||
/// Processes one item from m_Queue into m_Available. Blocks if m_Queue is empty; respects m_IsTerminatingThreads
|
||||
void thrProcessQueueItem(void);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -1,114 +0,0 @@
|
||||
|
||||
// BiomeColors.cpp
|
||||
|
||||
// Implements the g_BiomeColors[] array preparation based on a stored biome-to-color map
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BiomeColors.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int g_BiomeColors[256];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static struct
|
||||
{
|
||||
EMCSBiome Biome;
|
||||
int Color;
|
||||
} g_BiomeColorMap[] =
|
||||
{
|
||||
{ biOcean, 0x000070 },
|
||||
{ biPlains, 0x8db360 },
|
||||
{ biDesert, 0xfa9418 },
|
||||
{ biExtremeHills, 0x606060 },
|
||||
{ biForest, 0x056621 },
|
||||
{ biTaiga, 0x0b6659 },
|
||||
{ biSwampland, 0x2fffda },
|
||||
{ biRiver, 0x3030af },
|
||||
{ biHell, 0x7f0000 },
|
||||
{ biSky, 0x007fff },
|
||||
{ biFrozenOcean, 0xa0a0df },
|
||||
{ biFrozenRiver, 0xa0a0ff },
|
||||
{ biIcePlains, 0xffffff },
|
||||
{ biIceMountains, 0xa0a0a0 },
|
||||
{ biMushroomIsland, 0xff00ff },
|
||||
{ biMushroomShore, 0xa000ff },
|
||||
{ biBeach, 0xfade55 },
|
||||
{ biDesertHills, 0xd25f12 },
|
||||
{ biForestHills, 0x22551c },
|
||||
{ biTaigaHills, 0x163933 },
|
||||
{ biExtremeHillsEdge, 0x7f8f7f },
|
||||
{ biJungle, 0x537b09 },
|
||||
{ biJungleHills, 0x2c4205 },
|
||||
|
||||
{ biJungleEdge, 0x628b17 },
|
||||
{ biDeepOcean, 0x000030 },
|
||||
{ biStoneBeach, 0xa2a284 },
|
||||
{ biColdBeach, 0xfaf0c0 },
|
||||
{ biBirchForest, 0x307444 },
|
||||
{ biBirchForestHills, 0x1f5f32 },
|
||||
{ biRoofedForest, 0x40511a },
|
||||
{ biColdTaiga, 0x31554a },
|
||||
{ biColdTaigaHills, 0x597d72 },
|
||||
{ biMegaTaiga, 0x596651 },
|
||||
{ biMegaTaigaHills, 0x596659 },
|
||||
{ biExtremeHillsPlus, 0x507050 },
|
||||
{ biSavanna, 0xbdb25f },
|
||||
{ biSavannaPlateau, 0xa79d64 },
|
||||
{ biMesa, 0xd94515 },
|
||||
{ biMesaPlateauF, 0xb09765 },
|
||||
{ biMesaPlateau, 0xca8c65 },
|
||||
|
||||
// M variants:
|
||||
{ biSunflowerPlains, 0xb5db88 },
|
||||
{ biDesertM, 0xffbc40 },
|
||||
{ biExtremeHillsM, 0x888888 },
|
||||
{ biFlowerForest, 0x2d8e49 },
|
||||
{ biTaigaM, 0x338e81 },
|
||||
{ biSwamplandM, 0x07f9b2 },
|
||||
{ biIcePlainsSpikes, 0xb4dcdc },
|
||||
{ biJungleM, 0x7ba331 },
|
||||
{ biJungleEdgeM, 0x628b17 },
|
||||
{ biBirchForestM, 0x589c6c },
|
||||
{ biBirchForestHillsM, 0x47875a },
|
||||
{ biRoofedForestM, 0x687942 },
|
||||
{ biColdTaigaM, 0x243f36 },
|
||||
{ biMegaSpruceTaiga, 0x454f3e },
|
||||
{ biMegaSpruceTaigaHills, 0x454f4e },
|
||||
{ biExtremeHillsPlusM, 0x789878 },
|
||||
{ biSavannaM, 0xe5da87 },
|
||||
{ biSavannaPlateauM, 0xa79d74 },
|
||||
{ biMesaBryce, 0xff6d3d },
|
||||
{ biMesaPlateauFM, 0xd8bf8d },
|
||||
{ biMesaPlateauM, 0xf2b48d },
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static class cBiomeColorsInitializer
|
||||
{
|
||||
public:
|
||||
cBiomeColorsInitializer(void)
|
||||
{
|
||||
// Reset all colors to gray:
|
||||
for (size_t i = 0; i < ARRAYCOUNT(g_BiomeColors); i++)
|
||||
{
|
||||
g_BiomeColors[i] = 0x7f7f7f;
|
||||
}
|
||||
for (size_t i = 0; i < ARRAYCOUNT(g_BiomeColorMap); i++)
|
||||
{
|
||||
g_BiomeColors[g_BiomeColorMap[i].Biome] = g_BiomeColorMap[i].Color;
|
||||
}
|
||||
}
|
||||
} g_Initializer;
|
||||
|
||||
|
||||
|
||||
|
@ -1,15 +0,0 @@
|
||||
|
||||
// BiomeColors.h
|
||||
|
||||
// Declares the g_BiomeColors[] array used for biome color lookup
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern int g_BiomeColors[256];
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,119 +0,0 @@
|
||||
|
||||
// BiomeRenderer.cpp
|
||||
|
||||
// Implements the cBiomeRenderer class representing the rendering engine
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BiomeRenderer.h"
|
||||
#include "Pixmap.h"
|
||||
#include "Timer.h"
|
||||
#include "BiomeColors.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeRenderer::cBiomeRenderer(void) :
|
||||
m_OriginX(160),
|
||||
m_OriginY(160),
|
||||
m_Zoom(1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeRenderer::SetSource(cBiomeSource * a_Source)
|
||||
{
|
||||
m_Cache.SetSource(a_Source);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBiomeRenderer::Render(cPixmap & a_Pixmap)
|
||||
{
|
||||
cTimer Timer("cBiomeRenderer::Render");
|
||||
|
||||
int Wid = a_Pixmap.GetWidth();
|
||||
int Hei = a_Pixmap.GetHeight();
|
||||
|
||||
// Hint the approximate view area to the biome source so that it can adjust its caches:
|
||||
int MinBlockX = ( - m_OriginX) * m_Zoom;
|
||||
int MaxBlockX = (Wid - m_OriginX) * m_Zoom;
|
||||
int MinBlockZ = ( - m_OriginY) * m_Zoom;
|
||||
int MaxBlockZ = (Hei - m_OriginY) * m_Zoom;
|
||||
m_Cache.HintViewArea(MinBlockX / 16 - 1, MaxBlockX / 16 + 1, MinBlockZ / 16 - 1, MaxBlockZ / 16 + 1);
|
||||
|
||||
// Hold one current chunk of biome data:
|
||||
int CurChunkX = -10000;
|
||||
int CurChunkZ = -10000;
|
||||
cChunkDef::BiomeMap CurBiomes;
|
||||
|
||||
bool res = false;
|
||||
|
||||
for (int y = 0; y < Hei; y++)
|
||||
{
|
||||
int BlockZ = (y - m_OriginY) * m_Zoom;
|
||||
int ChunkZ = (BlockZ >= 0) ? (BlockZ / 16) : ((BlockZ + 1) / 16 - 1);
|
||||
int RelZ = BlockZ - ChunkZ * 16;
|
||||
for (int x = 0; x < Wid; x++)
|
||||
{
|
||||
int BlockX = (x - m_OriginX) * m_Zoom;
|
||||
int ChunkX = (BlockX >= 0) ? (BlockX / 16) : ((BlockX + 1) / 16 - 1);
|
||||
int RelX = BlockX - ChunkX * 16;
|
||||
if ((ChunkZ != CurChunkZ) || (ChunkX != CurChunkX))
|
||||
{
|
||||
CurChunkX = ChunkX;
|
||||
CurChunkZ = ChunkZ;
|
||||
switch (m_Cache.GetBiome(CurChunkX, CurChunkZ, CurBiomes))
|
||||
{
|
||||
case cBiomeSource::baLater:
|
||||
{
|
||||
res = true;
|
||||
// fallthrough:
|
||||
}
|
||||
case cBiomeSource::baNever:
|
||||
{
|
||||
for (int i = 0; i < ARRAYCOUNT(CurBiomes); i++)
|
||||
{
|
||||
CurBiomes[i] = biInvalidBiome;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // switch (Biome availability)
|
||||
}
|
||||
EMCSBiome Biome = cChunkDef::GetBiome(CurBiomes, RelX, RelZ);
|
||||
a_Pixmap.SetPixel(x, y, GetBiomeColor(Biome));
|
||||
} // for x
|
||||
} // for y
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cBiomeRenderer::GetBiomeColor(EMCSBiome a_Biome)
|
||||
{
|
||||
if ((a_Biome < 0) || (a_Biome >= ARRAYCOUNT(g_BiomeColors)))
|
||||
{
|
||||
return 0xff0000;
|
||||
}
|
||||
return g_BiomeColors[a_Biome];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeRenderer::MoveViewBy(int a_OffsX, int a_OffsY)
|
||||
{
|
||||
m_OriginX += a_OffsX;
|
||||
m_OriginY += a_OffsY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,55 +0,0 @@
|
||||
|
||||
// BiomeRenderer.h
|
||||
|
||||
// Declares the cBiomeRenderer class representing the rendering engine
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BiomeCache.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// fwd: Pixmap.h
|
||||
class cPixmap;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeRenderer
|
||||
{
|
||||
public:
|
||||
cBiomeRenderer(void);
|
||||
|
||||
void SetSource(cBiomeSource * a_Source); // Takes ownership of the source
|
||||
|
||||
/// Renders the biomes into the given pixmap. Returns true if some biome data was missing and can be retrieved later
|
||||
bool Render(cPixmap & a_Pixmap);
|
||||
|
||||
/// Returns the RGB color value for the specified biome
|
||||
int GetBiomeColor(EMCSBiome a_Biome);
|
||||
|
||||
void MoveViewBy(int a_OffsX, int a_OffsY);
|
||||
|
||||
void SetZoom(int a_NewZoom)
|
||||
{
|
||||
m_Zoom = a_NewZoom;
|
||||
}
|
||||
|
||||
protected:
|
||||
cBiomeCache m_Cache;
|
||||
|
||||
int m_OriginX;
|
||||
int m_OriginY;
|
||||
int m_Zoom;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -1,37 +0,0 @@
|
||||
|
||||
// BiomeSource.h
|
||||
|
||||
// Declares the cBiomeSource abstract class used as an interface for getting biomes from any source
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "ChunkDef.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeSource abstract
|
||||
{
|
||||
public:
|
||||
enum eAvailability
|
||||
{
|
||||
baNow, // Data returned now
|
||||
baLater, // Data not returned, but will be available later, try again after a while
|
||||
baNever, // Data not returned, will not be available at all
|
||||
} ;
|
||||
|
||||
/// Fills a_Biomes with the biomes for the chunk specified
|
||||
virtual eAvailability GetBiome(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_Biomes) = 0;
|
||||
|
||||
/// Used to inform the source about the view area that will be queried in the near future.
|
||||
virtual void HintViewArea(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ) = 0;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -1,247 +0,0 @@
|
||||
|
||||
// BiomeViewWnd.cpp
|
||||
|
||||
// Implements the cBiomeViewWnd class representing the window that displays biomes
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BiomeViewWnd.h"
|
||||
#include "BiomeCache.h"
|
||||
#include "GeneratorBiomeSource.h"
|
||||
#include "iniFile/iniFile.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const int TIMER_RERENDER = 1200;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeViewWnd::cBiomeViewWnd(void) :
|
||||
m_Wnd(NULL),
|
||||
m_Thunk(&cBiomeViewWnd::WndProc, this),
|
||||
m_IsLButtonDown(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBiomeViewWnd::Create(HWND a_ParentWnd, LPCTSTR a_Title)
|
||||
{
|
||||
ASSERT(m_Wnd == NULL);
|
||||
|
||||
InitBiomeView();
|
||||
|
||||
// Create a regular STATIC window, then override its window procedure with our own. No need for obnoxious RegisterWindowClass() stuff.
|
||||
m_Wnd = CreateWindow("STATIC", a_Title, WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 400, 300, a_ParentWnd, NULL, GetModuleHandle(NULL), NULL);
|
||||
if (m_Wnd == NULL)
|
||||
{
|
||||
LOGERROR("Cannot create main window: %d", GetLastError());
|
||||
return false;
|
||||
}
|
||||
SetWindowLongPtr(m_Wnd, GWLP_WNDPROC, m_Thunk);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeViewWnd::InitBiomeView(void)
|
||||
{
|
||||
cIniFile IniFile;
|
||||
IniFile.ReadFile("world.ini");
|
||||
int Seed = IniFile.GetValueSetI("Generator", "Seed", 0);
|
||||
bool CacheOffByDefault = false;
|
||||
m_BiomeGen = cBiomeGen::CreateBiomeGen(IniFile, Seed, CacheOffByDefault);
|
||||
m_Renderer.SetSource(new cGeneratorBiomeSource(m_BiomeGen));
|
||||
IniFile.WriteFile("world.ini");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeViewWnd::SetZoom(int a_NewZoom)
|
||||
{
|
||||
m_Renderer.SetZoom(a_NewZoom);
|
||||
Redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeViewWnd::Redraw(void)
|
||||
{
|
||||
if (m_Renderer.Render(m_Pixmap))
|
||||
{
|
||||
SetTimer(m_Wnd, TIMER_RERENDER, 200, NULL);
|
||||
}
|
||||
InvalidateRect(m_Wnd, NULL, FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::WndProc(HWND a_Wnd, UINT a_Msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (a_Msg)
|
||||
{
|
||||
case WM_CHAR: return OnChar (wParam, lParam);
|
||||
case WM_CLOSE: return OnClose ();
|
||||
case WM_COMMAND: return OnCommand (wParam, lParam);
|
||||
case WM_LBUTTONDOWN: return OnLButtonDown(wParam, lParam);
|
||||
case WM_LBUTTONUP: return OnLButtonUp (wParam, lParam);
|
||||
case WM_MOUSEMOVE: return OnMouseMove (wParam, lParam);
|
||||
case WM_PAINT: return OnPaint ();
|
||||
case WM_TIMER: return OnTimer (wParam);
|
||||
}
|
||||
return ::DefWindowProc(a_Wnd, a_Msg, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnChar(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (wParam)
|
||||
{
|
||||
case '1': SetZoom(1); break;
|
||||
case '2': SetZoom(2); break;
|
||||
case '3': SetZoom(3); break;
|
||||
case '4': SetZoom(4); break;
|
||||
case '5': SetZoom(5); break;
|
||||
case '6': SetZoom(6); break;
|
||||
case '7': SetZoom(7); break;
|
||||
case '8': SetZoom(8); break;
|
||||
case 27:
|
||||
{
|
||||
// Esc pressed, exit
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnClose(void)
|
||||
{
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnCommand(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// TODO: Handle menu commands, when we get menu
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnLButtonDown(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
m_IsLButtonDown = true;
|
||||
GetCursorPos(&m_MouseDown);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnMouseMove(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (!m_IsLButtonDown)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
POINT pnt;
|
||||
GetCursorPos(&pnt);
|
||||
m_Renderer.MoveViewBy(pnt.x - m_MouseDown.x, pnt.y - m_MouseDown.y);
|
||||
m_MouseDown = pnt;
|
||||
Redraw();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnLButtonUp(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
OnMouseMove(wParam, lParam); // Last movement - if the mouse move hasn't been reported due to speed
|
||||
m_IsLButtonDown = false;
|
||||
InvalidateRect(m_Wnd, NULL, FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnPaint(void)
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
HDC DC = BeginPaint(m_Wnd, &ps);
|
||||
|
||||
RECT rc;
|
||||
GetClientRect(m_Wnd, &rc);
|
||||
int Wid = rc.right - rc.left;
|
||||
int Hei = rc.bottom - rc.top;
|
||||
if ((m_Pixmap.GetWidth() != Wid) || (m_Pixmap.GetHeight() != Hei))
|
||||
{
|
||||
m_Pixmap.SetSize(Wid, Hei);
|
||||
if (m_Renderer.Render(m_Pixmap))
|
||||
{
|
||||
SetTimer(m_Wnd, TIMER_RERENDER, 200, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
m_Pixmap.DrawToDC(DC, 0, 0);
|
||||
|
||||
EndPaint(m_Wnd, &ps);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnTimer(WPARAM wParam)
|
||||
{
|
||||
switch (wParam)
|
||||
{
|
||||
case TIMER_RERENDER:
|
||||
{
|
||||
if (!m_Renderer.Render(m_Pixmap))
|
||||
{
|
||||
KillTimer(m_Wnd, TIMER_RERENDER);
|
||||
}
|
||||
InvalidateRect(m_Wnd, NULL, FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,69 +0,0 @@
|
||||
|
||||
// BiomeViewWnd.h
|
||||
|
||||
// Declares the cBiomeViewWnd class representing the window that displays biomes
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "WndProcThunk.h"
|
||||
#include "BiomeRenderer.h"
|
||||
#include "BiomeCache.h"
|
||||
#include "Pixmap.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// fwd:
|
||||
class cBiomeGen;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeViewWnd
|
||||
{
|
||||
public:
|
||||
cBiomeViewWnd(void);
|
||||
|
||||
bool Create(HWND a_ParentWnd, LPCTSTR a_Title);
|
||||
|
||||
protected:
|
||||
HWND m_Wnd;
|
||||
CWndProcThunk<cBiomeViewWnd> m_Thunk;
|
||||
|
||||
cBiomeRenderer m_Renderer;
|
||||
cPixmap m_Pixmap;
|
||||
|
||||
/// The generator that is to be visualised
|
||||
cBiomeGen * m_BiomeGen;
|
||||
|
||||
bool m_IsLButtonDown;
|
||||
POINT m_MouseDown;
|
||||
|
||||
|
||||
void InitBiomeView(void);
|
||||
|
||||
void SetZoom(int a_NewZoom);
|
||||
void Redraw(void);
|
||||
|
||||
LRESULT WndProc(HWND a_Wnd, UINT a_Msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
// Message handlers:
|
||||
LRESULT OnChar (WPARAM wParam, LPARAM lParam);
|
||||
LRESULT OnClose (void);
|
||||
LRESULT OnCommand (WPARAM wParam, LPARAM lParam);
|
||||
LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam);
|
||||
LRESULT OnMouseMove (WPARAM wParam, LPARAM lParam);
|
||||
LRESULT OnLButtonUp (WPARAM wParam, LPARAM lParam);
|
||||
LRESULT OnPaint (void);
|
||||
LRESULT OnTimer (WPARAM wParam);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -1,52 +0,0 @@
|
||||
|
||||
// BiomeVisualiser.cpp
|
||||
|
||||
// Implements the cBiomeVisualiser class representing the entire app. Also implements the WinMain() entrypoint
|
||||
|
||||
#include "Globals.h"
|
||||
#include "time.h"
|
||||
#include "BiomeVisualiser.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int WINAPI WinMain(HINSTANCE a_Instance, HINSTANCE a_PrevInstance, LPSTR a_CmdLine, int a_ShowCmd)
|
||||
{
|
||||
cBiomeVisualiser App;
|
||||
return App.Run();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeVisualiser::cBiomeVisualiser(void) :
|
||||
m_Logger(new cMCLogger(Printf("BiomeVisualiser_%08x.log", time(NULL))))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cBiomeVisualiser::Run(void)
|
||||
{
|
||||
if (!m_MainWnd.Create(GetDesktopWindow(), TEXT("BiomeVisualiser")))
|
||||
{
|
||||
LOGERROR("Cannot create main window: %d", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
MSG msg;
|
||||
while (GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
} // while (GetMessage)
|
||||
return msg.lParam;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,31 +0,0 @@
|
||||
|
||||
// BiomeVisualiser.h
|
||||
|
||||
// Declares the cBiomeVisualiser class representing the entire application
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "BiomeViewWnd.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeVisualiser
|
||||
{
|
||||
public:
|
||||
cBiomeVisualiser(void);
|
||||
|
||||
int Run(void);
|
||||
|
||||
protected:
|
||||
cBiomeViewWnd m_MainWnd;
|
||||
|
||||
cMCLogger * m_Logger;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -1,23 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BiomeVisualiser", "BiomeVisualiser.vcproj", "{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release profiled|Win32 = Release profiled|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Release profiled|Win32.ActiveCfg = Release profiled|Win32
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Release profiled|Win32.Build.0 = Release profiled|Win32
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -1,527 +0,0 @@
|
||||
<?xml version="1.0" encoding="windows-1250"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="BiomeVisualiser"
|
||||
ProjectGUID="{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}"
|
||||
RootNamespace="BiomeVisualiser"
|
||||
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="../../src;../../lib"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
|
||||
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="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|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"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
AdditionalIncludeDirectories="../../src;../../lib"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
EnableEnhancedInstructionSet="2"
|
||||
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="2"
|
||||
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"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
AdditionalIncludeDirectories="../../src;../../lib"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
EnableEnhancedInstructionSet="2"
|
||||
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="2"
|
||||
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=".\BiomeCache.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeCache.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeColors.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeColors.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeRenderer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeRenderer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeSource.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeViewWnd.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeViewWnd.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeVisualiser.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeVisualiser.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GeneratorBiomeSource.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Pixmap.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Pixmap.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Timer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\WndProcThunk.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="Shared"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\BiomeDef.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\BiomeDef.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\BlockID.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\BlockID.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ChunkDef.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Enchantments.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Enchantments.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\WorldStorage\FastNBT.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\WorldStorage\FastNBT.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\FastRandom.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\FastRandom.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\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="..\..\src\Globals.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Item.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Log.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Log.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\MCLogger.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\MCLogger.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Noise.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Noise.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Noise.inc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\StringUtils.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\StringUtils.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\VoronoiMap.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\VoronoiMap.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="OSSupport"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\CriticalSection.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\CriticalSection.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\Event.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\Event.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\File.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\File.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\IsThread.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\IsThread.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\Sleep.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Generating"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\Generating\BioGen.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Generating\BioGen.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Generating\ComposableGenerator.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="iniFile"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\lib\iniFile\iniFile.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\lib\iniFile\iniFile.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
@ -1,42 +0,0 @@
|
||||
|
||||
// GeneratorBiomeSource.h
|
||||
|
||||
// Declares the cGeneratorBiomeSource that adapts a cBiomeGen into a cBiomeSource
|
||||
|
||||
#include "../src/Generating/BioGen.h"
|
||||
#include "BiomeSource.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cGeneratorBiomeSource :
|
||||
public cBiomeSource
|
||||
{
|
||||
public:
|
||||
cGeneratorBiomeSource(cBiomeGen * a_Generator) : m_Generator(a_Generator) {} // Takes ownership of the generator ptr
|
||||
|
||||
~cGeneratorBiomeSource()
|
||||
{
|
||||
delete m_Generator;
|
||||
}
|
||||
|
||||
// cBiomeSource overrides:
|
||||
virtual eAvailability GetBiome(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_Biomes) override
|
||||
{
|
||||
m_Generator->GenBiomes(a_ChunkX, a_ChunkZ, a_Biomes);
|
||||
return baNow;
|
||||
}
|
||||
|
||||
virtual void HintViewArea(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ) override
|
||||
{
|
||||
// Nothing needed
|
||||
}
|
||||
|
||||
protected:
|
||||
cBiomeGen * m_Generator;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -1,120 +0,0 @@
|
||||
|
||||
// Pixmap.cpp
|
||||
|
||||
// Implements the cPixmap class that represents a RGB pixmap and allows simple operations on it
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Pixmap.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cPixmap::cPixmap(void) :
|
||||
m_Width(0),
|
||||
m_Height(0),
|
||||
m_Stride(0),
|
||||
m_Pixels(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cPixmap::cPixmap(int a_Width, int a_Height) :
|
||||
m_Width(0),
|
||||
m_Height(0),
|
||||
m_Stride(0),
|
||||
m_Pixels(NULL)
|
||||
{
|
||||
SetSize(a_Width, a_Height);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cPixmap::~cPixmap()
|
||||
{
|
||||
delete m_Pixels;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPixmap::SetSize(int a_Width, int a_Height)
|
||||
{
|
||||
delete m_Pixels;
|
||||
m_Pixels = new int[a_Width * a_Height];
|
||||
m_Width = a_Width;
|
||||
m_Height = a_Height;
|
||||
m_Stride = m_Width; // Currently we don't need a special stride value, but let's support it for the future :)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPixmap::SetPixel(int a_X, int a_Y, int a_Color)
|
||||
{
|
||||
ASSERT(a_X >= 0);
|
||||
ASSERT(a_X < m_Width);
|
||||
ASSERT(a_Y >= 0);
|
||||
ASSERT(a_Y < m_Height);
|
||||
|
||||
m_Pixels[a_X + a_Y * m_Stride] = a_Color;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cPixmap::GetPixel(int a_X, int a_Y) const
|
||||
{
|
||||
ASSERT(a_X >= 0);
|
||||
ASSERT(a_X < m_Width);
|
||||
ASSERT(a_Y >= 0);
|
||||
ASSERT(a_Y < m_Height);
|
||||
|
||||
return m_Pixels[a_X + a_Y * m_Stride];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPixmap::Fill(int a_Color)
|
||||
{
|
||||
int NumElements = m_Height * m_Stride;
|
||||
for (int i = 0; i < NumElements; i++)
|
||||
{
|
||||
m_Pixels[i] = a_Color;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPixmap::DrawToDC(HDC a_DC, int a_OriginX, int a_OriginY)
|
||||
{
|
||||
BITMAPINFO bmi;
|
||||
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
|
||||
bmi.bmiHeader.biWidth = m_Width;
|
||||
bmi.bmiHeader.biHeight = -m_Height; // Negative, we are top-down, unlike BMPs
|
||||
bmi.bmiHeader.biPlanes = 1;
|
||||
bmi.bmiHeader.biBitCount = 32;
|
||||
bmi.bmiHeader.biCompression = BI_RGB;
|
||||
bmi.bmiHeader.biSizeImage = m_Stride * m_Height * 4;
|
||||
bmi.bmiHeader.biXPelsPerMeter = 1440;
|
||||
bmi.bmiHeader.biYPelsPerMeter = 1440;
|
||||
bmi.bmiHeader.biClrUsed = 0;
|
||||
bmi.bmiHeader.biClrImportant = 0;
|
||||
SetDIBitsToDevice(a_DC, a_OriginX, a_OriginY, m_Width, m_Height, 0, 0, 0, m_Height, m_Pixels, &bmi, DIB_RGB_COLORS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,39 +0,0 @@
|
||||
|
||||
// Pixmap.h
|
||||
|
||||
// Declares a cPixmap class that represents a RGB pixmap and allows simple operations on it
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cPixmap
|
||||
{
|
||||
public:
|
||||
cPixmap(void);
|
||||
cPixmap(int a_Width, int a_Height);
|
||||
~cPixmap();
|
||||
|
||||
void SetSize(int a_Width, int a_Height);
|
||||
|
||||
int GetWidth (void) const { return m_Width; }
|
||||
int GetHeight(void) const { return m_Height; }
|
||||
|
||||
void SetPixel(int a_X, int a_Y, int a_Color);
|
||||
int GetPixel(int a_X, int a_Y) const;
|
||||
void Fill(int a_Color);
|
||||
|
||||
void DrawToDC(HDC a_DC, int a_OriginX, int a_OriginY);
|
||||
|
||||
protected:
|
||||
int m_Width;
|
||||
int m_Height;
|
||||
int m_Stride;
|
||||
int * m_Pixels;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -1,40 +0,0 @@
|
||||
|
||||
// Timer.h
|
||||
|
||||
// Declares the cTimer class representing a RAII class that measures time from its creation till its destruction
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "time.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cTimer
|
||||
{
|
||||
public:
|
||||
cTimer(const AString & a_Title) :
|
||||
m_Title(a_Title),
|
||||
m_StartTime(clock())
|
||||
{
|
||||
}
|
||||
|
||||
~cTimer()
|
||||
{
|
||||
clock_t NumTicks = clock() - m_StartTime;
|
||||
LOG("%s took %d ticks (%.02f sec)", m_Title.c_str(), NumTicks, (double)NumTicks / CLOCKS_PER_SEC);
|
||||
}
|
||||
|
||||
protected:
|
||||
AString m_Title;
|
||||
clock_t m_StartTime;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -1,143 +0,0 @@
|
||||
|
||||
// WndProcThunk.h
|
||||
|
||||
// Interfaces to the CWndProcThunk class responsible for WNDPROC class-thunking
|
||||
// For details, see http://www.hackcraft.net/cpp/windowsThunk/thiscall/
|
||||
// Also available is a CDlgProcThunk class doing the same work for DIALOGPROC
|
||||
|
||||
// MD: Made NX-compat by allocating the code structure using VirtualAlloc(..., PAGE_EXECUTE_READWRITE)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// fwd:
|
||||
template <class W> class CWndProcThunk;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef WNDPROCTHUNK_H_INCLUDED
|
||||
#define WNDPROCTHUNK_H_INCLUDED
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename To, typename From> inline To union_cast(From fr) throw()
|
||||
{
|
||||
union
|
||||
{
|
||||
From f;
|
||||
To t;
|
||||
} uc;
|
||||
uc.f = fr;
|
||||
return uc.t;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4355)
|
||||
|
||||
#if defined(_M_IX86)
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
template <class W> class CWndProcThunk
|
||||
{
|
||||
typedef ::LRESULT (W::* WndProc)(::HWND, ::UINT, ::WPARAM, ::LPARAM);
|
||||
typedef CWndProcThunk ThisClass;
|
||||
|
||||
struct SCode
|
||||
{
|
||||
BYTE m_mov; // mov ECX, m_this
|
||||
W * m_this; //
|
||||
BYTE m_jmp; // jmp m_relproc
|
||||
ptrdiff_t m_relproc; // relative jmp
|
||||
};
|
||||
|
||||
SCode * Code;
|
||||
|
||||
public:
|
||||
ThisClass(WndProc proc, W * obj)
|
||||
{
|
||||
Code = (SCode *)VirtualAlloc(NULL, sizeof(SCode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
Code->m_mov = 0xB9,
|
||||
Code->m_this = obj,
|
||||
Code->m_jmp = 0xE9,
|
||||
Code->m_relproc = union_cast<char *>(proc) - reinterpret_cast<char *>(Code) - sizeof(*Code);
|
||||
::FlushInstructionCache(::GetCurrentProcess(), Code, sizeof(*Code));
|
||||
}
|
||||
|
||||
virtual ~CWndProcThunk()
|
||||
{
|
||||
VirtualFree(Code, sizeof(*Code), MEM_RELEASE);
|
||||
Code = NULL;
|
||||
}
|
||||
|
||||
operator ::WNDPROC() const {return reinterpret_cast<::WNDPROC>(Code); }
|
||||
operator ::LONG_PTR() const {return reinterpret_cast<::LONG_PTR>(Code); }
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <class W> class CDlgProcThunk
|
||||
{
|
||||
typedef ::BOOL (W::* DlgProc)(::HWND, ::UINT, ::WPARAM, ::LPARAM);
|
||||
typedef CDlgProcThunk ThisClass;
|
||||
|
||||
struct SCode
|
||||
{
|
||||
BYTE m_mov; // mov ECX, m_this
|
||||
W * m_this; //
|
||||
BYTE m_jmp; // jmp m_relproc
|
||||
ptrdiff_t m_relproc; // relative jmp
|
||||
};
|
||||
|
||||
SCode * Code;
|
||||
|
||||
public:
|
||||
CDlgProcThunk(DlgProc proc, W * obj)
|
||||
{
|
||||
Code = (SCode *)VirtualAlloc(NULL, sizeof(SCode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
Code->m_mov = 0xB9,
|
||||
Code->m_this = obj,
|
||||
Code->m_jmp = 0xE9,
|
||||
Code->m_relproc = union_cast<char *>(proc) - reinterpret_cast<char *>(Code) - sizeof(*Code);
|
||||
::FlushInstructionCache(::GetCurrentProcess(), Code, sizeof(*Code));
|
||||
}
|
||||
|
||||
virtual ~CDlgProcThunk()
|
||||
{
|
||||
VirtualFree(Code, sizeof(*Code), MEM_RELEASE);
|
||||
Code = NULL;
|
||||
}
|
||||
|
||||
operator ::DLGPROC() const {return reinterpret_cast<::DLGPROC>(Code); }
|
||||
operator ::LONG_PTR() const {return reinterpret_cast<::LONG_PTR>(Code); }
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#else // _M_IX86
|
||||
#error Only X86 supported
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // WNDPROCTHUNK_H_INCLUDED
|
||||
|
||||
|
||||
|
||||
|
@ -1,70 +0,0 @@
|
||||
@echo off
|
||||
::
|
||||
:: Profiling using a MSVC standalone profiler
|
||||
::
|
||||
:: See http://www.codeproject.com/Articles/144643/Profiling-of-C-Applications-in-Visual-Studio-for-F for details
|
||||
::
|
||||
|
||||
|
||||
|
||||
|
||||
set pt="C:\Program Files\Microsoft Visual Studio 9.0\Team Tools\Performance Tools"
|
||||
set appdir="Release profiled"
|
||||
set app="Release profiled\BiomeVisualiser.exe"
|
||||
set args=""
|
||||
|
||||
:: outputdir is relative to appdir!
|
||||
set outputdir=Profiling
|
||||
set output=profile.vsp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
::Create the output directory, if it didn't exist
|
||||
mkdir %outputdir%
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:: Start the profiler
|
||||
%pt%\vsperfcmd /start:sample /output:%outputdir%\%output%
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
:: Launch the application via the profiler
|
||||
%pt%\vsperfcmd /launch:%app% /args:%args%
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
:: Shut down the profiler (this command waits, until the application is terminated)
|
||||
%pt%\vsperfcmd /shutdown
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:: cd to outputdir, so that the reports are generated there
|
||||
cd %outputdir%
|
||||
|
||||
:: generate the report files (.csv)
|
||||
%pt%\vsperfreport /summary:all %output% /symbolpath:"srv*C:\Programovani\Symbols*http://msdl.microsoft.com/download/symbols"
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
goto finished
|
||||
|
||||
|
||||
|
||||
|
||||
:haderror
|
||||
echo An error was encountered
|
||||
pause
|
||||
|
||||
|
||||
|
||||
|
||||
:finished
|
2
Tools/QtBiomeVisualiser/.gitignore
vendored
Normal file
2
Tools/QtBiomeVisualiser/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.pro.user
|
||||
*.pro.user.*
|
427
Tools/QtBiomeVisualiser/BiomeView.cpp
Normal file
427
Tools/QtBiomeVisualiser/BiomeView.cpp
Normal file
@ -0,0 +1,427 @@
|
||||
#include "Globals.h"
|
||||
#include "BiomeView.h"
|
||||
#include "Chunk.h"
|
||||
#include <QPainter>
|
||||
#include <QResizeEvent>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const int DELTA_STEP = 120; // The normal per-notch wheel delta
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BiomeView::BiomeView(QWidget * parent) :
|
||||
super(parent),
|
||||
m_X(0),
|
||||
m_Z(0),
|
||||
m_Zoom(1),
|
||||
m_IsMouseDragging(false),
|
||||
m_MouseWheelDelta(0)
|
||||
{
|
||||
// Create the image used for undefined chunks:
|
||||
int offset = 0;
|
||||
for (int y = 0; y < 16; y++)
|
||||
{
|
||||
for (int x = 0; x < 16; x++)
|
||||
{
|
||||
uchar color = (((x & 8) ^ (y & 8)) == 0) ? 0x44 : 0x88;
|
||||
m_EmptyChunkImage[offset++] = color;
|
||||
m_EmptyChunkImage[offset++] = color;
|
||||
m_EmptyChunkImage[offset++] = color;
|
||||
m_EmptyChunkImage[offset++] = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the startup image:
|
||||
redraw();
|
||||
|
||||
// Add a chunk-update callback mechanism:
|
||||
connect(&m_Cache, SIGNAL(chunkAvailable(int, int)), this, SLOT(chunkAvailable(int, int)));
|
||||
|
||||
// Allow keyboard interaction:
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QSize BiomeView::minimumSizeHint() const
|
||||
{
|
||||
return QSize(300, 300);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QSize BiomeView::sizeHint() const
|
||||
{
|
||||
return QSize(800, 600);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::setChunkSource(std::shared_ptr<ChunkSource> a_ChunkSource)
|
||||
{
|
||||
// Replace the source in the cache:
|
||||
m_Cache.setChunkSource(a_ChunkSource);
|
||||
|
||||
// Redraw with the new source:
|
||||
redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::redraw()
|
||||
{
|
||||
if (!hasData())
|
||||
{
|
||||
// No data means no image is displayed, no need to compose:
|
||||
update();
|
||||
return;
|
||||
}
|
||||
|
||||
int chunksize = 16 * m_Zoom;
|
||||
|
||||
// first find the center block position
|
||||
int centerchunkx = floor(m_X / 16);
|
||||
int centerchunkz = floor(m_Z / 16);
|
||||
// and the center of the screen
|
||||
int centerx = m_Image.width() / 2;
|
||||
int centery = m_Image.height() / 2;
|
||||
// and align for panning
|
||||
centerx -= (m_X - centerchunkx * 16) * m_Zoom;
|
||||
centery -= (m_Z - centerchunkz * 16) * m_Zoom;
|
||||
// now calculate the topleft block on the screen
|
||||
int startx = centerchunkx - centerx / chunksize - 1;
|
||||
int startz = centerchunkz - centery / chunksize - 1;
|
||||
// and the dimensions of the screen in blocks
|
||||
int blockswide = m_Image.width() / chunksize + 3;
|
||||
int blockstall = m_Image.height() / chunksize + 3;
|
||||
|
||||
for (int z = startz; z < startz + blockstall; z++)
|
||||
{
|
||||
for (int x = startx; x < startx + blockswide; x++)
|
||||
{
|
||||
drawChunk(x, z);
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::chunkAvailable(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
drawChunk(a_ChunkX, a_ChunkZ);
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::reload()
|
||||
{
|
||||
if (!hasData())
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_Cache.reload();
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::drawChunk(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
if (!hasData())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//fetch the chunk:
|
||||
ChunkPtr chunk = m_Cache.fetch(a_ChunkX, a_ChunkZ);
|
||||
|
||||
// Figure out where on the screen this chunk should be drawn:
|
||||
// first find the center chunk
|
||||
int centerchunkx = floor(m_X / 16);
|
||||
int centerchunkz = floor(m_Z / 16);
|
||||
// and the center chunk screen coordinates
|
||||
int centerx = m_Image.width() / 2;
|
||||
int centery = m_Image.height() / 2;
|
||||
// which need to be shifted to account for panning inside that chunk
|
||||
centerx -= (m_X - centerchunkx * 16) * m_Zoom;
|
||||
centery -= (m_Z - centerchunkz * 16) * m_Zoom;
|
||||
// centerx,y now points to the top left corner of the center chunk
|
||||
// so now calculate our x,y in relation
|
||||
double chunksize = 16 * m_Zoom;
|
||||
centerx += (a_ChunkX - centerchunkx) * chunksize;
|
||||
centery += (a_ChunkZ - centerchunkz) * chunksize;
|
||||
|
||||
int srcoffset = 0;
|
||||
uchar * bits = m_Image.bits();
|
||||
int imgstride = m_Image.bytesPerLine();
|
||||
|
||||
int skipx = 0,skipy = 0;
|
||||
int blockwidth = chunksize, blockheight = chunksize;
|
||||
// now if we're off the screen we need to crop
|
||||
if (centerx < 0)
|
||||
{
|
||||
skipx = -centerx;
|
||||
centerx = 0;
|
||||
}
|
||||
if (centery < 0)
|
||||
{
|
||||
skipy = -centery;
|
||||
centery = 0;
|
||||
}
|
||||
// or the other side, we need to trim
|
||||
if (centerx + blockwidth > m_Image.width())
|
||||
{
|
||||
blockwidth = m_Image.width() - centerx;
|
||||
}
|
||||
if (centery + blockheight > m_Image.height())
|
||||
{
|
||||
blockheight = m_Image.height() - centery;
|
||||
}
|
||||
if ((blockwidth <= 0) || (skipx >= blockwidth))
|
||||
{
|
||||
return;
|
||||
}
|
||||
int imgoffset = centerx * 4 + centery * imgstride;
|
||||
|
||||
// If the chunk is valid, use its data; otherwise use the empty placeholder:
|
||||
const uchar * src = m_EmptyChunkImage;
|
||||
if (chunk.get() != nullptr)
|
||||
{
|
||||
src = chunk->getImage();
|
||||
}
|
||||
|
||||
// Blit or scale-blit the image:
|
||||
for (int z = skipy; z < blockheight; z++, imgoffset += imgstride)
|
||||
{
|
||||
srcoffset = floor((double)z / m_Zoom) * 16 * 4;
|
||||
if (m_Zoom == 1.0)
|
||||
{
|
||||
memcpy(bits + imgoffset, src + srcoffset + skipx * 4, (blockwidth - skipx) * 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
int xofs = 0;
|
||||
for (int x = skipx; x < blockwidth; x++, xofs +=4)
|
||||
{
|
||||
memcpy(bits + imgoffset + xofs, src + srcoffset + (int)floor((double)x / m_Zoom) * 4, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::resizeEvent(QResizeEvent * a_Event)
|
||||
{
|
||||
m_Image = QImage(a_Event->size(), QImage::Format_RGB32);
|
||||
redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::paintEvent(QPaintEvent * a_Event)
|
||||
{
|
||||
QPainter p(this);
|
||||
if (hasData())
|
||||
{
|
||||
p.drawImage(QPoint(0, 0), m_Image);
|
||||
}
|
||||
else
|
||||
{
|
||||
p.drawText(a_Event->rect(), Qt::AlignCenter, "No chunk source selected");
|
||||
}
|
||||
p.end();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::mousePressEvent(QMouseEvent * a_Event)
|
||||
{
|
||||
m_LastX = a_Event->x();
|
||||
m_LastY = a_Event->y();
|
||||
m_IsMouseDragging = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::mouseMoveEvent(QMouseEvent * a_Event)
|
||||
{
|
||||
if (m_IsMouseDragging)
|
||||
{
|
||||
// The user is dragging the mouse, move the view around:
|
||||
m_X += (m_LastX - a_Event->x()) / m_Zoom;
|
||||
m_Z += (m_LastY - a_Event->y()) / m_Zoom;
|
||||
m_LastX = a_Event->x();
|
||||
m_LastY = a_Event->y();
|
||||
redraw();
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Update the status bar info for the biome currently pointed at
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::mouseReleaseEvent(QMouseEvent *)
|
||||
{
|
||||
m_IsMouseDragging = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::wheelEvent(QWheelEvent * a_Event)
|
||||
{
|
||||
m_MouseWheelDelta += a_Event->delta();
|
||||
while (m_MouseWheelDelta >= DELTA_STEP)
|
||||
{
|
||||
increaseZoom();
|
||||
m_MouseWheelDelta -= DELTA_STEP;
|
||||
}
|
||||
while (m_MouseWheelDelta <= -DELTA_STEP)
|
||||
{
|
||||
decreaseZoom();
|
||||
m_MouseWheelDelta += DELTA_STEP;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::keyPressEvent(QKeyEvent * a_Event)
|
||||
{
|
||||
switch (a_Event->key())
|
||||
{
|
||||
case Qt::Key_Up:
|
||||
case Qt::Key_W:
|
||||
{
|
||||
m_Z -= 10.0 / m_Zoom;
|
||||
redraw();
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_Down:
|
||||
case Qt::Key_S:
|
||||
{
|
||||
m_Z += 10.0 / m_Zoom;
|
||||
redraw();
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_Left:
|
||||
case Qt::Key_A:
|
||||
{
|
||||
m_X -= 10.0 / m_Zoom;
|
||||
redraw();
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_Right:
|
||||
case Qt::Key_D:
|
||||
{
|
||||
m_X += 10.0 / m_Zoom;
|
||||
redraw();
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_PageUp:
|
||||
case Qt::Key_Q:
|
||||
{
|
||||
increaseZoom();
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_PageDown:
|
||||
case Qt::Key_E:
|
||||
{
|
||||
decreaseZoom();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::decreaseZoom()
|
||||
{
|
||||
if (m_Zoom > 1.001)
|
||||
{
|
||||
m_Zoom--;
|
||||
if (m_Zoom < 1.0)
|
||||
{
|
||||
// Just crossed the 100%, fixate the 100% threshold:
|
||||
m_Zoom = 1.0;
|
||||
}
|
||||
}
|
||||
else if (m_Zoom > 0.01)
|
||||
{
|
||||
m_Zoom = m_Zoom / 2;
|
||||
}
|
||||
redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::increaseZoom()
|
||||
{
|
||||
if (m_Zoom > 0.99)
|
||||
{
|
||||
if (m_Zoom > 20.0)
|
||||
{
|
||||
// Zoom too large
|
||||
return;
|
||||
}
|
||||
m_Zoom++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Zoom = m_Zoom * 2;
|
||||
if (m_Zoom > 1.0)
|
||||
{
|
||||
// Just crossed the 100%, fixate the 100% threshold:
|
||||
m_Zoom = 1.0;
|
||||
}
|
||||
}
|
||||
redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
100
Tools/QtBiomeVisualiser/BiomeView.h
Normal file
100
Tools/QtBiomeVisualiser/BiomeView.h
Normal file
@ -0,0 +1,100 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <memory>
|
||||
#include "ChunkCache.h"
|
||||
#include "ChunkSource.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class BiomeView :
|
||||
public QWidget
|
||||
{
|
||||
typedef QWidget super;
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit BiomeView(QWidget * parent = NULL);
|
||||
|
||||
QSize minimumSizeHint() const;
|
||||
QSize sizeHint() const;
|
||||
|
||||
/** Replaces the chunk source used by the biome view to get the chunk biome data.
|
||||
The entire view is then invalidated and regenerated. */
|
||||
void setChunkSource(std::shared_ptr<ChunkSource> a_ChunkSource);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
/** Redraw the entire widget area. */
|
||||
void redraw();
|
||||
|
||||
/** A specified chunk has become available, redraw it. */
|
||||
void chunkAvailable(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
/** Reloads the current chunk source and redraws the entire workspace. */
|
||||
void reload();
|
||||
|
||||
protected:
|
||||
double m_X, m_Z;
|
||||
double m_Zoom;
|
||||
|
||||
/** Cache for the loaded chunk data. */
|
||||
ChunkCache m_Cache;
|
||||
|
||||
/** The entire view's contents in an offscreen image. */
|
||||
QImage m_Image;
|
||||
|
||||
/** Coords of the mouse for the previous position, used while dragging. */
|
||||
int m_LastX, m_LastY;
|
||||
|
||||
/** Set to true when the user has a mouse button depressed, and is dragging the view. */
|
||||
bool m_IsMouseDragging;
|
||||
|
||||
/** Accumulator for the mouse wheel's delta. When the accumulator hits a threshold, the view zooms. */
|
||||
int m_MouseWheelDelta;
|
||||
|
||||
/** Data used for rendering a chunk that hasn't been loaded yet */
|
||||
uchar m_EmptyChunkImage[16 * 16 * 4];
|
||||
|
||||
|
||||
/** Draws the specified chunk into m_Image */
|
||||
void drawChunk(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
/** Returns true iff the biome view has been initialized to contain proper biome data. */
|
||||
bool hasData(void) const { return m_Cache.hasData(); }
|
||||
|
||||
/** Called when the widget is resized */
|
||||
virtual void resizeEvent(QResizeEvent *) override;
|
||||
|
||||
/** Paints the entire widget */
|
||||
virtual void paintEvent(QPaintEvent *) override;
|
||||
|
||||
/** Called when the user presses any mouse button. */
|
||||
virtual void mousePressEvent(QMouseEvent * a_Event);
|
||||
|
||||
/** Called when the user moves the mouse. */
|
||||
virtual void mouseMoveEvent(QMouseEvent * a_Event);
|
||||
|
||||
/** Called when the user releases a previously held mouse button. */
|
||||
virtual void mouseReleaseEvent(QMouseEvent * a_Event) override;
|
||||
|
||||
/** Called when the user rotates the mouse wheel. */
|
||||
virtual void wheelEvent(QWheelEvent * a_Event) override;
|
||||
|
||||
/** Called when the user presses a key. */
|
||||
virtual void keyPressEvent(QKeyEvent * a_Event) override;
|
||||
|
||||
/** Decreases the zoom level and queues a redraw. */
|
||||
void decreaseZoom();
|
||||
|
||||
/** Increases the zoom level and queues a redraw. */
|
||||
void increaseZoom();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
36
Tools/QtBiomeVisualiser/Chunk.cpp
Normal file
36
Tools/QtBiomeVisualiser/Chunk.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include "Globals.h"
|
||||
#include "Globals.h"
|
||||
#include "Chunk.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Chunk::Chunk() :
|
||||
m_IsValid(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const uchar * Chunk::getImage(void) const
|
||||
{
|
||||
ASSERT(m_IsValid);
|
||||
return m_Image;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void Chunk::setImage(const Image & a_Image)
|
||||
{
|
||||
memcpy(m_Image, a_Image, sizeof(a_Image));
|
||||
m_IsValid = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
40
Tools/QtBiomeVisualiser/Chunk.h
Normal file
40
Tools/QtBiomeVisualiser/Chunk.h
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <qglobal.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class Chunk
|
||||
{
|
||||
public:
|
||||
/** The type used for storing image data for a chunk. */
|
||||
typedef uchar Image[16 * 16 * 4];
|
||||
|
||||
|
||||
Chunk(void);
|
||||
|
||||
/** Returns true iff the chunk data is valid - loaded or generated. */
|
||||
bool isValid(void) const { return m_IsValid; }
|
||||
|
||||
/** Returns the image of the chunk's biomes. Assumes that the chunk is valid. */
|
||||
const uchar * getImage(void) const;
|
||||
|
||||
/** Sets the image data for this chunk. */
|
||||
void setImage(const Image & a_Image);
|
||||
|
||||
protected:
|
||||
/** Flag that specifies if the chunk data is valid - loaded or generated. */
|
||||
bool m_IsValid;
|
||||
|
||||
/** Cached rendered image of this chunk's biomes. Updated in render(). */
|
||||
Image m_Image;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<Chunk> ChunkPtr;
|
||||
|
||||
|
||||
|
||||
|
||||
|
126
Tools/QtBiomeVisualiser/ChunkCache.cpp
Normal file
126
Tools/QtBiomeVisualiser/ChunkCache.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
#include "Globals.h"
|
||||
#include "ChunkCache.h"
|
||||
#include <QMutexLocker>
|
||||
#include <QThreadPool>
|
||||
#include "ChunkSource.h"
|
||||
#include "ChunkLoader.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ChunkCache::ChunkCache(QObject * parent) :
|
||||
super(parent)
|
||||
{
|
||||
m_Cache.setMaxCost(1024 * 1024 * 1024); // 1 GiB of memory for the cache
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ChunkPtr ChunkCache::fetch(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
// Retrieve from the cache:
|
||||
quint32 hash = getChunkHash(a_ChunkX, a_ChunkZ);
|
||||
ChunkPtr * res;
|
||||
{
|
||||
QMutexLocker lock(&m_Mtx);
|
||||
res = m_Cache[hash];
|
||||
// If succesful and chunk loaded, return the retrieved value:
|
||||
if ((res != nullptr) && (*res)->isValid())
|
||||
{
|
||||
return *res;
|
||||
}
|
||||
}
|
||||
|
||||
// If the chunk is in cache but not valid, it means it has been already queued for rendering, do nothing now:
|
||||
if (res != nullptr)
|
||||
{
|
||||
return ChunkPtr(nullptr);
|
||||
}
|
||||
|
||||
// There's no such item in the cache, create it now:
|
||||
res = new ChunkPtr(new Chunk);
|
||||
if (res == nullptr)
|
||||
{
|
||||
return ChunkPtr(nullptr);
|
||||
}
|
||||
{
|
||||
QMutexLocker lock(&m_Mtx);
|
||||
m_Cache.insert(hash, res, sizeof(Chunk));
|
||||
}
|
||||
|
||||
// Queue the chunk for rendering:
|
||||
queueChunkRender(a_ChunkX, a_ChunkZ, *res);
|
||||
|
||||
// Return failure, the chunk is not yet rendered:
|
||||
return ChunkPtr(nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ChunkCache::setChunkSource(std::shared_ptr<ChunkSource> a_ChunkSource)
|
||||
{
|
||||
// Replace the chunk source:
|
||||
m_ChunkSource = a_ChunkSource;
|
||||
|
||||
// Clear the cache:
|
||||
QMutexLocker lock(&m_Mtx);
|
||||
m_Cache.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ChunkCache::reload()
|
||||
{
|
||||
assert(m_ChunkSource.get() != nullptr);
|
||||
|
||||
// Reload the chunk source:
|
||||
m_ChunkSource->reload();
|
||||
|
||||
// Clear the cache:
|
||||
QMutexLocker lock(&m_Mtx);
|
||||
m_Cache.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ChunkCache::gotChunk(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
emit chunkAvailable(a_ChunkX, a_ChunkZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
quint32 ChunkCache::getChunkHash(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
// Simply join the two coords into a single int
|
||||
// The coords will never be larger than 16-bits, so we can do this safely
|
||||
return (((static_cast<quint32>(a_ChunkX) & 0xffff) << 16) | (static_cast<quint32>(a_ChunkZ) & 0xffff));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ChunkCache::queueChunkRender(int a_ChunkX, int a_ChunkZ, ChunkPtr & a_Chunk)
|
||||
{
|
||||
// Create a new loader task:
|
||||
ChunkLoader * loader = new ChunkLoader(a_ChunkX, a_ChunkZ, a_Chunk, m_ChunkSource);
|
||||
connect(loader, SIGNAL(loaded(int, int)), this, SLOT(gotChunk(int, int)));
|
||||
|
||||
QThreadPool::globalInstance()->start(loader);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
72
Tools/QtBiomeVisualiser/ChunkCache.h
Normal file
72
Tools/QtBiomeVisualiser/ChunkCache.h
Normal file
@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QCache>
|
||||
#include <QMutex>
|
||||
#include <memory>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class Chunk;
|
||||
typedef std::shared_ptr<Chunk> ChunkPtr;
|
||||
|
||||
class ChunkSource;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Caches chunk data for reuse */
|
||||
class ChunkCache :
|
||||
public QObject
|
||||
{
|
||||
typedef QObject super;
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ChunkCache(QObject * parent = NULL);
|
||||
|
||||
/** Retrieves the specified chunk from the cache.
|
||||
Only returns valid chunks; if the chunk is invalid, queues it for rendering and returns an empty ptr. */
|
||||
ChunkPtr fetch(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
/** Replaces the chunk source used by the biome view to get the chunk biome data.
|
||||
The cache is then invalidated. */
|
||||
void setChunkSource(std::shared_ptr<ChunkSource> a_ChunkSource);
|
||||
|
||||
/** Returns true iff the chunk source has been initialized. */
|
||||
bool hasData() const { return (m_ChunkSource.get() != nullptr); }
|
||||
|
||||
/** Reloads the current chunk source. */
|
||||
void reload();
|
||||
|
||||
signals:
|
||||
void chunkAvailable(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
protected slots:
|
||||
void gotChunk(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
protected:
|
||||
/** The cache of the chunks */
|
||||
QCache<quint32, ChunkPtr> m_Cache;
|
||||
|
||||
/** Locks te cache against multithreaded access */
|
||||
QMutex m_Mtx;
|
||||
|
||||
/** The source used to get the biome data. */
|
||||
std::shared_ptr<ChunkSource> m_ChunkSource;
|
||||
|
||||
|
||||
/** Returns the hash used by the chunk in the cache */
|
||||
quint32 getChunkHash(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
/** Queues the specified chunk for rendering by m_ChunkSource. */
|
||||
void queueChunkRender(int a_ChunkX, int a_ChunkZ, ChunkPtr & a_Chunk);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
29
Tools/QtBiomeVisualiser/ChunkLoader.cpp
Normal file
29
Tools/QtBiomeVisualiser/ChunkLoader.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
#include "Globals.h"
|
||||
#include "ChunkLoader.h"
|
||||
#include "ChunkSource.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ChunkLoader::ChunkLoader(int a_ChunkX, int a_ChunkZ, ChunkPtr a_Chunk, ChunkSourcePtr a_ChunkSource) :
|
||||
m_ChunkX(a_ChunkX),
|
||||
m_ChunkZ(a_ChunkZ),
|
||||
m_Chunk(a_Chunk),
|
||||
m_ChunkSource(a_ChunkSource)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ChunkLoader::run()
|
||||
{
|
||||
m_ChunkSource->getChunkBiomes(m_ChunkX, m_ChunkZ, m_Chunk);
|
||||
emit loaded(m_ChunkX, m_ChunkZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
45
Tools/QtBiomeVisualiser/ChunkLoader.h
Normal file
45
Tools/QtBiomeVisualiser/ChunkLoader.h
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QRunnable>
|
||||
#include <memory>
|
||||
|
||||
|
||||
|
||||
|
||||
// fwd:
|
||||
class Chunk;
|
||||
typedef std::shared_ptr<Chunk> ChunkPtr;
|
||||
|
||||
class ChunkSource;
|
||||
typedef std::shared_ptr<ChunkSource> ChunkSourcePtr;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class ChunkLoader :
|
||||
public QObject,
|
||||
public QRunnable
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ChunkLoader(int a_ChunkX, int a_ChunkZ, ChunkPtr a_Chunk, ChunkSourcePtr a_ChunkSource);
|
||||
virtual ~ChunkLoader() {}
|
||||
|
||||
signals:
|
||||
void loaded(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
protected:
|
||||
virtual void run() override;
|
||||
|
||||
private:
|
||||
int m_ChunkX, m_ChunkZ;
|
||||
ChunkPtr m_Chunk;
|
||||
ChunkSourcePtr m_ChunkSource;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
421
Tools/QtBiomeVisualiser/ChunkSource.cpp
Normal file
421
Tools/QtBiomeVisualiser/ChunkSource.cpp
Normal file
@ -0,0 +1,421 @@
|
||||
#include "Globals.h"
|
||||
#include "ChunkSource.h"
|
||||
#include <QThread>
|
||||
#include "src/Generating/BioGen.h"
|
||||
#include "inifile/iniFile.h"
|
||||
#include "src/StringCompression.h"
|
||||
#include "src/WorldStorage/FastNBT.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Map for converting biome values to colors. Initialized from biomeColors[]. */
|
||||
static uchar biomeToColor[256 * 4];
|
||||
|
||||
/** Map for converting biome values to colors. Used to initialize biomeToColor[].*/
|
||||
static struct
|
||||
{
|
||||
EMCSBiome m_Biome;
|
||||
uchar m_Color[3];
|
||||
} biomeColors[] =
|
||||
{
|
||||
{ biOcean, { 0x00, 0x00, 0x70 }, },
|
||||
{ biPlains, { 0x8d, 0xb3, 0x60 }, },
|
||||
{ biDesert, { 0xfa, 0x94, 0x18 }, },
|
||||
{ biExtremeHills, { 0x60, 0x60, 0x60 }, },
|
||||
{ biForest, { 0x05, 0x66, 0x21 }, },
|
||||
{ biTaiga, { 0x0b, 0x66, 0x59 }, },
|
||||
{ biSwampland, { 0x2f, 0xff, 0xda }, },
|
||||
{ biRiver, { 0x30, 0x30, 0xaf }, },
|
||||
{ biHell, { 0x7f, 0x00, 0x00 }, },
|
||||
{ biSky, { 0x00, 0x7f, 0xff }, },
|
||||
{ biFrozenOcean, { 0xa0, 0xa0, 0xdf }, },
|
||||
{ biFrozenRiver, { 0xa0, 0xa0, 0xff }, },
|
||||
{ biIcePlains, { 0xff, 0xff, 0xff }, },
|
||||
{ biIceMountains, { 0xa0, 0xa0, 0xa0 }, },
|
||||
{ biMushroomIsland, { 0xff, 0x00, 0xff }, },
|
||||
{ biMushroomShore, { 0xa0, 0x00, 0xff }, },
|
||||
{ biBeach, { 0xfa, 0xde, 0x55 }, },
|
||||
{ biDesertHills, { 0xd2, 0x5f, 0x12 }, },
|
||||
{ biForestHills, { 0x22, 0x55, 0x1c }, },
|
||||
{ biTaigaHills, { 0x16, 0x39, 0x33 }, },
|
||||
{ biExtremeHillsEdge, { 0x7f, 0x8f, 0x7f }, },
|
||||
{ biJungle, { 0x53, 0x7b, 0x09 }, },
|
||||
{ biJungleHills, { 0x2c, 0x42, 0x05 }, },
|
||||
|
||||
{ biJungleEdge, { 0x62, 0x8b, 0x17 }, },
|
||||
{ biDeepOcean, { 0x00, 0x00, 0x30 }, },
|
||||
{ biStoneBeach, { 0xa2, 0xa2, 0x84 }, },
|
||||
{ biColdBeach, { 0xfa, 0xf0, 0xc0 }, },
|
||||
{ biBirchForest, { 0x30, 0x74, 0x44 }, },
|
||||
{ biBirchForestHills, { 0x1f, 0x5f, 0x32 }, },
|
||||
{ biRoofedForest, { 0x40, 0x51, 0x1a }, },
|
||||
{ biColdTaiga, { 0x31, 0x55, 0x4a }, },
|
||||
{ biColdTaigaHills, { 0x59, 0x7d, 0x72 }, },
|
||||
{ biMegaTaiga, { 0x59, 0x66, 0x51 }, },
|
||||
{ biMegaTaigaHills, { 0x59, 0x66, 0x59 }, },
|
||||
{ biExtremeHillsPlus, { 0x50, 0x70, 0x50 }, },
|
||||
{ biSavanna, { 0xbd, 0xb2, 0x5f }, },
|
||||
{ biSavannaPlateau, { 0xa7, 0x9d, 0x64 }, },
|
||||
{ biMesa, { 0xd9, 0x45, 0x15 }, },
|
||||
{ biMesaPlateauF, { 0xb0, 0x97, 0x65 }, },
|
||||
{ biMesaPlateau, { 0xca, 0x8c, 0x65 }, },
|
||||
|
||||
// M variants:
|
||||
{ biSunflowerPlains, { 0xb5, 0xdb, 0x88 }, },
|
||||
{ biDesertM, { 0xff, 0xbc, 0x40 }, },
|
||||
{ biExtremeHillsM, { 0x88, 0x88, 0x88 }, },
|
||||
{ biFlowerForest, { 0x2d, 0x8e, 0x49 }, },
|
||||
{ biTaigaM, { 0x33, 0x8e, 0x81 }, },
|
||||
{ biSwamplandM, { 0x07, 0xf9, 0xb2 }, },
|
||||
{ biIcePlainsSpikes, { 0xb4, 0xdc, 0xdc }, },
|
||||
{ biJungleM, { 0x7b, 0xa3, 0x31 }, },
|
||||
{ biJungleEdgeM, { 0x62, 0x8b, 0x17 }, },
|
||||
{ biBirchForestM, { 0x58, 0x9c, 0x6c }, },
|
||||
{ biBirchForestHillsM, { 0x47, 0x87, 0x5a }, },
|
||||
{ biRoofedForestM, { 0x68, 0x79, 0x42 }, },
|
||||
{ biColdTaigaM, { 0x24, 0x3f, 0x36 }, },
|
||||
{ biMegaSpruceTaiga, { 0x45, 0x4f, 0x3e }, },
|
||||
{ biMegaSpruceTaigaHills, { 0x45, 0x4f, 0x4e }, },
|
||||
{ biExtremeHillsPlusM, { 0x78, 0x98, 0x78 }, },
|
||||
{ biSavannaM, { 0xe5, 0xda, 0x87 }, },
|
||||
{ biSavannaPlateauM, { 0xa7, 0x9d, 0x74 }, },
|
||||
{ biMesaBryce, { 0xff, 0x6d, 0x3d }, },
|
||||
{ biMesaPlateauFM, { 0xd8, 0xbf, 0x8d }, },
|
||||
{ biMesaPlateauM, { 0xf2, 0xb4, 0x8d }, },
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static class BiomeColorsInitializer
|
||||
{
|
||||
public:
|
||||
BiomeColorsInitializer(void)
|
||||
{
|
||||
// Reset all colors to gray:
|
||||
for (size_t i = 0; i < ARRAYCOUNT(biomeToColor); i++)
|
||||
{
|
||||
biomeToColor[i] = 0x7f;
|
||||
}
|
||||
|
||||
// Set known biomes to their colors:
|
||||
for (size_t i = 0; i < ARRAYCOUNT(biomeColors); i++)
|
||||
{
|
||||
uchar * color = &biomeToColor[4 * biomeColors[i].m_Biome];
|
||||
color[0] = biomeColors[i].m_Color[2];
|
||||
color[1] = biomeColors[i].m_Color[1];
|
||||
color[2] = biomeColors[i].m_Color[0];
|
||||
color[3] = 0xff;
|
||||
}
|
||||
}
|
||||
} biomeColorInitializer;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Converts biomes in an array into the chunk image data. */
|
||||
static void biomesToImage(cChunkDef::BiomeMap & a_Biomes, Chunk::Image & a_Image)
|
||||
{
|
||||
// Make sure the two arrays are of the same size, compile-time.
|
||||
// Note that a_Image is actually 4 items per pixel, so the array is 4 times bigger:
|
||||
static const char Check1[4 * ARRAYCOUNT(a_Biomes) - ARRAYCOUNT(a_Image) + 1] = {};
|
||||
static const char Check2[ARRAYCOUNT(a_Image) - 4 * ARRAYCOUNT(a_Biomes) + 1] = {};
|
||||
|
||||
// Convert the biomes into color:
|
||||
for (size_t i = 0; i < ARRAYCOUNT(a_Biomes); i++)
|
||||
{
|
||||
a_Image[4 * i + 0] = biomeToColor[4 * a_Biomes[i] + 0];
|
||||
a_Image[4 * i + 1] = biomeToColor[4 * a_Biomes[i] + 1];
|
||||
a_Image[4 * i + 2] = biomeToColor[4 * a_Biomes[i] + 2];
|
||||
a_Image[4 * i + 3] = biomeToColor[4 * a_Biomes[i] + 3];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// BioGenSource:
|
||||
|
||||
BioGenSource::BioGenSource(cIniFilePtr a_IniFile) :
|
||||
m_IniFile(a_IniFile),
|
||||
m_Mtx(QMutex::Recursive)
|
||||
{
|
||||
reload();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BioGenSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk)
|
||||
{
|
||||
cChunkDef::BiomeMap biomes;
|
||||
{
|
||||
QMutexLocker lock(&m_Mtx);
|
||||
m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, biomes);
|
||||
}
|
||||
Chunk::Image img;
|
||||
biomesToImage(biomes, img);
|
||||
a_DestChunk->setImage(img);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BioGenSource::reload()
|
||||
{
|
||||
int seed = m_IniFile->GetValueSetI("Generator", "Seed", 0);
|
||||
bool unused = false;
|
||||
QMutexLocker lock(&m_Mtx);
|
||||
m_BiomeGen.reset(cBiomeGen::CreateBiomeGen(*m_IniFile, seed, unused));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// AnvilSource::AnvilFile
|
||||
|
||||
class AnvilSource::AnvilFile
|
||||
{
|
||||
public:
|
||||
/** Coordinates of the region file. */
|
||||
int m_RegionX, m_RegionZ;
|
||||
|
||||
/** True iff the file contains proper data. */
|
||||
bool m_IsValid;
|
||||
|
||||
|
||||
|
||||
/** Creates a new instance with the specified region coords. Reads the file header. */
|
||||
AnvilFile(int a_RegionX, int a_RegionZ, const AString & a_WorldPath) :
|
||||
m_RegionX(a_RegionX),
|
||||
m_RegionZ(a_RegionZ),
|
||||
m_IsValid(false)
|
||||
{
|
||||
readFile(Printf("%s/r.%d.%d.mca", a_WorldPath.c_str(), a_RegionX, a_RegionZ));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Returns the compressed data of the specified chunk.
|
||||
Returns an empty string when chunk not present. */
|
||||
AString getChunkData(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
if (!m_IsValid)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
// Translate to local coords:
|
||||
int RelChunkX = a_ChunkX - m_RegionX * 32;
|
||||
int RelChunkZ = a_ChunkZ - m_RegionZ * 32;
|
||||
ASSERT((RelChunkX >= 0) && (RelChunkX < 32));
|
||||
ASSERT((RelChunkZ >= 0) && (RelChunkZ < 32));
|
||||
|
||||
// Get the chunk data location:
|
||||
UInt32 chunkOffset = m_Header[RelChunkX + 32 * RelChunkZ] >> 8;
|
||||
UInt32 numChunkSectors = m_Header[RelChunkX + 32 * RelChunkZ] & 0xff;
|
||||
if ((chunkOffset < 2) || (numChunkSectors == 0))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
// Get the real data size:
|
||||
const char * chunkData = m_FileData.data() + chunkOffset * 4096;
|
||||
UInt32 chunkSize = GetBEInt(chunkData);
|
||||
if ((chunkSize < 2) || (chunkSize / 4096 > numChunkSectors))
|
||||
{
|
||||
// Bad data, bail out
|
||||
return "";
|
||||
}
|
||||
|
||||
// Check the compression method:
|
||||
if (chunkData[4] != 2)
|
||||
{
|
||||
// Chunk is in an unknown compression
|
||||
return "";
|
||||
}
|
||||
chunkSize--;
|
||||
|
||||
// Read the chunk data:
|
||||
return m_FileData.substr(chunkOffset * 4096 + 5, chunkSize);
|
||||
}
|
||||
|
||||
protected:
|
||||
AString m_FileData;
|
||||
UInt32 m_Header[2048];
|
||||
|
||||
|
||||
/** Reads the whole specified file contents and parses the header. */
|
||||
void readFile(const AString & a_FileName)
|
||||
{
|
||||
// Read the entire file:
|
||||
m_FileData = cFile::ReadWholeFile(a_FileName);
|
||||
if (m_FileData.size() < sizeof(m_Header))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the header - change endianness:
|
||||
const char * hdr = m_FileData.data();
|
||||
for (size_t i = 0; i < ARRAYCOUNT(m_Header); i++)
|
||||
{
|
||||
m_Header[i] = GetBEInt(hdr + 4 * i);
|
||||
}
|
||||
m_IsValid = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// AnvilSource:
|
||||
|
||||
AnvilSource::AnvilSource(QString a_WorldRegionFolder) :
|
||||
m_WorldRegionFolder(a_WorldRegionFolder)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void AnvilSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk)
|
||||
{
|
||||
// Load the compressed data:
|
||||
AString compressedChunkData = getCompressedChunkData(a_ChunkX, a_ChunkZ);
|
||||
if (compressedChunkData.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Uncompress the chunk data:
|
||||
AString uncompressed;
|
||||
int res = InflateString(compressedChunkData.data(), compressedChunkData.size(), uncompressed);
|
||||
if (res != Z_OK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the NBT data:
|
||||
cParsedNBT nbt(uncompressed.data(), uncompressed.size());
|
||||
if (!nbt.IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the biomes out of the NBT:
|
||||
int Level = nbt.FindChildByName(0, "Level");
|
||||
if (Level < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
cChunkDef::BiomeMap biomeMap;
|
||||
int mcsBiomes = nbt.FindChildByName(Level, "MCSBiomes");
|
||||
if ((mcsBiomes >= 0) && (nbt.GetDataLength(mcsBiomes) == sizeof(biomeMap)))
|
||||
{
|
||||
// Convert the biomes from BigEndian to platform native numbers:
|
||||
const char * beBiomes = nbt.GetData(mcsBiomes);
|
||||
for (size_t i = 0; i < ARRAYCOUNT(biomeMap); i++)
|
||||
{
|
||||
biomeMap[i] = (EMCSBiome)GetBEInt(beBiomes + 4 * i);
|
||||
}
|
||||
// Render the biomes:
|
||||
Chunk::Image img;
|
||||
biomesToImage(biomeMap, img);
|
||||
a_DestChunk->setImage(img);
|
||||
return;
|
||||
}
|
||||
|
||||
// MCS biomes not found, load Vanilla biomes instead:
|
||||
int biomes = nbt.FindChildByName(Level, "Biomes");
|
||||
if ((biomes < 0) || (nbt.GetDataLength(biomes) != ARRAYCOUNT(biomeMap)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Convert the biomes from Vanilla to EMCSBiome:
|
||||
const char * vanillaBiomes = nbt.GetData(biomes);
|
||||
for (size_t i = 0; i < ARRAYCOUNT(biomeMap); i++)
|
||||
{
|
||||
biomeMap[i] = EMCSBiome(vanillaBiomes[i]);
|
||||
}
|
||||
// Render the biomes:
|
||||
Chunk::Image img;
|
||||
biomesToImage(biomeMap, img);
|
||||
a_DestChunk->setImage(img);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void AnvilSource::reload()
|
||||
{
|
||||
// Remove all files from the cache:
|
||||
QMutexLocker lock(&m_Mtx);
|
||||
m_Files.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void AnvilSource::chunkToRegion(int a_ChunkX, int a_ChunkZ, int & a_RegionX, int & a_RegionZ)
|
||||
{
|
||||
a_RegionX = a_ChunkX >> 5;
|
||||
a_RegionZ = a_ChunkZ >> 5;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AString AnvilSource::getCompressedChunkData(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
return getAnvilFile(a_ChunkX, a_ChunkZ)->getChunkData(a_ChunkX, a_ChunkZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AnvilSource::AnvilFilePtr AnvilSource::getAnvilFile(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
int RegionX, RegionZ;
|
||||
chunkToRegion(a_ChunkX, a_ChunkZ, RegionX, RegionZ);
|
||||
|
||||
// Search the cache for the file:
|
||||
QMutexLocker lock(&m_Mtx);
|
||||
for (auto itr = m_Files.cbegin(), end = m_Files.cend(); itr != end; ++itr)
|
||||
{
|
||||
if (((*itr)->m_RegionX == RegionX) && ((*itr)->m_RegionZ == RegionZ))
|
||||
{
|
||||
// Found the file in the cache, move it to front and return it:
|
||||
AnvilFilePtr file(*itr);
|
||||
m_Files.erase(itr);
|
||||
m_Files.push_front(file);
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
// File not in cache, create it:
|
||||
AnvilFilePtr file(new AnvilFile(RegionX, RegionZ, m_WorldRegionFolder.toStdString()));
|
||||
m_Files.push_front(file);
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
107
Tools/QtBiomeVisualiser/ChunkSource.h
Normal file
107
Tools/QtBiomeVisualiser/ChunkSource.h
Normal file
@ -0,0 +1,107 @@
|
||||
#pragma once
|
||||
#include "Globals.h"
|
||||
#include <QString>
|
||||
#include <QMutex>
|
||||
#include "Chunk.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// fwd:
|
||||
class cBiomeGen;
|
||||
typedef std::shared_ptr<cBiomeGen> cBiomeGenPtr;
|
||||
class cIniFile;
|
||||
typedef std::shared_ptr<cIniFile> cIniFilePtr;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Abstract interface for getting biome data for chunks. */
|
||||
class ChunkSource
|
||||
{
|
||||
public:
|
||||
virtual ~ChunkSource() {}
|
||||
|
||||
/** Fills the a_DestChunk with the biomes for the specified coords.
|
||||
It is expected to be thread-safe and re-entrant. Usually QThread::idealThreadCount() threads are used. */
|
||||
virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) = 0;
|
||||
|
||||
/** Forces a fresh reload of the source. Useful mainly for the generator, whose underlying definition file may have been changed. */
|
||||
virtual void reload() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class BioGenSource :
|
||||
public ChunkSource
|
||||
{
|
||||
public:
|
||||
/** Constructs a new BioGenSource based on the biome generator that is defined in the specified world.ini file. */
|
||||
BioGenSource(cIniFilePtr a_IniFile);
|
||||
|
||||
// ChunkSource overrides:
|
||||
virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) override;
|
||||
virtual void reload(void) override;
|
||||
|
||||
protected:
|
||||
/** The world.ini contents from which the generator is created and re-created on reload(). */
|
||||
cIniFilePtr m_IniFile;
|
||||
|
||||
/** The generator used for generating biomes. */
|
||||
std::unique_ptr<cBiomeGen> m_BiomeGen;
|
||||
|
||||
/** Guards m_BiomeGen against multithreaded access. */
|
||||
QMutex m_Mtx;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class AnvilSource :
|
||||
public ChunkSource
|
||||
{
|
||||
public:
|
||||
/** Constructs a new AnvilSource based on the world path. */
|
||||
AnvilSource(QString a_WorldRegionFolder);
|
||||
|
||||
// ChunkSource overrides:
|
||||
virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) override;
|
||||
virtual void reload() override;
|
||||
|
||||
protected:
|
||||
class AnvilFile;
|
||||
typedef std::shared_ptr<AnvilFile> AnvilFilePtr;
|
||||
|
||||
|
||||
/** Folder where the individual Anvil Region files are located. */
|
||||
QString m_WorldRegionFolder;
|
||||
|
||||
/** List of currently loaded files. Acts as a cache so that a file is not opened and closed over and over again.
|
||||
Protected against multithreaded access by m_Mtx. */
|
||||
std::list<AnvilFilePtr> m_Files;
|
||||
|
||||
/** Guards m_Files agains multithreaded access. */
|
||||
QMutex m_Mtx;
|
||||
|
||||
|
||||
/** Converts chunk coords to region coords. */
|
||||
void chunkToRegion(int a_ChunkX, int a_ChunkZ, int & a_RegionX, int & a_RegionZ);
|
||||
|
||||
/** Returns the compressed data of the specified chunk.
|
||||
Returns an empty string if the chunk is not available. */
|
||||
AString getCompressedChunkData(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
/** Returns the file object that contains the specified chunk.
|
||||
The file is taken from the cache if available there, otherwise it is created anew. */
|
||||
AnvilFilePtr getAnvilFile(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
159
Tools/QtBiomeVisualiser/GeneratorSetup.cpp
Normal file
159
Tools/QtBiomeVisualiser/GeneratorSetup.cpp
Normal file
@ -0,0 +1,159 @@
|
||||
#include "Globals.h"
|
||||
#include "GeneratorSetup.h"
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include "src/Generating/BioGen.h"
|
||||
#include "inifile/iniFile.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const QString s_GeneratorNames[] =
|
||||
{
|
||||
QString("Checkerboard"),
|
||||
QString("Constant"),
|
||||
QString("DistortedVoronoi"),
|
||||
QString("MultiStepMap"),
|
||||
QString("TwoLevel"),
|
||||
QString("Voronoi"),
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
GeneratorSetup::GeneratorSetup(const AString & a_IniFileName, QWidget * a_Parent) :
|
||||
super(a_Parent),
|
||||
m_IniFile(new cIniFile())
|
||||
{
|
||||
// The seed and generator name is in a separate form layout at the top, always present:
|
||||
m_eSeed = new QLineEdit();
|
||||
m_eSeed->setValidator(new QIntValidator());
|
||||
m_eSeed->setText("0");
|
||||
m_eSeed->setProperty("INI.ItemName", QVariant("Seed"));
|
||||
m_cbGenerator = new QComboBox();
|
||||
m_cbGenerator->setMinimumWidth(120);
|
||||
for (size_t i = 0; i < ARRAYCOUNT(s_GeneratorNames); i++)
|
||||
{
|
||||
m_cbGenerator->addItem(s_GeneratorNames[i]);
|
||||
}
|
||||
QFormLayout * baseLayout = new QFormLayout();
|
||||
baseLayout->addRow(new QLabel(tr("Seed")), m_eSeed);
|
||||
baseLayout->addRow(new QLabel(tr("Generator")), m_cbGenerator);
|
||||
|
||||
// The rest of the controls are in a dynamically created form layout:
|
||||
m_FormLayout = new QFormLayout();
|
||||
|
||||
// The main layout joins these two vertically:
|
||||
m_MainLayout = new QVBoxLayout();
|
||||
m_MainLayout->addLayout(baseLayout);
|
||||
m_MainLayout->addLayout(m_FormLayout);
|
||||
m_MainLayout->addStretch();
|
||||
setLayout(m_MainLayout);
|
||||
|
||||
// Load the INI file, if specified, otherwise set defaults:
|
||||
if (!a_IniFileName.empty() && m_IniFile->ReadFile(a_IniFileName))
|
||||
{
|
||||
m_cbGenerator->setCurrentText(QString::fromStdString(m_IniFile->GetValue("Generator", "BiomeGen")));
|
||||
m_eSeed->setText(QString::number(m_IniFile->GetValueI("Generator", "Seed")));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_IniFile->SetValue("Generator", "Generator", "Composable");
|
||||
m_IniFile->SetValue("Generator", "BiomeGen", m_cbGenerator->currentText().toStdString());
|
||||
bool dummy;
|
||||
delete cBiomeGen::CreateBiomeGen(*m_IniFile, 0, dummy);
|
||||
}
|
||||
updateFromIni();
|
||||
|
||||
// Connect the change events only after the data has been loaded:
|
||||
connect(m_cbGenerator, SIGNAL(currentIndexChanged(QString)), this, SLOT(generatorChanged(QString)));
|
||||
connect(m_eSeed, SIGNAL(textChanged(QString)), this, SLOT(editChanged(QString)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void GeneratorSetup::generatorChanged(const QString & a_NewName)
|
||||
{
|
||||
// Clear the current contents of the form layout by assigning it to a stack temporary:
|
||||
{
|
||||
m_MainLayout->takeAt(1);
|
||||
QWidget().setLayout(m_FormLayout);
|
||||
}
|
||||
|
||||
// Re-create the layout:
|
||||
m_FormLayout = new QFormLayout();
|
||||
m_MainLayout->insertLayout(1, m_FormLayout);
|
||||
|
||||
// Recreate the INI file:
|
||||
m_IniFile->Clear();
|
||||
m_IniFile->SetValue("Generator", "Generator", "Composable");
|
||||
m_IniFile->SetValue("Generator", "BiomeGen", a_NewName.toStdString());
|
||||
|
||||
// Create a dummy biome gen from the INI file, this will create the defaults in the INI file:
|
||||
bool dummy;
|
||||
delete cBiomeGen::CreateBiomeGen(*m_IniFile, m_Seed, dummy);
|
||||
|
||||
// Read all values from the INI file and put them into the form layout:
|
||||
updateFromIni();
|
||||
|
||||
// Notify of the changes:
|
||||
emit generatorUpdated();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void GeneratorSetup::editChanged(const QString & a_NewValue)
|
||||
{
|
||||
QString itemName = sender()->property("INI.ItemName").toString();
|
||||
m_IniFile->SetValue("Generator", itemName.toStdString(), a_NewValue.toStdString());
|
||||
emit generatorUpdated();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void GeneratorSetup::updateFromIni()
|
||||
{
|
||||
int keyID = m_IniFile->FindKey("Generator");
|
||||
if (keyID <= -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int numItems = m_IniFile->GetNumValues(keyID);
|
||||
AString generatorName = m_IniFile->GetValue("Generator", "BiomeGen");
|
||||
size_t generatorNameLen = generatorName.length();
|
||||
for (int i = 0; i < numItems; i++)
|
||||
{
|
||||
AString itemName = m_IniFile->GetValueName(keyID, i);
|
||||
if ((itemName == "Generator") || (itemName == "BiomeGen"))
|
||||
{
|
||||
// These special cases are not to be added
|
||||
continue;
|
||||
}
|
||||
AString itemValue = m_IniFile->GetValue(keyID, i);
|
||||
|
||||
QLineEdit * edit = new QLineEdit();
|
||||
edit->setText(QString::fromStdString(itemValue));
|
||||
edit->setProperty("INI.ItemName", QVariant(QString::fromStdString(itemName)));
|
||||
|
||||
// Remove the generator name prefix from the item name, for clarity purposes:
|
||||
if (NoCaseCompare(itemName.substr(0, generatorNameLen), generatorName) == 0)
|
||||
{
|
||||
itemName.erase(0, generatorNameLen);
|
||||
}
|
||||
|
||||
connect(edit, SIGNAL(textChanged(QString)), this, SLOT(editChanged(QString)));
|
||||
m_FormLayout->addRow(new QLabel(QString::fromStdString(itemName)), edit);
|
||||
} // for i - INI values[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
64
Tools/QtBiomeVisualiser/GeneratorSetup.h
Normal file
64
Tools/QtBiomeVisualiser/GeneratorSetup.h
Normal file
@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <QDialog>
|
||||
#include <QComboBox>
|
||||
#include <QVBoxLayout>
|
||||
#include <QFormLayout>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cIniFile;
|
||||
typedef std::shared_ptr<cIniFile> cIniFilePtr;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class GeneratorSetup :
|
||||
public QWidget
|
||||
{
|
||||
typedef QWidget super;
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/** Creates the widget and loads the contents of the INI file, if not empty. */
|
||||
explicit GeneratorSetup(const std::string & a_IniFileName, QWidget * parent = nullptr);
|
||||
|
||||
/** Returns the cIniFile instance that is being edited by this widget. */
|
||||
cIniFilePtr getIniFile() { return m_IniFile; }
|
||||
|
||||
signals:
|
||||
/** Emitted when the generator parameters have changed. */
|
||||
void generatorUpdated();
|
||||
|
||||
public slots:
|
||||
/** Called when the user selects a different generator from the top combobox.
|
||||
Re-creates m_IniFile and updates the form layout. */
|
||||
void generatorChanged(const QString & a_NewName);
|
||||
|
||||
protected slots:
|
||||
/** Called when any of the edit widgets are changed. */
|
||||
void editChanged(const QString & a_NewValue);
|
||||
|
||||
protected:
|
||||
QComboBox * m_cbGenerator;
|
||||
QLineEdit * m_eSeed;
|
||||
QVBoxLayout * m_MainLayout;
|
||||
QFormLayout * m_FormLayout;
|
||||
|
||||
cIniFilePtr m_IniFile;
|
||||
|
||||
int m_Seed;
|
||||
|
||||
|
||||
/** Updates the form layout with the values from m_IniFile. */
|
||||
void updateFromIni();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
386
Tools/QtBiomeVisualiser/Globals.h
Normal file
386
Tools/QtBiomeVisualiser/Globals.h
Normal file
@ -0,0 +1,386 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Compiler-dependent stuff:
|
||||
#if defined(_MSC_VER)
|
||||
// MSVC produces warning C4481 on the override keyword usage, so disable the warning altogether
|
||||
#pragma warning(disable:4481)
|
||||
|
||||
// Disable some warnings that we don't care about:
|
||||
#pragma warning(disable:4100) // Unreferenced formal parameter
|
||||
|
||||
// Useful warnings from warning level 4:
|
||||
#pragma warning(3 : 4127) // Conditional expression is constant
|
||||
#pragma warning(3 : 4189) // Local variable is initialized but not referenced
|
||||
#pragma warning(3 : 4245) // Conversion from 'type1' to 'type2', signed/unsigned mismatch
|
||||
#pragma warning(3 : 4310) // Cast truncates constant value
|
||||
#pragma warning(3 : 4389) // Signed/unsigned mismatch
|
||||
#pragma warning(3 : 4505) // Unreferenced local function has been removed
|
||||
#pragma warning(3 : 4701) // Potentially unitialized local variable used
|
||||
#pragma warning(3 : 4702) // Unreachable code
|
||||
#pragma warning(3 : 4706) // Assignment within conditional expression
|
||||
|
||||
// Disabling this warning, because we know what we're doing when we're doing this:
|
||||
#pragma warning(disable: 4355) // 'this' used in initializer list
|
||||
|
||||
// Disabled because it's useless:
|
||||
#pragma warning(disable: 4512) // 'class': assignment operator could not be generated - reported for each class that has a reference-type member
|
||||
|
||||
// 2014_01_06 xoft: Disabled this warning because MSVC is stupid and reports it in obviously wrong places
|
||||
// #pragma warning(3 : 4244) // Conversion from 'type1' to 'type2', possible loss of data
|
||||
|
||||
#define OBSOLETE __declspec(deprecated)
|
||||
|
||||
// No alignment needed in MSVC
|
||||
#define ALIGN_8
|
||||
#define ALIGN_16
|
||||
|
||||
#define FORMATSTRING(formatIndex, va_argsIndex)
|
||||
|
||||
// MSVC has its own custom version of zu format
|
||||
#define SIZE_T_FMT "%Iu"
|
||||
#define SIZE_T_FMT_PRECISION(x) "%" #x "Iu"
|
||||
#define SIZE_T_FMT_HEX "%Ix"
|
||||
|
||||
#define NORETURN __declspec(noreturn)
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
// TODO: Can GCC explicitly mark classes as abstract (no instances can be created)?
|
||||
#define abstract
|
||||
|
||||
// override is part of c++11
|
||||
#if __cplusplus < 201103L
|
||||
#define override
|
||||
#endif
|
||||
|
||||
#define OBSOLETE __attribute__((deprecated))
|
||||
|
||||
#define ALIGN_8 __attribute__((aligned(8)))
|
||||
#define ALIGN_16 __attribute__((aligned(16)))
|
||||
|
||||
// Some portability macros :)
|
||||
#define stricmp strcasecmp
|
||||
|
||||
#define FORMATSTRING(formatIndex, va_argsIndex) __attribute__((format (printf, formatIndex, va_argsIndex)))
|
||||
|
||||
#if defined(_WIN32)
|
||||
// We're compiling on MinGW, which uses an old MSVCRT library that has no support for size_t printfing.
|
||||
// We need direct size formats:
|
||||
#if defined(_WIN64)
|
||||
#define SIZE_T_FMT "%I64u"
|
||||
#define SIZE_T_FMT_PRECISION(x) "%" #x "I64u"
|
||||
#define SIZE_T_FMT_HEX "%I64x"
|
||||
#else
|
||||
#define SIZE_T_FMT "%u"
|
||||
#define SIZE_T_FMT_PRECISION(x) "%" #x "u"
|
||||
#define SIZE_T_FMT_HEX "%x"
|
||||
#endif
|
||||
#else
|
||||
// We're compiling on Linux, so we can use libc's size_t printf format:
|
||||
#define SIZE_T_FMT "%zu"
|
||||
#define SIZE_T_FMT_PRECISION(x) "%" #x "zu"
|
||||
#define SIZE_T_FMT_HEX "%zx"
|
||||
#endif
|
||||
|
||||
#define NORETURN __attribute((__noreturn__))
|
||||
|
||||
#else
|
||||
|
||||
#error "You are using an unsupported compiler, you might need to #define some stuff here for your compiler"
|
||||
|
||||
/*
|
||||
// Copy and uncomment this into another #elif section based on your compiler identification
|
||||
|
||||
// Explicitly mark classes as abstract (no instances can be created)
|
||||
#define abstract
|
||||
|
||||
// Mark virtual methods as overriding (forcing them to have a virtual function of the same signature in the base class)
|
||||
#define override
|
||||
|
||||
// Mark functions as obsolete, so that their usage results in a compile-time warning
|
||||
#define OBSOLETE
|
||||
|
||||
// Mark types / variables for alignment. Do the platforms need it?
|
||||
#define ALIGN_8
|
||||
#define ALIGN_16
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define NORETURNDEBUG NORETURN
|
||||
#else
|
||||
#define NORETURNDEBUG
|
||||
#endif
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
// Integral types with predefined sizes:
|
||||
typedef long long Int64;
|
||||
typedef int Int32;
|
||||
typedef short Int16;
|
||||
|
||||
typedef unsigned long long UInt64;
|
||||
typedef unsigned int UInt32;
|
||||
typedef unsigned short UInt16;
|
||||
|
||||
typedef unsigned char Byte;
|
||||
|
||||
|
||||
// If you get an error about specialization check the size of integral types
|
||||
template <typename T, size_t Size, bool x = sizeof(T) == Size>
|
||||
class SizeChecker;
|
||||
|
||||
template <typename T, size_t Size>
|
||||
class SizeChecker<T, Size, true>
|
||||
{
|
||||
T v;
|
||||
};
|
||||
|
||||
template class SizeChecker<Int64, 8>;
|
||||
template class SizeChecker<Int32, 4>;
|
||||
template class SizeChecker<Int16, 2>;
|
||||
|
||||
template class SizeChecker<UInt64, 8>;
|
||||
template class SizeChecker<UInt32, 4>;
|
||||
template class SizeChecker<UInt16, 2>;
|
||||
|
||||
// A macro to disallow the copy constructor and operator = functions
|
||||
// This should be used in the private: declarations for any class that shouldn't allow copying itself
|
||||
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||
TypeName(const TypeName &); \
|
||||
void operator =(const TypeName &)
|
||||
|
||||
// A macro that is used to mark unused function parameters, to avoid pedantic warnings in gcc
|
||||
#define UNUSED(X) (void)(X)
|
||||
|
||||
|
||||
|
||||
|
||||
// OS-dependent stuff:
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#define _WIN32_WINNT 0x501 // We want to target WinXP and higher
|
||||
|
||||
#include <Windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <Ws2tcpip.h> // IPv6 stuff
|
||||
|
||||
// Windows SDK defines min and max macros, messing up with our std::min and std::max usage
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
// Windows SDK defines GetFreeSpace as a constant, probably a Win16 API remnant
|
||||
#ifdef GetFreeSpace
|
||||
#undef GetFreeSpace
|
||||
#endif // GetFreeSpace
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <time.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#if defined(ANDROID_NDK)
|
||||
#define FILE_IO_PREFIX "/sdcard/mcserver/"
|
||||
#else
|
||||
#define FILE_IO_PREFIX ""
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// CRT stuff:
|
||||
#include <sys/stat.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// STL stuff:
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <queue>
|
||||
#include <limits>
|
||||
|
||||
|
||||
|
||||
#ifndef TEST_GLOBALS
|
||||
// Common headers (part 1, without macros):
|
||||
#include "src/StringUtils.h"
|
||||
#include "src/OSSupport/Sleep.h"
|
||||
#include "src/OSSupport/CriticalSection.h"
|
||||
#include "src/OSSupport/Semaphore.h"
|
||||
#include "src/OSSupport/Event.h"
|
||||
#include "src/OSSupport/Thread.h"
|
||||
#include "src/OSSupport/File.h"
|
||||
#include "src/Logger.h"
|
||||
#else
|
||||
// Logging functions
|
||||
void inline LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2);
|
||||
|
||||
void inline LOGERROR(const char* a_Format, ...)
|
||||
{
|
||||
va_list argList;
|
||||
va_start(argList, a_Format);
|
||||
vprintf(a_Format, argList);
|
||||
va_end(argList);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Common definitions:
|
||||
|
||||
/// Evaluates to the number of elements in an array (compile-time!)
|
||||
#define ARRAYCOUNT(X) (sizeof(X) / sizeof(*(X)))
|
||||
|
||||
/// Allows arithmetic expressions like "32 KiB" (but consider using parenthesis around it, "(32 KiB)")
|
||||
#define KiB * 1024
|
||||
#define MiB * 1024 * 1024
|
||||
|
||||
/// Faster than (int)floorf((float)x / (float)div)
|
||||
#define FAST_FLOOR_DIV( x, div) (((x) - (((x) < 0) ? ((div) - 1) : 0)) / (div))
|
||||
|
||||
// Own version of assert() that writes failed assertions to the log for review
|
||||
#ifdef TEST_GLOBALS
|
||||
|
||||
class cAssertFailure
|
||||
{
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
#if (defined(_MSC_VER) && defined(_DEBUG))
|
||||
#define DBG_BREAK _CrtDbgBreak()
|
||||
#else
|
||||
#define DBG_BREAK
|
||||
#endif
|
||||
#define REPORT_ERROR(FMT, ...) \
|
||||
{ \
|
||||
AString msg = Printf(FMT, __VA_ARGS__); \
|
||||
puts(msg.c_str()); \
|
||||
fflush(stdout); \
|
||||
OutputDebugStringA(msg.c_str()); \
|
||||
DBG_BREAK; \
|
||||
}
|
||||
#else
|
||||
#define REPORT_ERROR(FMT, ...) \
|
||||
{ \
|
||||
AString msg = Printf(FMT, __VA_ARGS__); \
|
||||
puts(msg.c_str()); \
|
||||
fflush(stdout); \
|
||||
}
|
||||
#endif
|
||||
#define ASSERT(x) do { if (!(x)) { throw cAssertFailure();} } while (0)
|
||||
#define testassert(x) do { if (!(x)) { REPORT_ERROR("Test failure: %s, file %s, line %d\n", #x, __FILE__, __LINE__); exit(1); } } while (0)
|
||||
#define CheckAsserts(x) do { try {x} catch (cAssertFailure) { break; } REPORT_ERROR("Test failure: assert didn't fire for %s, file %s, line %d\n", #x, __FILE__, __LINE__); exit(1); } while (0)
|
||||
|
||||
#else
|
||||
#ifdef _DEBUG
|
||||
#define ASSERT( x) ( !!(x) || ( LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__), assert(0), 0))
|
||||
#else
|
||||
#define ASSERT(x) ((void)(x))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Pretty much the same as ASSERT() but stays in Release builds
|
||||
#define VERIFY( x) ( !!(x) || ( LOGERROR("Verification failed: %s, file %s, line %i", #x, __FILE__, __LINE__), exit(1), 0))
|
||||
|
||||
// Same as assert but in all Self test builds
|
||||
#ifdef SELF_TEST
|
||||
#define assert_test(x) ( !!(x) || (assert(!#x), exit(1), 0))
|
||||
#endif
|
||||
|
||||
// Allow both Older versions of MSVC and newer versions of everything use a shared_ptr:
|
||||
// Note that we cannot typedef, because C++ doesn't allow (partial) templates to be typedeffed.
|
||||
#if (defined(_MSC_VER) && (_MSC_VER < 1600))
|
||||
// MSVC before 2010 doesn't have std::shared_ptr, but has std::tr1::shared_ptr, defined in <memory> included earlier
|
||||
#define SharedPtr std::tr1::shared_ptr
|
||||
#elif (defined(_MSC_VER) || (__cplusplus >= 201103L))
|
||||
// C++11 has std::shared_ptr in <memory>, included earlier
|
||||
#define SharedPtr std::shared_ptr
|
||||
#else
|
||||
// C++03 has std::tr1::shared_ptr in <tr1/memory>
|
||||
#include <tr1/memory>
|
||||
#define SharedPtr std::tr1::shared_ptr
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** A generic interface used mainly in ForEach() functions */
|
||||
template <typename Type> class cItemCallback
|
||||
{
|
||||
public:
|
||||
virtual ~cItemCallback() {}
|
||||
|
||||
/** Called for each item in the internal list; return true to stop the loop, or false to continue enumerating */
|
||||
virtual bool Item(Type * a_Type) = 0;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
/** Clamp X 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef TOLUA_TEMPLATE_BIND
|
||||
#define TOLUA_TEMPLATE_BIND(x)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Common headers (part 2, with macros):
|
||||
#include "src/ChunkDef.h"
|
||||
#include "src/BiomeDef.h"
|
||||
#include "src/BlockID.h"
|
||||
#include "src/BlockInfo.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
310
Tools/QtBiomeVisualiser/MainWindow.cpp
Normal file
310
Tools/QtBiomeVisualiser/MainWindow.cpp
Normal file
@ -0,0 +1,310 @@
|
||||
#include "Globals.h"
|
||||
#include "MainWindow.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QAction>
|
||||
#include <QMenuBar>
|
||||
#include <QApplication>
|
||||
#include <QFileDialog>
|
||||
#include <QSettings>
|
||||
#include <QDirIterator>
|
||||
#include "inifile/iniFile.h"
|
||||
#include "ChunkSource.h"
|
||||
#include "src/Generating/BioGen.h"
|
||||
#include "src/StringCompression.h"
|
||||
#include "src/WorldStorage/FastNBT.h"
|
||||
#include "GeneratorSetup.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
MainWindow::MainWindow(QWidget * parent) :
|
||||
QMainWindow(parent),
|
||||
m_GeneratorSetup(nullptr),
|
||||
m_LineSeparator(nullptr)
|
||||
{
|
||||
initMinecraftPath();
|
||||
|
||||
m_BiomeView = new BiomeView();
|
||||
m_MainLayout = new QHBoxLayout();
|
||||
m_MainLayout->addWidget(m_BiomeView, 1);
|
||||
m_MainLayout->setMenuBar(menuBar());
|
||||
m_MainLayout->setMargin(0);
|
||||
QWidget * central = new QWidget();
|
||||
central->setLayout(m_MainLayout);
|
||||
setCentralWidget(central);
|
||||
|
||||
createActions();
|
||||
createMenus();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::newGenerator()
|
||||
{
|
||||
// (Re-)open the generator setup dialog with empty settings:
|
||||
openGeneratorSetup("");
|
||||
|
||||
// Set the chunk source:
|
||||
cIniFilePtr iniFile = m_GeneratorSetup->getIniFile();
|
||||
m_BiomeView->setChunkSource(std::shared_ptr<BioGenSource>(new BioGenSource(iniFile)));
|
||||
m_BiomeView->redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::openGenerator()
|
||||
{
|
||||
// Let the user specify the world.ini file:
|
||||
QString worldIni = QFileDialog::getOpenFileName(this, tr("Open world.ini"), QString(), tr("world.ini (world.ini)"));
|
||||
if (worldIni.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// (Re-)open the generator setup dialog:
|
||||
openGeneratorSetup(worldIni.toStdString());
|
||||
|
||||
// Set the chunk source:
|
||||
m_BiomeView->setChunkSource(std::shared_ptr<BioGenSource>(new BioGenSource(m_GeneratorSetup->getIniFile())));
|
||||
m_BiomeView->redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::openWorld()
|
||||
{
|
||||
// Let the user specify the world:
|
||||
QString regionFolder = QFileDialog::getExistingDirectory(this, tr("Select the region folder"), QString());
|
||||
if (regionFolder.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the generator setup dialog, if open:
|
||||
closeGeneratorSetup();
|
||||
|
||||
// Set the chunk source:
|
||||
m_BiomeView->setChunkSource(std::shared_ptr<AnvilSource>(new AnvilSource(regionFolder)));
|
||||
m_BiomeView->redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::openVanillaWorld()
|
||||
{
|
||||
// The world is stored in the sender action's data, retrieve it:
|
||||
QAction * action = qobject_cast<QAction *>(sender());
|
||||
if (action == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the generator setup dialog, if open:
|
||||
closeGeneratorSetup();
|
||||
|
||||
// Set the chunk source:
|
||||
m_BiomeView->setChunkSource(std::shared_ptr<AnvilSource>(new AnvilSource(action->data().toString())));
|
||||
m_BiomeView->redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::initMinecraftPath()
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
m_MinecraftPath = QDir::homePath() + QDir::toNativeSeparators("/Library/Application Support/minecraft");
|
||||
#elif defined Q_OS_WIN32
|
||||
QSettings ini(QSettings::IniFormat, QSettings::UserScope, ".minecraft", "minecraft1");
|
||||
m_MinecraftPath = QFileInfo(ini.fileName()).absolutePath();
|
||||
#else
|
||||
m_MinecraftPath = QDir::homePath() + QDir::toNativeSeparators("/.minecraft");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::createActions()
|
||||
{
|
||||
createWorldActions();
|
||||
|
||||
m_actNewGen = new QAction(tr("&New generator"), this);
|
||||
m_actNewGen->setShortcut(tr("Ctrl+N"));
|
||||
m_actNewGen->setStatusTip(tr("Open a generator INI file and display the generated biomes"));
|
||||
connect(m_actNewGen, SIGNAL(triggered()), this, SLOT(newGenerator()));
|
||||
|
||||
m_actOpenGen = new QAction(tr("&Open generator..."), this);
|
||||
m_actOpenGen->setShortcut(tr("Ctrl+G"));
|
||||
m_actOpenGen->setStatusTip(tr("Open a generator INI file and display the generated biomes"));
|
||||
connect(m_actOpenGen, SIGNAL(triggered()), this, SLOT(openGenerator()));
|
||||
|
||||
m_actOpenWorld = new QAction(tr("&Open world..."), this);
|
||||
m_actOpenWorld->setShortcut(tr("Ctrl+O"));
|
||||
m_actOpenWorld->setStatusTip(tr("Open an existing world and display its biomes"));
|
||||
connect(m_actOpenWorld, SIGNAL(triggered()), this, SLOT(openWorld()));
|
||||
|
||||
m_actReload = new QAction(tr("&Reload"), this);
|
||||
m_actReload->setShortcut(tr("F5"));
|
||||
m_actReload->setStatusTip(tr("Clear the view cache and force a reload of all the data"));
|
||||
connect(m_actReload, SIGNAL(triggered()), m_BiomeView, SLOT(reload()));
|
||||
|
||||
m_actExit = new QAction(tr("E&xit"), this);
|
||||
m_actExit->setShortcut(tr("Alt+X"));
|
||||
m_actExit->setStatusTip(tr("Exit %1").arg(QApplication::instance()->applicationName()));
|
||||
connect(m_actExit, SIGNAL(triggered()), this, SLOT(close()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::createWorldActions()
|
||||
{
|
||||
QDir mc(m_MinecraftPath);
|
||||
if (!mc.cd("saves"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QDirIterator it(mc);
|
||||
int key = 1;
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
if (!it.fileInfo().isDir())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QString name = getWorldName(it.filePath().toStdString());
|
||||
if (name.isEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QAction * w = new QAction(this);
|
||||
w->setText(name);
|
||||
w->setData(it.filePath() + "/region");
|
||||
if (key < 10)
|
||||
{
|
||||
w->setShortcut("Ctrl+" + QString::number(key));
|
||||
key++;
|
||||
}
|
||||
connect(w, SIGNAL(triggered()), this, SLOT(openVanillaWorld()));
|
||||
m_WorldActions.append(w);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::createMenus()
|
||||
{
|
||||
QMenu * file = menuBar()->addMenu(tr("&Map"));
|
||||
file->addAction(m_actNewGen);
|
||||
file->addAction(m_actOpenGen);
|
||||
file->addSeparator();
|
||||
QMenu * worlds = file->addMenu(tr("Open existing"));
|
||||
worlds->addActions(m_WorldActions);
|
||||
if (m_WorldActions.empty())
|
||||
{
|
||||
worlds->setEnabled(false);
|
||||
}
|
||||
file->addAction(m_actOpenWorld);
|
||||
file->addSeparator();
|
||||
file->addAction(m_actReload);
|
||||
file->addSeparator();
|
||||
file->addAction(m_actExit);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QString MainWindow::getWorldName(const AString & a_Path)
|
||||
{
|
||||
AString levelData = cFile::ReadWholeFile(a_Path + "/level.dat");
|
||||
if (levelData.empty())
|
||||
{
|
||||
// No such file / no data
|
||||
return QString();
|
||||
}
|
||||
|
||||
AString uncompressed;
|
||||
if (UncompressStringGZIP(levelData.data(), levelData.size(), uncompressed) != Z_OK)
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
cParsedNBT nbt(uncompressed.data(), uncompressed.size());
|
||||
if (!nbt.IsValid())
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
AString name = nbt.GetName(1);
|
||||
int levelNameTag = nbt.FindTagByPath(nbt.GetRoot(), "Data\\LevelName");
|
||||
if ((levelNameTag <= 0) || (nbt.GetType(levelNameTag) != TAG_String))
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
return QString::fromStdString(nbt.GetString(levelNameTag));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::openGeneratorSetup(const AString & a_IniFileName)
|
||||
{
|
||||
// Close any previous editor:
|
||||
closeGeneratorSetup();
|
||||
|
||||
// Open up a new editor:
|
||||
m_GeneratorSetup = new GeneratorSetup(a_IniFileName);
|
||||
m_LineSeparator = new QWidget();
|
||||
m_LineSeparator->setFixedWidth(2);
|
||||
m_LineSeparator->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
|
||||
m_LineSeparator->setStyleSheet(QString("background-color: #c0c0c0;"));
|
||||
m_MainLayout->addWidget(m_LineSeparator);
|
||||
m_MainLayout->addWidget(m_GeneratorSetup);
|
||||
|
||||
// Connect the signals from the setup pane:
|
||||
connect(m_GeneratorSetup, SIGNAL(generatorUpdated()), m_BiomeView, SLOT(reload()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::closeGeneratorSetup()
|
||||
{
|
||||
delete m_MainLayout->takeAt(2);
|
||||
delete m_MainLayout->takeAt(1);
|
||||
delete m_GeneratorSetup;
|
||||
delete m_LineSeparator;
|
||||
m_GeneratorSetup = nullptr;
|
||||
m_LineSeparator = nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
96
Tools/QtBiomeVisualiser/MainWindow.h
Normal file
96
Tools/QtBiomeVisualiser/MainWindow.h
Normal file
@ -0,0 +1,96 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <QList>
|
||||
#include <QMainWindow>
|
||||
#include <QHBoxLayout>
|
||||
#include "BiomeView.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// fwd:
|
||||
class GeneratorSetup;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class MainWindow :
|
||||
public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow(QWidget * parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
private slots:
|
||||
/** Creates a generator definition from scratch, lets user modify generator params in realtime. */
|
||||
void newGenerator();
|
||||
|
||||
/** Opens a generator definition and generates the biomes based on that. */
|
||||
void openGenerator();
|
||||
|
||||
/** Opens an existing world and displays the loaded biomes. */
|
||||
void openWorld();
|
||||
|
||||
/** Opens a vanilla world that is specified by the calling action. */
|
||||
void openVanillaWorld();
|
||||
|
||||
protected:
|
||||
// Actions:
|
||||
QAction * m_actNewGen;
|
||||
QAction * m_actOpenGen;
|
||||
QAction * m_actOpenWorld;
|
||||
QAction * m_actReload;
|
||||
QAction * m_actExit;
|
||||
|
||||
/** List of actions that open the specific vanilla world. */
|
||||
QList<QAction *> m_WorldActions;
|
||||
|
||||
/** Path to the vanilla folder. */
|
||||
QString m_MinecraftPath;
|
||||
|
||||
/** The pane for setting up the generator, available when visualising a generator. */
|
||||
GeneratorSetup * m_GeneratorSetup;
|
||||
|
||||
/** The main biome display widget. */
|
||||
BiomeView * m_BiomeView;
|
||||
|
||||
/** The layout for the window. */
|
||||
QHBoxLayout * m_MainLayout;
|
||||
|
||||
/** The separator line between biome view and generator setup. */
|
||||
QWidget * m_LineSeparator;
|
||||
|
||||
|
||||
/** Initializes the m_MinecraftPath based on the proper MC path */
|
||||
void initMinecraftPath();
|
||||
|
||||
/** Creates the actions that the UI supports. */
|
||||
void createActions();
|
||||
|
||||
/** Creates the actions that open a specific vanilla world. Iterates over the minecraft saves folder. */
|
||||
void createWorldActions();
|
||||
|
||||
/** Creates the menu bar and connects its events. */
|
||||
void createMenus();
|
||||
|
||||
/** Returns the name of the vanilla world in the specified path.
|
||||
Reads the level.dat file for the name. Returns an empty string on failure. */
|
||||
QString getWorldName(const AString & a_Path);
|
||||
|
||||
/** Opens the generator setup pane, if not already open, and loads the specified INI file to it. */
|
||||
void openGeneratorSetup(const AString & a_IniFileName);
|
||||
|
||||
/** Closes and destroys the generator setup pane, if there is one. */
|
||||
void closeGeneratorSetup();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
94
Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro
Normal file
94
Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro
Normal file
@ -0,0 +1,94 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2014-09-11T15:22:43
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = QtBiomeVisualiser
|
||||
TEMPLATE = app
|
||||
|
||||
|
||||
SOURCES += main.cpp\
|
||||
MainWindow.cpp \
|
||||
BiomeView.cpp \
|
||||
../../src/Generating/BioGen.cpp \
|
||||
../../src/VoronoiMap.cpp \
|
||||
../../src/Noise.cpp \
|
||||
../../src/StringUtils.cpp \
|
||||
../../src/LoggerListeners.cpp \
|
||||
../../src/Logger.cpp \
|
||||
../../lib/inifile/iniFile.cpp \
|
||||
../../src/OSSupport/File.cpp \
|
||||
../../src/OSSupport/CriticalSection.cpp \
|
||||
../../src/OSSupport/IsThread.cpp \
|
||||
../../src/BiomeDef.cpp \
|
||||
ChunkCache.cpp \
|
||||
Chunk.cpp \
|
||||
ChunkSource.cpp \
|
||||
ChunkLoader.cpp \
|
||||
../../src/StringCompression.cpp \
|
||||
../../src/WorldStorage/FastNBT.cpp \
|
||||
../../lib/zlib/adler32.c \
|
||||
../../lib/zlib/compress.c \
|
||||
../../lib/zlib/crc32.c \
|
||||
../../lib/zlib/deflate.c \
|
||||
../../lib/zlib/gzclose.c \
|
||||
../../lib/zlib/gzlib.c \
|
||||
../../lib/zlib/gzread.c \
|
||||
../../lib/zlib/gzwrite.c \
|
||||
../../lib/zlib/infback.c \
|
||||
../../lib/zlib/inffast.c \
|
||||
../../lib/zlib/inflate.c \
|
||||
../../lib/zlib/inftrees.c \
|
||||
../../lib/zlib/trees.c \
|
||||
../../lib/zlib/uncompr.c \
|
||||
../../lib/zlib/zutil.c \
|
||||
GeneratorSetup.cpp
|
||||
|
||||
HEADERS += MainWindow.h \
|
||||
Globals.h \
|
||||
BiomeView.h \
|
||||
../../src/Generating/BioGen.h \
|
||||
../../src/VoronoiMap.h \
|
||||
../../src/Noise.h \
|
||||
../../src/StringUtils.h \
|
||||
../../src/LoggerListeners.h \
|
||||
../../src/Logger.h \
|
||||
../../lib/inifile/iniFile.h \
|
||||
../../src/OSSupport/File.h \
|
||||
../../src/OSSupport/CriticalSection.h \
|
||||
../../src/OSSupport/IsThread.h \
|
||||
../../src/BiomeDef.h \
|
||||
ChunkCache.h \
|
||||
Chunk.h \
|
||||
ChunkSource.h \
|
||||
ChunkLoader.h \
|
||||
../../src/StringCompression.h \
|
||||
../../src/WorldStorage/FastNBT.h \
|
||||
../../lib/zlib/crc32.h \
|
||||
../../lib/zlib/deflate.h \
|
||||
../../lib/zlib/gzguts.h \
|
||||
../../lib/zlib/inffast.h \
|
||||
../../lib/zlib/inffixed.h \
|
||||
../../lib/zlib/inflate.h \
|
||||
../../lib/zlib/inftrees.h \
|
||||
../../lib/zlib/trees.h \
|
||||
../../lib/zlib/zconf.h \
|
||||
../../lib/zlib/zlib.h \
|
||||
../../lib/zlib/zutil.h \
|
||||
GeneratorSetup.h
|
||||
|
||||
INCLUDEPATH += $$_PRO_FILE_PWD_ \
|
||||
$$_PRO_FILE_PWD_/../../lib \
|
||||
$$_PRO_FILE_PWD_/../../
|
||||
|
||||
|
||||
CONFIG += C++11
|
||||
|
||||
OTHER_FILES +=
|
||||
|
||||
|
20
Tools/QtBiomeVisualiser/main.cpp
Normal file
20
Tools/QtBiomeVisualiser/main.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
#include "Globals.h"
|
||||
#include "MainWindow.h"
|
||||
#include <QApplication>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 27b9d111818af3b05bcf4153bb6e380fe1dd6816
|
||||
Subproject commit 203c2fb68bbf871eaf4ca98756a113d74d620dea
|
@ -668,6 +668,24 @@ void cIniFile::Clear(void)
|
||||
|
||||
|
||||
|
||||
bool cIniFile::HasValue(const AString & a_KeyName, const AString & a_ValueName)
|
||||
{
|
||||
// Find the key:
|
||||
int keyID = FindKey(a_KeyName);
|
||||
if (keyID == noID)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find the value:
|
||||
int valueID = FindValue(keyID, a_ValueName);
|
||||
return (valueID != noID);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cIniFile::AddHeaderComment(const AString & comment)
|
||||
{
|
||||
comments.push_back(comment);
|
||||
|
@ -53,7 +53,9 @@ private:
|
||||
|
||||
/// Removes the UTF-8 BOMs (Byte order makers), if present.
|
||||
void RemoveBom(AString & a_line) const;
|
||||
|
||||
public:
|
||||
|
||||
enum errors
|
||||
{
|
||||
noID = -1,
|
||||
@ -79,6 +81,9 @@ public:
|
||||
|
||||
/// Deletes all stored ini data (but doesn't touch the file)
|
||||
void Clear(void);
|
||||
|
||||
/** Returns true iff the specified value exists. */
|
||||
bool HasValue(const AString & a_KeyName, const AString & a_ValueName);
|
||||
|
||||
/// Returns index of specified key, or noID if not found
|
||||
int FindKey(const AString & keyname) const;
|
||||
|
@ -36,7 +36,9 @@ extern "C" {
|
||||
#define TEMPLATE_BIND(p)
|
||||
#endif
|
||||
|
||||
#define TOLUA_TEMPLATE_BIND(p)
|
||||
#ifndef TOLUA_TEMPLATE_BIND
|
||||
#define TOLUA_TEMPLATE_BIND(p)
|
||||
#endif
|
||||
|
||||
#define TOLUA_PROTECTED_DESTRUCTOR
|
||||
#define TOLUA_PROPERTY_TYPE(p)
|
||||
|
@ -107,7 +107,7 @@ void cLuaChunkStay::AddChunkCoord(cLuaState & L, int a_Index)
|
||||
}
|
||||
} // for itr - m_Chunks[]
|
||||
|
||||
m_Chunks.push_back(cChunkCoords(ChunkX, ZERO_CHUNK_Y, ChunkZ));
|
||||
m_Chunks.push_back(cChunkCoords(ChunkX, ChunkZ));
|
||||
}
|
||||
|
||||
|
||||
|
@ -859,6 +859,32 @@ void cLuaState::GetStackValue(int a_StackPos, eWeather & a_ReturnedVal)
|
||||
|
||||
|
||||
|
||||
void cLuaState::GetStackValue(int a_StackPos, pBoundingBox & a_ReturnedVal)
|
||||
{
|
||||
tolua_Error err;
|
||||
if (tolua_isusertype(m_LuaState, a_StackPos, "cBoundingBox", false, &err))
|
||||
{
|
||||
a_ReturnedVal = *((cBoundingBox **)lua_touserdata(m_LuaState, a_StackPos));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cLuaState::GetStackValue(int a_StackPos, pWorld & a_ReturnedVal)
|
||||
{
|
||||
tolua_Error err;
|
||||
if (tolua_isusertype(m_LuaState, a_StackPos, "cWorld", false, &err))
|
||||
{
|
||||
a_ReturnedVal = *((cWorld **)lua_touserdata(m_LuaState, a_StackPos));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cLuaState::CallFunction(int a_NumResults)
|
||||
{
|
||||
ASSERT (m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first
|
||||
|
@ -59,6 +59,10 @@ class cTNTEntity;
|
||||
class cCreeper;
|
||||
class cHopperEntity;
|
||||
class cBlockEntity;
|
||||
class cBoundingBox;
|
||||
|
||||
typedef cBoundingBox * pBoundingBox;
|
||||
typedef cWorld * pWorld;
|
||||
|
||||
|
||||
|
||||
@ -230,6 +234,12 @@ public:
|
||||
/** Retrieve value at a_StackPos, if it is a valid number, converting and clamping it to eWeather.
|
||||
If not, a_Value is unchanged. */
|
||||
void GetStackValue(int a_StackPos, eWeather & a_Value);
|
||||
|
||||
/** Retrieve value at a_StackPos, if it is a valid cBoundingBox class. If not, a_Value is unchanged */
|
||||
void GetStackValue(int a_StackPos, pBoundingBox & a_Value);
|
||||
|
||||
/** Retrieve value at a_StackPos, if it is a valid cWorld class. If not, a_Value is unchanged */
|
||||
void GetStackValue(int a_StackPos, pWorld & a_Value);
|
||||
|
||||
|
||||
// Include the cLuaState::Call() overload implementation that is generated by the gen_LuaState_Call.lua script:
|
||||
@ -328,6 +338,14 @@ protected:
|
||||
*/
|
||||
bool PushFunction(int a_FnRef);
|
||||
|
||||
/** Pushes a function that has been saved as a reference.
|
||||
Returns true if successful. Logs a warning on failure
|
||||
*/
|
||||
bool PushFunction(const cRef & a_FnRef)
|
||||
{
|
||||
return PushFunction((int)a_FnRef);
|
||||
}
|
||||
|
||||
/** Pushes a function that is stored in a referenced table by name
|
||||
Returns true if successful. Logs a warning on failure
|
||||
*/
|
||||
|
@ -676,6 +676,75 @@ static int tolua_ForEachInChunk(lua_State * tolua_S)
|
||||
|
||||
|
||||
|
||||
template <
|
||||
class Ty1,
|
||||
class Ty2,
|
||||
bool (Ty1::*Func1)(const cBoundingBox &, cItemCallback<Ty2> &)
|
||||
>
|
||||
static int tolua_ForEachInBox(lua_State * tolua_S)
|
||||
{
|
||||
// Check params:
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamUserType(1, "cWorld") ||
|
||||
!L.CheckParamUserType(2, "cBoundingBox") ||
|
||||
!L.CheckParamFunction(3) ||
|
||||
!L.CheckParamEnd(4)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
Ty1 * Self = NULL;
|
||||
cBoundingBox * Box = NULL;
|
||||
L.GetStackValues(1, Self, Box);
|
||||
ASSERT(Self != NULL); // We have verified the type at the top, so we should get valid objects here
|
||||
ASSERT(Box != NULL);
|
||||
|
||||
// Create a reference for the function:
|
||||
cLuaState::cRef FnRef(L, 3);
|
||||
|
||||
// Callback wrapper for the Lua function:
|
||||
class cLuaCallback : public cItemCallback<Ty2>
|
||||
{
|
||||
public:
|
||||
cLuaCallback(cLuaState & a_LuaState, cLuaState::cRef & a_FuncRef) :
|
||||
m_LuaState(a_LuaState),
|
||||
m_FnRef(a_FuncRef)
|
||||
{}
|
||||
|
||||
private:
|
||||
// cItemCallback<Ty2> overrides:
|
||||
virtual bool Item(Ty2 * a_Item) override
|
||||
{
|
||||
bool res = false;
|
||||
if (!m_LuaState.Call(m_FnRef, a_Item, cLuaState::Return, res))
|
||||
{
|
||||
LOGWARNING("Failed to call Lua callback");
|
||||
m_LuaState.LogStackTrace();
|
||||
return true; // Abort enumeration
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
cLuaState & m_LuaState;
|
||||
cLuaState::cRef & m_FnRef;
|
||||
} Callback(L, FnRef);
|
||||
|
||||
bool bRetVal = (Self->*Func1)(*Box, Callback);
|
||||
|
||||
FnRef.UnRef();
|
||||
|
||||
/* Push return value on stack */
|
||||
tolua_pushboolean(tolua_S, bRetVal);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <
|
||||
class Ty1,
|
||||
class Ty2,
|
||||
@ -3327,6 +3396,7 @@ void ManualBindings::Bind(lua_State * tolua_S)
|
||||
tolua_function(tolua_S, "ForEachBlockEntityInChunk", tolua_ForEachInChunk<cWorld, cBlockEntity, &cWorld::ForEachBlockEntityInChunk>);
|
||||
tolua_function(tolua_S, "ForEachChestInChunk", tolua_ForEachInChunk<cWorld, cChestEntity, &cWorld::ForEachChestInChunk>);
|
||||
tolua_function(tolua_S, "ForEachEntity", tolua_ForEach< cWorld, cEntity, &cWorld::ForEachEntity>);
|
||||
tolua_function(tolua_S, "ForEachEntityInBox", tolua_ForEachInBox< cWorld, cEntity, &cWorld::ForEachEntityInBox>);
|
||||
tolua_function(tolua_S, "ForEachEntityInChunk", tolua_ForEachInChunk<cWorld, cEntity, &cWorld::ForEachEntityInChunk>);
|
||||
tolua_function(tolua_S, "ForEachFurnaceInChunk", tolua_ForEachInChunk<cWorld, cFurnaceEntity, &cWorld::ForEachFurnaceInChunk>);
|
||||
tolua_function(tolua_S, "ForEachPlayer", tolua_ForEach< cWorld, cPlayer, &cWorld::ForEachPlayer>);
|
||||
|
@ -109,7 +109,7 @@ local function WriteOverload(f, a_NumParams, a_NumReturns)
|
||||
|
||||
-- Write the function signature:
|
||||
f:write("bool Call(")
|
||||
f:write("FnT a_Function")
|
||||
f:write("const FnT & a_Function")
|
||||
for i = 1, a_NumParams do
|
||||
f:write(", ParamT", i, " a_Param", i)
|
||||
end
|
||||
|
@ -6,7 +6,7 @@ class cRedstonePoweredEntity
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~cRedstonePoweredEntity() {};
|
||||
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;
|
||||
|
@ -15,6 +15,7 @@
|
||||
cSignEntity::cSignEntity(BLOCKTYPE a_BlockType, int a_X, int a_Y, int a_Z, cWorld * a_World) :
|
||||
super(a_BlockType, a_X, a_Y, a_Z, a_World)
|
||||
{
|
||||
ASSERT((a_Y >= 0) && (a_Y < cChunkDef::Height));
|
||||
}
|
||||
|
||||
|
||||
|
@ -362,6 +362,8 @@ enum ENUM_ITEM_ID
|
||||
E_ITEM_LEAD = 420,
|
||||
E_ITEM_NAME_TAG = 421,
|
||||
E_ITEM_MINECART_WITH_COMMAND_BLOCK = 422,
|
||||
E_ITEM_RAW_MUTTON = 423,
|
||||
E_ITEM_MUTTON = 424,
|
||||
|
||||
// Keep these two as the last values of the consecutive list, without a number - they will get their correct number assigned automagically by C++
|
||||
// IsValidItem() depends on this!
|
||||
|
@ -18,6 +18,7 @@ cBlockInfo::cBlockInfo()
|
||||
, m_IsSolid(true)
|
||||
, m_FullyOccupiesVoxel(false)
|
||||
, m_CanBeTerraformed(false)
|
||||
, m_PlaceSound("")
|
||||
, m_Handler(NULL)
|
||||
{}
|
||||
|
||||
@ -571,6 +572,172 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
|
||||
a_Info[E_BLOCK_SOULSAND ].m_CanBeTerraformed = true;
|
||||
a_Info[E_BLOCK_STAINED_CLAY ].m_CanBeTerraformed = true;
|
||||
a_Info[E_BLOCK_STONE ].m_CanBeTerraformed = true;
|
||||
|
||||
|
||||
// Block place sounds:
|
||||
a_Info[E_BLOCK_STONE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_GRASS ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_DIRT ].m_PlaceSound = "dig.gravel";
|
||||
a_Info[E_BLOCK_COBBLESTONE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_PLANKS ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_SAPLING ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_BEDROCK ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_SAND ].m_PlaceSound = "dig.sand";
|
||||
a_Info[E_BLOCK_GRAVEL ].m_PlaceSound = "dig.gravel";
|
||||
a_Info[E_BLOCK_GOLD_ORE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_IRON_ORE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_COAL_ORE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_LOG ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_LEAVES ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_SPONGE ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_GLASS ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_LAPIS_ORE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_LAPIS_BLOCK ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_DISPENSER ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_SANDSTONE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_NOTE_BLOCK ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_POWERED_RAIL ].m_PlaceSound = "dig.metal";
|
||||
a_Info[E_BLOCK_DETECTOR_RAIL ].m_PlaceSound = "dig.metal";
|
||||
a_Info[E_BLOCK_STICKY_PISTON ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_COBWEB ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_TALL_GRASS ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_DEAD_BUSH ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_PISTON ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_PISTON_EXTENSION ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_WOOL ].m_PlaceSound = "dig.cloth";
|
||||
a_Info[E_BLOCK_PISTON_MOVED_BLOCK ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_DANDELION ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_FLOWER ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_BROWN_MUSHROOM ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_RED_MUSHROOM ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_GOLD_BLOCK ].m_PlaceSound = "dig.metal";
|
||||
a_Info[E_BLOCK_IRON_BLOCK ].m_PlaceSound = "dig.metal";
|
||||
a_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_STONE_SLAB ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_BRICK ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_TNT ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_BOOKCASE ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_OBSIDIAN ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_TORCH ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_FIRE ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_MOB_SPAWNER ].m_PlaceSound = "dig.metal";
|
||||
a_Info[E_BLOCK_WOODEN_STAIRS ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_CHEST ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_REDSTONE_WIRE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_DIAMOND_ORE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_DIAMOND_BLOCK ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_CRAFTING_TABLE ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_FARMLAND ].m_PlaceSound = "dig.gravel";
|
||||
a_Info[E_BLOCK_FURNACE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_LIT_FURNACE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_SIGN_POST ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_WOODEN_DOOR ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_LADDER ].m_PlaceSound = "dig.ladder";
|
||||
a_Info[E_BLOCK_RAIL ].m_PlaceSound = "dig.metal";
|
||||
a_Info[E_BLOCK_COBBLESTONE_STAIRS ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_WALLSIGN ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_LEVER ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_STONE_PRESSURE_PLATE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_IRON_DOOR ].m_PlaceSound = "dig.metal";
|
||||
a_Info[E_BLOCK_WOODEN_PRESSURE_PLATE ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_REDSTONE_ORE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_REDSTONE_ORE_GLOWING ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_STONE_BUTTON ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_SNOW ].m_PlaceSound = "dig.snow";
|
||||
a_Info[E_BLOCK_ICE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_SNOW_BLOCK ].m_PlaceSound = "dig.snow";
|
||||
a_Info[E_BLOCK_CACTUS ].m_PlaceSound = "dig.cloth";
|
||||
a_Info[E_BLOCK_CLAY ].m_PlaceSound = "dig.gravel";
|
||||
a_Info[E_BLOCK_SUGARCANE ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_JUKEBOX ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_FENCE ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_PUMPKIN ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_NETHERRACK ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_SOULSAND ].m_PlaceSound = "dig.sand";
|
||||
a_Info[E_BLOCK_GLOWSTONE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_NETHER_PORTAL ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_JACK_O_LANTERN ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_CAKE ].m_PlaceSound = "dig.snow";
|
||||
a_Info[E_BLOCK_REDSTONE_REPEATER_OFF ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_REDSTONE_REPEATER_ON ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_STAINED_GLASS ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_TRAPDOOR ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_SILVERFISH_EGG ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_STONE_BRICKS ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_HUGE_BROWN_MUSHROOM ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_HUGE_RED_MUSHROOM ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_IRON_BARS ].m_PlaceSound = "dig.metal";
|
||||
a_Info[E_BLOCK_GLASS_PANE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_MELON ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_PUMPKIN_STEM ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_MELON_STEM ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_VINES ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_FENCE_GATE ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_BRICK_STAIRS ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_STONE_BRICK_STAIRS ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_MYCELIUM ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_LILY_PAD ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_NETHER_BRICK ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_NETHER_BRICK_FENCE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_NETHER_BRICK_STAIRS ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_NETHER_WART ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_ENCHANTMENT_TABLE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_BREWING_STAND ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_CAULDRON ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_END_PORTAL ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_END_PORTAL_FRAME ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_END_STONE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_DRAGON_EGG ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_REDSTONE_LAMP_OFF ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_DOUBLE_WOODEN_SLAB ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_WOODEN_SLAB ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_COCOA_POD ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_SANDSTONE_STAIRS ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_EMERALD_ORE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_ENDER_CHEST ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_TRIPWIRE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_EMERALD_BLOCK ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_SPRUCE_WOOD_STAIRS ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_BIRCH_WOOD_STAIRS ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_JUNGLE_WOOD_STAIRS ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_COMMAND_BLOCK ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_BEACON ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_COBBLESTONE_WALL ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_FLOWER_POT ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_CARROTS ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_POTATOES ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_HEAD ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_ANVIL ].m_PlaceSound = "random.anvil_land";
|
||||
a_Info[E_BLOCK_TRAPPED_CHEST ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_DAYLIGHT_SENSOR ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_BLOCK_OF_REDSTONE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_NETHER_QUARTZ_ORE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_HOPPER ].m_PlaceSound = "dig.metal";
|
||||
a_Info[E_BLOCK_QUARTZ_BLOCK ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_QUARTZ_STAIRS ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_ACTIVATOR_RAIL ].m_PlaceSound = "dig.metal";
|
||||
a_Info[E_BLOCK_DROPPER ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_STAINED_CLAY ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_NEW_LEAVES ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_NEW_LOG ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_ACACIA_WOOD_STAIRS ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_DARK_OAK_WOOD_STAIRS ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_HAY_BALE ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_CARPET ].m_PlaceSound = "dig.cloth";
|
||||
a_Info[E_BLOCK_HARDENED_CLAY ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_BLOCK_OF_COAL ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_PACKED_ICE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_BIG_FLOWER ].m_PlaceSound = "dig.grass";
|
||||
}
|
||||
|
||||
|
||||
|
@ -48,6 +48,9 @@ public:
|
||||
/** Can a finisher change it? */
|
||||
bool m_CanBeTerraformed;
|
||||
|
||||
/** Sound when placing this block */
|
||||
AString m_PlaceSound;
|
||||
|
||||
// tolua_end
|
||||
|
||||
/** Associated block handler. */
|
||||
@ -64,6 +67,7 @@ public:
|
||||
inline static bool IsSolid (BLOCKTYPE a_Type) { return Get(a_Type).m_IsSolid; }
|
||||
inline static bool FullyOccupiesVoxel (BLOCKTYPE a_Type) { return Get(a_Type).m_FullyOccupiesVoxel; }
|
||||
inline static bool CanBeTerraformed (BLOCKTYPE a_Type) { return Get(a_Type).m_CanBeTerraformed; }
|
||||
inline static AString GetPlaceSound (BLOCKTYPE a_Type) { return Get(a_Type).m_PlaceSound; }
|
||||
|
||||
// tolua_end
|
||||
|
||||
|
@ -15,7 +15,7 @@ void cBlockBedHandler::OnPlacedByPlayer(
|
||||
if (a_BlockMeta < 8)
|
||||
{
|
||||
Vector3i Direction = MetaDataToDirection(a_BlockMeta);
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z, E_BLOCK_BED, a_BlockMeta | 0x8);
|
||||
a_ChunkInterface.SetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z, E_BLOCK_BED, a_BlockMeta | 0x8);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,16 +19,16 @@ public:
|
||||
}
|
||||
|
||||
|
||||
virtual void DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_CanDrop, bool a_DropVerbatim) override
|
||||
virtual void DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_CanDrop) override
|
||||
{
|
||||
NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
|
||||
if (Meta & 0x8)
|
||||
{
|
||||
super::DropBlock(a_ChunkInterface, a_WorldInterface, a_BlockPluginInterface, a_Digger, a_BlockX, a_BlockY - 1, a_BlockZ, a_CanDrop, a_DropVerbatim);
|
||||
super::DropBlock(a_ChunkInterface, a_WorldInterface, a_BlockPluginInterface, a_Digger, a_BlockX, a_BlockY - 1, a_BlockZ, a_CanDrop);
|
||||
}
|
||||
else
|
||||
{
|
||||
super::DropBlock(a_ChunkInterface, a_WorldInterface, a_BlockPluginInterface, a_Digger, a_BlockX, a_BlockY, a_BlockZ, a_CanDrop, a_DropVerbatim);
|
||||
super::DropBlock(a_ChunkInterface, a_WorldInterface, a_BlockPluginInterface, a_Digger, a_BlockX, a_BlockY, a_BlockZ, a_CanDrop);
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,12 +118,6 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
return "step.grass";
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -57,12 +57,6 @@ public:
|
||||
}
|
||||
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
return m_BlockType == E_BLOCK_WOODEN_BUTTON ? "step.wood" : "step.stone";
|
||||
}
|
||||
|
||||
|
||||
inline static NIBBLETYPE BlockFaceToMetaData(eBlockFace a_BlockFace)
|
||||
{
|
||||
switch (a_BlockFace)
|
||||
|
@ -69,12 +69,6 @@ public:
|
||||
{
|
||||
a_Chunk.GetWorld()->GrowCactus(a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width, 1);
|
||||
}
|
||||
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
return "step.cloth";
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -43,11 +43,6 @@ public:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
return "step.cloth";
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -22,12 +22,6 @@ public:
|
||||
cBlockHandler(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
return "step.cloth";
|
||||
}
|
||||
|
||||
|
||||
virtual bool GetPlacementBlockTypeMeta(
|
||||
|
@ -106,12 +106,6 @@ public:
|
||||
// Single chest, no further processing needed
|
||||
}
|
||||
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
return "step.wood";
|
||||
}
|
||||
|
||||
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
|
||||
{
|
||||
int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
|
||||
|
@ -15,11 +15,6 @@ public:
|
||||
: cBlockHandler(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
return "step.cloth";
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -20,11 +20,6 @@ public:
|
||||
{
|
||||
a_Pickups.push_back(cItem(E_BLOCK_AIR, 8, 0));
|
||||
}
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
return "step.stone";
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -64,12 +64,6 @@ public:
|
||||
a_BlockMeta = cBlockRedstoneRepeaterHandler::RepeaterRotationToMetaData(a_Player->GetYaw());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
return "step.wood";
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -100,12 +100,6 @@ public:
|
||||
{
|
||||
return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) == E_BLOCK_FARMLAND));
|
||||
}
|
||||
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
return "step.grass";
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -88,12 +88,6 @@ public:
|
||||
}
|
||||
} // for i - repeat twice
|
||||
}
|
||||
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
return "step.gravel";
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -102,16 +102,7 @@ void cBlockDoorHandler::OnPlacedByPlayer(
|
||||
{
|
||||
a_TopBlockMeta = 9;
|
||||
}
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY + 1, a_BlockZ, m_BlockType, a_TopBlockMeta);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const char * cBlockDoorHandler::GetStepSound(void)
|
||||
{
|
||||
return (m_BlockType == E_BLOCK_WOODEN_DOOR) ? "step.wood" : "step.stone";
|
||||
a_ChunkInterface.SetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, m_BlockType, a_TopBlockMeta);
|
||||
}
|
||||
|
||||
|
||||
|
@ -19,7 +19,6 @@ public:
|
||||
virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override;
|
||||
virtual void OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override;
|
||||
virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override;
|
||||
virtual const char * GetStepSound(void) override;
|
||||
|
||||
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override;
|
||||
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override;
|
||||
|
@ -33,11 +33,6 @@ public:
|
||||
a_BlockMeta = RotationToMetaData(a_Player->GetYaw());
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
return "step.stone";
|
||||
}
|
||||
|
||||
static NIBBLETYPE RotationToMetaData(double a_Rotation)
|
||||
{
|
||||
|
@ -28,49 +28,12 @@ public:
|
||||
|
||||
virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
|
||||
{
|
||||
bool Found = false;
|
||||
|
||||
EMCSBiome Biome = a_Chunk.GetBiomeAt(a_RelX, a_RelZ);
|
||||
if (a_Chunk.GetWorld()->IsWeatherWet() && !IsBiomeNoDownfall(Biome))
|
||||
{
|
||||
// Rain hydrates farmland, too, except in Desert biomes.
|
||||
Found = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Search for water in a close proximity:
|
||||
// Ref.: http://www.minecraftwiki.net/wiki/Farmland#Hydrated_Farmland_Tiles
|
||||
// TODO: Rewrite this to use the chunk and its neighbors directly
|
||||
cBlockArea Area;
|
||||
int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
|
||||
int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width;
|
||||
if (!Area.Read(a_Chunk.GetWorld(), BlockX - 4, BlockX + 4, a_RelY, a_RelY + 1, BlockZ - 4, BlockZ + 4))
|
||||
{
|
||||
// Too close to the world edge, cannot check surroundings; don't tick at all
|
||||
return;
|
||||
}
|
||||
|
||||
size_t NumBlocks = Area.GetBlockCount();
|
||||
BLOCKTYPE * BlockTypes = Area.GetBlockTypes();
|
||||
for (size_t i = 0; i < NumBlocks; i++)
|
||||
{
|
||||
if (IsBlockWater(BlockTypes[i]))
|
||||
{
|
||||
Found = true;
|
||||
break;
|
||||
}
|
||||
} // for i - BlockTypes[]
|
||||
}
|
||||
|
||||
NIBBLETYPE BlockMeta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ);
|
||||
|
||||
if (Found)
|
||||
|
||||
if (IsWaterInNear(a_Chunk, a_RelX, a_RelY, a_RelZ))
|
||||
{
|
||||
// Water was found, hydrate the block until hydration reaches 7:
|
||||
if (BlockMeta < 7)
|
||||
{
|
||||
a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, m_BlockType, ++BlockMeta);
|
||||
}
|
||||
// Water was found, set block meta to 7
|
||||
a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, m_BlockType, 7);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -80,9 +43,10 @@ public:
|
||||
a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_FARMLAND, --BlockMeta);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Farmland too dry. If nothing is growing on top, turn back to dirt:
|
||||
switch (a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ))
|
||||
BLOCKTYPE UpperBlock = (a_RelY >= cChunkDef::Height) ? E_BLOCK_AIR : a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ);
|
||||
switch (UpperBlock)
|
||||
{
|
||||
case E_BLOCK_CROPS:
|
||||
case E_BLOCK_POTATOES:
|
||||
@ -95,16 +59,63 @@ public:
|
||||
}
|
||||
default:
|
||||
{
|
||||
a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, 0);
|
||||
a_Chunk.SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override
|
||||
{
|
||||
if (a_BlockY >= cChunkDef::Height)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BLOCKTYPE UpperBlock = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ);
|
||||
if (cBlockInfo::FullyOccupiesVoxel(UpperBlock))
|
||||
{
|
||||
a_ChunkInterface.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_DIRT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
a_Pickups.Add(E_BLOCK_DIRT, 1, 0); // Reset meta
|
||||
}
|
||||
|
||||
bool IsWaterInNear(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ)
|
||||
{
|
||||
if (a_Chunk.GetWorld()->IsWeatherWetAt(a_RelX, a_RelZ))
|
||||
{
|
||||
// Rain hydrates farmland, too, except in Desert biomes.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Search for water in a close proximity:
|
||||
// Ref.: http://www.minecraftwiki.net/wiki/Farmland#Hydrated_Farmland_Tiles
|
||||
// TODO: Rewrite this to use the chunk and its neighbors directly
|
||||
cBlockArea Area;
|
||||
int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
|
||||
int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width;
|
||||
if (!Area.Read(a_Chunk.GetWorld(), BlockX - 4, BlockX + 4, a_RelY, a_RelY + 1, BlockZ - 4, BlockZ + 4))
|
||||
{
|
||||
// Too close to the world edge, cannot check surroundings
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t NumBlocks = Area.GetBlockCount();
|
||||
BLOCKTYPE * BlockTypes = Area.GetBlockTypes();
|
||||
for (size_t i = 0; i < NumBlocks; i++)
|
||||
{
|
||||
if (IsBlockWater(BlockTypes[i]))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
} // for i - BlockTypes[]
|
||||
|
||||
return false;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -17,6 +17,12 @@ public:
|
||||
}
|
||||
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
a_Pickups.Add(E_BLOCK_FENCE_GATE, 1, 0); // Reset meta to zero
|
||||
}
|
||||
|
||||
|
||||
virtual bool GetPlacementBlockTypeMeta(
|
||||
cChunkInterface & a_ChunkInterface, cPlayer * a_Player,
|
||||
int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
|
||||
|
@ -50,11 +50,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
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 */
|
||||
int FindObsidianCeiling(int X, int Y, int Z, cChunkInterface & a_ChunkInterface, int MaxY = 0)
|
||||
@ -131,11 +126,11 @@ public:
|
||||
{
|
||||
if (Dir == 1)
|
||||
{
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, Width, Height, Z, E_BLOCK_NETHER_PORTAL, Dir);
|
||||
a_ChunkInterface.SetBlock(Width, Height, Z, E_BLOCK_NETHER_PORTAL, Dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, X, Height, Width, E_BLOCK_NETHER_PORTAL, Dir);
|
||||
a_ChunkInterface.SetBlock(X, Height, Width, E_BLOCK_NETHER_PORTAL, Dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,12 +28,6 @@ public:
|
||||
{
|
||||
return (a_RelY > 0) && IsBlockTypeOfDirt(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ));
|
||||
}
|
||||
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
return "step.grass";
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user