Merge remote-tracking branch 'origin/master' into potions
Conflicts: src/Entities/Player.cpp src/Entities/ProjectileEntity.cpp
This commit is contained in:
commit
e824cd09b3
1
.gitignore
vendored
1
.gitignore
vendored
@ -26,6 +26,7 @@ cloc.xsl
|
||||
## Eclipse
|
||||
.cproject
|
||||
.project
|
||||
*.cbp
|
||||
|
||||
# world inside source
|
||||
ChunkWorx.ini
|
||||
|
@ -62,7 +62,10 @@ add_subdirectory(lib/tolua++/)
|
||||
add_subdirectory(lib/sqlite/)
|
||||
add_subdirectory(lib/expat/)
|
||||
add_subdirectory(lib/luaexpat/)
|
||||
add_subdirectory(lib/md5/)
|
||||
|
||||
if (WIN32)
|
||||
add_subdirectory(lib/luaproxy/)
|
||||
endif()
|
||||
|
||||
|
||||
# We use EXCLUDE_FROM_ALL so that only the explicit dependencies are used
|
||||
|
@ -1,5 +1,6 @@
|
||||
Many people have contributed to MCServer, and this list attempts to broadcast at least some of them.
|
||||
|
||||
BasedDoge (Donated AlchemistVillage prefabs)
|
||||
bearbin (Alexander Harkness)
|
||||
derouinw
|
||||
Diusrex
|
||||
@ -26,5 +27,6 @@ tonibm19
|
||||
UltraCoderRU
|
||||
worktycho
|
||||
xoft
|
||||
Yeeeeezus (Donated AlchemistVillage prefabs)
|
||||
|
||||
Please add yourself to this list if you contribute to MCServer.
|
||||
|
@ -523,13 +523,16 @@ 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 36-char UUID (with dashes)." },
|
||||
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." },
|
||||
GetUniqueID = { Params = "", Return = "number", Notes = "Returns the UniqueID of the client used to identify the client in the server" },
|
||||
GetUUID = { Params = "", Return = "string", Notes = "Returns the authentication-based UUID of the client. This UUID should be used to identify the player when persisting any player-related data." },
|
||||
GetUsername = { Params = "", Return = "string", Notes = "Returns the username that the client has provided" },
|
||||
GetViewDistance = { Params = "", Return = "number", Notes = "Returns the viewdistance (number of chunks loaded for the player in each direction)" },
|
||||
HasPluginChannel = { Params = "ChannelName", Return = "bool", Notes = "Returns true if the client has registered to receive messages on the specified plugin channel." },
|
||||
IsUUIDOnline = { Params = "UUID", Return = "bool", Notes = "(STATIC) Returns true if the UUID is generated by online auth, false if it is an offline-generated UUID. We use Version-3 UUIDs for offline UUIDs, online UUIDs are Version-4, thus we can tell them apart. Accepts both 32-char and 36-char UUIDs (with and without dashes). If the string given is not a valid UUID, returns false."},
|
||||
Kick = { Params = "Reason", Return = "", Notes = "Kicks the user with the specified reason" },
|
||||
SendPluginMessage = { Params = "Channel, Message", Return = "", Notes = "Sends the plugin message on the specified channel." },
|
||||
SetLocale = { Params = "Locale", Return = "", Notes = "Sets the locale that MCServer keeps on record. Initially the locale is initialized in protocol handshake, this function allows plugins to override the stored value (but only server-side and only until the user disconnects)." },
|
||||
@ -1875,9 +1878,9 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
|
||||
},
|
||||
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." },
|
||||
ExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "bool", Notes = "Executes the command as if given by the specified Player. Checks permissions. Returns true if executed." },
|
||||
ExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "{{cPluginManager#CommandResult|CommandResult}}", Notes = "Executes the command as if given by the specified Player. Checks permissions." },
|
||||
FindPlugins = { Params = "", Return = "", Notes = "Refreshes the list of plugins to include all folders inside the Plugins folder (potentially new disabled plugins)" },
|
||||
ForceExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "bool", Notes = "Same as ExecuteCommand, but doesn't check permissions" },
|
||||
ForceExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "{{cPluginManager#CommandResult|CommandResult}}", Notes = "Same as ExecuteCommand, but doesn't check permissions" },
|
||||
ForEachCommand = { Params = "CallbackFn", Return = "bool", Notes = "Calls the CallbackFn function for each command that has been bound using BindCommand(). The CallbackFn has the following signature: <pre class=\"prettyprint lang-lua\">function(Command, Permission, HelpString)</pre>. If the callback returns true, the enumeration is aborted and this API function returns false; if it returns false or no value, the enumeration continues with the next command, and the API function returns true." },
|
||||
ForEachConsoleCommand = { Params = "CallbackFn", Return = "bool", Notes = "Calls the CallbackFn function for each command that has been bound using BindConsoleCommand(). The CallbackFn has the following signature: <pre class=\"prettyprint lang-lua\">function (Command, HelpString)</pre>. If the callback returns true, the enumeration is aborted and this API function returns false; if it returns false or no value, the enumeration continues with the next command, and the API function returns true." },
|
||||
Get = { Params = "", Return = "cPluginManager", Notes = "(STATIC) Returns the single instance of the plugin manager" },
|
||||
@ -1893,8 +1896,23 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
|
||||
LogStackTrace = { Params = "", Return = "", Notes = "(STATIC) Logs a current stack trace of the Lua engine to the server console log. Same format as is used when the plugin fails." },
|
||||
ReloadPlugins = { Params = "", Return = "", Notes = "Reloads all active plugins" },
|
||||
},
|
||||
ConstantGroups=
|
||||
{
|
||||
CommandResult =
|
||||
{
|
||||
Include = "^cr.*",
|
||||
TextBefore = [[
|
||||
Results that the (Force)ExecuteCommand return. This gives information if the command is executed or not and the reason.
|
||||
]],
|
||||
},
|
||||
},
|
||||
Constants =
|
||||
{
|
||||
crBlocked = { Notes = "When a plugin stopped the command using the OnExecuteCommand hook" },
|
||||
crError = { Notes = "When the command handler for the given command results in an error" },
|
||||
crExecuted = { Notes = "When the command is successfully executed." },
|
||||
crNoPermission = { Notes = "When the player doesn't have permission to execute the given command." },
|
||||
crUnknownCommand = { Notes = "When the given command doesn't exist." },
|
||||
HOOK_BLOCK_SPREAD = { Notes = "Called when a block spreads based on world conditions" },
|
||||
HOOK_BLOCK_TO_PICKUPS = { Notes = "Called when a block has been dug and is being converted to pickups. The server has provided the default pickups and the plugins may modify them." },
|
||||
HOOK_CHAT = { Notes = "Called when a client sends a chat message that is not a command. The plugin may modify the chat message" },
|
||||
|
27
MCServer/Plugins/APIDump/Hooks/OnPlayerFoodLevelChange.lua
Normal file
27
MCServer/Plugins/APIDump/Hooks/OnPlayerFoodLevelChange.lua
Normal file
@ -0,0 +1,27 @@
|
||||
return
|
||||
{
|
||||
HOOK_PLAYER_FOOD_LEVEL_CHANGE =
|
||||
{
|
||||
CalledWhen = "Called before the player food level changed. Plugin may override",
|
||||
DefaultFnName = "OnPlayerFoodLevelChange", -- also used as pagename
|
||||
Desc = [[
|
||||
This hook is called before the food level changes.
|
||||
The food level is not changed yet, plugins may choose
|
||||
to refuse the change.
|
||||
]],
|
||||
Params =
|
||||
{
|
||||
{ Name = "Player", Type = "{{cPlayer}}", Notes = "The player who changes the food level." },
|
||||
{ Name = "NewFoodLevel", Type = "number", Notes = "The new food level." },
|
||||
},
|
||||
Returns = [[
|
||||
If the function returns false or no value, the next plugin's callback is called. Afterwards, the
|
||||
server changes the food level of the player. If the function returns true, no
|
||||
other callback is called for this event and the player's food level doesn't change.
|
||||
]],
|
||||
}, -- HOOK_PLAYER_FOOD_LEVEL_CHANGE
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -6,7 +6,7 @@ return
|
||||
DefaultFnName = "OnWeatherChanging", -- also used as pagename
|
||||
Desc = [[
|
||||
This hook is called when the current weather has expired and a new weather is selected. Plugins may
|
||||
override the new weather setting.</p>
|
||||
override the new weather being set.</p>
|
||||
<p>
|
||||
The new weather setting is sent to the clients only after this hook has been processed.</p>
|
||||
<p>
|
||||
@ -19,9 +19,12 @@ return
|
||||
{ Name = "Weather", Type = "number", Notes = "The newly selected weather. One of wSunny, wRain, wStorm" },
|
||||
},
|
||||
Returns = [[
|
||||
If the function returns false or no value, the server calls other plugins' callbacks and finally
|
||||
sets the weather. If the function returns true, the server takes the second returned value (wSunny
|
||||
by default) and sets it as the new weather. No other plugins' callbacks are called in this case.
|
||||
The hook handler can return up to two values. If the first value is false or not present, the server
|
||||
calls other plugins' callbacks and finally sets the weather. If it is true, the server doesn't call any
|
||||
more callbacks for this hook. The second value returned is used as the new weather. If no value is
|
||||
given, the weather from the parameters is used as the weather. Returning false as the first value and a
|
||||
specific weather constant as the second value makes the server call the rest of the hook handlers with
|
||||
the new weather value.
|
||||
]],
|
||||
}, -- HOOK_WEATHER_CHANGING
|
||||
}
|
||||
|
@ -346,7 +346,7 @@ end
|
||||
|
||||
function OnUsingBlazeRod(Player, BlockX, BlockY, BlockZ, BlockFace, CursorX, CursorY, CursorZ)
|
||||
-- Magic rod of query: show block types and metas for both neighbors of the pointed face
|
||||
local Type, Meta, Valid = Player:GetWorld():GetBlockTypeMeta(BlockX, BlockY, BlockZ, Type, Meta);
|
||||
local Valid, Type, Meta = Player:GetWorld():GetBlockTypeMeta(BlockX, BlockY, BlockZ);
|
||||
|
||||
if (Type == E_BLOCK_AIR) then
|
||||
Player:SendMessage(cChatColor.LightGray .. "Block {" .. BlockX .. ", " .. BlockY .. ", " .. BlockZ .. "}: air:" .. Meta);
|
||||
@ -356,7 +356,7 @@ function OnUsingBlazeRod(Player, BlockX, BlockY, BlockZ, BlockFace, CursorX, Cur
|
||||
end
|
||||
|
||||
local X, Y, Z = AddFaceDirection(BlockX, BlockY, BlockZ, BlockFace);
|
||||
Valid, Type, Meta = Player:GetWorld():GetBlockTypeMeta(X, Y, Z, Type, Meta);
|
||||
Valid, Type, Meta = Player:GetWorld():GetBlockTypeMeta(X, Y, Z);
|
||||
if (Type == E_BLOCK_AIR) then
|
||||
Player:SendMessage(cChatColor.LightGray .. "Block {" .. X .. ", " .. Y .. ", " .. Z .. "}: air:" .. Meta);
|
||||
else
|
||||
|
Binary file not shown.
@ -26,10 +26,18 @@ endmacro()
|
||||
|
||||
|
||||
macro(set_flags)
|
||||
# Add the preprocessor macros used for distinguishing between debug and release builds (CMake does this automatically for MSVC):
|
||||
# Add coverage processing, if requested:
|
||||
if (NOT MSVC)
|
||||
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "COVERAGE")
|
||||
message("Including CodeCoverage")
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/lib/cmake-coverage/")
|
||||
include(CodeCoverage)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Add the preprocessor macros used for distinguishing between debug and release builds (CMake does this automatically for MSVC):
|
||||
if (NOT MSVC)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG")
|
||||
set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -D_DEBUG")
|
||||
@ -63,7 +71,11 @@ macro(set_flags)
|
||||
|
||||
else()
|
||||
# Let gcc / clang know that we're compiling a multi-threaded app:
|
||||
if (UNIX)
|
||||
add_flags_cxx("-pthread")
|
||||
endif()
|
||||
|
||||
# Make CLang use C++11, otherwise MSVC2008-supported extensions don't work ("override" keyword etc.):
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="windows-1250"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Version="9,00"
|
||||
Name="BiomeVisualiser"
|
||||
ProjectGUID="{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}"
|
||||
RootNamespace="BiomeVisualiser"
|
||||
@ -327,6 +327,14 @@
|
||||
<Filter
|
||||
Name="Shared"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\BiomeDef.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\BiomeDef.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\BlockID.cpp"
|
||||
>
|
||||
@ -355,6 +363,14 @@
|
||||
RelativePath="..\..\src\WorldStorage\FastNBT.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\FastRandom.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\FastRandom.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Globals.cpp"
|
||||
>
|
||||
|
@ -11,21 +11,16 @@ file(GLOB SOURCE
|
||||
list(REMOVE_ITEM SOURCE "${PROJECT_SOURCE_DIR}/src/lua.c" "${PROJECT_SOURCE_DIR}/src/luac.c")
|
||||
|
||||
# add headers to MSVC project files:
|
||||
if (WIN32)
|
||||
if (MSVC)
|
||||
file(GLOB HEADERS "src/*.h")
|
||||
list(REMOVE_ITEM SOURCE "${PROJECT_SOURCE_DIR}/src/lua.h" "${PROJECT_SOURCE_DIR}/src/luac.h")
|
||||
set(SOURCE ${SOURCE} ${HEADERS})
|
||||
source_group("Sources" FILES ${SOURCE})
|
||||
endif()
|
||||
|
||||
|
||||
# Lua needs to be linked dynamically on Windows and statically on *nix, so that LuaRocks work
|
||||
if (WIN32)
|
||||
|
||||
#for compiliers other than msvc we need to tell lua that its building as a dll
|
||||
if (NOT MSVC)
|
||||
add_flags_cxx(-DLUA_BUILD_AS_DLL=1)
|
||||
endif()
|
||||
|
||||
add_library(lua SHARED ${SOURCE})
|
||||
set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/MCServer)
|
||||
|
||||
@ -53,7 +48,7 @@ if (WIN32)
|
||||
)
|
||||
endif()
|
||||
|
||||
set_target_properties(lua PROPERTIES OUTPUT_NAME "lua51")
|
||||
set_target_properties(lua PROPERTIES OUTPUT_NAME "lua51" PREFIX "")
|
||||
|
||||
# NOTE: The DLL for each configuration is stored at the same place, thus overwriting each other.
|
||||
# This is known, however such behavior is needed for LuaRocks - they always load "lua5.1.dll" or "lua51.dll"
|
||||
@ -63,6 +58,7 @@ else()
|
||||
add_library(lua ${SOURCE})
|
||||
endif()
|
||||
|
||||
|
||||
# Tell Lua what dynamic loader to use (for LuaRocks):
|
||||
if (UNIX)
|
||||
add_definitions(-DLUA_USE_DLOPEN)
|
||||
|
61
lib/luaproxy/CMakeLists.txt
Normal file
61
lib/luaproxy/CMakeLists.txt
Normal file
@ -0,0 +1,61 @@
|
||||
|
||||
# This project adds a Lua Proxy DLL on Windows
|
||||
# By an unfortunate choice in the popular LuaBinaries distribution, there are two names for the Lua DLL on Windows: lua51.dll and lua5.1.dll.
|
||||
# Some binary Lua packages are built for one, the others for the other. Messy!
|
||||
# In order to support both package flavors, we create a "proxy DLL":
|
||||
# Basically the lua5.1.dll has its PE Exports section manipulated so that it points each exported function to its lua51.dll implementation.
|
||||
# Effectively, this forwards all calls from lua5.1.dll to lua51.dll without any performance costs (the forwarding is done in the Windows PE loader on app start).
|
||||
|
||||
# This project creates the proxy DLL by using a specially crafted .DEF file that is used to link the Proxy DLL.
|
||||
# Note that it has been tested only on MSVC, it might not work with other compilers.
|
||||
# The initial implementation was taken from http://lua-users.org/wiki/LuaProxyDllFour , but adapted to MSVC
|
||||
|
||||
|
||||
|
||||
|
||||
if (WIN32)
|
||||
|
||||
if (MSVC)
|
||||
# Tell the linker to use the DEF file to generate the proxy:
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /NOENTRY /DEF:lua5.1.def /MANIFEST:NO")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /NOENTRY /DEF:lua5.1.def /MANIFEST:NO")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} /NOENTRY /DEF:lua5.1.def /MANIFEST:NO")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NOENTRY /DEF:lua5.1.def /MANIFEST:NO")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /NOENTRY /DEF:lua5.1.def /MANIFEST:NO")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} /NOENTRY /DEF:lua5.1.def /MANIFEST:NO")
|
||||
elseif (MINGW)
|
||||
# MinGW requires no further flags and has been tested
|
||||
else()
|
||||
message ("LuaProxy: This cmake code has not been tested on your compiler. Please report your success or failure in the forum.")
|
||||
endif()
|
||||
|
||||
add_library(luaproxy SHARED "lua5.1.def" "Dummy.c")
|
||||
set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/MCServer)
|
||||
set_target_properties(luaproxy PROPERTIES
|
||||
OUTPUT_NAME "lua5.1"
|
||||
PREFIX ""
|
||||
)
|
||||
target_link_libraries(luaproxy lua)
|
||||
|
||||
# Output the executable into the $/MCServer folder, so that MCServer can find it:
|
||||
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/MCServer)
|
||||
SET_TARGET_PROPERTIES(luaproxy PROPERTIES
|
||||
ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/MCServer
|
||||
ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
ARCHIVE_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
ARCHIVE_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/MCServer
|
||||
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
LIBRARY_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
LIBRARY_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/MCServer
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
)
|
||||
|
||||
else()
|
||||
|
||||
message (FATAL_ERROR "This project is needed only for Windows, modify your cmake file not to include it on Linux")
|
||||
|
||||
endif()
|
4
lib/luaproxy/Dummy.c
Normal file
4
lib/luaproxy/Dummy.c
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
// Dummy.c
|
||||
|
||||
// Because the MSVC compiler needs at least one C file to compile the project
|
115
lib/luaproxy/lua5.1.def
Normal file
115
lib/luaproxy/lua5.1.def
Normal file
@ -0,0 +1,115 @@
|
||||
EXPORTS
|
||||
luaL_addlstring=lua51.luaL_addlstring
|
||||
luaL_addstring=lua51.luaL_addstring
|
||||
luaL_addvalue=lua51.luaL_addvalue
|
||||
luaL_argerror=lua51.luaL_argerror
|
||||
luaL_buffinit=lua51.luaL_buffinit
|
||||
luaL_callmeta=lua51.luaL_callmeta
|
||||
luaL_checkany=lua51.luaL_checkany
|
||||
luaL_checkinteger=lua51.luaL_checkinteger
|
||||
luaL_checklstring=lua51.luaL_checklstring
|
||||
luaL_checknumber=lua51.luaL_checknumber
|
||||
luaL_checkoption=lua51.luaL_checkoption
|
||||
luaL_checkstack=lua51.luaL_checkstack
|
||||
luaL_checktype=lua51.luaL_checktype
|
||||
luaL_checkudata=lua51.luaL_checkudata
|
||||
luaL_error=lua51.luaL_error
|
||||
luaL_findtable=lua51.luaL_findtable
|
||||
luaL_getmetafield=lua51.luaL_getmetafield
|
||||
luaL_gsub=lua51.luaL_gsub
|
||||
luaL_loadbuffer=lua51.luaL_loadbuffer
|
||||
luaL_loadfile=lua51.luaL_loadfile
|
||||
luaL_loadstring=lua51.luaL_loadstring
|
||||
luaL_newmetatable=lua51.luaL_newmetatable
|
||||
luaL_newstate=lua51.luaL_newstate
|
||||
luaL_openlib=lua51.luaL_openlib
|
||||
luaL_openlibs=lua51.luaL_openlibs
|
||||
luaL_optinteger=lua51.luaL_optinteger
|
||||
luaL_optlstring=lua51.luaL_optlstring
|
||||
luaL_optnumber=lua51.luaL_optnumber
|
||||
luaL_prepbuffer=lua51.luaL_prepbuffer
|
||||
luaL_pushresult=lua51.luaL_pushresult
|
||||
luaL_ref=lua51.luaL_ref
|
||||
luaL_register=lua51.luaL_register
|
||||
luaL_typerror=lua51.luaL_typerror
|
||||
luaL_unref=lua51.luaL_unref
|
||||
luaL_where=lua51.luaL_where
|
||||
lua_atpanic=lua51.lua_atpanic
|
||||
lua_call=lua51.lua_call
|
||||
lua_checkstack=lua51.lua_checkstack
|
||||
lua_close=lua51.lua_close
|
||||
lua_concat=lua51.lua_concat
|
||||
lua_cpcall=lua51.lua_cpcall
|
||||
lua_createtable=lua51.lua_createtable
|
||||
lua_dump=lua51.lua_dump
|
||||
lua_equal=lua51.lua_equal
|
||||
lua_error=lua51.lua_error
|
||||
lua_gc=lua51.lua_gc
|
||||
lua_getallocf=lua51.lua_getallocf
|
||||
lua_getfenv=lua51.lua_getfenv
|
||||
lua_getfield=lua51.lua_getfield
|
||||
lua_gethook=lua51.lua_gethook
|
||||
lua_gethookcount=lua51.lua_gethookcount
|
||||
lua_gethookmask=lua51.lua_gethookmask
|
||||
lua_getinfo=lua51.lua_getinfo
|
||||
lua_getlocal=lua51.lua_getlocal
|
||||
lua_getmetatable=lua51.lua_getmetatable
|
||||
lua_getstack=lua51.lua_getstack
|
||||
lua_gettable=lua51.lua_gettable
|
||||
lua_gettop=lua51.lua_gettop
|
||||
lua_getupvalue=lua51.lua_getupvalue
|
||||
lua_insert=lua51.lua_insert
|
||||
lua_iscfunction=lua51.lua_iscfunction
|
||||
lua_isnumber=lua51.lua_isnumber
|
||||
lua_isstring=lua51.lua_isstring
|
||||
lua_isuserdata=lua51.lua_isuserdata
|
||||
lua_lessthan=lua51.lua_lessthan
|
||||
lua_load=lua51.lua_load
|
||||
lua_newstate=lua51.lua_newstate
|
||||
lua_newthread=lua51.lua_newthread
|
||||
lua_newuserdata=lua51.lua_newuserdata
|
||||
lua_next=lua51.lua_next
|
||||
lua_objlen=lua51.lua_objlen
|
||||
lua_pcall=lua51.lua_pcall
|
||||
lua_pushboolean=lua51.lua_pushboolean
|
||||
lua_pushcclosure=lua51.lua_pushcclosure
|
||||
lua_pushfstring=lua51.lua_pushfstring
|
||||
lua_pushinteger=lua51.lua_pushinteger
|
||||
lua_pushlightuserdata=lua51.lua_pushlightuserdata
|
||||
lua_pushlstring=lua51.lua_pushlstring
|
||||
lua_pushnil=lua51.lua_pushnil
|
||||
lua_pushnumber=lua51.lua_pushnumber
|
||||
lua_pushstring=lua51.lua_pushstring
|
||||
lua_pushthread=lua51.lua_pushthread
|
||||
lua_pushvalue=lua51.lua_pushvalue
|
||||
lua_pushvfstring=lua51.lua_pushvfstring
|
||||
lua_rawequal=lua51.lua_rawequal
|
||||
lua_rawget=lua51.lua_rawget
|
||||
lua_rawgeti=lua51.lua_rawgeti
|
||||
lua_rawset=lua51.lua_rawset
|
||||
lua_rawseti=lua51.lua_rawseti
|
||||
lua_remove=lua51.lua_remove
|
||||
lua_replace=lua51.lua_replace
|
||||
lua_resume=lua51.lua_resume
|
||||
lua_setallocf=lua51.lua_setallocf
|
||||
lua_setfenv=lua51.lua_setfenv
|
||||
lua_setfield=lua51.lua_setfield
|
||||
lua_sethook=lua51.lua_sethook
|
||||
lua_setlocal=lua51.lua_setlocal
|
||||
lua_setmetatable=lua51.lua_setmetatable
|
||||
lua_settable=lua51.lua_settable
|
||||
lua_settop=lua51.lua_settop
|
||||
lua_setupvalue=lua51.lua_setupvalue
|
||||
lua_status=lua51.lua_status
|
||||
lua_toboolean=lua51.lua_toboolean
|
||||
lua_tocfunction=lua51.lua_tocfunction
|
||||
lua_tointeger=lua51.lua_tointeger
|
||||
lua_tolstring=lua51.lua_tolstring
|
||||
lua_tonumber=lua51.lua_tonumber
|
||||
lua_topointer=lua51.lua_topointer
|
||||
lua_tothread=lua51.lua_tothread
|
||||
lua_touserdata=lua51.lua_touserdata
|
||||
lua_type=lua51.lua_type
|
||||
lua_typename=lua51.lua_typename
|
||||
lua_xmove=lua51.lua_xmove
|
||||
lua_yield=lua51.lua_yield
|
140
lib/luaproxy/lua5.1.lua
Normal file
140
lib/luaproxy/lua5.1.lua
Normal file
@ -0,0 +1,140 @@
|
||||
|
||||
-- lua5.1.lua
|
||||
-- Generates the lua5.1.def file from the list of Lua symbols below
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
local symbols =
|
||||
{
|
||||
"luaL_addlstring",
|
||||
"luaL_addstring",
|
||||
"luaL_addvalue",
|
||||
"luaL_argerror",
|
||||
"luaL_buffinit",
|
||||
"luaL_callmeta",
|
||||
"luaL_checkany",
|
||||
"luaL_checkinteger",
|
||||
"luaL_checklstring",
|
||||
"luaL_checknumber",
|
||||
"luaL_checkoption",
|
||||
"luaL_checkstack",
|
||||
"luaL_checktype",
|
||||
"luaL_checkudata",
|
||||
"luaL_error",
|
||||
"luaL_findtable",
|
||||
"luaL_getmetafield",
|
||||
"luaL_gsub",
|
||||
"luaL_loadbuffer",
|
||||
"luaL_loadfile",
|
||||
"luaL_loadstring",
|
||||
"luaL_newmetatable",
|
||||
"luaL_newstate",
|
||||
"luaL_openlib",
|
||||
"luaL_openlibs",
|
||||
"luaL_optinteger",
|
||||
"luaL_optlstring",
|
||||
"luaL_optnumber",
|
||||
"luaL_prepbuffer",
|
||||
"luaL_pushresult",
|
||||
"luaL_ref",
|
||||
"luaL_register",
|
||||
"luaL_typerror",
|
||||
"luaL_unref",
|
||||
"luaL_where",
|
||||
"lua_atpanic",
|
||||
"lua_call",
|
||||
"lua_checkstack",
|
||||
"lua_close",
|
||||
"lua_concat",
|
||||
"lua_cpcall",
|
||||
"lua_createtable",
|
||||
"lua_dump",
|
||||
"lua_equal",
|
||||
"lua_error",
|
||||
"lua_gc",
|
||||
"lua_getallocf",
|
||||
"lua_getfenv",
|
||||
"lua_getfield",
|
||||
"lua_gethook",
|
||||
"lua_gethookcount",
|
||||
"lua_gethookmask",
|
||||
"lua_getinfo",
|
||||
"lua_getlocal",
|
||||
"lua_getmetatable",
|
||||
"lua_getstack",
|
||||
"lua_gettable",
|
||||
"lua_gettop",
|
||||
"lua_getupvalue",
|
||||
"lua_insert",
|
||||
"lua_iscfunction",
|
||||
"lua_isnumber",
|
||||
"lua_isstring",
|
||||
"lua_isuserdata",
|
||||
"lua_lessthan",
|
||||
"lua_load",
|
||||
"lua_newstate",
|
||||
"lua_newthread",
|
||||
"lua_newuserdata",
|
||||
"lua_next",
|
||||
"lua_objlen",
|
||||
"lua_pcall",
|
||||
"lua_pushboolean",
|
||||
"lua_pushcclosure",
|
||||
"lua_pushfstring",
|
||||
"lua_pushinteger",
|
||||
"lua_pushlightuserdata",
|
||||
"lua_pushlstring",
|
||||
"lua_pushnil",
|
||||
"lua_pushnumber",
|
||||
"lua_pushstring",
|
||||
"lua_pushthread",
|
||||
"lua_pushvalue",
|
||||
"lua_pushvfstring",
|
||||
"lua_rawequal",
|
||||
"lua_rawget",
|
||||
"lua_rawgeti",
|
||||
"lua_rawset",
|
||||
"lua_rawseti",
|
||||
"lua_remove",
|
||||
"lua_replace",
|
||||
"lua_resume",
|
||||
"lua_setallocf",
|
||||
"lua_setfenv",
|
||||
"lua_setfield",
|
||||
"lua_sethook",
|
||||
"lua_setlocal",
|
||||
"lua_setmetatable",
|
||||
"lua_settable",
|
||||
"lua_settop",
|
||||
"lua_setupvalue",
|
||||
"lua_status",
|
||||
"lua_toboolean",
|
||||
"lua_tocfunction",
|
||||
"lua_tointeger",
|
||||
"lua_tolstring",
|
||||
"lua_tonumber",
|
||||
"lua_topointer",
|
||||
"lua_tothread",
|
||||
"lua_touserdata",
|
||||
"lua_type",
|
||||
"lua_typename",
|
||||
"lua_xmove",
|
||||
"lua_yield",
|
||||
-- "luaopen_base",
|
||||
-- "luaopen_debug",
|
||||
-- "luaopen_io",
|
||||
-- "luaopen_math",
|
||||
-- "luaopen_os",
|
||||
-- "luaopen_package",
|
||||
-- "luaopen_string",
|
||||
-- "luaopen_table",
|
||||
}
|
||||
|
||||
local def = io.open("lua5.1.def", "w")
|
||||
def:write("EXPORTS\n")
|
||||
for _,symbol in ipairs(symbols) do
|
||||
def:write("\t" .. symbol .. "=lua51." .. symbol .. "\n")
|
||||
end
|
||||
def:close()
|
@ -1,12 +0,0 @@
|
||||
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
project (md5)
|
||||
|
||||
include_directories ("${PROJECT_SOURCE_DIR}/../../src/")
|
||||
|
||||
file(GLOB SOURCE
|
||||
"*.cpp"
|
||||
"*.h"
|
||||
)
|
||||
|
||||
add_library(md5 ${SOURCE})
|
369
lib/md5/md5.cpp
369
lib/md5/md5.cpp
@ -1,369 +0,0 @@
|
||||
/* MD5
|
||||
converted to C++ class by Frank Thilo (thilo@unix-ag.org)
|
||||
for bzflag (http://www.bzflag.org)
|
||||
|
||||
based on:
|
||||
|
||||
md5.h and md5.c
|
||||
reference implemantion of RFC 1321
|
||||
|
||||
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
rights reserved.
|
||||
|
||||
License to copy and use this software is granted provided that it
|
||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
Algorithm" in all material mentioning or referencing this software
|
||||
or this function.
|
||||
|
||||
License is also granted to make and use derivative works provided
|
||||
that such works are identified as "derived from the RSA Data
|
||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
mentioning or referencing the derived work.
|
||||
|
||||
RSA Data Security, Inc. makes no representations concerning either
|
||||
the merchantability of this software or the suitability of this
|
||||
software for any particular purpose. It is provided "as is"
|
||||
without express or implied warranty of any kind.
|
||||
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
|
||||
*/
|
||||
|
||||
/* interface header */
|
||||
#include "md5.h"
|
||||
|
||||
/* system implementation headers */
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <cstring>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Constants for MD5Transform routine.
|
||||
#define S11 7
|
||||
#define S12 12
|
||||
#define S13 17
|
||||
#define S14 22
|
||||
#define S21 5
|
||||
#define S22 9
|
||||
#define S23 14
|
||||
#define S24 20
|
||||
#define S31 4
|
||||
#define S32 11
|
||||
#define S33 16
|
||||
#define S34 23
|
||||
#define S41 6
|
||||
#define S42 10
|
||||
#define S43 15
|
||||
#define S44 21
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
// F, G, H and I are basic MD5 functions.
|
||||
inline MD5::uint4 MD5::F(uint4 x, uint4 y, uint4 z) {
|
||||
return x&y | ~x&z;
|
||||
}
|
||||
|
||||
inline MD5::uint4 MD5::G(uint4 x, uint4 y, uint4 z) {
|
||||
return x&z | y&~z;
|
||||
}
|
||||
|
||||
inline MD5::uint4 MD5::H(uint4 x, uint4 y, uint4 z) {
|
||||
return x^y^z;
|
||||
}
|
||||
|
||||
inline MD5::uint4 MD5::I(uint4 x, uint4 y, uint4 z) {
|
||||
return y ^ (x | ~z);
|
||||
}
|
||||
|
||||
// rotate_left rotates x left n bits.
|
||||
inline MD5::uint4 MD5::rotate_left(uint4 x, int n) {
|
||||
return (x << n) | (x >> (32-n));
|
||||
}
|
||||
|
||||
// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
||||
// Rotation is separate from addition to prevent recomputation.
|
||||
inline void MD5::FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
|
||||
a = rotate_left(a+ F(b,c,d) + x + ac, s) + b;
|
||||
}
|
||||
|
||||
inline void MD5::GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
|
||||
a = rotate_left(a + G(b,c,d) + x + ac, s) + b;
|
||||
}
|
||||
|
||||
inline void MD5::HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
|
||||
a = rotate_left(a + H(b,c,d) + x + ac, s) + b;
|
||||
}
|
||||
|
||||
inline void MD5::II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
|
||||
a = rotate_left(a + I(b,c,d) + x + ac, s) + b;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
|
||||
// default ctor, just initailize
|
||||
MD5::MD5()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
|
||||
// nifty shortcut ctor, compute MD5 for string and finalize it right away
|
||||
MD5::MD5(const std::string &text)
|
||||
{
|
||||
init();
|
||||
update(text.c_str(), text.length());
|
||||
finalize();
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
void MD5::init()
|
||||
{
|
||||
finalized=false;
|
||||
|
||||
count[0] = 0;
|
||||
count[1] = 0;
|
||||
|
||||
// load magic initialization constants.
|
||||
state[0] = 0x67452301;
|
||||
state[1] = 0xefcdab89;
|
||||
state[2] = 0x98badcfe;
|
||||
state[3] = 0x10325476;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// decodes input (unsigned char) into output (uint4). Assumes len is a multiple of 4.
|
||||
void MD5::decode(uint4 output[], const uint1 input[], size_type len)
|
||||
{
|
||||
for (unsigned int i = 0, j = 0; j < len; i++, j += 4)
|
||||
output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
|
||||
(((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// encodes input (uint4) into output (unsigned char). Assumes len is
|
||||
// a multiple of 4.
|
||||
void MD5::encode(uint1 output[], const uint4 input[], size_type len)
|
||||
{
|
||||
for (size_type i = 0, j = 0; j < len; i++, j += 4) {
|
||||
output[j] = input[i] & 0xff;
|
||||
output[j+1] = (input[i] >> 8) & 0xff;
|
||||
output[j+2] = (input[i] >> 16) & 0xff;
|
||||
output[j+3] = (input[i] >> 24) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// apply MD5 algo on a block
|
||||
void MD5::transform(const uint1 block[blocksize])
|
||||
{
|
||||
uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||
decode (x, block, blocksize);
|
||||
|
||||
/* Round 1 */
|
||||
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
|
||||
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
|
||||
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
|
||||
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
|
||||
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
|
||||
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
|
||||
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
|
||||
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
|
||||
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
|
||||
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
|
||||
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
|
||||
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
|
||||
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
|
||||
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
|
||||
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
|
||||
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
|
||||
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
|
||||
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
|
||||
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
|
||||
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
|
||||
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
|
||||
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
|
||||
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
|
||||
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
|
||||
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
|
||||
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
|
||||
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
|
||||
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
|
||||
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
|
||||
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
|
||||
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
|
||||
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
|
||||
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
|
||||
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
|
||||
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
|
||||
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
|
||||
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
|
||||
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
|
||||
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
|
||||
// Zeroize sensitive information.
|
||||
memset(x, 0, sizeof x);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// MD5 block update operation. Continues an MD5 message-digest
|
||||
// operation, processing another message block
|
||||
void MD5::update(const unsigned char input[], size_type length)
|
||||
{
|
||||
// compute number of bytes mod 64
|
||||
size_type index = count[0] / 8 % blocksize;
|
||||
|
||||
// Update number of bits
|
||||
if ((count[0] += (length << 3)) < (length << 3))
|
||||
count[1]++;
|
||||
count[1] += (length >> 29);
|
||||
|
||||
// number of bytes we need to fill in buffer
|
||||
size_type firstpart = 64 - index;
|
||||
|
||||
size_type i;
|
||||
|
||||
// transform as many times as possible.
|
||||
if (length >= firstpart)
|
||||
{
|
||||
// fill buffer first, transform
|
||||
memcpy(&buffer[index], input, firstpart);
|
||||
transform(buffer);
|
||||
|
||||
// transform chunks of blocksize (64 bytes)
|
||||
for (i = firstpart; i + blocksize <= length; i += blocksize)
|
||||
transform(&input[i]);
|
||||
|
||||
index = 0;
|
||||
}
|
||||
else
|
||||
i = 0;
|
||||
|
||||
// buffer remaining input
|
||||
memcpy(&buffer[index], &input[i], length-i);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// for convenience provide a verson with signed char
|
||||
void MD5::update(const char input[], size_type length)
|
||||
{
|
||||
update((const unsigned char*)input, length);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// MD5 finalization. Ends an MD5 message-digest operation, writing the
|
||||
// the message digest and zeroizing the context.
|
||||
MD5& MD5::finalize()
|
||||
{
|
||||
static unsigned char padding[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
if (!finalized) {
|
||||
// Save number of bits
|
||||
unsigned char bits[8];
|
||||
encode(bits, count, 8);
|
||||
|
||||
// pad out to 56 mod 64.
|
||||
size_type index = count[0] / 8 % 64;
|
||||
size_type padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||
update(padding, padLen);
|
||||
|
||||
// Append length (before padding)
|
||||
update(bits, 8);
|
||||
|
||||
// Store state in digest
|
||||
encode(digest, state, 16);
|
||||
|
||||
// Zeroize sensitive information.
|
||||
memset(buffer, 0, sizeof buffer);
|
||||
memset(count, 0, sizeof count);
|
||||
|
||||
finalized=true;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// return hex representation of digest as string
|
||||
std::string MD5::hexdigest() const
|
||||
{
|
||||
if (!finalized)
|
||||
return "";
|
||||
|
||||
char buf[33];
|
||||
for (int i=0; i<16; i++)
|
||||
sprintf(buf+i*2, "%02x", digest[i]);
|
||||
buf[32]=0;
|
||||
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, MD5 md5)
|
||||
{
|
||||
return out << md5.hexdigest();
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
std::string md5(const std::string & str)
|
||||
{
|
||||
MD5 md5 = MD5(str);
|
||||
|
||||
return md5.hexdigest();
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
/* MD5
|
||||
converted to C++ class by Frank Thilo (thilo@unix-ag.org)
|
||||
for bzflag (http://www.bzflag.org)
|
||||
|
||||
based on:
|
||||
|
||||
md5.h and md5.c
|
||||
reference implementation of RFC 1321
|
||||
|
||||
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
rights reserved.
|
||||
|
||||
License to copy and use this software is granted provided that it
|
||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
Algorithm" in all material mentioning or referencing this software
|
||||
or this function.
|
||||
|
||||
License is also granted to make and use derivative works provided
|
||||
that such works are identified as "derived from the RSA Data
|
||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
mentioning or referencing the derived work.
|
||||
|
||||
RSA Data Security, Inc. makes no representations concerning either
|
||||
the merchantability of this software or the suitability of this
|
||||
software for any particular purpose. It is provided "as is"
|
||||
without express or implied warranty of any kind.
|
||||
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef BZF_MD5_H
|
||||
#define BZF_MD5_H
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
// a small class for calculating MD5 hashes of strings or byte arrays
|
||||
// it is not meant to be fast or secure
|
||||
//
|
||||
// usage: 1) feed it blocks of uchars with update()
|
||||
// 2) finalize()
|
||||
// 3) get hexdigest() string
|
||||
// or
|
||||
// MD5(std::string).hexdigest()
|
||||
//
|
||||
// assumes that char is 8 bit and int is 32 bit
|
||||
class MD5
|
||||
{
|
||||
public:
|
||||
typedef unsigned int size_type; // must be 32bit
|
||||
|
||||
MD5();
|
||||
MD5(const std::string& text);
|
||||
void update(const unsigned char *buf, size_type length);
|
||||
void update(const char *buf, size_type length);
|
||||
MD5& finalize();
|
||||
std::string hexdigest() const;
|
||||
friend std::ostream& operator<<(std::ostream&, MD5 md5);
|
||||
|
||||
private:
|
||||
void init();
|
||||
typedef unsigned char uint1; // 8bit
|
||||
typedef unsigned int uint4; // 32bit
|
||||
enum {blocksize = 64}; // VC6 won't eat a const static int here
|
||||
|
||||
void transform(const uint1 block[blocksize]);
|
||||
static void decode(uint4 output[], const uint1 input[], size_type len);
|
||||
static void encode(uint1 output[], const uint4 input[], size_type len);
|
||||
|
||||
bool finalized;
|
||||
uint1 buffer[blocksize]; // bytes that didn't fit in last 64 byte chunk
|
||||
uint4 count[2]; // 64bit counter for number of bits (lo, hi)
|
||||
uint4 state[4]; // digest so far
|
||||
uint1 digest[16]; // the result
|
||||
|
||||
// low level logic operations
|
||||
static inline uint4 F(uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 G(uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 H(uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 I(uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 rotate_left(uint4 x, int n);
|
||||
static inline void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
|
||||
static inline void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
|
||||
static inline void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
|
||||
static inline void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
|
||||
};
|
||||
|
||||
std::string md5(const std::string & str);
|
||||
|
||||
#endif
|
@ -1,9 +1,9 @@
|
||||
|
||||
if(NOT TARGET polarssl)
|
||||
message("including polarssl")
|
||||
if (SELF_TEST)
|
||||
set(ENABLE_TESTING OFF CACHE BOOL "Disable tests")
|
||||
set(ENABLE_PROGRAMS OFF CACHE BOOL "Disable programs")
|
||||
if (SELF_TEST)
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/polarssl/ ${CMAKE_CURRENT_BINARY_DIR}/lib/polarssl)
|
||||
else()
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/polarssl/ ${CMAKE_CURRENT_BINARY_DIR}/lib/polarssl EXCLUDE_FROM_ALL)
|
||||
|
@ -9,8 +9,14 @@ file(GLOB SOURCE
|
||||
)
|
||||
|
||||
|
||||
# add headers to MSVC project files:
|
||||
# Lua is required as a DLL for LuaSQLite:
|
||||
if (WIN32)
|
||||
add_definitions(-DLUA_BUILD_AS_DLL)
|
||||
endif()
|
||||
|
||||
|
||||
# add headers to MSVC project files:
|
||||
if (MSVC)
|
||||
file(GLOB HEADERS "src/*.h")
|
||||
list(REMOVE_ITEM SOURCE "${PROJECT_SOURCE_DIR}/src/lua.h" "${PROJECT_SOURCE_DIR}/src/luac.h")
|
||||
set(SOURCE ${SOURCE} ${HEADERS})
|
||||
@ -23,6 +29,7 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
|
||||
endif()
|
||||
|
||||
add_library(sqlite ${SOURCE})
|
||||
target_link_libraries(sqlite lua)
|
||||
|
||||
if (UNIX)
|
||||
target_link_libraries(sqlite ${DYNAMIC_LOADER})
|
||||
|
@ -44,14 +44,13 @@ file(GLOB BIN_SOURCE
|
||||
"src/bin/*.c"
|
||||
)
|
||||
|
||||
|
||||
|
||||
add_executable(tolua ${BIN_SOURCE})
|
||||
add_library(tolualib ${LIB_SOURCE})
|
||||
target_link_libraries(tolualib lua)
|
||||
|
||||
#m is the standard math librarys
|
||||
if(UNIX)
|
||||
target_link_libraries(tolua m ${DYNAMIC_LOADER})
|
||||
endif()
|
||||
|
||||
target_link_libraries(tolua lua tolualib)
|
||||
target_link_libraries(tolua tolualib lua)
|
||||
|
1
src/Bindings/.gitignore
vendored
1
src/Bindings/.gitignore
vendored
@ -1 +1,2 @@
|
||||
lua51.dll
|
||||
LuaState_Call.inc
|
||||
|
@ -811,6 +811,18 @@ void cLuaState::GetStackValue(int a_StackPos, double & a_ReturnedVal)
|
||||
|
||||
|
||||
|
||||
void cLuaState::GetStackValue(int a_StackPos, eWeather & a_ReturnedVal)
|
||||
{
|
||||
if (lua_isnumber(m_LuaState, a_StackPos))
|
||||
{
|
||||
a_ReturnedVal = (eWeather)Clamp((int)tolua_tonumber(m_LuaState, a_StackPos, a_ReturnedVal), (int)wSunny, (int)wThunderstorm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cLuaState::CallFunction(int a_NumResults)
|
||||
{
|
||||
ASSERT (m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first
|
||||
|
@ -9,10 +9,11 @@ Owned lua_State is created by calling Create() and the cLuaState automatically c
|
||||
Or, lua_State can be attached by calling Attach(), the cLuaState doesn't close such a state
|
||||
Attaching a state will automatically close an owned state.
|
||||
|
||||
Calling a Lua function is done by pushing the function, either by PushFunction() or PushFunctionFromRegistry(),
|
||||
then pushing the arguments (PushString(), PushNumber(), PushUserData() etc.) and finally
|
||||
executing CallFunction(). cLuaState automatically keeps track of the number of arguments and the name of the
|
||||
function (for logging purposes), which makes the call less error-prone.
|
||||
Calling a Lua function is done internally by pushing the function using PushFunction(), then pushing the
|
||||
arguments and finally executing CallFunction(). cLuaState automatically keeps track of the number of
|
||||
arguments and the name of the function (for logging purposes). After the call the return values are read from
|
||||
the stack using GetStackValue(). All of this is wrapped in a templated function overloads cLuaState::Call(),
|
||||
which is generated automatically by gen_LuaState_Call.lua script file into the LuaState_Call.inc file.
|
||||
|
||||
Reference management is provided by the cLuaState::cRef class. This is used when you need to hold a reference to
|
||||
any Lua object across several function calls; usually this is used for callbacks. The class is RAII-like, with
|
||||
@ -30,6 +31,7 @@ extern "C"
|
||||
}
|
||||
|
||||
#include "../Vector3.h"
|
||||
#include "../Defines.h"
|
||||
|
||||
|
||||
|
||||
@ -222,625 +224,13 @@ public:
|
||||
/** Retrieve value at a_StackPos, if it is a valid number. If not, a_Value is unchanged */
|
||||
void GetStackValue(int a_StackPos, double & a_Value);
|
||||
|
||||
/** 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);
|
||||
|
||||
/** Call any 0-param 0-return Lua function in a single line: */
|
||||
template <typename FnT>
|
||||
bool Call(FnT a_FnName)
|
||||
{
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return CallFunction(0);
|
||||
}
|
||||
|
||||
/** Call any 1-param 0-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT,
|
||||
typename ArgT1
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1)
|
||||
{
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
return CallFunction(0);
|
||||
}
|
||||
|
||||
/** Call any 2-param 0-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2)
|
||||
{
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
Push(a_Arg2);
|
||||
return CallFunction(0);
|
||||
}
|
||||
|
||||
/** Call any 3-param 0-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3)
|
||||
{
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
Push(a_Arg2);
|
||||
Push(a_Arg3);
|
||||
return CallFunction(0);
|
||||
}
|
||||
|
||||
/** Call any 0-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename RetT1
|
||||
>
|
||||
bool Call(FnT a_FnName, const cRet & a_Mark, RetT1 & a_Ret1)
|
||||
{
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!CallFunction(1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Call any 1-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename RetT1
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, const cRet & a_Mark, RetT1 & a_Ret1)
|
||||
{
|
||||
int InitialTop = lua_gettop(m_LuaState);
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
if (!CallFunction(1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
ASSERT(InitialTop == lua_gettop(m_LuaState));
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Call any 2-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename RetT1
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, const cRet & a_Mark, RetT1 & a_Ret1)
|
||||
{
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
Push(a_Arg2);
|
||||
if (!CallFunction(1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Call any 3-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename RetT1
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, const cRet & a_Mark, RetT1 & a_Ret1)
|
||||
{
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
Push(a_Arg2);
|
||||
Push(a_Arg3);
|
||||
if (!CallFunction(1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Call any 4-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename RetT1
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, const cRet & a_Mark, RetT1 & a_Ret1)
|
||||
{
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
Push(a_Arg2);
|
||||
Push(a_Arg3);
|
||||
Push(a_Arg4);
|
||||
if (!CallFunction(1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Call any 5-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename RetT1
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, const cRet & a_Mark, RetT1 & a_Ret1)
|
||||
{
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
Push(a_Arg2);
|
||||
Push(a_Arg3);
|
||||
Push(a_Arg4);
|
||||
Push(a_Arg5);
|
||||
if (!CallFunction(1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Call any 6-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6,
|
||||
typename RetT1
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, const cRet & a_Mark, RetT1 & a_Ret1)
|
||||
{
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
Push(a_Arg2);
|
||||
Push(a_Arg3);
|
||||
Push(a_Arg4);
|
||||
Push(a_Arg5);
|
||||
Push(a_Arg6);
|
||||
if (!CallFunction(1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Call any 7-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6,
|
||||
typename ArgT7, typename RetT1
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, const cRet & a_Mark, RetT1 & a_Ret1)
|
||||
{
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
Push(a_Arg2);
|
||||
Push(a_Arg3);
|
||||
Push(a_Arg4);
|
||||
Push(a_Arg5);
|
||||
Push(a_Arg6);
|
||||
Push(a_Arg7);
|
||||
if (!CallFunction(1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Call any 8-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6,
|
||||
typename ArgT7, typename ArgT8, typename RetT1
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, ArgT8 a_Arg8, const cRet & a_Mark, RetT1 & a_Ret1)
|
||||
{
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
Push(a_Arg2);
|
||||
Push(a_Arg3);
|
||||
Push(a_Arg4);
|
||||
Push(a_Arg5);
|
||||
Push(a_Arg6);
|
||||
Push(a_Arg7);
|
||||
Push(a_Arg8);
|
||||
if (!CallFunction(1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Call any 9-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6,
|
||||
typename ArgT7, typename ArgT8, typename ArgT9, typename RetT1
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, ArgT8 a_Arg8, ArgT9 a_Arg9, const cRet & a_Mark, RetT1 & a_Ret1)
|
||||
{
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
Push(a_Arg2);
|
||||
Push(a_Arg3);
|
||||
Push(a_Arg4);
|
||||
Push(a_Arg5);
|
||||
Push(a_Arg6);
|
||||
Push(a_Arg7);
|
||||
Push(a_Arg8);
|
||||
Push(a_Arg9);
|
||||
if (!CallFunction(1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Call any 10-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6,
|
||||
typename ArgT7, typename ArgT8, typename ArgT9, typename ArgT10, typename RetT1
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, ArgT8 a_Arg8, ArgT9 a_Arg9, ArgT10 a_Arg10, const cRet & a_Mark, RetT1 & a_Ret1)
|
||||
{
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
Push(a_Arg2);
|
||||
Push(a_Arg3);
|
||||
Push(a_Arg4);
|
||||
Push(a_Arg5);
|
||||
Push(a_Arg6);
|
||||
Push(a_Arg7);
|
||||
Push(a_Arg8);
|
||||
Push(a_Arg9);
|
||||
Push(a_Arg10);
|
||||
if (!CallFunction(1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Call any 1-param 2-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename RetT1, typename RetT2
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2)
|
||||
{
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
if (!CallFunction(2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-2, a_Ret1);
|
||||
GetStackValue(-1, a_Ret2);
|
||||
lua_pop(m_LuaState, 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Call any 2-param 2-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename RetT1, typename RetT2
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2)
|
||||
{
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
Push(a_Arg2);
|
||||
if (!CallFunction(2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-2, a_Ret1);
|
||||
GetStackValue(-1, a_Ret2);
|
||||
lua_pop(m_LuaState, 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Call any 3-param 2-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3,
|
||||
typename RetT1, typename RetT2
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2)
|
||||
{
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
Push(a_Arg2);
|
||||
Push(a_Arg3);
|
||||
if (!CallFunction(2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-2, a_Ret1);
|
||||
GetStackValue(-1, a_Ret2);
|
||||
lua_pop(m_LuaState, 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Call any 4-param 2-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4,
|
||||
typename RetT1, typename RetT2
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2)
|
||||
{
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
Push(a_Arg2);
|
||||
Push(a_Arg3);
|
||||
Push(a_Arg4);
|
||||
if (!CallFunction(2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-2, a_Ret1);
|
||||
GetStackValue(-1, a_Ret2);
|
||||
lua_pop(m_LuaState, 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Call any 5-param 2-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5,
|
||||
typename RetT1, typename RetT2
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2)
|
||||
{
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
Push(a_Arg2);
|
||||
Push(a_Arg3);
|
||||
Push(a_Arg4);
|
||||
Push(a_Arg5);
|
||||
if (!CallFunction(2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-2, a_Ret1);
|
||||
GetStackValue(-1, a_Ret2);
|
||||
lua_pop(m_LuaState, 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Call any 6-param 2-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5,
|
||||
typename ArgT6,
|
||||
typename RetT1, typename RetT2
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2)
|
||||
{
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
Push(a_Arg2);
|
||||
Push(a_Arg3);
|
||||
Push(a_Arg4);
|
||||
Push(a_Arg5);
|
||||
Push(a_Arg6);
|
||||
if (!CallFunction(2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-2, a_Ret1);
|
||||
GetStackValue(-1, a_Ret2);
|
||||
lua_pop(m_LuaState, 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Call any 7-param 2-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5,
|
||||
typename ArgT6, typename ArgT7,
|
||||
typename RetT1, typename RetT2
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2)
|
||||
{
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
Push(a_Arg2);
|
||||
Push(a_Arg3);
|
||||
Push(a_Arg4);
|
||||
Push(a_Arg5);
|
||||
Push(a_Arg6);
|
||||
Push(a_Arg7);
|
||||
if (!CallFunction(2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-2, a_Ret1);
|
||||
GetStackValue(-1, a_Ret2);
|
||||
lua_pop(m_LuaState, 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Call any 7-param 3-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5,
|
||||
typename ArgT6, typename ArgT7,
|
||||
typename RetT1, typename RetT2, typename RetT3
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2, RetT3 & a_Ret3)
|
||||
{
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
Push(a_Arg2);
|
||||
Push(a_Arg3);
|
||||
Push(a_Arg4);
|
||||
Push(a_Arg5);
|
||||
Push(a_Arg6);
|
||||
Push(a_Arg7);
|
||||
if (!CallFunction(3))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-3, a_Ret1);
|
||||
GetStackValue(-2, a_Ret2);
|
||||
GetStackValue(-1, a_Ret3);
|
||||
lua_pop(m_LuaState, 3);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Call any 8-param 3-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5,
|
||||
typename ArgT6, typename ArgT7, typename ArgT8,
|
||||
typename RetT1, typename RetT2, typename RetT3
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, ArgT8 a_Arg8, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2, RetT3 & a_Ret3)
|
||||
{
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
Push(a_Arg2);
|
||||
Push(a_Arg3);
|
||||
Push(a_Arg4);
|
||||
Push(a_Arg5);
|
||||
Push(a_Arg6);
|
||||
Push(a_Arg7);
|
||||
Push(a_Arg8);
|
||||
if (!CallFunction(3))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-3, a_Ret1);
|
||||
GetStackValue(-2, a_Ret2);
|
||||
GetStackValue(-1, a_Ret3);
|
||||
lua_pop(m_LuaState, 3);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Call any 9-param 5-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5,
|
||||
typename ArgT6, typename ArgT7, typename ArgT8, typename ArgT9,
|
||||
typename RetT1, typename RetT2, typename RetT3, typename RetT4, typename RetT5
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, ArgT8 a_Arg8, ArgT9 a_Arg9, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2, RetT3 & a_Ret3, RetT4 & a_Ret4, RetT5 & a_Ret5)
|
||||
{
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Arg1);
|
||||
Push(a_Arg2);
|
||||
Push(a_Arg3);
|
||||
Push(a_Arg4);
|
||||
Push(a_Arg5);
|
||||
Push(a_Arg6);
|
||||
Push(a_Arg7);
|
||||
Push(a_Arg8);
|
||||
Push(a_Arg9);
|
||||
if (!CallFunction(5))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-5, a_Ret1);
|
||||
GetStackValue(-4, a_Ret2);
|
||||
GetStackValue(-3, a_Ret3);
|
||||
GetStackValue(-2, a_Ret4);
|
||||
GetStackValue(-1, a_Ret5);
|
||||
lua_pop(m_LuaState, 5);
|
||||
return true;
|
||||
}
|
||||
// Include the cLuaState::Call() overload implementation that is generated by the gen_LuaState_Call.lua script:
|
||||
#include "LuaState_Call.inc"
|
||||
|
||||
|
||||
/** Returns true if the specified parameters on the stack are of the specified usertable type; also logs warning if not. Used for static functions */
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "ManualBindings.h"
|
||||
#undef TOLUA_TEMPLATE_BIND
|
||||
#include "tolua++/include/tolua++.h"
|
||||
|
||||
#include "polarssl/md5.h"
|
||||
#include "Plugin.h"
|
||||
#include "PluginLua.h"
|
||||
#include "PluginManager.h"
|
||||
@ -25,7 +25,6 @@
|
||||
#include "../BlockEntities/NoteEntity.h"
|
||||
#include "../BlockEntities/MobHeadEntity.h"
|
||||
#include "../BlockEntities/FlowerPotEntity.h"
|
||||
#include "md5/md5.h"
|
||||
#include "../LineBlockTracer.h"
|
||||
#include "../WorldStorage/SchematicFileSerializer.h"
|
||||
#include "../CompositeChat.h"
|
||||
@ -1765,6 +1764,7 @@ static int tolua_cWorld_ChunkStay(lua_State * tolua_S)
|
||||
if (!ChunkStay->AddChunks(2))
|
||||
{
|
||||
delete ChunkStay;
|
||||
ChunkStay = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2000,9 +2000,11 @@ static int tolua_cPlugin_Call(lua_State * tolua_S)
|
||||
|
||||
static int tolua_md5(lua_State* tolua_S)
|
||||
{
|
||||
std::string SourceString = tolua_tostring(tolua_S, 1, 0);
|
||||
std::string CryptedString = md5( SourceString );
|
||||
tolua_pushstring( tolua_S, CryptedString.c_str() );
|
||||
unsigned char Output[16];
|
||||
size_t len = 0;
|
||||
const unsigned char * SourceString = (const unsigned char *)lua_tolstring(tolua_S, 1, &len);
|
||||
md5(SourceString, len, Output);
|
||||
lua_pushlstring(tolua_S, (const char *)Output, ARRAYCOUNT(Output));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -73,6 +73,7 @@ public:
|
||||
virtual bool OnPlayerEating (cPlayer & a_Player) = 0;
|
||||
virtual bool OnPlayerFished (cPlayer & a_Player, const cItems & a_Reward) = 0;
|
||||
virtual bool OnPlayerFishing (cPlayer & a_Player, cItems & a_Reward) = 0;
|
||||
virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) = 0;
|
||||
virtual bool OnPlayerJoined (cPlayer & a_Player) = 0;
|
||||
virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) = 0;
|
||||
virtual bool OnPlayerMoved (cPlayer & a_Player) = 0;
|
||||
|
@ -735,6 +735,26 @@ bool cPluginLua::OnPlayerEating(cPlayer & a_Player)
|
||||
|
||||
|
||||
|
||||
bool cPluginLua::OnPlayerFoodLevelChange(cPlayer & a_Player, int a_NewFoodLevel)
|
||||
{
|
||||
cCSLock Lock(m_CriticalSection);
|
||||
bool res = false;
|
||||
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLAYER_FOOD_LEVEL_CHANGE];
|
||||
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
|
||||
{
|
||||
m_LuaState.Call((int)(**itr), &a_Player, a_NewFoodLevel, cLuaState::Return, res);
|
||||
if (res)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPluginLua::OnPlayerFished(cPlayer & a_Player, const cItems & a_Reward)
|
||||
{
|
||||
cCSLock Lock(m_CriticalSection);
|
||||
@ -1347,18 +1367,15 @@ bool cPluginLua::OnWeatherChanging(cWorld & a_World, eWeather & a_NewWeather)
|
||||
{
|
||||
cCSLock Lock(m_CriticalSection);
|
||||
bool res = false;
|
||||
int NewWeather = a_NewWeather;
|
||||
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_WEATHER_CHANGING];
|
||||
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
|
||||
{
|
||||
m_LuaState.Call((int)(**itr), &a_World, NewWeather, cLuaState::Return, res, NewWeather);
|
||||
m_LuaState.Call((int)(**itr), &a_World, a_NewWeather, cLuaState::Return, res, a_NewWeather);
|
||||
if (res)
|
||||
{
|
||||
a_NewWeather = (eWeather)NewWeather;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
a_NewWeather = (eWeather)NewWeather;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1592,6 +1609,7 @@ bool cPluginLua::AddHookRef(int a_HookType, int a_FnRefIdx)
|
||||
LOGWARNING("Plugin %s tried to add a hook %d with bad handler function.", GetName().c_str(), a_HookType);
|
||||
m_LuaState.LogStackTrace();
|
||||
delete Ref;
|
||||
Ref = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1734,7 +1752,7 @@ bool cPluginLua::CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPlayer
|
||||
ASSERT(a_FnRef != LUA_REFNIL);
|
||||
|
||||
cCSLock Lock(m_CriticalSection);
|
||||
bool res;
|
||||
bool res = false;
|
||||
m_LuaState.Call(a_FnRef, &a_Window, &a_Player, a_CanRefuse, cLuaState::Return, res);
|
||||
return res;
|
||||
}
|
||||
|
@ -96,6 +96,7 @@ public:
|
||||
virtual bool OnPlayerEating (cPlayer & a_Player) override;
|
||||
virtual bool OnPlayerFished (cPlayer & a_Player, const cItems & a_Reward) override;
|
||||
virtual bool OnPlayerFishing (cPlayer & a_Player, cItems & a_Reward) override;
|
||||
virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) override;
|
||||
virtual bool OnPlayerJoined (cPlayer & a_Player) override;
|
||||
virtual bool OnPlayerMoved (cPlayer & a_Player) override;
|
||||
virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) override;
|
||||
|
@ -257,18 +257,44 @@ bool cPluginManager::CallHookBlockToPickups(
|
||||
|
||||
bool cPluginManager::CallHookChat(cPlayer * a_Player, AString & a_Message)
|
||||
{
|
||||
bool WasCommandForbidden = false;
|
||||
if (HandleCommand(a_Player, a_Message, true, WasCommandForbidden)) // We use HandleCommand as opposed to ExecuteCommand to accomodate the need to the WasCommandForbidden bool
|
||||
// Check if the message contains a command, execute it:
|
||||
switch (HandleCommand(a_Player, a_Message, true))
|
||||
{
|
||||
return true; // Chat message was handled as command
|
||||
}
|
||||
else if (WasCommandForbidden) // Couldn't be handled as command, was it because of insufficient permissions?
|
||||
case crExecuted:
|
||||
{
|
||||
return true; // Yes - message was sent in HandleCommand, abort
|
||||
// The command has executed successfully
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if it was a standard command (starts with a slash)
|
||||
// If it was, we know that it was completely unrecognised (WasCommandForbidden == false)
|
||||
case crBlocked:
|
||||
{
|
||||
// The command was blocked by a plugin using HOOK_EXECUTE_COMMAND
|
||||
// The plugin has most likely sent a message to the player already
|
||||
return true;
|
||||
}
|
||||
|
||||
case crError:
|
||||
{
|
||||
// An error in the plugin has prevented the command from executing. Report the error to the player:
|
||||
a_Player->SendMessageFailure(Printf("Something went wrong while executing command \"%s\"", a_Message.c_str()));
|
||||
return true;
|
||||
}
|
||||
|
||||
case crNoPermission:
|
||||
{
|
||||
// The player is not allowed to execute this command
|
||||
a_Player->SendMessageFailure(Printf("Forbidden command; insufficient privileges: \"%s\"", a_Message.c_str()));
|
||||
return true;
|
||||
}
|
||||
|
||||
case crUnknownCommand:
|
||||
{
|
||||
// This was not a known command, keep processing as a message
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the message is a command (starts with a slash). If it is, we know that it wasn't recognised:
|
||||
if (!a_Message.empty() && (a_Message[0] == '/'))
|
||||
{
|
||||
AStringVector Split(StringSplit(a_Message, " "));
|
||||
@ -716,6 +742,25 @@ bool cPluginManager::CallHookPlayerEating(cPlayer & a_Player)
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::CallHookPlayerFoodLevelChange(cPlayer & a_Player, int a_NewFoodLevel)
|
||||
{
|
||||
FIND_HOOK(HOOK_PLAYER_FOOD_LEVEL_CHANGE);
|
||||
VERIFY_HOOK;
|
||||
|
||||
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->OnPlayerFoodLevelChange(a_Player, a_NewFoodLevel))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::CallHookPlayerFished(cPlayer & a_Player, const cItems a_Reward)
|
||||
{
|
||||
FIND_HOOK(HOOK_PLAYER_FISHED);
|
||||
@ -1339,28 +1384,28 @@ bool cPluginManager::CallHookWorldTick(cWorld & a_World, float a_Dt, int a_LastT
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions, bool & a_WasCommandForbidden)
|
||||
cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions)
|
||||
{
|
||||
ASSERT(a_Player != NULL);
|
||||
|
||||
AStringVector Split(StringSplit(a_Command, " "));
|
||||
if (Split.empty())
|
||||
{
|
||||
return false;
|
||||
return crUnknownCommand;
|
||||
}
|
||||
|
||||
CommandMap::iterator cmd = m_Commands.find(Split[0]);
|
||||
if (cmd == m_Commands.end())
|
||||
{
|
||||
// Command not found
|
||||
return false;
|
||||
return crUnknownCommand;
|
||||
}
|
||||
|
||||
// Ask plugins first if a command is okay to execute the command:
|
||||
if (CallHookExecuteCommand(a_Player, Split))
|
||||
{
|
||||
LOGINFO("Player %s tried executing command \"%s\" that was stopped by the HOOK_EXECUTE_COMMAND hook", a_Player->GetName().c_str(), Split[0].c_str());
|
||||
return false;
|
||||
return crBlocked;
|
||||
}
|
||||
|
||||
if (
|
||||
@ -1369,15 +1414,18 @@ bool cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command
|
||||
!a_Player->HasPermission(cmd->second.m_Permission)
|
||||
)
|
||||
{
|
||||
a_Player->SendMessageFailure(Printf("Forbidden command; insufficient privileges: \"%s\"", Split[0].c_str()));
|
||||
LOGINFO("Player %s tried to execute forbidden command: \"%s\"", a_Player->GetName().c_str(), Split[0].c_str());
|
||||
a_WasCommandForbidden = true;
|
||||
return false;
|
||||
return crNoPermission;
|
||||
}
|
||||
|
||||
ASSERT(cmd->second.m_Plugin != NULL);
|
||||
|
||||
return cmd->second.m_Plugin->HandleCommand(Split, a_Player);
|
||||
if (!cmd->second.m_Plugin->HandleCommand(Split, a_Player))
|
||||
{
|
||||
return crError;
|
||||
}
|
||||
|
||||
return crExecuted;
|
||||
}
|
||||
|
||||
|
||||
@ -1488,6 +1536,7 @@ void cPluginManager::RemovePlugin(cPlugin * a_Plugin)
|
||||
a_Plugin->OnDisable();
|
||||
}
|
||||
delete a_Plugin;
|
||||
a_Plugin = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -1574,7 +1623,7 @@ AString cPluginManager::GetCommandPermission(const AString & a_Command)
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::ExecuteCommand(cPlayer * a_Player, const AString & a_Command)
|
||||
cPluginManager::CommandResult cPluginManager::ExecuteCommand(cPlayer * a_Player, const AString & a_Command)
|
||||
{
|
||||
return HandleCommand(a_Player, a_Command, true);
|
||||
}
|
||||
@ -1583,7 +1632,7 @@ bool cPluginManager::ExecuteCommand(cPlayer * a_Player, const AString & a_Comman
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command)
|
||||
cPluginManager::CommandResult cPluginManager::ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command)
|
||||
{
|
||||
return HandleCommand(a_Player, a_Command, false);
|
||||
}
|
||||
|
@ -59,6 +59,15 @@ public: // tolua_export
|
||||
virtual void Tick(float a_Dt);
|
||||
|
||||
// tolua_begin
|
||||
enum CommandResult
|
||||
{
|
||||
crExecuted,
|
||||
crUnknownCommand,
|
||||
crError,
|
||||
crBlocked,
|
||||
crNoPermission,
|
||||
} ;
|
||||
|
||||
enum PluginHook
|
||||
{
|
||||
HOOK_BLOCK_SPREAD,
|
||||
@ -88,6 +97,7 @@ public: // tolua_export
|
||||
HOOK_PLAYER_EATING,
|
||||
HOOK_PLAYER_FISHED,
|
||||
HOOK_PLAYER_FISHING,
|
||||
HOOK_PLAYER_FOOD_LEVEL_CHANGE,
|
||||
HOOK_PLAYER_JOINED,
|
||||
HOOK_PLAYER_LEFT_CLICK,
|
||||
HOOK_PLAYER_MOVING,
|
||||
@ -190,6 +200,7 @@ public: // tolua_export
|
||||
bool CallHookPlayerEating (cPlayer & a_Player);
|
||||
bool CallHookPlayerFished (cPlayer & a_Player, const cItems a_Reward);
|
||||
bool CallHookPlayerFishing (cPlayer & a_Player, cItems a_Reward);
|
||||
bool CallHookPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel);
|
||||
bool CallHookPlayerJoined (cPlayer & a_Player);
|
||||
bool CallHookPlayerMoving (cPlayer & a_Player);
|
||||
bool CallHookPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status);
|
||||
@ -246,11 +257,11 @@ public: // tolua_export
|
||||
/** Returns the permission needed for the specified command; empty string if command not found */
|
||||
AString GetCommandPermission(const AString & a_Command); // tolua_export
|
||||
|
||||
/** Executes the command, as if it was requested by a_Player. Checks permissions first. Returns true if executed. */
|
||||
bool ExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export
|
||||
/** Executes the command, as if it was requested by a_Player. Checks permissions first. Returns crExecuted if executed. */
|
||||
CommandResult ExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export
|
||||
|
||||
/** Executes the command, as if it was requested by a_Player. Permisssions are not checked. Returns true if executed (false if not found) */
|
||||
bool ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export
|
||||
/** Executes the command, as if it was requested by a_Player. Permisssions are not checked. Returns crExecuted if executed. */
|
||||
CommandResult ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export
|
||||
|
||||
/** Removes all console command bindings that the specified plugin has made */
|
||||
void RemovePluginConsoleCommands(cPlugin * a_Plugin);
|
||||
@ -323,13 +334,8 @@ private:
|
||||
/** Adds the plugin into the internal list of plugins and initializes it. If initialization fails, the plugin is removed again. */
|
||||
bool AddPlugin(cPlugin * a_Plugin);
|
||||
|
||||
/** Tries to match a_Command to the internal table of commands, if a match is found, the corresponding plugin is called. Returns true if the command is handled. */
|
||||
bool HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions, bool & a_WasCommandForbidden);
|
||||
bool HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions)
|
||||
{
|
||||
bool DummyBoolean = false;
|
||||
return HandleCommand(a_Player, a_Command, a_ShouldCheckPermissions, DummyBoolean);
|
||||
}
|
||||
/** Tries to match a_Command to the internal table of commands, if a match is found, the corresponding plugin is called. Returns crExecuted if the command is executed. */
|
||||
cPluginManager::CommandResult HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions);
|
||||
} ; // tolua_export
|
||||
|
||||
|
||||
|
196
src/Bindings/gen_LuaState_Call.lua
Normal file
196
src/Bindings/gen_LuaState_Call.lua
Normal file
@ -0,0 +1,196 @@
|
||||
|
||||
-- gen_LuaState_Call.lua
|
||||
|
||||
-- Generates the cLuaState::Call() function templates that are included from LuaState.h
|
||||
|
||||
--[[
|
||||
The cLuaState::Call() family of functions provides a template-based system for calling any Lua function
|
||||
either by name or by reference with almost any number of parameters and return values. This is done by
|
||||
providing a number of overloads of the same name with variable number of template-type parameters. To
|
||||
separate the arguments from the return values, a special type of cLuaState::cRet is used.
|
||||
--]]
|
||||
|
||||
|
||||
|
||||
|
||||
print("Generating LuaState_Call.inc...")
|
||||
|
||||
|
||||
|
||||
|
||||
-- List of combinations (# params, # returns) to generate:
|
||||
local Combinations =
|
||||
{
|
||||
-- no return values:
|
||||
{0, 0},
|
||||
{1, 0},
|
||||
{2, 0},
|
||||
{3, 0},
|
||||
{4, 0},
|
||||
|
||||
-- 1 return value:
|
||||
{0, 1},
|
||||
{1, 1},
|
||||
{2, 1},
|
||||
{3, 1},
|
||||
{4, 1},
|
||||
{5, 1},
|
||||
{6, 1},
|
||||
{7, 1},
|
||||
{8, 1},
|
||||
{9, 1},
|
||||
{10, 1},
|
||||
|
||||
-- 2 return values:
|
||||
{0, 2},
|
||||
{1, 2},
|
||||
{2, 2},
|
||||
{3, 2},
|
||||
{4, 2},
|
||||
{5, 2},
|
||||
{6, 2},
|
||||
{7, 2},
|
||||
{8, 2},
|
||||
{9, 2},
|
||||
|
||||
-- Special combinations:
|
||||
{7, 3},
|
||||
{8, 3},
|
||||
{9, 5},
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
--- Writes a single overloaded function definition for the specified number of params and returns into f
|
||||
--[[
|
||||
The format for the generated function is this:
|
||||
/** Call the specified 3-param 2-return Lua function:
|
||||
Returns true if call succeeded, false if there was an error. */
|
||||
template <typename FnT, typename ParamT1, typename ParamT2, typename ParamT3, typename RetT1, typename RetT2>
|
||||
bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2)
|
||||
{
|
||||
UNUSED(a_RetMark);
|
||||
if (!PushFunction(a_Function))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Push(a_Param1);
|
||||
Push(a_Param2);
|
||||
Push(a_Param3);
|
||||
if (!CallFunction(2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GetStackValue(-2, a_Ret1);
|
||||
GetStackValue(-1, a_Ret2);
|
||||
lua_pop(m_LuaState, 2);
|
||||
return true;
|
||||
}
|
||||
Note especially the negative numbers in GetStackValue() calls.
|
||||
--]]
|
||||
local function WriteOverload(f, a_NumParams, a_NumReturns)
|
||||
-- Write the function doxy-comments:
|
||||
f:write("/** Call the specified ", a_NumParams, "-param ", a_NumReturns, "-return Lua function:\n")
|
||||
f:write("Returns true if call succeeded, false if there was an error. */\n")
|
||||
|
||||
-- Write the template <...> line:
|
||||
f:write("template <typename FnT")
|
||||
for i = 1, a_NumParams do
|
||||
f:write(", typename ParamT", i)
|
||||
end
|
||||
if (a_NumReturns > 0) then
|
||||
for i = 1, a_NumReturns do
|
||||
f:write(", typename RetT", i)
|
||||
end
|
||||
end
|
||||
f:write(">\n")
|
||||
|
||||
-- Write the function signature:
|
||||
f:write("bool Call(")
|
||||
f:write("FnT a_Function")
|
||||
for i = 1, a_NumParams do
|
||||
f:write(", ParamT", i, " a_Param", i)
|
||||
end
|
||||
if (a_NumReturns > 0) then
|
||||
f:write(", const cLuaState::cRet & a_RetMark")
|
||||
for i = 1, a_NumReturns do
|
||||
f:write(", RetT", i, " & a_Ret", i)
|
||||
end
|
||||
end
|
||||
f:write(")\n")
|
||||
|
||||
-- Common code:
|
||||
f:write("{\n")
|
||||
if (a_NumReturns > 0) then
|
||||
f:write("\tUNUSED(a_RetMark);\n")
|
||||
end
|
||||
f:write("\tif (!PushFunction(a_Function))\n")
|
||||
f:write("\t{\n")
|
||||
f:write("\t\treturn false;\n")
|
||||
f:write("\t}\n")
|
||||
|
||||
-- Push the params:
|
||||
for i = 1, a_NumParams do
|
||||
f:write("\tPush(a_Param", i, ");\n")
|
||||
end
|
||||
|
||||
-- Call the function:
|
||||
f:write("\tif (!CallFunction(", a_NumReturns, "))\n")
|
||||
f:write("\t{\n")
|
||||
f:write("\t\treturn false;\n")
|
||||
f:write("\t}\n")
|
||||
|
||||
-- Get the return values:
|
||||
for i = 1, a_NumReturns do
|
||||
f:write("\tGetStackValue(", -1 - a_NumReturns + i, ", a_Ret", i, ");\n")
|
||||
end
|
||||
|
||||
-- Pop the returns off the stack, if needed:
|
||||
if (a_NumReturns > 0) then
|
||||
f:write("\tlua_pop(m_LuaState, ", a_NumReturns, ");\n")
|
||||
end
|
||||
|
||||
-- Everything ok:
|
||||
f:write("\treturn true;\n")
|
||||
f:write("}\n")
|
||||
|
||||
-- Separate from the next function:
|
||||
f:write("\n\n\n\n\n")
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
local f = assert(io.open("LuaState_Call.inc", "w"))
|
||||
|
||||
-- Write file header:
|
||||
f:write([[
|
||||
// LuaState_Call.inc
|
||||
|
||||
// This file is auto-generated by gen_LuaState_Call.lua
|
||||
// Make changes to the generator instead of to this file!
|
||||
|
||||
// This file contains the various overloads for the cLuaState::Call() function
|
||||
// Each overload handles a different number of parameters / return values
|
||||
]])
|
||||
f:write("\n\n\n\n\n")
|
||||
|
||||
-- Write out a template function for each overload:
|
||||
for _, combination in ipairs(Combinations) do
|
||||
WriteOverload(f, combination[1], combination[2])
|
||||
end
|
||||
|
||||
-- Close the generated file
|
||||
f:close()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
print("LuaState_Call.inc generated")
|
||||
|
||||
|
||||
|
||||
|
@ -3,6 +3,20 @@ local disable_virtual_hooks = true
|
||||
local enable_pure_virtual = true
|
||||
local default_private_access = false
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- Code generators used by the build
|
||||
-- Note that these are not exactly needed for the bindings, but rather we
|
||||
-- misuse tolua's Lua engine to process files for us
|
||||
dofile("gen_LuaState_Call.lua")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
local access = {public = 0, protected = 1, private = 2}
|
||||
|
||||
function preparse_hook(p)
|
||||
|
@ -1013,8 +1013,8 @@ void cBlockArea::RotateCCW(void)
|
||||
} // for x
|
||||
std::swap(m_BlockTypes, NewTypes);
|
||||
std::swap(m_BlockMetas, NewMetas);
|
||||
delete[] NewTypes;
|
||||
delete[] NewMetas;
|
||||
delete[] NewTypes; NewTypes = NULL;
|
||||
delete[] NewMetas; NewMetas = NULL;
|
||||
|
||||
std::swap(m_Size.x, m_Size.z);
|
||||
}
|
||||
@ -1058,8 +1058,8 @@ void cBlockArea::RotateCW(void)
|
||||
} // for x
|
||||
std::swap(m_BlockTypes, NewTypes);
|
||||
std::swap(m_BlockMetas, NewMetas);
|
||||
delete[] NewTypes;
|
||||
delete[] NewMetas;
|
||||
delete[] NewTypes; NewTypes = NULL;
|
||||
delete[] NewMetas; NewMetas = NULL;
|
||||
|
||||
std::swap(m_Size.x, m_Size.z);
|
||||
}
|
||||
@ -1206,7 +1206,7 @@ void cBlockArea::RotateCCWNoMeta(void)
|
||||
} // for z
|
||||
} // for x
|
||||
std::swap(m_BlockTypes, NewTypes);
|
||||
delete[] NewTypes;
|
||||
delete[] NewTypes; NewTypes = NULL;
|
||||
}
|
||||
if (HasBlockMetas())
|
||||
{
|
||||
@ -1224,7 +1224,7 @@ void cBlockArea::RotateCCWNoMeta(void)
|
||||
} // for z
|
||||
} // for x
|
||||
std::swap(m_BlockMetas, NewMetas);
|
||||
delete[] NewMetas;
|
||||
delete[] NewMetas; NewMetas = NULL;
|
||||
}
|
||||
std::swap(m_Size.x, m_Size.z);
|
||||
}
|
||||
@ -1251,7 +1251,7 @@ void cBlockArea::RotateCWNoMeta(void)
|
||||
} // for x
|
||||
} // for z
|
||||
std::swap(m_BlockTypes, NewTypes);
|
||||
delete[] NewTypes;
|
||||
delete[] NewTypes; NewTypes = NULL;
|
||||
}
|
||||
if (HasBlockMetas())
|
||||
{
|
||||
@ -1269,7 +1269,7 @@ void cBlockArea::RotateCWNoMeta(void)
|
||||
} // for x
|
||||
} // for z
|
||||
std::swap(m_BlockMetas, NewMetas);
|
||||
delete[] NewMetas;
|
||||
delete[] NewMetas; NewMetas = NULL;
|
||||
}
|
||||
std::swap(m_Size.x, m_Size.z);
|
||||
}
|
||||
@ -1658,6 +1658,7 @@ bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes)
|
||||
if (m_BlockMetas == NULL)
|
||||
{
|
||||
delete[] m_BlockTypes;
|
||||
m_BlockTypes = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1667,7 +1668,9 @@ bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes)
|
||||
if (m_BlockLight == NULL)
|
||||
{
|
||||
delete[] m_BlockMetas;
|
||||
m_BlockMetas = NULL;
|
||||
delete[] m_BlockTypes;
|
||||
m_BlockTypes = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1677,8 +1680,11 @@ bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes)
|
||||
if (m_BlockSkyLight == NULL)
|
||||
{
|
||||
delete[] m_BlockLight;
|
||||
m_BlockLight = NULL;
|
||||
delete[] m_BlockMetas;
|
||||
m_BlockMetas = NULL;
|
||||
delete[] m_BlockTypes;
|
||||
m_BlockTypes = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -122,6 +122,13 @@ void cChestEntity::UsedBy(cPlayer * a_Player)
|
||||
|
||||
void cChestEntity::OpenNewWindow(void)
|
||||
{
|
||||
// TODO: cats are an obstruction
|
||||
if ((GetPosY() + 1 < cChunkDef::Height) && cBlockInfo::IsSolid(GetWorld()->GetBlock(GetPosX(), GetPosY() + 1, GetPosZ())))
|
||||
{
|
||||
// Obstruction, don't open
|
||||
return;
|
||||
}
|
||||
|
||||
// Callback for opening together with neighbor chest:
|
||||
class cOpenDouble :
|
||||
public cChestCallback
|
||||
@ -135,6 +142,12 @@ void cChestEntity::OpenNewWindow(void)
|
||||
|
||||
virtual bool Item(cChestEntity * a_Chest) override
|
||||
{
|
||||
if ((a_Chest->GetPosY() + 1 < cChunkDef::Height) && cBlockInfo::IsSolid(a_Chest->GetWorld()->GetBlock(a_Chest->GetPosX(), a_Chest->GetPosY() + 1, a_Chest->GetPosZ())))
|
||||
{
|
||||
// Obstruction, don't open
|
||||
return false;
|
||||
}
|
||||
|
||||
// The primary chest should eb the one with lesser X or Z coord:
|
||||
cChestEntity * Primary = a_Chest;
|
||||
cChestEntity * Secondary = m_ThisChest;
|
||||
|
@ -12,9 +12,8 @@
|
||||
|
||||
|
||||
cEnderChestEntity::cEnderChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
|
||||
super(E_BLOCK_ENDER_CHEST, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World)
|
||||
super(E_BLOCK_ENDER_CHEST, a_BlockX, a_BlockY, a_BlockZ, a_World)
|
||||
{
|
||||
cBlockEntityWindowOwner::SetBlockEntity(this);
|
||||
}
|
||||
|
||||
|
||||
@ -34,60 +33,6 @@ cEnderChestEntity::~cEnderChestEntity()
|
||||
|
||||
|
||||
|
||||
bool cEnderChestEntity::LoadFromJson(const Json::Value & a_Value)
|
||||
{
|
||||
m_PosX = a_Value.get("x", 0).asInt();
|
||||
m_PosY = a_Value.get("y", 0).asInt();
|
||||
m_PosZ = a_Value.get("z", 0).asInt();
|
||||
|
||||
Json::Value AllSlots = a_Value.get("Slots", 0);
|
||||
int SlotIdx = 0;
|
||||
for (Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr)
|
||||
{
|
||||
cItem Item;
|
||||
Item.FromJson(*itr);
|
||||
SetSlot(SlotIdx, Item);
|
||||
SlotIdx++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cEnderChestEntity::SaveToJson(Json::Value & a_Value)
|
||||
{
|
||||
a_Value["x"] = m_PosX;
|
||||
a_Value["y"] = m_PosY;
|
||||
a_Value["z"] = m_PosZ;
|
||||
|
||||
Json::Value AllSlots;
|
||||
for (int i = m_Contents.GetNumSlots() - 1; i >= 0; i--)
|
||||
{
|
||||
Json::Value Slot;
|
||||
m_Contents.GetSlot(i).GetJson(Slot);
|
||||
AllSlots.append(Slot);
|
||||
}
|
||||
a_Value["Slots"] = AllSlots;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cEnderChestEntity::SendTo(cClientHandle & a_Client)
|
||||
{
|
||||
// The chest entity doesn't need anything sent to the client when it's created / gets in the viewdistance
|
||||
// All the actual handling is in the cWindow UI code that gets called when the chest is rclked
|
||||
|
||||
UNUSED(a_Client);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cEnderChestEntity::UsedBy(cPlayer * a_Player)
|
||||
{
|
||||
// If the window is not created, open it anew:
|
||||
@ -106,21 +51,13 @@ void cEnderChestEntity::UsedBy(cPlayer * a_Player)
|
||||
a_Player->OpenWindow(Window);
|
||||
}
|
||||
}
|
||||
|
||||
// This is rather a hack
|
||||
// Instead of marking the chunk as dirty upon chest contents change, we mark it dirty now
|
||||
// We cannot properly detect contents change, but such a change doesn't happen without a player opening the chest first.
|
||||
// The few false positives aren't much to worry about
|
||||
int ChunkX, ChunkZ;
|
||||
cChunkDef::BlockToChunk(m_PosX, m_PosZ, ChunkX, ChunkZ);
|
||||
m_World->MarkChunkDirty(ChunkX, ChunkZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cEnderChestEntity::OpenNewWindow(void)
|
||||
void cEnderChestEntity::OpenNewWindow()
|
||||
{
|
||||
OpenWindow(new cEnderChestWindow(this));
|
||||
}
|
||||
@ -128,3 +65,33 @@ void cEnderChestEntity::OpenNewWindow(void)
|
||||
|
||||
|
||||
|
||||
|
||||
void cEnderChestEntity::LoadFromJson(const Json::Value & a_Value, cItemGrid & a_Grid)
|
||||
{
|
||||
int SlotIdx = 0;
|
||||
for (Json::Value::iterator itr = a_Value.begin(); itr != a_Value.end(); ++itr)
|
||||
{
|
||||
cItem Item;
|
||||
Item.FromJson(*itr);
|
||||
a_Grid.SetSlot(SlotIdx, Item);
|
||||
SlotIdx++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cEnderChestEntity::SaveToJson(Json::Value & a_Value, const cItemGrid & a_Grid)
|
||||
{
|
||||
for (int i = 0; i < a_Grid.GetNumSlots(); i++)
|
||||
{
|
||||
Json::Value Slot;
|
||||
a_Grid.GetSlot(i).GetJson(Slot);
|
||||
a_Value.append(Slot);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,20 +1,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BlockEntityWithItems.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace Json
|
||||
{
|
||||
class Value;
|
||||
};
|
||||
|
||||
class cClientHandle;
|
||||
class cServer;
|
||||
class cNBTData;
|
||||
#include "BlockEntity.h"
|
||||
#include "UI/WindowOwner.h"
|
||||
#include "json/json.h"
|
||||
|
||||
|
||||
|
||||
@ -22,33 +11,28 @@ class cNBTData;
|
||||
|
||||
// tolua_begin
|
||||
class cEnderChestEntity :
|
||||
public cBlockEntityWithItems
|
||||
public cBlockEntity,
|
||||
public cBlockEntityWindowOwner
|
||||
{
|
||||
typedef cBlockEntityWithItems super;
|
||||
typedef cBlockEntity super;
|
||||
|
||||
public:
|
||||
enum {
|
||||
ContentsHeight = 3,
|
||||
ContentsWidth = 9,
|
||||
} ;
|
||||
|
||||
// tolua_end
|
||||
|
||||
/// Constructor used for normal operation
|
||||
cEnderChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
|
||||
|
||||
virtual ~cEnderChestEntity();
|
||||
|
||||
static const char * GetClassStatic(void) { return "cEnderChestEntity"; }
|
||||
|
||||
bool LoadFromJson(const Json::Value & a_Value);
|
||||
|
||||
// cBlockEntity overrides:
|
||||
virtual void SaveToJson(Json::Value & a_Value) override;
|
||||
virtual void SendTo(cClientHandle & a_Client) override;
|
||||
virtual void UsedBy(cPlayer * a_Player) override;
|
||||
virtual void SaveToJson(Json::Value & a_Value) override { UNUSED(a_Value); }
|
||||
virtual void SendTo(cClientHandle & a_Client) override { UNUSED(a_Client); }
|
||||
|
||||
/// Opens a new chest window for this chest. Scans for neighbors to open a double chest window, if appropriate.
|
||||
static void LoadFromJson(const Json::Value & a_Value, cItemGrid & a_Grid);
|
||||
static void SaveToJson(Json::Value & a_Value, const cItemGrid & a_Grid);
|
||||
|
||||
/** Opens a new enderchest window for this enderchest */
|
||||
void OpenNewWindow(void);
|
||||
} ; // tolua_export
|
||||
|
||||
|
@ -294,23 +294,24 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick)
|
||||
return false;
|
||||
}
|
||||
|
||||
int bx, by, bz;
|
||||
// Get the coords of the block where to output items:
|
||||
int OutX, OutY, OutZ;
|
||||
NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ);
|
||||
if (!GetOutputBlockPos(Meta, bx, by, bz))
|
||||
if (!GetOutputBlockPos(Meta, OutX, OutY, OutZ))
|
||||
{
|
||||
// Not attached to another container
|
||||
return false;
|
||||
}
|
||||
if (by < 0)
|
||||
if (OutY < 0)
|
||||
{
|
||||
// Cannot output below the zero-th block level
|
||||
return false;
|
||||
}
|
||||
|
||||
// Convert coords to relative:
|
||||
int rx = bx - a_Chunk.GetPosX() * cChunkDef::Width;
|
||||
int rz = bz - a_Chunk.GetPosZ() * cChunkDef::Width;
|
||||
cChunk * DestChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(rx, rz);
|
||||
int OutRelX = OutX - a_Chunk.GetPosX() * cChunkDef::Width;
|
||||
int OutRelZ = OutZ - a_Chunk.GetPosZ() * cChunkDef::Width;
|
||||
cChunk * DestChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(OutRelX, OutRelZ);
|
||||
if (DestChunk == NULL)
|
||||
{
|
||||
// The destination chunk has been unloaded, don't tick
|
||||
@ -319,26 +320,32 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick)
|
||||
|
||||
// Call proper moving function, based on the blocktype present at the coords:
|
||||
bool res = false;
|
||||
switch (DestChunk->GetBlock(rx, by, rz))
|
||||
switch (DestChunk->GetBlock(OutRelX, OutY, OutRelZ))
|
||||
{
|
||||
case E_BLOCK_CHEST:
|
||||
{
|
||||
// Chests have special handling because of double-chests
|
||||
res = MoveItemsToChest(*DestChunk, bx, by, bz);
|
||||
res = MoveItemsToChest(*DestChunk, OutX, OutY, OutZ);
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_LIT_FURNACE:
|
||||
case E_BLOCK_FURNACE:
|
||||
{
|
||||
// Furnaces have special handling because of the direction-to-slot relation
|
||||
res = MoveItemsToFurnace(*DestChunk, bx, by, bz, Meta);
|
||||
res = MoveItemsToFurnace(*DestChunk, OutX, OutY, OutZ, Meta);
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_DISPENSER:
|
||||
case E_BLOCK_DROPPER:
|
||||
case E_BLOCK_HOPPER:
|
||||
{
|
||||
res = MoveItemsToGrid(*(cBlockEntityWithItems *)DestChunk->GetBlockEntity(bx, by, bz));
|
||||
cBlockEntityWithItems * BlockEntity = (cBlockEntityWithItems *)DestChunk->GetBlockEntity(OutX, OutY, OutZ);
|
||||
if (BlockEntity == NULL)
|
||||
{
|
||||
LOGWARNING("%s: A block entity was not found where expected at {%d, %d, %d}", __FUNCTION__, OutX, OutY, OutZ);
|
||||
return false;
|
||||
}
|
||||
res = MoveItemsToGrid(*BlockEntity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -359,7 +366,13 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick)
|
||||
/// Moves items from a chest (dblchest) above the hopper into this hopper. Returns true if contents have changed.
|
||||
bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
|
||||
{
|
||||
if (MoveItemsFromGrid(*(cChestEntity *)a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ)))
|
||||
cChestEntity * Chest = (cChestEntity *)a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ);
|
||||
if (Chest == NULL)
|
||||
{
|
||||
LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, m_PosX, m_PosY + 1, m_PosZ);
|
||||
return false;
|
||||
}
|
||||
if (MoveItemsFromGrid(*Chest))
|
||||
{
|
||||
// Moved the item from the chest directly above the hopper
|
||||
return true;
|
||||
@ -389,10 +402,18 @@ bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (MoveItemsFromGrid(*(cChestEntity *)Neighbor->GetBlockEntity(x, m_PosY, z)))
|
||||
Chest = (cChestEntity *)Neighbor->GetBlockEntity(m_PosX + Coords[i].x, m_PosY + 1, m_PosZ + Coords[i].z);
|
||||
if (Chest == NULL)
|
||||
{
|
||||
LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, m_PosX + Coords[i].x, m_PosY + 1, m_PosZ + Coords[i].z);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MoveItemsFromGrid(*Chest))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -408,7 +429,11 @@ bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
|
||||
bool cHopperEntity::MoveItemsFromFurnace(cChunk & a_Chunk)
|
||||
{
|
||||
cFurnaceEntity * Furnace = (cFurnaceEntity *)a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ);
|
||||
ASSERT(Furnace != NULL);
|
||||
if (Furnace == NULL)
|
||||
{
|
||||
LOGWARNING("%s: A furnace entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, m_PosX, m_PosY + 1, m_PosZ);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try move from the output slot:
|
||||
if (MoveItemsFromSlot(*Furnace, cFurnaceEntity::fsOutput, true))
|
||||
@ -517,7 +542,13 @@ bool cHopperEntity::MoveItemsFromSlot(cBlockEntityWithItems & a_Entity, int a_Sl
|
||||
bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Try the chest directly connected to the hopper:
|
||||
if (MoveItemsToGrid(*(cChestEntity *)a_Chunk.GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ)))
|
||||
cChestEntity * Chest = (cChestEntity *)a_Chunk.GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ);
|
||||
if (Chest == NULL)
|
||||
{
|
||||
LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, a_BlockX, a_BlockY, a_BlockZ);
|
||||
return false;
|
||||
}
|
||||
if (MoveItemsToGrid(*Chest))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -534,19 +565,27 @@ bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_Block
|
||||
{0, 1},
|
||||
{0, -1},
|
||||
} ;
|
||||
int RelX = a_BlockX - a_Chunk.GetPosX() * cChunkDef::Width;
|
||||
int RelZ = a_BlockZ - a_Chunk.GetPosZ() * cChunkDef::Width;
|
||||
for (size_t i = 0; i < ARRAYCOUNT(Coords); i++)
|
||||
{
|
||||
int x = m_RelX + Coords[i].x;
|
||||
int z = m_RelZ + Coords[i].z;
|
||||
int x = RelX + Coords[i].x;
|
||||
int z = RelZ + Coords[i].z;
|
||||
cChunk * Neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(x, z);
|
||||
if (
|
||||
(Neighbor == NULL) ||
|
||||
(Neighbor->GetBlock(x, m_PosY + 1, z) != E_BLOCK_CHEST)
|
||||
(Neighbor->GetBlock(x, a_BlockY, z) != E_BLOCK_CHEST)
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (MoveItemsToGrid(*(cChestEntity *)Neighbor->GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ)))
|
||||
Chest = (cChestEntity *)Neighbor->GetBlockEntity(a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z);
|
||||
if (Chest == NULL)
|
||||
{
|
||||
LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d} (%d, %d)", __FUNCTION__, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z, x, z);
|
||||
continue;
|
||||
}
|
||||
if (MoveItemsToGrid(*Chest))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -70,6 +70,8 @@ void cMobHeadEntity::SetOwner(const AString & a_Owner)
|
||||
|
||||
void cMobHeadEntity::SendTo(cClientHandle & a_Client)
|
||||
{
|
||||
cWorld * World = a_Client.GetPlayer()->GetWorld();
|
||||
a_Client.SendBlockChange(m_PosX, m_PosY, m_PosZ, m_BlockType, World->GetBlockMeta(m_PosX, m_PosY, m_PosZ));
|
||||
a_Client.SendUpdateBlockEntity(*this);
|
||||
}
|
||||
|
||||
|
@ -8,12 +8,6 @@
|
||||
|
||||
|
||||
|
||||
cBlockInfo cBlockInfo::ms_Info[256];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBlockInfo::cBlockInfo()
|
||||
: m_LightValue(0x00)
|
||||
, m_SpreadLightFalloff(0x0f)
|
||||
@ -34,14 +28,25 @@ cBlockInfo::cBlockInfo()
|
||||
cBlockInfo::~cBlockInfo()
|
||||
{
|
||||
delete m_Handler;
|
||||
m_Handler = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** This accessor makes sure that the cBlockInfo structures are properly initialized exactly once.
|
||||
It does so by using the C++ singleton approximation - storing the actual singleton as the function's static variable.
|
||||
It works only if it is called for the first time before the app spawns other threads. */
|
||||
cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type)
|
||||
{
|
||||
static cBlockInfo ms_Info[256];
|
||||
static bool IsBlockInfoInitialized = false;
|
||||
if (!IsBlockInfoInitialized)
|
||||
{
|
||||
cBlockInfo::Initialize(ms_Info);
|
||||
IsBlockInfoInitialized = true;
|
||||
}
|
||||
return ms_Info[a_Type];
|
||||
}
|
||||
|
||||
@ -49,416 +54,409 @@ cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type)
|
||||
|
||||
|
||||
|
||||
void cBlockInfo::Initialize(void)
|
||||
void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
|
||||
{
|
||||
for (unsigned int i = 0; i < 256; ++i)
|
||||
{
|
||||
if (ms_Info[i].m_Handler == NULL)
|
||||
if (a_Info[i].m_Handler == NULL)
|
||||
{
|
||||
ms_Info[i].m_Handler = cBlockHandler::CreateBlockHandler((BLOCKTYPE) i);
|
||||
a_Info[i].m_Handler = cBlockHandler::CreateBlockHandler((BLOCKTYPE) i);
|
||||
}
|
||||
}
|
||||
|
||||
// Emissive blocks
|
||||
ms_Info[E_BLOCK_FIRE ].m_LightValue = 15;
|
||||
ms_Info[E_BLOCK_GLOWSTONE ].m_LightValue = 15;
|
||||
ms_Info[E_BLOCK_JACK_O_LANTERN ].m_LightValue = 15;
|
||||
ms_Info[E_BLOCK_LAVA ].m_LightValue = 15;
|
||||
ms_Info[E_BLOCK_STATIONARY_LAVA ].m_LightValue = 15;
|
||||
ms_Info[E_BLOCK_END_PORTAL ].m_LightValue = 15;
|
||||
ms_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_LightValue = 15;
|
||||
ms_Info[E_BLOCK_TORCH ].m_LightValue = 14;
|
||||
ms_Info[E_BLOCK_BURNING_FURNACE ].m_LightValue = 13;
|
||||
ms_Info[E_BLOCK_NETHER_PORTAL ].m_LightValue = 11;
|
||||
ms_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_LightValue = 9;
|
||||
ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_LightValue = 9;
|
||||
ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_LightValue = 7;
|
||||
ms_Info[E_BLOCK_BREWING_STAND ].m_LightValue = 1;
|
||||
ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_LightValue = 1;
|
||||
ms_Info[E_BLOCK_DRAGON_EGG ].m_LightValue = 1;
|
||||
a_Info[E_BLOCK_FIRE ].m_LightValue = 15;
|
||||
a_Info[E_BLOCK_GLOWSTONE ].m_LightValue = 15;
|
||||
a_Info[E_BLOCK_JACK_O_LANTERN ].m_LightValue = 15;
|
||||
a_Info[E_BLOCK_LAVA ].m_LightValue = 15;
|
||||
a_Info[E_BLOCK_STATIONARY_LAVA ].m_LightValue = 15;
|
||||
a_Info[E_BLOCK_END_PORTAL ].m_LightValue = 15;
|
||||
a_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_LightValue = 15;
|
||||
a_Info[E_BLOCK_TORCH ].m_LightValue = 14;
|
||||
a_Info[E_BLOCK_BURNING_FURNACE ].m_LightValue = 13;
|
||||
a_Info[E_BLOCK_NETHER_PORTAL ].m_LightValue = 11;
|
||||
a_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_LightValue = 9;
|
||||
a_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_LightValue = 9;
|
||||
a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_LightValue = 7;
|
||||
a_Info[E_BLOCK_BREWING_STAND ].m_LightValue = 1;
|
||||
a_Info[E_BLOCK_BROWN_MUSHROOM ].m_LightValue = 1;
|
||||
a_Info[E_BLOCK_DRAGON_EGG ].m_LightValue = 1;
|
||||
|
||||
|
||||
// Spread blocks
|
||||
ms_Info[E_BLOCK_AIR ].m_SpreadLightFalloff = 1;
|
||||
ms_Info[E_BLOCK_CAKE ].m_SpreadLightFalloff = 1;
|
||||
ms_Info[E_BLOCK_CHEST ].m_SpreadLightFalloff = 1;
|
||||
ms_Info[E_BLOCK_COBWEB ].m_SpreadLightFalloff = 1;
|
||||
ms_Info[E_BLOCK_CROPS ].m_SpreadLightFalloff = 1;
|
||||
ms_Info[E_BLOCK_FENCE ].m_SpreadLightFalloff = 1;
|
||||
ms_Info[E_BLOCK_FENCE_GATE ].m_SpreadLightFalloff = 1;
|
||||
ms_Info[E_BLOCK_FIRE ].m_SpreadLightFalloff = 1;
|
||||
ms_Info[E_BLOCK_GLASS ].m_SpreadLightFalloff = 1;
|
||||
ms_Info[E_BLOCK_GLASS_PANE ].m_SpreadLightFalloff = 1;
|
||||
ms_Info[E_BLOCK_GLOWSTONE ].m_SpreadLightFalloff = 1;
|
||||
ms_Info[E_BLOCK_IRON_BARS ].m_SpreadLightFalloff = 1;
|
||||
ms_Info[E_BLOCK_IRON_DOOR ].m_SpreadLightFalloff = 1;
|
||||
ms_Info[E_BLOCK_LEAVES ].m_SpreadLightFalloff = 1;
|
||||
ms_Info[E_BLOCK_NEW_LEAVES ].m_SpreadLightFalloff = 1;
|
||||
ms_Info[E_BLOCK_SIGN_POST ].m_SpreadLightFalloff = 1;
|
||||
ms_Info[E_BLOCK_TORCH ].m_SpreadLightFalloff = 1;
|
||||
ms_Info[E_BLOCK_VINES ].m_SpreadLightFalloff = 1;
|
||||
ms_Info[E_BLOCK_WALLSIGN ].m_SpreadLightFalloff = 1;
|
||||
ms_Info[E_BLOCK_WOODEN_DOOR ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_AIR ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_CAKE ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_CHEST ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_COBWEB ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_CROPS ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_FENCE ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_FENCE_GATE ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_FIRE ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_GLASS ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_GLASS_PANE ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_GLOWSTONE ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_IRON_BARS ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_IRON_DOOR ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_LEAVES ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_NEW_LEAVES ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_SIGN_POST ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_TORCH ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_TRIPWIRE ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_VINES ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_WALLSIGN ].m_SpreadLightFalloff = 1;
|
||||
a_Info[E_BLOCK_WOODEN_DOOR ].m_SpreadLightFalloff = 1;
|
||||
|
||||
// Light in water and lava dissapears faster:
|
||||
ms_Info[E_BLOCK_LAVA ].m_SpreadLightFalloff = 3;
|
||||
ms_Info[E_BLOCK_STATIONARY_LAVA ].m_SpreadLightFalloff = 3;
|
||||
ms_Info[E_BLOCK_STATIONARY_WATER ].m_SpreadLightFalloff = 3;
|
||||
ms_Info[E_BLOCK_WATER ].m_SpreadLightFalloff = 3;
|
||||
a_Info[E_BLOCK_LAVA ].m_SpreadLightFalloff = 3;
|
||||
a_Info[E_BLOCK_STATIONARY_LAVA ].m_SpreadLightFalloff = 3;
|
||||
a_Info[E_BLOCK_STATIONARY_WATER ].m_SpreadLightFalloff = 3;
|
||||
a_Info[E_BLOCK_WATER ].m_SpreadLightFalloff = 3;
|
||||
|
||||
|
||||
// Transparent blocks
|
||||
ms_Info[E_BLOCK_ACTIVATOR_RAIL ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_AIR ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_ANVIL ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_BIG_FLOWER ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_CAKE ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_CARROTS ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_CHEST ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_COBBLESTONE_WALL ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_COBWEB ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_CROPS ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_DANDELION ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_DETECTOR_RAIL ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_ENDER_CHEST ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_FENCE ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_FENCE_GATE ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_FIRE ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_FLOWER ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_FLOWER_POT ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_GLASS ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_GLASS_PANE ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_HEAD ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_ICE ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_IRON_DOOR ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_LADDER ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_LAVA ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_LEAVES ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_LEVER ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_MELON_STEM ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_NETHER_BRICK_FENCE ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_NEW_LEAVES ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_POTATOES ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_POWERED_RAIL ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_PISTON_EXTENSION ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_PUMPKIN_STEM ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_RAIL ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_RED_MUSHROOM ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_SIGN_POST ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_SNOW ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_STAINED_GLASS ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_STAINED_GLASS_PANE ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_STATIONARY_LAVA ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_STATIONARY_WATER ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_STONE_BUTTON ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_TALL_GRASS ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_TORCH ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_VINES ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_WALLSIGN ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_WATER ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_WOODEN_BUTTON ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_WOODEN_DOOR ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_Transparent = true;
|
||||
a_Info[E_BLOCK_ACTIVATOR_RAIL ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_AIR ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_ANVIL ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_BIG_FLOWER ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_BROWN_MUSHROOM ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_CAKE ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_CARROTS ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_CHEST ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_COBBLESTONE_WALL ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_COBWEB ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_CROPS ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_DANDELION ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_DETECTOR_RAIL ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_ENDER_CHEST ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_FENCE ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_FENCE_GATE ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_FIRE ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_FLOWER ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_FLOWER_POT ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_GLASS ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_GLASS_PANE ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_HEAD ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_Transparent = true;
|
||||
a_Info[E_BLOCK_ICE ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_IRON_DOOR ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_LADDER ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_LAVA ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_LEAVES ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_LEVER ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_Transparent = true;
|
||||
a_Info[E_BLOCK_MELON_STEM ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_NETHER_BRICK_FENCE ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_NEW_LEAVES ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_POTATOES ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_POWERED_RAIL ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_PISTON_EXTENSION ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_PUMPKIN_STEM ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_RAIL ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_RED_MUSHROOM ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_SIGN_POST ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_SNOW ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_STAINED_GLASS ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_STATIONARY_LAVA ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_STATIONARY_WATER ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_STONE_BUTTON ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_Transparent = true;
|
||||
a_Info[E_BLOCK_TRIPWIRE ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_TALL_GRASS ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_TORCH ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_VINES ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_WALLSIGN ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_WATER ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_WOODEN_BUTTON ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_WOODEN_DOOR ].m_Transparent = true;
|
||||
a_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_Transparent = true;
|
||||
|
||||
// TODO: Any other transparent blocks?
|
||||
|
||||
|
||||
// One hit break blocks:
|
||||
ms_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_BIG_FLOWER ].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_CARROTS ].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_CROPS ].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_DANDELION ].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_FIRE ].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_FLOWER ].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_FLOWER_POT ].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_MELON_STEM ].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_POTATOES ].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_PUMPKIN_STEM ].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_REDSTONE_WIRE ].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_RED_MUSHROOM ].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_REEDS ].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_SAPLING ].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_TNT ].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_TALL_GRASS ].m_OneHitDig = true;
|
||||
ms_Info[E_BLOCK_TORCH ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_BIG_FLOWER ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_BROWN_MUSHROOM ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_CARROTS ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_CROPS ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_DANDELION ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_FIRE ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_FLOWER ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_FLOWER_POT ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_MELON_STEM ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_POTATOES ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_PUMPKIN_STEM ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_REDSTONE_WIRE ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_RED_MUSHROOM ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_REEDS ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_SAPLING ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_TNT ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_TALL_GRASS ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_TORCH ].m_OneHitDig = true;
|
||||
a_Info[E_BLOCK_TRIPWIRE ].m_OneHitDig = true;
|
||||
|
||||
|
||||
// Blocks that break when pushed by piston:
|
||||
ms_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_AIR ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_BED ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_BIG_FLOWER ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_CAKE ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_COBWEB ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_CROPS ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_DANDELION ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_DEAD_BUSH ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_FIRE ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_FLOWER ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_HEAD ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_IRON_DOOR ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_JACK_O_LANTERN ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_LADDER ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_LAVA ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_LEVER ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_MELON ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_MELON_STEM ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_PUMPKIN ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_PUMPKIN_STEM ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_REDSTONE_WIRE ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_RED_MUSHROOM ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_REEDS ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_SNOW ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_STATIONARY_LAVA ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_STATIONARY_WATER ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_STONE_BUTTON ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_TALL_GRASS ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_TORCH ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_VINES ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_WATER ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_WOODEN_BUTTON ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_WOODEN_DOOR ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_AIR ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_BED ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_BIG_FLOWER ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_BROWN_MUSHROOM ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_CAKE ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_COBWEB ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_CROPS ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_DANDELION ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_DEAD_BUSH ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_FIRE ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_FLOWER ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_HEAD ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_IRON_DOOR ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_JACK_O_LANTERN ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_LADDER ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_LAVA ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_LEVER ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_MELON ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_MELON_STEM ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_PUMPKIN ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_PUMPKIN_STEM ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_REDSTONE_WIRE ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_RED_MUSHROOM ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_REEDS ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_SNOW ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_STATIONARY_LAVA ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_STATIONARY_WATER ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_STONE_BUTTON ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_TALL_GRASS ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_TORCH ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_TRIPWIRE ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_VINES ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_WATER ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_WOODEN_BUTTON ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_WOODEN_DOOR ].m_PistonBreakable = true;
|
||||
a_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_PistonBreakable = true;
|
||||
|
||||
|
||||
// Blocks that cannot be snowed over:
|
||||
ms_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_AIR ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_BIG_FLOWER ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_CACTUS ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_CHEST ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_CROPS ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_COBBLESTONE_WALL ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_DANDELION ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_FIRE ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_FLOWER ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_GLASS ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_ICE ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_LAVA ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_LILY_PAD ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_REDSTONE_WIRE ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_RED_MUSHROOM ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_REEDS ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_SAPLING ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_SIGN_POST ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_SNOW ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_STAINED_GLASS ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_STAINED_GLASS_PANE ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_STATIONARY_WATER ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_TALL_GRASS ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_TNT ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_TORCH ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_VINES ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_WALLSIGN ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_WATER ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_RAIL ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_ACTIVATOR_RAIL ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_POWERED_RAIL ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_COBWEB ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_HEAD ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_AIR ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_BIG_FLOWER ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_CACTUS ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_CHEST ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_CROPS ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_COBBLESTONE_WALL ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_DANDELION ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_FIRE ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_FLOWER ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_GLASS ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_ICE ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_LAVA ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_LILY_PAD ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_REDSTONE_WIRE ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_RED_MUSHROOM ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_REEDS ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_SAPLING ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_SIGN_POST ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_SNOW ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_STAINED_GLASS ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_STATIONARY_WATER ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_TALL_GRASS ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_TNT ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_TORCH ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_TRIPWIRE ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_VINES ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_WALLSIGN ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_WATER ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_RAIL ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_ACTIVATOR_RAIL ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_POWERED_RAIL ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_COBWEB ].m_IsSnowable = false;
|
||||
a_Info[E_BLOCK_HEAD ].m_IsSnowable = false;
|
||||
|
||||
|
||||
// Blocks that don't drop without a special tool:
|
||||
ms_Info[E_BLOCK_BRICK ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_CAULDRON ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_COAL_ORE ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_COBBLESTONE ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_COBBLESTONE_WALL ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_COBBLESTONE_STAIRS ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_COBWEB ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_DIAMOND_BLOCK ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_DIAMOND_ORE ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_EMERALD_ORE ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_END_STONE ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_GOLD_BLOCK ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_GOLD_ORE ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_IRON_BLOCK ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_IRON_ORE ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_LAPIS_BLOCK ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_LAPIS_ORE ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_NETHERRACK ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_NETHER_BRICK ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_NETHER_BRICK_STAIRS ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_OBSIDIAN ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_REDSTONE_ORE ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_SANDSTONE ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_SANDSTONE_STAIRS ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_SNOW ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_STONE ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_STONE_BRICKS ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_STONE_BRICK_STAIRS ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_STONE_SLAB ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_VINES ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_FURNACE ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_LIT_FURNACE ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_ANVIL ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_ENCHANTMENT_TABLE ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_BRICK ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_CAULDRON ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_COAL_ORE ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_COBBLESTONE ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_COBBLESTONE_WALL ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_COBBLESTONE_STAIRS ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_COBWEB ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_DIAMOND_BLOCK ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_DIAMOND_ORE ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_EMERALD_ORE ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_END_STONE ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_GOLD_BLOCK ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_GOLD_ORE ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_IRON_BLOCK ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_IRON_ORE ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_LAPIS_BLOCK ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_LAPIS_ORE ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_NETHERRACK ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_NETHER_BRICK ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_NETHER_BRICK_STAIRS ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_OBSIDIAN ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_REDSTONE_ORE ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_SANDSTONE ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_SANDSTONE_STAIRS ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_SNOW ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_STONE ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_STONE_BRICKS ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_STONE_BRICK_STAIRS ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_STONE_SLAB ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_VINES ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_FURNACE ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_LIT_FURNACE ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_ANVIL ].m_RequiresSpecialTool = true;
|
||||
a_Info[E_BLOCK_ENCHANTMENT_TABLE ].m_RequiresSpecialTool = true;
|
||||
|
||||
|
||||
// Nonsolid blocks:
|
||||
ms_Info[E_BLOCK_ACTIVATOR_RAIL ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_AIR ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_BIG_FLOWER ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_CAKE ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_CARROTS ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_COBWEB ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_CROPS ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_DANDELION ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_END_PORTAL ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_FENCE ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_FENCE_GATE ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_FIRE ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_FLOWER ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_LAVA ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_LEVER ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_MELON_STEM ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_NETHER_PORTAL ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_PISTON_EXTENSION ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_POTATOES ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_POWERED_RAIL ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_RAIL ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_REDSTONE_WIRE ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_RED_MUSHROOM ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_REEDS ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_SAPLING ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_SIGN_POST ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_SNOW ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_STATIONARY_WATER ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_STONE_BUTTON ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_TALL_GRASS ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_TORCH ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_TRIPWIRE ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_VINES ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_WALLSIGN ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_WATER ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_WOODEN_BUTTON ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_WOODEN_SLAB ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_ACTIVATOR_RAIL ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_AIR ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_BIG_FLOWER ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_CAKE ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_CARROTS ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_COBWEB ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_CROPS ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_DANDELION ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_END_PORTAL ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_FENCE ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_FENCE_GATE ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_FIRE ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_FLOWER ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_LAVA ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_LEVER ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_MELON_STEM ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_NETHER_PORTAL ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_POTATOES ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_POWERED_RAIL ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_RAIL ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_REDSTONE_WIRE ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_RED_MUSHROOM ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_REEDS ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_SAPLING ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_SIGN_POST ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_SNOW ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_STATIONARY_WATER ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_STONE_BUTTON ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_TALL_GRASS ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_TORCH ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_TRIPWIRE ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_VINES ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_WALLSIGN ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_WATER ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_WOODEN_BUTTON ].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_IsSolid = false;
|
||||
a_Info[E_BLOCK_WOODEN_SLAB ].m_IsSolid = false;
|
||||
|
||||
|
||||
// Blocks that fully occupy their voxel - used as a guide for torch placeable blocks, amongst other things:
|
||||
ms_Info[E_BLOCK_NEW_LOG ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_BEDROCK ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_BLOCK_OF_COAL ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_BLOCK_OF_REDSTONE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_BOOKCASE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_BRICK ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_CLAY ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_COAL_ORE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_COBBLESTONE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_COMMAND_BLOCK ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_CRAFTING_TABLE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_DIAMOND_BLOCK ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_DIAMOND_ORE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_DIRT ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_DISPENSER ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_DOUBLE_WOODEN_SLAB ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_DROPPER ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_EMERALD_BLOCK ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_EMERALD_ORE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_END_STONE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_FURNACE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_GLOWSTONE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_GOLD_BLOCK ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_GOLD_ORE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_GRASS ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_GRAVEL ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_HARDENED_CLAY ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_HAY_BALE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_HUGE_BROWN_MUSHROOM ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_HUGE_RED_MUSHROOM ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_ICE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_IRON_BLOCK ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_IRON_ORE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_JACK_O_LANTERN ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_JUKEBOX ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_LAPIS_BLOCK ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_LAPIS_ORE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_LOG ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_MELON ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_MYCELIUM ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_NETHERRACK ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_NETHER_BRICK ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_NETHER_QUARTZ_ORE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_NOTE_BLOCK ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_OBSIDIAN ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_PACKED_ICE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_PLANKS ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_PUMPKIN ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_QUARTZ_BLOCK ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_REDSTONE_LAMP_OFF ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_REDSTONE_ORE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_SANDSTONE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_SAND ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_SILVERFISH_EGG ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_SPONGE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_STAINED_CLAY ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_WOOL ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_STONE ].m_FullyOccupiesVoxel = true;
|
||||
ms_Info[E_BLOCK_STONE_BRICKS ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_NEW_LOG ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_BEDROCK ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_BLOCK_OF_COAL ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_BLOCK_OF_REDSTONE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_BOOKCASE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_BRICK ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_CLAY ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_COAL_ORE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_COBBLESTONE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_COMMAND_BLOCK ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_CRAFTING_TABLE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_DIAMOND_BLOCK ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_DIAMOND_ORE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_DIRT ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_DISPENSER ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_DOUBLE_WOODEN_SLAB ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_DROPPER ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_EMERALD_BLOCK ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_EMERALD_ORE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_END_STONE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_FURNACE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_GLOWSTONE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_GOLD_BLOCK ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_GOLD_ORE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_GRASS ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_GRAVEL ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_HARDENED_CLAY ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_HAY_BALE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_HUGE_BROWN_MUSHROOM ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_HUGE_RED_MUSHROOM ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_ICE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_IRON_BLOCK ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_IRON_ORE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_JACK_O_LANTERN ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_JUKEBOX ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_LAPIS_BLOCK ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_LAPIS_ORE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_LOG ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_MELON ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_MYCELIUM ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_NETHERRACK ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_NETHER_BRICK ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_NETHER_QUARTZ_ORE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_NOTE_BLOCK ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_OBSIDIAN ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_PACKED_ICE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_PLANKS ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_PUMPKIN ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_QUARTZ_BLOCK ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_REDSTONE_LAMP_OFF ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_REDSTONE_ORE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_SANDSTONE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_SAND ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_SILVERFISH_EGG ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_SPONGE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_STAINED_CLAY ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_WOOL ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_STONE ].m_FullyOccupiesVoxel = true;
|
||||
a_Info[E_BLOCK_STONE_BRICKS ].m_FullyOccupiesVoxel = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// This is actually just some code that needs to run at program startup, so it is wrapped into a global var's constructor:
|
||||
class cBlockInfoInitializer
|
||||
{
|
||||
public:
|
||||
cBlockInfoInitializer(void)
|
||||
{
|
||||
cBlockInfo::Initialize();
|
||||
}
|
||||
} BlockInfoInitializer;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -16,18 +16,8 @@ class cBlockHandler;
|
||||
class cBlockInfo
|
||||
{
|
||||
public:
|
||||
// tolua_end
|
||||
|
||||
cBlockInfo();
|
||||
|
||||
~cBlockInfo();
|
||||
|
||||
/** (Re-)Initializes the internal BlockInfo structures. */
|
||||
static void Initialize(void);
|
||||
|
||||
// tolua_begin
|
||||
|
||||
/** Returns the associated BlockInfo structure. */
|
||||
/** Returns the associated BlockInfo structure for the specified block type. */
|
||||
static cBlockInfo & Get(BLOCKTYPE a_Type);
|
||||
|
||||
|
||||
@ -79,13 +69,18 @@ public:
|
||||
|
||||
inline static cBlockHandler * GetHandler (BLOCKTYPE a_Type) { return Get(a_Type).m_Handler; }
|
||||
|
||||
|
||||
protected:
|
||||
/** Storage for all the BlockInfo structures. */
|
||||
typedef cBlockInfo cBlockInfoArray[256];
|
||||
|
||||
// TODO xdot: Change to std::vector to support dynamic block IDs
|
||||
static cBlockInfo ms_Info[256];
|
||||
/** Creates a default BlockInfo structure, initializes all values to their defaults */
|
||||
cBlockInfo();
|
||||
|
||||
/** Cleans up the stored values */
|
||||
~cBlockInfo();
|
||||
|
||||
/** Initializes the specified BlockInfo structures with block-specific values. */
|
||||
static void Initialize(cBlockInfoArray & a_BlockInfos);
|
||||
}; // tolua_export
|
||||
|
||||
|
||||
|
@ -23,6 +23,7 @@ public:
|
||||
NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) | 0x08);
|
||||
|
||||
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
|
||||
a_WorldInterface.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ);
|
||||
a_WorldInterface.GetBroadcastManager().BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f);
|
||||
|
||||
// Queue a button reset (unpress)
|
||||
@ -102,7 +103,7 @@ public:
|
||||
AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true);
|
||||
BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn);
|
||||
|
||||
return (a_RelY > 0) && (cBlockInfo::IsSolid(BlockIsOn));
|
||||
return (a_RelY > 0) && (cBlockInfo::FullyOccupiesVoxel(BlockIsOn));
|
||||
}
|
||||
} ;
|
||||
|
||||
|
@ -45,9 +45,16 @@ void cBlockDoorHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldIn
|
||||
|
||||
void cBlockDoorHandler::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)
|
||||
{
|
||||
UNUSED(a_WorldInterface);
|
||||
UNUSED(a_BlockFace);
|
||||
UNUSED(a_CursorX);
|
||||
UNUSED(a_CursorY);
|
||||
UNUSED(a_CursorZ);
|
||||
|
||||
if (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_WOODEN_DOOR)
|
||||
{
|
||||
ChangeDoor(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
|
||||
a_Player->GetWorld()->BroadcastSoundParticleEffect(1003, a_BlockX, a_BlockY, a_BlockZ, 0, a_Player->GetClientHandle());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,7 @@ public:
|
||||
// Standing aside - use last direction
|
||||
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, OldMetaData);
|
||||
}
|
||||
a_Player->GetWorld()->BroadcastSoundParticleEffect(1003, a_BlockX, a_BlockY, a_BlockZ, 0, a_Player->GetClientHandle());
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,8 +36,8 @@ public:
|
||||
- Loop through boundary variables, and fill with portal blocks based on Dir with meta from Dir
|
||||
*/
|
||||
|
||||
a_BlockY--; // Because we want the block below the fire
|
||||
FindAndSetPortalFrame(a_BlockX, a_BlockY, a_BlockZ, a_ChunkInterface, a_WorldInterface);
|
||||
// a_BlockY - 1: Because we want the block below the fire
|
||||
FindAndSetPortalFrame(a_BlockX, a_BlockY - 1, a_BlockZ, a_ChunkInterface, a_WorldInterface);
|
||||
}
|
||||
|
||||
virtual void OnDigging(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "BlockGlass.h"
|
||||
#include "BlockGlowstone.h"
|
||||
#include "BlockGravel.h"
|
||||
#include "BlockHayBale.h"
|
||||
#include "BlockMobHead.h"
|
||||
#include "BlockHopper.h"
|
||||
#include "BlockIce.h"
|
||||
@ -64,6 +65,8 @@
|
||||
#include "BlockRedstoneRepeater.h"
|
||||
#include "BlockRedstoneTorch.h"
|
||||
#include "BlockTNT.h"
|
||||
#include "BlockTripwire.h"
|
||||
#include "BlockTripwireHook.h"
|
||||
#include "BlockSand.h"
|
||||
#include "BlockSapling.h"
|
||||
#include "BlockSideways.h"
|
||||
@ -84,6 +87,91 @@
|
||||
|
||||
|
||||
|
||||
/*
|
||||
// Tests the meta rotation and mirroring.
|
||||
// Note that the cMetaRotator needs to have its assert paths disabled for this test to work!
|
||||
static class cBlockHandlerRotationTester
|
||||
{
|
||||
public:
|
||||
cBlockHandlerRotationTester(void)
|
||||
{
|
||||
printf("Performing block handlers test...\n");
|
||||
for (BLOCKTYPE Type = 0; Type < E_BLOCK_MAX_TYPE_ID; Type++)
|
||||
{
|
||||
cBlockHandler * Handler = cBlockInfo::GetHandler(Type);
|
||||
if (Handler == NULL)
|
||||
{
|
||||
printf("NULL handler for block type %d!\n", Type);
|
||||
continue;
|
||||
}
|
||||
AString BlockName = ItemTypeToString(Type);
|
||||
for (NIBBLETYPE Meta = 0; Meta < 16; Meta++)
|
||||
{
|
||||
// Test the CW / CCW rotations:
|
||||
NIBBLETYPE TestMeta;
|
||||
TestMeta = Handler->MetaRotateCW(Handler->MetaRotateCW(Handler->MetaRotateCW(Handler->MetaRotateCW(Meta))));
|
||||
if (TestMeta != Meta)
|
||||
{
|
||||
// 4 CW rotations should produce no change in the meta
|
||||
printf("Handler for blocktype %d (%s) fails CW 4-rotation test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
|
||||
}
|
||||
TestMeta = Handler->MetaRotateCCW(Handler->MetaRotateCCW(Handler->MetaRotateCCW(Handler->MetaRotateCCW(Meta))));
|
||||
if (TestMeta != Meta)
|
||||
{
|
||||
// 4 CCW rotations should produce no change in the meta
|
||||
printf("Handler for blocktype %d (%s) fails CCW 4-rotation test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
|
||||
}
|
||||
TestMeta = Handler->MetaRotateCCW(Handler->MetaRotateCW(Meta));
|
||||
if (TestMeta != Meta)
|
||||
{
|
||||
// CCW rotation of a CW rotation should produce no change in the meta
|
||||
printf("Handler for blocktype %d (%s) fails CCW(CW) rotation test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
|
||||
}
|
||||
TestMeta = Handler->MetaRotateCW(Handler->MetaRotateCCW(Meta));
|
||||
if (TestMeta != Meta)
|
||||
{
|
||||
// CW rotation of a CCW rotation should produce no change in the meta
|
||||
printf("Handler for blocktype %d (%s) fails CW(CCW) rotation test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
|
||||
}
|
||||
|
||||
// Test the mirroring:
|
||||
TestMeta = Handler->MetaMirrorXY(Handler->MetaMirrorXY(Meta));
|
||||
if (TestMeta != Meta)
|
||||
{
|
||||
// Double-mirroring should produce the same meta:
|
||||
printf("Handler for blocktype %d (%s) fails XY mirror test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
|
||||
}
|
||||
TestMeta = Handler->MetaMirrorXZ(Handler->MetaMirrorXZ(Meta));
|
||||
if (TestMeta != Meta)
|
||||
{
|
||||
// Double-mirroring should produce the same meta:
|
||||
printf("Handler for blocktype %d (%s) fails XZ mirror test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
|
||||
}
|
||||
TestMeta = Handler->MetaMirrorYZ(Handler->MetaMirrorYZ(Meta));
|
||||
if (TestMeta != Meta)
|
||||
{
|
||||
// Double-mirroring should produce the same meta:
|
||||
printf("Handler for blocktype %d (%s) fails YZ mirror test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
|
||||
}
|
||||
|
||||
// Test mirror-rotating:
|
||||
TestMeta = Handler->MetaRotateCW(Handler->MetaRotateCW(Handler->MetaMirrorXY(Handler->MetaMirrorYZ(Meta))));
|
||||
if (TestMeta != Meta)
|
||||
{
|
||||
// 2 CW rotations should be the same as XY, YZ mirroring:
|
||||
printf("Handler for blocktype %d (%s) fails rotation-mirror test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
|
||||
}
|
||||
}
|
||||
} // for Type
|
||||
printf("Block handlers test complete.\n");
|
||||
}
|
||||
} g_BlockHandlerRotationTester;
|
||||
//*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
|
||||
{
|
||||
switch(a_BlockType)
|
||||
@ -134,7 +222,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
|
||||
case E_BLOCK_GLASS_PANE: return new cBlockGlassHandler (a_BlockType);
|
||||
case E_BLOCK_GRASS: return new cBlockDirtHandler (a_BlockType);
|
||||
case E_BLOCK_GRAVEL: return new cBlockGravelHandler (a_BlockType);
|
||||
case E_BLOCK_HAY_BALE: return new cBlockSidewaysHandler (a_BlockType);
|
||||
case E_BLOCK_HAY_BALE: return new cBlockHayBaleHandler (a_BlockType);
|
||||
case E_BLOCK_HEAD: return new cBlockMobHeadHandler (a_BlockType);
|
||||
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: return new cBlockPressurePlateHandler(a_BlockType);
|
||||
case E_BLOCK_HOPPER: return new cBlockHopperHandler (a_BlockType);
|
||||
@ -174,7 +262,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
|
||||
case E_BLOCK_QUARTZ_BLOCK: return new cBlockQuartzHandler (a_BlockType);
|
||||
case E_BLOCK_QUARTZ_STAIRS: return new cBlockStairsHandler (a_BlockType);
|
||||
case E_BLOCK_RAIL: return new cBlockRailHandler (a_BlockType);
|
||||
case E_BLOCK_REDSTONE_LAMP_ON: return new cBlockRedstoneLampHandler (a_BlockType); // We need this to change pickups to an off lamp; else 1.7+ clients crash
|
||||
case E_BLOCK_REDSTONE_LAMP_ON: return new cBlockRedstoneLampHandler (a_BlockType);
|
||||
case E_BLOCK_REDSTONE_ORE: return new cBlockOreHandler (a_BlockType);
|
||||
case E_BLOCK_REDSTONE_ORE_GLOWING: return new cBlockOreHandler (a_BlockType);
|
||||
case E_BLOCK_REDSTONE_REPEATER_OFF: return new cBlockRedstoneRepeaterHandler(a_BlockType);
|
||||
@ -205,8 +293,10 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
|
||||
case E_BLOCK_TORCH: return new cBlockTorchHandler (a_BlockType);
|
||||
case E_BLOCK_TRAPDOOR: return new cBlockTrapdoorHandler (a_BlockType);
|
||||
case E_BLOCK_TNT: return new cBlockTNTHandler (a_BlockType);
|
||||
case E_BLOCK_TRIPWIRE: return new cBlockTripwireHandler (a_BlockType);
|
||||
case E_BLOCK_TRIPWIRE_HOOK: return new cBlockTripwireHookHandler (a_BlockType);
|
||||
case E_BLOCK_VINES: return new cBlockVineHandler (a_BlockType);
|
||||
case E_BLOCK_WALLSIGN: return new cBlockSignHandler (a_BlockType);
|
||||
case E_BLOCK_WALLSIGN: return new cBlockSignHandler (a_BlockType); // TODO: This needs a special handler
|
||||
case E_BLOCK_WATER: return new cBlockFluidHandler (a_BlockType);
|
||||
case E_BLOCK_WOODEN_BUTTON: return new cBlockButtonHandler (a_BlockType);
|
||||
case E_BLOCK_WOODEN_DOOR: return new cBlockDoorHandler (a_BlockType);
|
||||
|
29
src/Blocks/BlockHayBale.h
Normal file
29
src/Blocks/BlockHayBale.h
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
#include "BlockSideways.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockHayBaleHandler :
|
||||
public cBlockSidewaysHandler
|
||||
{
|
||||
public:
|
||||
cBlockHayBaleHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockSidewaysHandler(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
return "step.grass";
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -7,12 +7,13 @@
|
||||
|
||||
|
||||
class cBlockLeverHandler :
|
||||
public cMetaRotator<cBlockHandler, 0x07, 0x04, 0x02, 0x03, 0x01, false>
|
||||
public cMetaRotator<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, false>
|
||||
{
|
||||
typedef cMetaRotator<cBlockHandler, 0x07, 0x04, 0x02, 0x03, 0x01, false> super;
|
||||
typedef cMetaRotator<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, false> super;
|
||||
|
||||
public:
|
||||
cBlockLeverHandler(BLOCKTYPE a_BlockType)
|
||||
: cMetaRotator<cBlockHandler, 0x07, 0x04, 0x02, 0x03, 0x01, false>(a_BlockType)
|
||||
cBlockLeverHandler(BLOCKTYPE a_BlockType) :
|
||||
super(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
@ -21,7 +22,8 @@ public:
|
||||
// Flip the ON bit on/off using the XOR bitwise operation
|
||||
NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08);
|
||||
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LEVER, Meta); // SetMeta doesn't work for unpowering levers, so setblock
|
||||
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
|
||||
a_WorldInterface.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ);
|
||||
a_WorldInterface.GetBroadcastManager().BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f);
|
||||
}
|
||||
|
||||
@ -103,7 +105,7 @@ public:
|
||||
AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true);
|
||||
BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn);
|
||||
|
||||
return (a_RelY > 0) && cBlockInfo::IsSolid(BlockIsOn);
|
||||
return (a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(BlockIsOn);
|
||||
}
|
||||
|
||||
|
||||
@ -132,7 +134,7 @@ public:
|
||||
case 0x05: return 0x06; // Ground rotation
|
||||
case 0x06: return 0x05;
|
||||
|
||||
default: return super::MetaRotateCCW(a_Meta); // Wall Rotation
|
||||
default: return super::MetaRotateCW(a_Meta); // Wall Rotation
|
||||
}
|
||||
}
|
||||
} ;
|
||||
|
@ -19,24 +19,69 @@ public:
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
a_Pickups.push_back(cItem(E_ITEM_HEAD, 1, 0));
|
||||
// The drop spawn is in OnDestroyed method
|
||||
}
|
||||
|
||||
bool TrySpawnWither(cChunkInterface & a_ChunkInterface, cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
virtual void OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override
|
||||
{
|
||||
if (a_Player->IsGameModeCreative())
|
||||
{
|
||||
// No drops in creative mode
|
||||
return;
|
||||
}
|
||||
|
||||
class cCallback : public cBlockEntityCallback
|
||||
{
|
||||
virtual bool Item(cBlockEntity * a_BlockEntity)
|
||||
{
|
||||
if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
cMobHeadEntity * MobHeadEntity = static_cast<cMobHeadEntity*>(a_BlockEntity);
|
||||
|
||||
cItems Pickups;
|
||||
Pickups.Add(E_ITEM_HEAD, 1, (short) MobHeadEntity->GetType());
|
||||
MTRand r1;
|
||||
|
||||
// Mid-block position first
|
||||
double MicroX, MicroY, MicroZ;
|
||||
MicroX = MobHeadEntity->GetPosX() + 0.5;
|
||||
MicroY = MobHeadEntity->GetPosY() + 0.5;
|
||||
MicroZ = MobHeadEntity->GetPosZ() + 0.5;
|
||||
|
||||
// Add random offset second
|
||||
MicroX += r1.rand(1) - 0.5;
|
||||
MicroZ += r1.rand(1) - 0.5;
|
||||
|
||||
MobHeadEntity->GetWorld()->SpawnItemPickups(Pickups, MicroX, MicroY, MicroZ);
|
||||
return false;
|
||||
}
|
||||
} Callback;
|
||||
|
||||
a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
|
||||
}
|
||||
|
||||
bool TrySpawnWither(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
if (a_BlockY < 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
class cCallback : public cMobHeadCallback
|
||||
class cCallback : public cBlockEntityCallback
|
||||
{
|
||||
bool m_IsWither;
|
||||
|
||||
virtual bool Item (cMobHeadEntity * a_MobHeadEntity)
|
||||
virtual bool Item(cBlockEntity * a_BlockEntity)
|
||||
{
|
||||
m_IsWither = (a_MobHeadEntity->GetType() == SKULL_TYPE_WITHER);
|
||||
if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
cMobHeadEntity * MobHeadEntity = static_cast<cMobHeadEntity*>(a_BlockEntity);
|
||||
|
||||
m_IsWither = (MobHeadEntity->GetType() == SKULL_TYPE_WITHER);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -70,7 +115,7 @@ public:
|
||||
|
||||
} PlayerCallback(Vector3f((float)a_BlockX, (float)a_BlockY, (float)a_BlockZ));
|
||||
|
||||
a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA);
|
||||
a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA);
|
||||
|
||||
if (!CallbackA.IsWither())
|
||||
{
|
||||
@ -87,8 +132,8 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
a_World->DoWithMobHeadAt(a_BlockX - 1, a_BlockY, a_BlockZ, CallbackA);
|
||||
a_World->DoWithMobHeadAt(a_BlockX + 1, a_BlockY, a_BlockZ, CallbackB);
|
||||
a_WorldInterface.DoWithBlockEntityAt(a_BlockX - 1, a_BlockY, a_BlockZ, CallbackA);
|
||||
a_WorldInterface.DoWithBlockEntityAt(a_BlockX + 1, a_BlockY, a_BlockZ, CallbackB);
|
||||
|
||||
BLOCKTYPE Block1 = a_ChunkInterface.GetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ);
|
||||
BLOCKTYPE Block2 = a_ChunkInterface.GetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ);
|
||||
@ -101,15 +146,15 @@ public:
|
||||
a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
|
||||
|
||||
// Block entities
|
||||
a_World->SetBlock(a_BlockX + 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||
a_World->SetBlock(a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX + 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||
|
||||
// Spawn the wither:
|
||||
a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
|
||||
a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
|
||||
|
||||
// Award Achievement
|
||||
a_World->ForEachPlayer(PlayerCallback);
|
||||
a_WorldInterface.ForEachPlayer(PlayerCallback);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -117,8 +162,8 @@ public:
|
||||
CallbackA.Reset();
|
||||
CallbackB.Reset();
|
||||
|
||||
a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ - 1, CallbackA);
|
||||
a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ + 1, CallbackB);
|
||||
a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ - 1, CallbackA);
|
||||
a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ + 1, CallbackB);
|
||||
|
||||
Block1 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1);
|
||||
Block2 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1);
|
||||
@ -131,15 +176,15 @@ public:
|
||||
a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
|
||||
|
||||
// Block entities
|
||||
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ + 1, E_BLOCK_AIR, 0);
|
||||
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0);
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ + 1, E_BLOCK_AIR, 0);
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0);
|
||||
|
||||
// Spawn the wither:
|
||||
a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
|
||||
a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
|
||||
|
||||
// Award Achievement
|
||||
a_World->ForEachPlayer(PlayerCallback);
|
||||
a_WorldInterface.ForEachPlayer(PlayerCallback);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -154,23 +199,29 @@ public:
|
||||
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
|
||||
) override
|
||||
{
|
||||
class cCallback : public cMobHeadCallback
|
||||
class cCallback : public cBlockEntityCallback
|
||||
{
|
||||
cPlayer * m_Player;
|
||||
NIBBLETYPE m_OldBlockMeta;
|
||||
NIBBLETYPE m_NewBlockMeta;
|
||||
|
||||
virtual bool Item (cMobHeadEntity * a_MobHeadEntity)
|
||||
virtual bool Item(cBlockEntity * a_BlockEntity)
|
||||
{
|
||||
if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
cMobHeadEntity * MobHeadEntity = static_cast<cMobHeadEntity*>(a_BlockEntity);
|
||||
|
||||
int Rotation = 0;
|
||||
if (m_NewBlockMeta == 1)
|
||||
{
|
||||
Rotation = (int) floor(m_Player->GetYaw() * 16.0F / 360.0F + 0.5) & 0xF;
|
||||
}
|
||||
|
||||
a_MobHeadEntity->SetType(static_cast<eMobHeadType>(m_OldBlockMeta));
|
||||
a_MobHeadEntity->SetRotation(static_cast<eMobHeadRotation>(Rotation));
|
||||
a_MobHeadEntity->GetWorld()->BroadcastBlockEntity(a_MobHeadEntity->GetPosX(), a_MobHeadEntity->GetPosY(), a_MobHeadEntity->GetPosZ(), m_Player->GetClientHandle());
|
||||
MobHeadEntity->SetType(static_cast<eMobHeadType>(m_OldBlockMeta));
|
||||
MobHeadEntity->SetRotation(static_cast<eMobHeadRotation>(Rotation));
|
||||
MobHeadEntity->GetWorld()->BroadcastBlockEntity(MobHeadEntity->GetPosX(), MobHeadEntity->GetPosY(), MobHeadEntity->GetPosZ());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -184,8 +235,7 @@ public:
|
||||
cCallback Callback(a_Player, a_BlockMeta, static_cast<NIBBLETYPE>(a_BlockFace));
|
||||
|
||||
a_BlockMeta = (NIBBLETYPE)a_BlockFace;
|
||||
cWorld * World = (cWorld *) &a_WorldInterface;
|
||||
World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
|
||||
a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
|
||||
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta);
|
||||
|
||||
if (a_BlockMeta == SKULL_TYPE_WITHER)
|
||||
@ -200,7 +250,7 @@ public:
|
||||
};
|
||||
for (size_t i = 0; i < ARRAYCOUNT(Coords); ++i)
|
||||
{
|
||||
if (TrySpawnWither(a_ChunkInterface, World, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z))
|
||||
if (TrySpawnWither(a_ChunkInterface, a_WorldInterface, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -75,13 +75,13 @@ public:
|
||||
|
||||
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
return (++a_Meta) & 0x0F;
|
||||
return (a_Meta + 4) & 0x0f;
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
return (--a_Meta) & 0x0F;
|
||||
return (a_Meta + 12) & 0x0f;
|
||||
}
|
||||
|
||||
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
|
||||
@ -90,7 +90,7 @@ public:
|
||||
|
||||
// There are 16 meta values which correspond to different directions.
|
||||
// These values are equated to angles on a circle; 0x08 = 180 degrees.
|
||||
return (a_Meta < 0x08) ? 0x08 + a_Meta : 0x08 - a_Meta;
|
||||
return (a_Meta < 0x08) ? (0x08 + a_Meta) : (0x08 - a_Meta);
|
||||
}
|
||||
|
||||
|
||||
|
@ -80,6 +80,7 @@ public:
|
||||
if (IsAnySlabType(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ)))
|
||||
{
|
||||
a_BlockType = GetDoubleSlabType(m_BlockType);
|
||||
a_BlockMeta = a_BlockMeta & 0x7;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -123,6 +124,12 @@ public:
|
||||
return E_BLOCK_AIR;
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Toggle the 4th bit - up / down:
|
||||
return (a_Meta ^ 0x08);
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
@ -166,15 +173,6 @@ public:
|
||||
ASSERT(!"Unhandled double slab type!");
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
NIBBLETYPE OtherMeta = a_Meta & 0x07; // Contains unrelated meta data.
|
||||
|
||||
// 8th bit is up/down. 1 right-side-up, 0 is up-side-down.
|
||||
return (a_Meta & 0x08) ? 0x00 + OtherMeta : 0x01 + OtherMeta;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -2,8 +2,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
#include "../MersenneTwister.h"
|
||||
#include "../World.h"
|
||||
|
||||
|
||||
|
||||
|
@ -154,7 +154,11 @@ public:
|
||||
|
||||
if (
|
||||
(BlockInQuestion == E_BLOCK_GLASS) ||
|
||||
(BlockInQuestion == E_BLOCK_STAINED_GLASS) ||
|
||||
(BlockInQuestion == E_BLOCK_FENCE) ||
|
||||
(BlockInQuestion == E_BLOCK_SOULSAND) ||
|
||||
(BlockInQuestion == E_BLOCK_MOB_SPAWNER) ||
|
||||
(BlockInQuestion == E_BLOCK_END_PORTAL_FRAME) || // Actual vanilla behaviour
|
||||
(BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) ||
|
||||
(BlockInQuestion == E_BLOCK_COBBLESTONE_WALL)
|
||||
)
|
||||
|
32
src/Blocks/BlockTripwire.h
Normal file
32
src/Blocks/BlockTripwire.h
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockTripwireHandler :
|
||||
public cBlockHandler
|
||||
{
|
||||
public:
|
||||
cBlockTripwireHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
a_Pickups.push_back(cItem(E_ITEM_STRING, 1, 0));
|
||||
}
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
82
src/Blocks/BlockTripwireHook.h
Normal file
82
src/Blocks/BlockTripwireHook.h
Normal file
@ -0,0 +1,82 @@
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
#include "MetaRotator.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockTripwireHookHandler :
|
||||
public cMetaRotator<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01>
|
||||
{
|
||||
public:
|
||||
cBlockTripwireHookHandler(BLOCKTYPE a_BlockType)
|
||||
: cMetaRotator<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01>(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool GetPlacementBlockTypeMeta(
|
||||
cChunkInterface & a_ChunkInterface, cPlayer * a_Player,
|
||||
int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
|
||||
int a_CursorX, int a_CursorY, int a_CursorZ,
|
||||
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
|
||||
) override
|
||||
{
|
||||
a_BlockType = m_BlockType;
|
||||
|
||||
a_BlockMeta = DirectionToMetadata(a_BlockFace);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline static NIBBLETYPE DirectionToMetadata(eBlockFace a_Direction)
|
||||
{
|
||||
switch (a_Direction)
|
||||
{
|
||||
case BLOCK_FACE_XM: return 0x1;
|
||||
case BLOCK_FACE_XP: return 0x3;
|
||||
case BLOCK_FACE_ZM: return 0x2;
|
||||
case BLOCK_FACE_ZP: return 0x0;
|
||||
default: ASSERT(!"Unhandled tripwire hook direction!"); return 0x0;
|
||||
}
|
||||
}
|
||||
|
||||
inline static eBlockFace MetadataToDirection(NIBBLETYPE a_Meta)
|
||||
{
|
||||
switch (a_Meta & 0x03)
|
||||
{
|
||||
case 0x1: return BLOCK_FACE_XM;
|
||||
case 0x3: return BLOCK_FACE_XP;
|
||||
case 0x2: return BLOCK_FACE_ZM;
|
||||
case 0x0: return BLOCK_FACE_ZP;
|
||||
default: ASSERT(!"Unhandled tripwire hook metadata!"); return BLOCK_FACE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
// Reset meta to 0
|
||||
a_Pickups.push_back(cItem(E_BLOCK_TRIPWIRE_HOOK, 1, 0));
|
||||
}
|
||||
|
||||
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
|
||||
{
|
||||
NIBBLETYPE Meta;
|
||||
a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta);
|
||||
|
||||
AddFaceDirection(a_RelX, a_RelY, a_RelZ, MetadataToDirection(Meta), true);
|
||||
BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn);
|
||||
|
||||
return (a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(BlockIsOn);
|
||||
}
|
||||
|
||||
virtual const char * GetStepSound(void) override
|
||||
{
|
||||
return "step.wood";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -6,6 +6,12 @@
|
||||
|
||||
class cItems;
|
||||
|
||||
typedef cItemCallback<cBlockEntity> cBlockEntityCallback;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cWorldInterface
|
||||
{
|
||||
public:
|
||||
@ -29,6 +35,9 @@ public:
|
||||
/** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */
|
||||
virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) = 0;
|
||||
|
||||
/** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */
|
||||
virtual bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback) = 0;
|
||||
|
||||
/** Sends the block on those coords to the player */
|
||||
virtual void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, cPlayer * a_Player) = 0;
|
||||
|
||||
@ -37,4 +46,7 @@ public:
|
||||
|
||||
virtual void SetTimeOfDay(Int64 a_TimeOfDay) = 0;
|
||||
|
||||
/** Wakes up the simulators for the specified block */
|
||||
virtual void WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) = 0;
|
||||
|
||||
};
|
||||
|
@ -165,6 +165,7 @@ cByteBuffer::~cByteBuffer()
|
||||
{
|
||||
CheckValid();
|
||||
delete[] m_Buffer;
|
||||
m_Buffer = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
cmake_minimum_required (VERSION 2.8.2)
|
||||
project (MCServer)
|
||||
|
||||
include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/")
|
||||
include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/jsoncpp/include")
|
||||
include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/polarssl/include")
|
||||
include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/")
|
||||
include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/jsoncpp/include")
|
||||
include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/polarssl/include")
|
||||
|
||||
set(FOLDERS OSSupport HTTPServer Items Blocks Protocol Generating PolarSSL++)
|
||||
set(FOLDERS ${FOLDERS} WorldStorage Mobs Entities Simulator UI BlockEntities Generating/Prefabs)
|
||||
@ -12,6 +12,7 @@ set(BINDING_DEPENDECIES
|
||||
tolua
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Bindings/virtual_method_hooks.lua
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Bindings/AllToLua.pkg
|
||||
Bindings/gen_LuaState_Call.lua
|
||||
Bindings/LuaFunctions.h
|
||||
Bindings/LuaWindow.h
|
||||
Bindings/Plugin.h
|
||||
@ -79,16 +80,22 @@ set(BINDING_DEPENDECIES
|
||||
World.h
|
||||
)
|
||||
|
||||
# List all the files that are generated as part of the Bindings build process
|
||||
set (BINDING_OUTPUTS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Bindings/LuaState_Call.inc
|
||||
)
|
||||
|
||||
include_directories(Bindings)
|
||||
include_directories(.)
|
||||
|
||||
if (WIN32)
|
||||
ADD_CUSTOM_COMMAND(
|
||||
# add any new generated bindings here
|
||||
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.h
|
||||
OUTPUT ${BINDING_OUTPUTS}
|
||||
|
||||
# Copy the Lua DLL into the Bindings folder, so that tolua can run from there:
|
||||
COMMAND copy /y ..\\..\\MCServer\\lua51.dll .
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ../../MCServer/lua51.dll ./lua51.dll
|
||||
|
||||
# Regenerate bindings:
|
||||
COMMAND tolua -L virtual_method_hooks.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
|
||||
@ -119,6 +126,7 @@ if (NOT MSVC)
|
||||
|
||||
# lib dependencies are not included
|
||||
|
||||
include_directories ("${CMAKE_CURRENT_SOURCE_DIR}/../lib/polarssl/include")
|
||||
|
||||
#add cpp files here
|
||||
add_library(Bindings
|
||||
@ -134,7 +142,7 @@ if (NOT MSVC)
|
||||
Bindings/WebPlugin
|
||||
)
|
||||
|
||||
target_link_libraries(Bindings lua sqlite tolualib)
|
||||
target_link_libraries(Bindings lua sqlite tolualib polarssl)
|
||||
|
||||
#clear file
|
||||
file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/BindingDependecies.txt)
|
||||
@ -260,4 +268,4 @@ endif ()
|
||||
if (WIN32)
|
||||
target_link_libraries(${EXECUTABLE} expat tolualib ws2_32.lib Psapi.lib)
|
||||
endif()
|
||||
target_link_libraries(${EXECUTABLE} md5 luaexpat iniFile jsoncpp polarssl zlib lua sqlite)
|
||||
target_link_libraries(${EXECUTABLE} luaexpat iniFile jsoncpp polarssl zlib sqlite lua)
|
||||
|
@ -152,7 +152,9 @@ cChunk::~cChunk()
|
||||
m_NeighborZP->m_NeighborZM = NULL;
|
||||
}
|
||||
delete m_WaterSimulatorData;
|
||||
m_WaterSimulatorData = NULL;
|
||||
delete m_LavaSimulatorData;
|
||||
m_LavaSimulatorData = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -596,6 +598,7 @@ void cChunk::Tick(float a_Dt)
|
||||
cEntity * ToDelete = *itr;
|
||||
itr = m_Entities.erase(itr);
|
||||
delete ToDelete;
|
||||
ToDelete = NULL;
|
||||
continue;
|
||||
}
|
||||
++itr;
|
||||
@ -1417,6 +1420,7 @@ void cChunk::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType,
|
||||
BlockEntity->Destroy();
|
||||
RemoveBlockEntity(BlockEntity);
|
||||
delete BlockEntity;
|
||||
BlockEntity = NULL;
|
||||
}
|
||||
|
||||
// If the new block is a block entity, create the entity object:
|
||||
@ -1612,6 +1616,12 @@ void cChunk::AddBlockEntity(cBlockEntity * a_BlockEntity)
|
||||
|
||||
cBlockEntity * cChunk::GetBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Check that the query coords are within chunk bounds:
|
||||
ASSERT(a_BlockX >= m_PosX * cChunkDef::Width);
|
||||
ASSERT(a_BlockX < m_PosX * cChunkDef::Width + cChunkDef::Width);
|
||||
ASSERT(a_BlockZ >= m_PosZ * cChunkDef::Width);
|
||||
ASSERT(a_BlockZ < m_PosZ * cChunkDef::Width + cChunkDef::Width);
|
||||
|
||||
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
|
||||
{
|
||||
if (
|
||||
@ -2691,7 +2701,7 @@ void cChunk::BroadcastChunkData(cChunkDataSerializer & a_Serializer, const cClie
|
||||
|
||||
|
||||
|
||||
void cChunk::BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude)
|
||||
void cChunk::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude)
|
||||
{
|
||||
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr )
|
||||
{
|
||||
@ -2699,7 +2709,7 @@ void cChunk::BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_
|
||||
{
|
||||
continue;
|
||||
}
|
||||
(*itr)->SendCollectPickup(a_Pickup, a_Player);
|
||||
(*itr)->SendCollectEntity(a_Entity, a_Player);
|
||||
} // for itr - LoadedByClient[]
|
||||
}
|
||||
|
||||
|
@ -279,7 +279,7 @@ public:
|
||||
void BroadcastBlockBreakAnimation(int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastChunkData (cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL);
|
||||
|
@ -419,16 +419,16 @@ void cChunkMap::BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSeriali
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude)
|
||||
void cChunkMap::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSLayers);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Pickup.GetChunkX(), ZERO_CHUNK_Y, a_Pickup.GetChunkZ());
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ());
|
||||
if (Chunk == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastCollectPickup(a_Pickup, a_Player, a_Exclude);
|
||||
Chunk->BroadcastCollectEntity(a_Entity, a_Player, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
@ -70,6 +70,7 @@ public:
|
||||
void BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a_blockY, int a_blockZ, char a_stage, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude);
|
||||
void BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = NULL);
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "CompositeChat.h"
|
||||
#include "Items/ItemSword.h"
|
||||
|
||||
#include "md5/md5.h"
|
||||
#include "polarssl/md5.h"
|
||||
|
||||
|
||||
|
||||
@ -232,22 +232,49 @@ AString cClientHandle::FormatMessageType(bool ShouldAppendChatPrefixes, eMessage
|
||||
|
||||
AString cClientHandle::GenerateOfflineUUID(const AString & a_Username)
|
||||
{
|
||||
// Online UUIDs are always version 4 (random)
|
||||
// We use Version 3 (MD5 hash) UUIDs for the offline UUIDs
|
||||
// This guarantees that they will never collide with an online UUID and can be distinguished.
|
||||
// Proper format for a version 3 UUID is:
|
||||
// xxxxxxxx-xxxx-3xxx-yxxx-xxxxxxxxxxxx where x is any hexadecimal digit and y is one of 8, 9, A, or B
|
||||
|
||||
// Generate an md5 checksum, and use it as base for the ID:
|
||||
MD5 Checksum(a_Username);
|
||||
AString UUID = Checksum.hexdigest();
|
||||
UUID[12] = '3'; // Version 3 UUID
|
||||
UUID[16] = '8'; // Variant 1 UUID
|
||||
unsigned char MD5[16];
|
||||
md5((const unsigned char *)a_Username.c_str(), a_Username.length(), MD5);
|
||||
MD5[6] &= 0x0f; // Need to trim to 4 bits only...
|
||||
MD5[8] &= 0x0f; // ... otherwise %01x overflows into two chars
|
||||
return Printf("%02x%02x%02x%02x-%02x%02x-3%01x%02x-8%01x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
MD5[0], MD5[1], MD5[2], MD5[3],
|
||||
MD5[4], MD5[5], MD5[6], MD5[7],
|
||||
MD5[8], MD5[9], MD5[10], MD5[11],
|
||||
MD5[12], MD5[13], MD5[14], MD5[15]
|
||||
);
|
||||
}
|
||||
|
||||
// Now the digest doesn't have the UUID slashes, but the client requires them, so add them into the appropriate positions:
|
||||
UUID.insert(8, "-");
|
||||
UUID.insert(13, "-");
|
||||
UUID.insert(18, "-");
|
||||
UUID.insert(23, "-");
|
||||
|
||||
return UUID;
|
||||
|
||||
|
||||
|
||||
bool cClientHandle::IsUUIDOnline(const AString & a_UUID)
|
||||
{
|
||||
// Online UUIDs are always version 4 (random)
|
||||
// We use Version 3 (MD5 hash) UUIDs for the offline UUIDs
|
||||
// This guarantees that they will never collide with an online UUID and can be distinguished.
|
||||
// The version-specifying char is at pos #12 of raw UUID, pos #14 in dashed-UUID.
|
||||
switch (a_UUID.size())
|
||||
{
|
||||
case 32:
|
||||
{
|
||||
// This is the UUID format without dashes, the version char is at pos #12:
|
||||
return (a_UUID[12] == '4');
|
||||
}
|
||||
case 36:
|
||||
{
|
||||
// This is the UUID format with dashes, the version char is at pos #14:
|
||||
return (a_UUID[14] == '4');
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -336,6 +363,9 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID)
|
||||
// Send scoreboard data
|
||||
World->GetScoreBoard().SendTo(*this);
|
||||
|
||||
// Send statistics
|
||||
SendStatistics(m_Player->GetStatManager());
|
||||
|
||||
// Delay the first ping until the client "settles down"
|
||||
// This should fix #889, "BadCast exception, cannot convert bit to fm" error in client
|
||||
cTimer t1;
|
||||
@ -953,6 +983,26 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc
|
||||
m_LastDigBlockY = a_BlockY;
|
||||
m_LastDigBlockZ = a_BlockZ;
|
||||
|
||||
// Check for clickthrough-blocks:
|
||||
/* When the user breaks a fire block, the client send the wrong block location.
|
||||
We must find the right block with the face direction. */
|
||||
if (a_BlockFace != BLOCK_FACE_NONE)
|
||||
{
|
||||
int pX = a_BlockX;
|
||||
int pY = a_BlockY;
|
||||
int pZ = a_BlockZ;
|
||||
|
||||
AddFaceDirection(pX, pY, pZ, a_BlockFace); // Get the block in front of the clicked coordinates (m_bInverse defaulted to false)
|
||||
cBlockHandler * Handler = cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(pX, pY, pZ));
|
||||
|
||||
if (Handler->IsClickedThrough())
|
||||
{
|
||||
cChunkInterface ChunkInterface(m_Player->GetWorld()->GetChunkMap());
|
||||
Handler->OnDigging(ChunkInterface, *m_Player->GetWorld(), m_Player, pX, pY, pZ);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(m_Player->IsGameModeCreative()) || // In creative mode, digging is done immediately
|
||||
cBlockInfo::IsOneHitDig(a_OldBlock) // One-hit blocks get destroyed immediately, too
|
||||
@ -979,22 +1029,6 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc
|
||||
|
||||
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem());
|
||||
ItemHandler->OnDiggingBlock(World, m_Player, m_Player->GetEquippedItem(), a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
|
||||
|
||||
// Check for clickthrough-blocks:
|
||||
if (a_BlockFace != BLOCK_FACE_NONE)
|
||||
{
|
||||
int pX = a_BlockX;
|
||||
int pY = a_BlockY;
|
||||
int pZ = a_BlockZ;
|
||||
|
||||
AddFaceDirection(pX, pY, pZ, a_BlockFace); // Get the block in front of the clicked coordinates (m_bInverse defaulted to false)
|
||||
Handler = cBlockInfo::GetHandler(World->GetBlock(pX, pY, pZ));
|
||||
|
||||
if (Handler->IsClickedThrough())
|
||||
{
|
||||
Handler->OnDigging(ChunkInterface, *World, m_Player, pX, pY, pZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1052,12 +1086,7 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo
|
||||
|
||||
void cClientHandle::FinishDigAnimation()
|
||||
{
|
||||
if (
|
||||
!m_HasStartedDigging || // Hasn't received the DIG_STARTED packet
|
||||
(m_LastDigBlockX == -1) ||
|
||||
(m_LastDigBlockY == -1) ||
|
||||
(m_LastDigBlockZ == -1)
|
||||
)
|
||||
if (!m_HasStartedDigging) // Hasn't received the DIG_STARTED packet
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -1195,9 +1224,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
|
||||
{
|
||||
// A plugin won't let us eat, abort (send the proper packets to the client, too):
|
||||
m_Player->AbortEating();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2045,9 +2072,9 @@ void cClientHandle::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializ
|
||||
|
||||
|
||||
|
||||
void cClientHandle::SendCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player)
|
||||
void cClientHandle::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player)
|
||||
{
|
||||
m_Protocol->SendCollectPickup(a_Pickup, a_Player);
|
||||
m_Protocol->SendCollectEntity(a_Entity, a_Player);
|
||||
}
|
||||
|
||||
|
||||
@ -2369,9 +2396,9 @@ void cClientHandle::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Effec
|
||||
|
||||
|
||||
|
||||
void cClientHandle::SendRespawn(const cWorld & a_World)
|
||||
void cClientHandle::SendRespawn(const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks)
|
||||
{
|
||||
m_Protocol->SendRespawn(a_World);
|
||||
m_Protocol->SendRespawn(a_World, a_ShouldIgnoreDimensionChecks);
|
||||
}
|
||||
|
||||
|
||||
|
@ -63,7 +63,7 @@ public:
|
||||
|
||||
const AString & GetIPString(void) const { return m_IPString; }
|
||||
|
||||
cPlayer* GetPlayer() { return m_Player; } // tolua_export
|
||||
cPlayer * GetPlayer(void) { return m_Player; } // tolua_export
|
||||
|
||||
const AString & GetUUID(void) const { return m_UUID; } // tolua_export
|
||||
void SetUUID(const AString & a_UUID) { m_UUID = a_UUID; }
|
||||
@ -76,9 +76,16 @@ public:
|
||||
|
||||
/** 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. */
|
||||
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 36-char UUID (with dashes). */
|
||||
static AString GenerateOfflineUUID(const AString & a_Username); // tolua_export
|
||||
|
||||
/** Returns true if the UUID is generated by online auth, false if it is an offline-generated UUID.
|
||||
We use Version-3 UUIDs for offline UUIDs, online UUIDs are Version-4, thus we can tell them apart.
|
||||
Accepts both 32-char and 36-char UUIDs (with and without dashes).
|
||||
If the string given is not a valid UUID, returns false. */
|
||||
static bool IsUUIDOnline(const AString & a_UUID); // tolua_export
|
||||
|
||||
/** Formats the type of message with the proper color and prefix for sending to the client. **/
|
||||
static AString FormatMessageType(bool ShouldAppendChatPrefixes, eMessageType a_ChatPrefix, const AString & a_AdditionalData);
|
||||
|
||||
@ -116,7 +123,7 @@ public:
|
||||
void SendChat (const AString & a_Message, eMessageType a_ChatPrefix, const AString & a_AdditionalData = "");
|
||||
void SendChat (const cCompositeChat & a_Message);
|
||||
void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer);
|
||||
void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player);
|
||||
void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player);
|
||||
void SendDestroyEntity (const cEntity & a_Entity);
|
||||
void SendDisconnect (const AString & a_Reason);
|
||||
void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
@ -149,7 +156,7 @@ public:
|
||||
void SendPlayerSpawn (const cPlayer & a_Player);
|
||||
void SendPluginMessage (const AString & a_Channel, const AString & a_Message); // Exported in ManualBindings.cpp
|
||||
void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID);
|
||||
void SendRespawn (const cWorld & a_World);
|
||||
void SendRespawn (const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks = false);
|
||||
void SendExperience (void);
|
||||
void SendExperienceOrb (const cExpOrb & a_ExpOrb);
|
||||
void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode);
|
||||
|
@ -59,6 +59,7 @@ cCraftingGrid::cCraftingGrid(const cCraftingGrid & a_Original) :
|
||||
cCraftingGrid::~cCraftingGrid()
|
||||
{
|
||||
delete[] m_Items;
|
||||
m_Items = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -274,8 +274,19 @@ inline eBlockFace RotateBlockFaceCW(eBlockFace a_BlockFace)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline eBlockFace ReverseBlockFace(eBlockFace a_BlockFace)
|
||||
{
|
||||
switch (a_BlockFace)
|
||||
{
|
||||
case BLOCK_FACE_YP: return BLOCK_FACE_YM;
|
||||
case BLOCK_FACE_XP: return BLOCK_FACE_XM;
|
||||
case BLOCK_FACE_ZP: return BLOCK_FACE_ZM;
|
||||
case BLOCK_FACE_YM: return BLOCK_FACE_YP;
|
||||
case BLOCK_FACE_XM: return BLOCK_FACE_XP;
|
||||
case BLOCK_FACE_ZM: return BLOCK_FACE_ZP;
|
||||
default: return a_BlockFace;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Returns the textual representation of the BlockFace constant. */
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "Player.h"
|
||||
#include "ArrowEntity.h"
|
||||
#include "../Chunk.h"
|
||||
#include "FastRandom.h"
|
||||
|
||||
|
||||
|
||||
@ -44,6 +45,10 @@ cArrowEntity::cArrowEntity(cPlayer & a_Player, double a_Force) :
|
||||
m_bIsCollected(false),
|
||||
m_HitBlockPos(0, 0, 0)
|
||||
{
|
||||
if (a_Player.IsGameModeCreative())
|
||||
{
|
||||
m_PickupState = psInCreative;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -68,25 +73,23 @@ bool cArrowEntity::CanPickup(const cPlayer & a_Player) const
|
||||
|
||||
void cArrowEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace)
|
||||
{
|
||||
if (a_HitFace == BLOCK_FACE_NONE) { return; }
|
||||
|
||||
super::OnHitSolidBlock(a_HitPos, a_HitFace);
|
||||
int a_X = (int)a_HitPos.x, a_Y = (int)a_HitPos.y, a_Z = (int)a_HitPos.z;
|
||||
|
||||
switch (a_HitFace)
|
||||
if (GetSpeed().EqualsEps(Vector3d(0, 0, 0), 0.0000001))
|
||||
{
|
||||
case BLOCK_FACE_XM: // Strangely, bounding boxes / block tracers return the actual block for these two directions, so AddFace not needed
|
||||
case BLOCK_FACE_YM:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default: AddFaceDirection(a_X, a_Y, a_Z, a_HitFace, true);
|
||||
SetSpeed(GetLookVector().NormalizeCopy() * 0.1); // Ensure that no division by zero happens later
|
||||
}
|
||||
|
||||
m_HitBlockPos = Vector3i(a_X, a_Y, a_Z);
|
||||
Vector3d Hit = a_HitPos;
|
||||
Vector3d SinkMovement = (GetSpeed() / 800);
|
||||
Hit += (SinkMovement * 0.01) / SinkMovement.Length(); // Make arrow sink into block a centimetre so it lodges (but not to far so it goes black clientside)
|
||||
|
||||
super::OnHitSolidBlock(Hit, a_HitFace);
|
||||
Vector3i BlockHit = Hit.Floor();
|
||||
|
||||
int X = BlockHit.x, Y = BlockHit.y, Z = BlockHit.z;
|
||||
m_HitBlockPos = Vector3i(X, Y, Z);
|
||||
|
||||
// Broadcast arrow hit sound
|
||||
m_World->BroadcastSoundEffect("random.bowhit", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
|
||||
m_World->BroadcastSoundEffect("random.bowhit", X * 8, Y * 8, Z * 8, 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
|
||||
}
|
||||
|
||||
|
||||
@ -95,12 +98,6 @@ void cArrowEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFa
|
||||
|
||||
void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos)
|
||||
{
|
||||
if (!a_EntityHit.IsMob() && !a_EntityHit.IsMinecart() && !a_EntityHit.IsPlayer() && !a_EntityHit.IsBoat())
|
||||
{
|
||||
// Not an entity that interacts with an arrow
|
||||
return;
|
||||
}
|
||||
|
||||
int Damage = (int)(GetSpeed().Length() / 20 * m_DamageCoeff + 0.5);
|
||||
if (m_IsCritical)
|
||||
{
|
||||
@ -109,7 +106,7 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos)
|
||||
a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, 1);
|
||||
|
||||
// Broadcast successful hit sound
|
||||
m_World->BroadcastSoundEffect("random.successful_hit", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
|
||||
GetWorld()->BroadcastSoundEffect("random.successful_hit", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
|
||||
|
||||
Destroy();
|
||||
}
|
||||
@ -120,17 +117,23 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos)
|
||||
|
||||
void cArrowEntity::CollectedBy(cPlayer * a_Dest)
|
||||
{
|
||||
if ((m_IsInGround) && (!m_bIsCollected) && (CanPickup(*a_Dest)))
|
||||
if (m_IsInGround && !m_bIsCollected && CanPickup(*a_Dest))
|
||||
{
|
||||
// Do not add the arrow to the inventory when the player is in creative:
|
||||
if (!a_Dest->IsGameModeCreative())
|
||||
{
|
||||
int NumAdded = a_Dest->GetInventory().AddItem(E_ITEM_ARROW);
|
||||
if (NumAdded > 0) // Only play effects if there was space in inventory
|
||||
if (NumAdded == 0)
|
||||
{
|
||||
m_World->BroadcastCollectPickup((const cPickup &)*this, *a_Dest);
|
||||
// Also send the "pop" sound effect with a somewhat random pitch (fast-random using EntityID ;)
|
||||
m_World->BroadcastSoundEffect("random.pop", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
|
||||
m_bIsCollected = true;
|
||||
// No space in the inventory
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
GetWorld()->BroadcastCollectEntity(*this, *a_Dest);
|
||||
GetWorld()->BroadcastSoundEffect("random.pop", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
|
||||
m_bIsCollected = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -165,7 +168,7 @@ void cArrowEntity::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
|
||||
if (!m_HasTeleported) // Sent a teleport already, don't do again
|
||||
{
|
||||
if (m_HitGroundTimer > 1000.f) // Send after a second, could be less, but just in case
|
||||
if (m_HitGroundTimer > 500.f) // Send after half a second, could be less, but just in case
|
||||
{
|
||||
m_World->BroadcastTeleportEntity(*this);
|
||||
m_HasTeleported = true;
|
||||
|
@ -59,8 +59,14 @@ public:
|
||||
/// Sets the IsCritical flag
|
||||
void SetIsCritical(bool a_IsCritical) { m_IsCritical = a_IsCritical; }
|
||||
|
||||
/** Gets the block arrow is in */
|
||||
Vector3i GetBlockHit(void) const { return m_HitBlockPos; }
|
||||
|
||||
// tolua_end
|
||||
|
||||
/** Sets the block arrow is in. To be used by the MCA loader only! */
|
||||
void SetBlockHit(const Vector3i & a_BlockHit) { m_HitBlockPos = a_BlockHit; }
|
||||
|
||||
protected:
|
||||
|
||||
/// Determines when the arrow can be picked up by players
|
||||
|
@ -1091,8 +1091,11 @@ void cEntity::HandleAir(void)
|
||||
// Get the type of block the entity is standing in:
|
||||
|
||||
if (IsSubmerged())
|
||||
{
|
||||
if (!IsPlayer()) // Players control themselves
|
||||
{
|
||||
SetSpeedY(1); // Float in the water
|
||||
}
|
||||
|
||||
// Either reduce air level or damage player
|
||||
if (m_AirLevel < 1)
|
||||
@ -1479,7 +1482,6 @@ void cEntity::SetWidth(double a_Width)
|
||||
void cEntity::AddPosX(double a_AddPosX)
|
||||
{
|
||||
m_Pos.x += a_AddPosX;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1488,7 +1490,6 @@ void cEntity::AddPosX(double a_AddPosX)
|
||||
void cEntity::AddPosY(double a_AddPosY)
|
||||
{
|
||||
m_Pos.y += a_AddPosY;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1497,7 +1498,6 @@ void cEntity::AddPosY(double a_AddPosY)
|
||||
void cEntity::AddPosZ(double a_AddPosZ)
|
||||
{
|
||||
m_Pos.z += a_AddPosZ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1508,7 +1508,6 @@ void cEntity::AddPosition(double a_AddPosX, double a_AddPosY, double a_AddPosZ)
|
||||
m_Pos.x += a_AddPosX;
|
||||
m_Pos.y += a_AddPosY;
|
||||
m_Pos.z += a_AddPosZ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -238,9 +238,9 @@ public:
|
||||
void AddPosY (double a_AddPosY);
|
||||
void AddPosZ (double a_AddPosZ);
|
||||
void AddPosition(double a_AddPosX, double a_AddPosY, double a_AddPosZ);
|
||||
void AddPosition(const Vector3d & a_AddPos) { AddPosition(a_AddPos.x,a_AddPos.y,a_AddPos.z);}
|
||||
void AddPosition(const Vector3d & a_AddPos) { AddPosition(a_AddPos.x, a_AddPos.y, a_AddPos.z); }
|
||||
void AddSpeed (double a_AddSpeedX, double a_AddSpeedY, double a_AddSpeedZ);
|
||||
void AddSpeed (const Vector3d & a_AddSpeed) { AddSpeed(a_AddSpeed.x,a_AddSpeed.y,a_AddSpeed.z);}
|
||||
void AddSpeed (const Vector3d & a_AddSpeed) { AddSpeed(a_AddSpeed.x, a_AddSpeed.y, a_AddSpeed.z); }
|
||||
void AddSpeedX (double a_AddSpeedX);
|
||||
void AddSpeedY (double a_AddSpeedY);
|
||||
void AddSpeedZ (double a_AddSpeedZ);
|
||||
|
@ -30,7 +30,7 @@ public:
|
||||
|
||||
virtual bool Item(cEntity * a_Entity) override
|
||||
{
|
||||
if (!a_Entity->IsPickup() || (a_Entity->GetUniqueID() == m_Pickup->GetUniqueID()) || a_Entity->IsDestroyed())
|
||||
if (!a_Entity->IsPickup() || (a_Entity->GetUniqueID() <= m_Pickup->GetUniqueID()) || a_Entity->IsDestroyed())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -38,10 +38,31 @@ public:
|
||||
Vector3d EntityPos = a_Entity->GetPosition();
|
||||
double Distance = (EntityPos - m_Position).Length();
|
||||
|
||||
if ((Distance < 1.2) && ((cPickup *)a_Entity)->GetItem().IsEqual(m_Pickup->GetItem()))
|
||||
cItem & Item = ((cPickup *)a_Entity)->GetItem();
|
||||
if ((Distance < 1.2) && Item.IsEqual(m_Pickup->GetItem()))
|
||||
{
|
||||
short CombineCount = Item.m_ItemCount;
|
||||
if ((CombineCount + m_Pickup->GetItem().m_ItemCount) > Item.GetMaxStackSize())
|
||||
{
|
||||
CombineCount = Item.GetMaxStackSize() - m_Pickup->GetItem().m_ItemCount;
|
||||
}
|
||||
|
||||
if (CombineCount <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Pickup->GetItem().AddCount((char)CombineCount);
|
||||
Item.m_ItemCount -= CombineCount;
|
||||
|
||||
if (Item.m_ItemCount <= 0)
|
||||
{
|
||||
m_Pickup->GetItem().AddCount(((cPickup *)a_Entity)->GetItem().m_ItemCount);
|
||||
a_Entity->Destroy();
|
||||
}
|
||||
else
|
||||
{
|
||||
a_Entity->GetWorld()->BroadcastEntityMetadata(*a_Entity);
|
||||
}
|
||||
m_FoundMatchingPickup = true;
|
||||
}
|
||||
return false;
|
||||
@ -129,7 +150,7 @@ void cPickup::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsDestroyed()) // Don't try to combine if someone has tried to combine me
|
||||
if (!IsDestroyed() && (m_Item.m_ItemCount < m_Item.GetMaxStackSize())) // Don't combine into an already full pickup
|
||||
{
|
||||
cPickupCombiningCallback PickupCombiningCallback(GetPosition(), this);
|
||||
m_World->ForEachEntity(PickupCombiningCallback); // Not ForEachEntityInChunk, otherwise pickups don't combine across chunk boundaries
|
||||
@ -203,10 +224,10 @@ bool cPickup::CollectedBy(cPlayer * a_Dest)
|
||||
}
|
||||
|
||||
m_Item.m_ItemCount -= NumAdded;
|
||||
m_World->BroadcastCollectPickup(*this, *a_Dest);
|
||||
m_World->BroadcastCollectEntity(*this, *a_Dest);
|
||||
// Also send the "pop" sound effect with a somewhat random pitch (fast-random using EntityID ;)
|
||||
m_World->BroadcastSoundEffect("random.pop",(int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
|
||||
if (m_Item.m_ItemCount == 0)
|
||||
if (m_Item.m_ItemCount <= 0)
|
||||
{
|
||||
// All of the pickup has been collected, schedule the pickup for destroying
|
||||
m_bCollected = true;
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#include "Player.h"
|
||||
@ -8,6 +8,7 @@
|
||||
#include "../World.h"
|
||||
#include "../Bindings/PluginManager.h"
|
||||
#include "../BlockEntities/BlockEntity.h"
|
||||
#include "../BlockEntities/EnderChestEntity.h"
|
||||
#include "../GroupManager.h"
|
||||
#include "../Group.h"
|
||||
#include "../Root.h"
|
||||
@ -37,14 +38,15 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
|
||||
: super(etPlayer, 0.6, 1.8)
|
||||
, m_bVisible(true)
|
||||
, m_FoodLevel(MAX_FOOD_LEVEL)
|
||||
, m_FoodSaturationLevel(5)
|
||||
, m_FoodSaturationLevel(5.0)
|
||||
, m_FoodTickTimer(0)
|
||||
, m_FoodExhaustionLevel(0)
|
||||
, m_FoodExhaustionLevel(0.0)
|
||||
, m_LastJumpHeight(0)
|
||||
, m_LastGroundHeight(0)
|
||||
, m_bTouchGround(false)
|
||||
, m_Stance(0.0)
|
||||
, m_Inventory(*this)
|
||||
, m_EnderChestContents(9, 3)
|
||||
, m_CurrentWindow(NULL)
|
||||
, m_InventoryWindow(NULL)
|
||||
, m_Color('-')
|
||||
@ -70,6 +72,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
|
||||
, m_FloaterID(-1)
|
||||
, m_Team(NULL)
|
||||
, m_TicksUntilNextSave(PLAYER_INVENTORY_SAVE_INTERVAL)
|
||||
, m_bIsTeleporting(false)
|
||||
{
|
||||
LOGD("Created a player object for \"%s\" @ \"%s\" at %p, ID %d",
|
||||
a_PlayerName.c_str(), a_Client->GetIPString().c_str(),
|
||||
@ -145,6 +148,7 @@ cPlayer::~cPlayer(void)
|
||||
m_ClientHandle = NULL;
|
||||
|
||||
delete m_InventoryWindow;
|
||||
m_InventoryWindow = NULL;
|
||||
|
||||
LOGD("Player %p deleted", this);
|
||||
}
|
||||
@ -223,7 +227,7 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
SendExperience();
|
||||
}
|
||||
|
||||
if (GetPosition() != m_LastPos) // Change in position from last tick?
|
||||
if (!GetPosition().EqualsEps(m_LastPos, 0.01)) // Non negligible change in position from last tick?
|
||||
{
|
||||
// Apply food exhaustion from movement:
|
||||
ApplyFoodExhaustionFromMovement();
|
||||
@ -410,6 +414,7 @@ void cPlayer::StartChargingBow(void)
|
||||
LOGD("Player \"%s\" started charging their bow", GetName().c_str());
|
||||
m_IsChargingBow = true;
|
||||
m_BowCharge = 0;
|
||||
m_World->BroadcastEntityMetadata(*this, m_ClientHandle);
|
||||
}
|
||||
|
||||
|
||||
@ -422,6 +427,8 @@ int cPlayer::FinishChargingBow(void)
|
||||
int res = m_BowCharge;
|
||||
m_IsChargingBow = false;
|
||||
m_BowCharge = 0;
|
||||
m_World->BroadcastEntityMetadata(*this, m_ClientHandle);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -434,6 +441,7 @@ void cPlayer::CancelChargingBow(void)
|
||||
LOGD("Player \"%s\" cancelled charging their bow at a charge of %d", GetName().c_str(), m_BowCharge);
|
||||
m_IsChargingBow = false;
|
||||
m_BowCharge = 0;
|
||||
m_World->BroadcastEntityMetadata(*this, m_ClientHandle);
|
||||
}
|
||||
|
||||
|
||||
@ -515,7 +523,15 @@ void cPlayer::Heal(int a_Health)
|
||||
|
||||
void cPlayer::SetFoodLevel(int a_FoodLevel)
|
||||
{
|
||||
m_FoodLevel = std::max(0, std::min(a_FoodLevel, (int)MAX_FOOD_LEVEL));
|
||||
int FoodLevel = std::max(0, std::min(a_FoodLevel, (int)MAX_FOOD_LEVEL));
|
||||
|
||||
if (cRoot::Get()->GetPluginManager()->CallHookPlayerFoodLevelChange(*this, FoodLevel))
|
||||
{
|
||||
m_FoodSaturationLevel = 5.0;
|
||||
return;
|
||||
}
|
||||
|
||||
m_FoodLevel = FoodLevel;
|
||||
SendHealth();
|
||||
}
|
||||
|
||||
@ -557,10 +573,8 @@ bool cPlayer::Feed(int a_Food, double a_Saturation)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_FoodLevel = std::min(a_Food + m_FoodLevel, (int)MAX_FOOD_LEVEL);
|
||||
m_FoodSaturationLevel = std::min(m_FoodSaturationLevel + a_Saturation, (double)m_FoodLevel);
|
||||
|
||||
SendHealth();
|
||||
SetFoodSaturationLevel(m_FoodSaturationLevel + a_Saturation);
|
||||
SetFoodLevel(m_FoodLevel + a_Food);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -944,14 +958,15 @@ void cPlayer::Respawn(void)
|
||||
|
||||
// Reset food level:
|
||||
m_FoodLevel = MAX_FOOD_LEVEL;
|
||||
m_FoodSaturationLevel = 5;
|
||||
m_FoodSaturationLevel = 5.0;
|
||||
m_FoodExhaustionLevel = 0.0;
|
||||
|
||||
// Reset Experience
|
||||
m_CurrentXp = 0;
|
||||
m_LifetimeTotalXp = 0;
|
||||
// ToDo: send score to client? How?
|
||||
|
||||
m_ClientHandle->SendRespawn(*m_World);
|
||||
m_ClientHandle->SendRespawn(*m_World, true);
|
||||
|
||||
// Extinguish the fire:
|
||||
StopBurning();
|
||||
@ -1201,6 +1216,7 @@ void cPlayer::TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ)
|
||||
SetPosition(a_PosX, a_PosY, a_PosZ);
|
||||
m_LastGroundHeight = (float)a_PosY;
|
||||
m_LastJumpHeight = (float)a_PosY;
|
||||
m_bIsTeleporting = true;
|
||||
|
||||
m_World->BroadcastTeleportEntity(*this, GetClientHandle());
|
||||
m_ClientHandle->SendPlayerMoveLook();
|
||||
@ -1718,6 +1734,7 @@ bool cPlayer::LoadFromDisk()
|
||||
}
|
||||
|
||||
m_Inventory.LoadFromJson(root["inventory"]);
|
||||
cEnderChestEntity::LoadFromJson(root["enderchestinventory"], m_EnderChestContents);
|
||||
|
||||
m_LoadedWorldName = root.get("world", "world").asString();
|
||||
|
||||
@ -1755,10 +1772,14 @@ bool cPlayer::SaveToDisk()
|
||||
Json::Value JSON_Inventory;
|
||||
m_Inventory.SaveToJson(JSON_Inventory);
|
||||
|
||||
Json::Value JSON_EnderChestInventory;
|
||||
cEnderChestEntity::SaveToJson(JSON_EnderChestInventory, m_EnderChestContents);
|
||||
|
||||
Json::Value root;
|
||||
root["position"] = JSON_PlayerPosition;
|
||||
root["rotation"] = JSON_PlayerRotation;
|
||||
root["inventory"] = JSON_Inventory;
|
||||
root["enderchestinventory"] = JSON_EnderChestInventory;
|
||||
root["health"] = m_Health;
|
||||
root["xpTotal"] = m_LifetimeTotalXp;
|
||||
root["xpCurrent"] = m_CurrentXp;
|
||||
@ -1877,9 +1898,6 @@ void cPlayer::HandleFood(void)
|
||||
return;
|
||||
}
|
||||
|
||||
// Remember the food level before processing, for later comparison
|
||||
int LastFoodLevel = m_FoodLevel;
|
||||
|
||||
// Heal or damage, based on the food level, using the m_FoodTickTimer:
|
||||
if ((m_FoodLevel > 17) || (m_FoodLevel <= 0))
|
||||
{
|
||||
@ -1888,11 +1906,11 @@ void cPlayer::HandleFood(void)
|
||||
{
|
||||
m_FoodTickTimer = 0;
|
||||
|
||||
if (m_FoodLevel >= 17)
|
||||
if ((m_FoodLevel > 17) && (GetHealth() < GetMaxHealth()))
|
||||
{
|
||||
// Regenerate health from food, incur 3 pts of food exhaustion:
|
||||
Heal(1);
|
||||
m_FoodExhaustionLevel += 3;
|
||||
m_FoodExhaustionLevel += 3.0;
|
||||
}
|
||||
else if ((m_FoodLevel <= 0) && (m_Health > 1))
|
||||
{
|
||||
@ -1903,24 +1921,19 @@ void cPlayer::HandleFood(void)
|
||||
}
|
||||
|
||||
// Apply food exhaustion that has accumulated:
|
||||
if (m_FoodExhaustionLevel >= 4)
|
||||
if (m_FoodExhaustionLevel >= 4.0)
|
||||
{
|
||||
m_FoodExhaustionLevel -= 4;
|
||||
m_FoodExhaustionLevel -= 4.0;
|
||||
|
||||
if (m_FoodSaturationLevel >= 1)
|
||||
if (m_FoodSaturationLevel >= 1.0)
|
||||
{
|
||||
m_FoodSaturationLevel -= 1;
|
||||
m_FoodSaturationLevel -= 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_FoodLevel = std::max(m_FoodLevel - 1, 0);
|
||||
SetFoodLevel(m_FoodLevel - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_FoodLevel != LastFoodLevel)
|
||||
{
|
||||
SendHealth();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2043,6 +2056,11 @@ void cPlayer::ApplyFoodExhaustionFromMovement()
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (m_bIsTeleporting)
|
||||
{
|
||||
m_bIsTeleporting = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// If riding anything, apply no food exhaustion
|
||||
if (m_AttachedTo != NULL)
|
||||
|
@ -125,6 +125,9 @@ public:
|
||||
inline cInventory & GetInventory(void) { return m_Inventory; } // tolua_export
|
||||
inline const cInventory & GetInventory(void) const { return m_Inventory; }
|
||||
|
||||
/** Gets the contents of the player's associated enderchest */
|
||||
cItemGrid & GetEnderChestContents(void) { return m_EnderChestContents; }
|
||||
|
||||
inline const cItem & GetEquippedItem(void) const { return GetInventory().GetEquippedItem(); } // tolua_export
|
||||
|
||||
/** Returns whether the player is climbing (ladders, vines e.t.c). */
|
||||
@ -402,7 +405,7 @@ public:
|
||||
// cEntity overrides:
|
||||
virtual bool IsCrouched (void) const { return m_IsCrouched; }
|
||||
virtual bool IsSprinting(void) const { return m_IsSprinting; }
|
||||
virtual bool IsRclking (void) const { return IsEating(); }
|
||||
virtual bool IsRclking (void) const { return IsEating() || IsChargingBow(); }
|
||||
|
||||
virtual void Detach(void);
|
||||
|
||||
@ -444,7 +447,13 @@ protected:
|
||||
float m_LastGroundHeight;
|
||||
bool m_bTouchGround;
|
||||
double m_Stance;
|
||||
|
||||
/** Stores the player's inventory, consisting of crafting grid, hotbar, and main slots */
|
||||
cInventory m_Inventory;
|
||||
|
||||
/** An item grid that stores the player specific enderchest contents */
|
||||
cItemGrid m_EnderChestContents;
|
||||
|
||||
cWindow * m_CurrentWindow;
|
||||
cWindow * m_InventoryWindow;
|
||||
|
||||
@ -505,8 +514,6 @@ protected:
|
||||
|
||||
cStatManager m_Stats;
|
||||
|
||||
|
||||
|
||||
/** Sets the speed and sends it to the client, so that they are forced to move so. */
|
||||
virtual void DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ) override;
|
||||
|
||||
@ -541,6 +548,11 @@ protected:
|
||||
Default save interval is #defined in PLAYER_INVENTORY_SAVE_INTERVAL */
|
||||
unsigned int m_TicksUntilNextSave;
|
||||
|
||||
/** Flag used by food handling system to determine whether a teleport has just happened
|
||||
Will not apply food penalties if found to be true; will set to false after processing
|
||||
*/
|
||||
bool m_bIsTeleporting;
|
||||
|
||||
} ; // tolua_export
|
||||
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "FireworkEntity.h"
|
||||
#include "GhastFireballEntity.h"
|
||||
#include "WitherSkullEntity.h"
|
||||
#include "Player.h"
|
||||
|
||||
|
||||
|
||||
@ -68,16 +69,17 @@ protected:
|
||||
|
||||
if (cBlockInfo::IsSolid(a_BlockType))
|
||||
{
|
||||
// The projectile hit a solid block
|
||||
// Calculate the exact hit coords:
|
||||
cBoundingBox bb(a_BlockX, a_BlockX + 1, a_BlockY, a_BlockY + 1, a_BlockZ, a_BlockZ + 1);
|
||||
Vector3d Line1 = m_Projectile->GetPosition();
|
||||
Vector3d Line2 = Line1 + m_Projectile->GetSpeed();
|
||||
double LineCoeff = 0;
|
||||
eBlockFace Face;
|
||||
if (bb.CalcLineIntersection(Line1, Line2, LineCoeff, Face))
|
||||
// The projectile hit a solid block, calculate the exact hit coords:
|
||||
cBoundingBox bb(a_BlockX, a_BlockX + 1, a_BlockY, a_BlockY + 1, a_BlockZ, a_BlockZ + 1); // Bounding box of the block hit
|
||||
const Vector3d LineStart = m_Projectile->GetPosition(); // Start point for the imaginary line that goes through the block hit
|
||||
const Vector3d LineEnd = LineStart + m_Projectile->GetSpeed(); // End point for the imaginary line that goes through the block hit
|
||||
double LineCoeff = 0; // Used to calculate where along the line an intersection with the bounding box occurs
|
||||
eBlockFace Face; // Face hit
|
||||
|
||||
if (bb.CalcLineIntersection(LineStart, LineEnd, LineCoeff, Face))
|
||||
{
|
||||
Vector3d Intersection = Line1 + m_Projectile->GetSpeed() * LineCoeff;
|
||||
Vector3d Intersection = LineStart + m_Projectile->GetSpeed() * LineCoeff; // Point where projectile goes into the hit block
|
||||
|
||||
if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile, a_BlockX, a_BlockY, a_BlockZ, Face, &Intersection))
|
||||
{
|
||||
return false;
|
||||
@ -141,7 +143,7 @@ public:
|
||||
{
|
||||
if (
|
||||
(a_Entity == m_Projectile) || // Do not check collisions with self
|
||||
(a_Entity == m_Projectile->GetCreator()) // Do not check whoever shot the projectile
|
||||
(a_Entity->GetUniqueID() == m_Projectile->GetCreatorUniqueID()) // Do not check whoever shot the projectile
|
||||
)
|
||||
{
|
||||
// TODO: Don't check creator only for the first 5 ticks
|
||||
@ -162,7 +164,12 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Some entities don't interact with the projectiles (pickups, falling blocks)
|
||||
if (!a_Entity->IsMob() && !a_Entity->IsMinecart() && !a_Entity->IsPlayer() && !a_Entity->IsBoat())
|
||||
{
|
||||
// Not an entity that interacts with a projectile
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cPluginManager::Get()->CallHookProjectileHitEntity(*m_Projectile, *a_Entity))
|
||||
{
|
||||
// A plugin disagreed.
|
||||
@ -210,7 +217,10 @@ protected:
|
||||
cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, double a_Width, double a_Height) :
|
||||
super(etProjectile, a_X, a_Y, a_Z, a_Width, a_Height),
|
||||
m_ProjectileKind(a_Kind),
|
||||
m_Creator(a_Creator),
|
||||
m_CreatorData(
|
||||
((a_Creator != NULL) ? a_Creator->GetUniqueID() : -1),
|
||||
((a_Creator != NULL) ? (a_Creator->IsPlayer() ? ((cPlayer *)a_Creator)->GetName() : "") : "")
|
||||
),
|
||||
m_IsInGround(false)
|
||||
{
|
||||
}
|
||||
@ -222,7 +232,7 @@ cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, double a
|
||||
cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, const Vector3d & a_Pos, const Vector3d & a_Speed, double a_Width, double a_Height) :
|
||||
super(etProjectile, a_Pos.x, a_Pos.y, a_Pos.z, a_Width, a_Height),
|
||||
m_ProjectileKind(a_Kind),
|
||||
m_Creator(a_Creator),
|
||||
m_CreatorData(a_Creator->GetUniqueID(), a_Creator->IsPlayer() ? ((cPlayer *)a_Creator)->GetName() : ""),
|
||||
m_IsInGround(false)
|
||||
{
|
||||
SetSpeed(a_Speed);
|
||||
@ -300,7 +310,7 @@ AString cProjectileEntity::GetMCAClassName(void) const
|
||||
case pkEgg: return "Egg";
|
||||
case pkGhastFireball: return "Fireball";
|
||||
case pkFireCharge: return "SmallFireball";
|
||||
case pkEnderPearl: return "ThrownEnderPearl";
|
||||
case pkEnderPearl: return "ThrownEnderpearl";
|
||||
case pkExpBottle: return "ThrownExpBottle";
|
||||
case pkSplashPotion: return "ThrownPotion";
|
||||
case pkWitherSkull: return "WitherSkull";
|
||||
@ -319,7 +329,8 @@ void cProjectileEntity::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
{
|
||||
super::Tick(a_Dt, a_Chunk);
|
||||
|
||||
if (GetProjectileKind() != pkArrow) // See cArrow::Tick
|
||||
// TODO: see BroadcastMovementUpdate; RelativeMove packet jerkiness affects projectiles too (cause of sympton described in cArrowEntity::Tick())
|
||||
if (GetProjectileKind() != pkArrow)
|
||||
{
|
||||
BroadcastMovementUpdate();
|
||||
}
|
||||
@ -337,18 +348,9 @@ void cProjectileEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3d PerTickSpeed = GetSpeed() / 20;
|
||||
Vector3d Pos = GetPosition();
|
||||
|
||||
// Trace the tick's worth of movement as a line:
|
||||
Vector3d NextPos = Pos + PerTickSpeed;
|
||||
cProjectileTracerCallback TracerCallback(this);
|
||||
if (!cLineBlockTracer::Trace(*m_World, TracerCallback, Pos, NextPos))
|
||||
{
|
||||
// Something has been hit, abort all other processing
|
||||
return;
|
||||
}
|
||||
// The tracer also checks the blocks for slowdown blocks - water and lava - and stores it for later in its SlowdownCoeff
|
||||
const Vector3d PerTickSpeed = GetSpeed() / 20;
|
||||
const Vector3d Pos = GetPosition();
|
||||
const Vector3d NextPos = Pos + PerTickSpeed;
|
||||
|
||||
// Test for entity collisions:
|
||||
cProjectileEntityCollisionCallback EntityCollisionCallback(this, Pos, NextPos);
|
||||
@ -371,6 +373,15 @@ void cProjectileEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
|
||||
}
|
||||
// TODO: Test the entities in the neighboring chunks, too
|
||||
|
||||
// Trace the tick's worth of movement as a line:
|
||||
cProjectileTracerCallback TracerCallback(this);
|
||||
if (!cLineBlockTracer::Trace(*m_World, TracerCallback, Pos, NextPos))
|
||||
{
|
||||
// Something has been hit, abort all other processing
|
||||
return;
|
||||
}
|
||||
// The tracer also checks the blocks for slowdown blocks - water and lava - and stores it for later in its SlowdownCoeff
|
||||
|
||||
// Update the position:
|
||||
SetPosition(NextPos);
|
||||
|
||||
|
@ -66,8 +66,15 @@ public:
|
||||
/// Returns the kind of the projectile (fast class identification)
|
||||
eKind GetProjectileKind(void) const { return m_ProjectileKind; }
|
||||
|
||||
/// Returns the entity who created this projectile; may be NULL
|
||||
cEntity * GetCreator(void) { return m_Creator; }
|
||||
/** Returns the unique ID of the entity who created this projectile
|
||||
May return an ID <0
|
||||
*/
|
||||
int GetCreatorUniqueID(void) { return m_CreatorData.m_UniqueID; }
|
||||
|
||||
/** Returns the name of the player that created the projectile
|
||||
Will be empty for non-player creators
|
||||
*/
|
||||
AString GetCreatorName(void) const { return m_CreatorData.m_Name; }
|
||||
|
||||
/// Returns the string that is used as the entity type (class name) in MCA files
|
||||
AString GetMCAClassName(void) const;
|
||||
@ -81,10 +88,29 @@ public:
|
||||
void SetIsInGround(bool a_IsInGround) { m_IsInGround = a_IsInGround; }
|
||||
|
||||
protected:
|
||||
|
||||
/** A structure that stores the Entity ID and Playername of the projectile's creator
|
||||
Used to migitate invalid pointers caused by the creator being destroyed
|
||||
*/
|
||||
struct CreatorData
|
||||
{
|
||||
CreatorData(int a_UniqueID, const AString & a_Name) :
|
||||
m_UniqueID(a_UniqueID),
|
||||
m_Name(a_Name)
|
||||
{
|
||||
}
|
||||
|
||||
const int m_UniqueID;
|
||||
AString m_Name;
|
||||
};
|
||||
|
||||
/** The type of projectile I am */
|
||||
eKind m_ProjectileKind;
|
||||
|
||||
/// The entity who has created this projectile; may be NULL (e. g. for dispensers)
|
||||
cEntity * m_Creator;
|
||||
/** The structure for containing the entity ID and name who has created this projectile
|
||||
The ID and/or name may be NULL (e.g. for dispensers/mobs)
|
||||
*/
|
||||
CreatorData m_CreatorData;
|
||||
|
||||
/// True if the projectile has hit the ground and is stuck there
|
||||
bool m_IsInGround;
|
||||
|
@ -8,7 +8,8 @@
|
||||
|
||||
|
||||
cThrownEggEntity::cThrownEggEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed) :
|
||||
super(pkEgg, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25)
|
||||
super(pkEgg, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25),
|
||||
m_DestroyTimer(-1)
|
||||
{
|
||||
SetSpeed(a_Speed);
|
||||
}
|
||||
@ -21,7 +22,7 @@ void cThrownEggEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_H
|
||||
{
|
||||
TrySpawnChicken(a_HitPos);
|
||||
|
||||
Destroy();
|
||||
m_DestroyTimer = 2;
|
||||
}
|
||||
|
||||
|
||||
@ -36,7 +37,7 @@ void cThrownEggEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_Hit
|
||||
TrySpawnChicken(a_HitPos);
|
||||
a_EntityHit.TakeDamage(dtRangedAttack, this, TotalDamage, 1);
|
||||
|
||||
Destroy(true);
|
||||
m_DestroyTimer = 5;
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,8 +30,29 @@ protected:
|
||||
// cProjectileEntity overrides:
|
||||
virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override;
|
||||
virtual void OnHitEntity (cEntity & a_EntityHit, const Vector3d & a_HitPos) override;
|
||||
virtual void Tick (float a_Dt, cChunk & a_Chunk) override
|
||||
{
|
||||
if (m_DestroyTimer > 0)
|
||||
{
|
||||
m_DestroyTimer--;
|
||||
if (m_DestroyTimer == 0)
|
||||
{
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
super::Tick(a_Dt, a_Chunk);
|
||||
}
|
||||
}
|
||||
|
||||
// Randomly decides whether to spawn a chicken where the egg lands.
|
||||
void TrySpawnChicken(const Vector3d & a_HitPos);
|
||||
|
||||
private:
|
||||
|
||||
/** Time in ticks to wait for the hit animation to begin before destroying */
|
||||
int m_DestroyTimer;
|
||||
|
||||
} ; // tolua_export
|
||||
|
@ -1,13 +1,15 @@
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#include "ThrownEnderPearlEntity.h"
|
||||
#include "Player.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cThrownEnderPearlEntity::cThrownEnderPearlEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed) :
|
||||
super(pkEnderPearl, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25)
|
||||
super(pkEnderPearl, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25),
|
||||
m_DestroyTimer(-1)
|
||||
{
|
||||
SetSpeed(a_Speed);
|
||||
}
|
||||
@ -21,7 +23,7 @@ void cThrownEnderPearlEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockF
|
||||
// TODO: Tweak a_HitPos based on block face.
|
||||
TeleportCreator(a_HitPos);
|
||||
|
||||
Destroy();
|
||||
m_DestroyTimer = 2;
|
||||
}
|
||||
|
||||
|
||||
@ -36,7 +38,7 @@ void cThrownEnderPearlEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d
|
||||
TeleportCreator(a_HitPos);
|
||||
a_EntityHit.TakeDamage(dtRangedAttack, this, TotalDamage, 1);
|
||||
|
||||
Destroy(true);
|
||||
m_DestroyTimer = 5;
|
||||
}
|
||||
|
||||
|
||||
@ -45,10 +47,34 @@ void cThrownEnderPearlEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d
|
||||
|
||||
void cThrownEnderPearlEntity::TeleportCreator(const Vector3d & a_HitPos)
|
||||
{
|
||||
// Teleport the creator here, make them take 5 damage:
|
||||
if (m_Creator != NULL)
|
||||
if (m_CreatorData.m_Name.empty())
|
||||
{
|
||||
m_Creator->TeleportToCoords(a_HitPos.x + 0.5, a_HitPos.y + 1.7, a_HitPos.z + 0.5);
|
||||
m_Creator->TakeDamage(dtEnderPearl, this, 5, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
class cProjectileCreatorCallbackForPlayers : public cPlayerListCallback
|
||||
{
|
||||
public:
|
||||
cProjectileCreatorCallbackForPlayers(cEntity * a_Attacker, Vector3i a_HitPos) :
|
||||
m_Attacker(a_Attacker),
|
||||
m_HitPos(a_HitPos)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool Item(cPlayer * a_Entity) override
|
||||
{
|
||||
// Teleport the creator here, make them take 5 damage:
|
||||
a_Entity->TeleportToCoords(m_HitPos.x, m_HitPos.y + 0.2, m_HitPos.z);
|
||||
a_Entity->TakeDamage(dtEnderPearl, m_Attacker, 5, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
cEntity * m_Attacker;
|
||||
Vector3i m_HitPos;
|
||||
};
|
||||
|
||||
cProjectileCreatorCallbackForPlayers PCCFP(this, a_HitPos);
|
||||
GetWorld()->FindAndDoWithPlayer(m_CreatorData.m_Name, PCCFP);
|
||||
}
|
||||
|
@ -30,8 +30,29 @@ protected:
|
||||
// cProjectileEntity overrides:
|
||||
virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override;
|
||||
virtual void OnHitEntity (cEntity & a_EntityHit, const Vector3d & a_HitPos) override;
|
||||
virtual void Tick (float a_Dt, cChunk & a_Chunk) override
|
||||
{
|
||||
if (m_DestroyTimer > 0)
|
||||
{
|
||||
m_DestroyTimer--;
|
||||
if (m_DestroyTimer == 0)
|
||||
{
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
super::Tick(a_Dt, a_Chunk);
|
||||
}
|
||||
}
|
||||
|
||||
// Teleports the creator where the ender pearl lands.
|
||||
/** Teleports the creator where the ender pearl lands */
|
||||
void TeleportCreator(const Vector3d & a_HitPos);
|
||||
|
||||
private:
|
||||
|
||||
/** Time in ticks to wait for the hit animation to begin before destroying */
|
||||
int m_DestroyTimer;
|
||||
|
||||
} ; // tolua_export
|
||||
|
@ -8,7 +8,8 @@
|
||||
|
||||
|
||||
cThrownSnowballEntity::cThrownSnowballEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed) :
|
||||
super(pkSnowball, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25)
|
||||
super(pkSnowball, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25),
|
||||
m_DestroyTimer(-1)
|
||||
{
|
||||
SetSpeed(a_Speed);
|
||||
}
|
||||
@ -19,7 +20,7 @@ cThrownSnowballEntity::cThrownSnowballEntity(cEntity * a_Creator, double a_X, do
|
||||
|
||||
void cThrownSnowballEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace)
|
||||
{
|
||||
Destroy();
|
||||
m_DestroyTimer = 2;
|
||||
}
|
||||
|
||||
|
||||
@ -36,13 +37,9 @@ void cThrownSnowballEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d &
|
||||
{
|
||||
TotalDamage = 3;
|
||||
}
|
||||
else if (MobType == cMonster::mtEnderDragon)
|
||||
{
|
||||
TotalDamage = 1;
|
||||
}
|
||||
}
|
||||
// TODO: If entity is Ender Crystal, destroy it
|
||||
a_EntityHit.TakeDamage(dtRangedAttack, this, TotalDamage, 1);
|
||||
|
||||
Destroy(true);
|
||||
m_DestroyTimer = 5;
|
||||
}
|
||||
|
@ -30,5 +30,26 @@ protected:
|
||||
// cProjectileEntity overrides:
|
||||
virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override;
|
||||
virtual void OnHitEntity (cEntity & a_EntityHit, const Vector3d & a_HitPos) override;
|
||||
virtual void Tick (float a_Dt, cChunk & a_Chunk) override
|
||||
{
|
||||
if (m_DestroyTimer > 0)
|
||||
{
|
||||
m_DestroyTimer--;
|
||||
if (m_DestroyTimer == 0)
|
||||
{
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
super::Tick(a_Dt, a_Chunk);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** Time in ticks to wait for the hit animation to begin before destroying */
|
||||
int m_DestroyTimer;
|
||||
|
||||
} ; // tolua_export
|
||||
|
@ -5,7 +5,8 @@
|
||||
#include "Item.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#define FURNACE_RECIPE_FILE "furnace.txt"
|
||||
|
||||
|
||||
|
||||
@ -42,6 +43,7 @@ cFurnaceRecipe::~cFurnaceRecipe()
|
||||
{
|
||||
ClearRecipes();
|
||||
delete m_pState;
|
||||
m_pState = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -53,128 +55,207 @@ void cFurnaceRecipe::ReloadRecipes(void)
|
||||
ClearRecipes();
|
||||
LOGD("Loading furnace recipes...");
|
||||
|
||||
std::ifstream f;
|
||||
char a_File[] = "furnace.txt";
|
||||
f.open(a_File, std::ios::in);
|
||||
|
||||
std::ifstream f(FURNACE_RECIPE_FILE, std::ios::in);
|
||||
if (!f.good())
|
||||
{
|
||||
f.close();
|
||||
LOG("Could not open the furnace recipes file \"%s\"", a_File);
|
||||
LOG("Could not open the furnace recipes file \"%s\". No furnace recipes are available.", FURNACE_RECIPE_FILE);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Replace this messy parse with a high-level-structured one (ReadLine / ProcessLine)
|
||||
bool bSyntaxError = false;
|
||||
while (f.good())
|
||||
{
|
||||
char c;
|
||||
unsigned int LineNum = 0;
|
||||
AString ParsingLine;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// comments
|
||||
f >> c;
|
||||
f.unget();
|
||||
if( c == '#' )
|
||||
while (std::getline(f, ParsingLine))
|
||||
{
|
||||
while( f.good() && c != '\n' )
|
||||
LineNum++;
|
||||
ParsingLine.erase(std::remove_if(ParsingLine.begin(), ParsingLine.end(), isspace), ParsingLine.end()); // Remove ALL whitespace from the line
|
||||
if (ParsingLine.empty())
|
||||
{
|
||||
f.get( c );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Line breaks
|
||||
f.get( c );
|
||||
while( f.good() && ( c == '\n' || c == '\r' ) ) { f.get( c ); }
|
||||
if (f.eof())
|
||||
switch (ParsingLine[0])
|
||||
{
|
||||
case '#':
|
||||
{
|
||||
// Comment
|
||||
break;
|
||||
}
|
||||
f.unget();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Check for fuel
|
||||
f >> c;
|
||||
if( c == '!' ) // It's fuel :)
|
||||
case '!':
|
||||
{
|
||||
// Read item
|
||||
int IItemID = 0, IItemCount = 0, IItemHealth = 0;
|
||||
f >> IItemID;
|
||||
f >> c; if( c != ':' ) { bSyntaxError = true; break; }
|
||||
f >> IItemCount;
|
||||
|
||||
// Optional health
|
||||
f >> c;
|
||||
if( c != ':' )
|
||||
f.unget();
|
||||
else
|
||||
{
|
||||
f >> IItemHealth;
|
||||
AddFuelFromLine(ParsingLine, LineNum);
|
||||
break;
|
||||
}
|
||||
|
||||
// Burn time
|
||||
int BurnTime;
|
||||
f >> c; if( c != '=' ) { bSyntaxError = true; break; }
|
||||
f >> BurnTime;
|
||||
default:
|
||||
{
|
||||
AddRecipeFromLine(ParsingLine, LineNum);
|
||||
break;
|
||||
}
|
||||
} // switch (ParsingLine[0])
|
||||
} // while (getline(ParsingLine))
|
||||
|
||||
// Add to fuel list
|
||||
LOG("Loaded " SIZE_T_FMT " furnace recipes and " SIZE_T_FMT " fuels", m_pState->Recipes.size(), m_pState->Fuel.size());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cFurnaceRecipe::AddFuelFromLine(const AString & a_Line, int a_LineNum)
|
||||
{
|
||||
// Fuel
|
||||
int IItemID = 0, IItemCount = 0, IItemHealth = 0, IBurnTime = 0;
|
||||
AString::size_type BeginPos = 1; // Begin at one after exclamation mark (bang)
|
||||
|
||||
if (
|
||||
!ReadMandatoryNumber(BeginPos, ":", a_Line, a_LineNum, IItemID) || // Read item ID
|
||||
!ReadOptionalNumbers(BeginPos, ":", "=", a_Line, a_LineNum, IItemCount, IItemHealth) || // Read item count (and optionally health)
|
||||
!ReadMandatoryNumber(BeginPos, "0123456789", a_Line, a_LineNum, IBurnTime, true) // Read item burn time - last value
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Add to fuel list:
|
||||
Fuel F;
|
||||
F.In = new cItem( (ENUM_ITEM_ID) IItemID, (char)IItemCount, (short)IItemHealth );
|
||||
F.BurnTime = BurnTime;
|
||||
m_pState->Fuel.push_back( F );
|
||||
continue;
|
||||
}
|
||||
f.unget();
|
||||
F.In = new cItem((ENUM_ITEM_ID)IItemID, (char)IItemCount, (short)IItemHealth);
|
||||
F.BurnTime = IBurnTime;
|
||||
m_pState->Fuel.push_back(F);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Read items
|
||||
int IItemID = 0, IItemCount = 0, IItemHealth = 0;
|
||||
f >> IItemID;
|
||||
f >> c; if( c != ':' ) { bSyntaxError = true; break; }
|
||||
f >> IItemCount;
|
||||
|
||||
// Optional health
|
||||
f >> c;
|
||||
if( c != ':' )
|
||||
f.unget();
|
||||
else
|
||||
{
|
||||
f >> IItemHealth;
|
||||
}
|
||||
|
||||
int CookTime;
|
||||
f >> c; if( c != '@' ) { bSyntaxError = true; break; }
|
||||
f >> CookTime;
|
||||
|
||||
|
||||
void cFurnaceRecipe::AddRecipeFromLine(const AString & a_Line, int a_LineNum)
|
||||
{
|
||||
int IItemID = 0, IItemCount = 0, IItemHealth = 0, IBurnTime = 0;
|
||||
int OItemID = 0, OItemCount = 0, OItemHealth = 0;
|
||||
f >> c; if( c != '=' ) { bSyntaxError = true; break; }
|
||||
f >> OItemID;
|
||||
f >> c; if( c != ':' ) { bSyntaxError = true; break; }
|
||||
f >> OItemCount;
|
||||
AString::size_type BeginPos = 0; // Begin at start of line
|
||||
|
||||
// Optional health
|
||||
f >> c;
|
||||
if( c != ':' )
|
||||
f.unget();
|
||||
else
|
||||
if (
|
||||
!ReadMandatoryNumber(BeginPos, ":", a_Line, a_LineNum, IItemID) || // Read item ID
|
||||
!ReadOptionalNumbers(BeginPos, ":", "@", a_Line, a_LineNum, IItemCount, IItemHealth) || // Read item count (and optionally health)
|
||||
!ReadMandatoryNumber(BeginPos, "=", a_Line, a_LineNum, IBurnTime) || // Read item burn time
|
||||
!ReadMandatoryNumber(BeginPos, ":", a_Line, a_LineNum, OItemID) || // Read result ID
|
||||
!ReadOptionalNumbers(BeginPos, ":", "012456789", a_Line, a_LineNum, OItemCount, OItemHealth, true) // Read result count (and optionally health) - last value
|
||||
)
|
||||
{
|
||||
f >> OItemHealth;
|
||||
return;
|
||||
}
|
||||
|
||||
// Add to recipe list
|
||||
Recipe R;
|
||||
R.In = new cItem( (ENUM_ITEM_ID)IItemID, (char)IItemCount, (short)IItemHealth );
|
||||
R.Out = new cItem( (ENUM_ITEM_ID)OItemID, (char)OItemCount, (short)OItemHealth );
|
||||
R.CookTime = CookTime;
|
||||
m_pState->Recipes.push_back( R );
|
||||
}
|
||||
if (bSyntaxError)
|
||||
R.In = new cItem((ENUM_ITEM_ID)IItemID, (char)IItemCount, (short)IItemHealth);
|
||||
R.Out = new cItem((ENUM_ITEM_ID)OItemID, (char)OItemCount, (short)OItemHealth);
|
||||
R.CookTime = IBurnTime;
|
||||
m_pState->Recipes.push_back(R);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cFurnaceRecipe::PrintParseError(unsigned int a_Line, size_t a_Position, const AString & a_CharactersMissing)
|
||||
{
|
||||
LOGWARN("Error parsing furnace recipes at line %i pos " SIZE_T_FMT ": missing '%s'", a_Line, a_Position, a_CharactersMissing.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cFurnaceRecipe::ReadMandatoryNumber(AString::size_type & a_Begin, const AString & a_Delimiter, const AString & a_Text, unsigned int a_Line, int & a_Value, bool a_IsLastValue)
|
||||
{
|
||||
// TODO: replace atoi with std::stoi
|
||||
AString::size_type End;
|
||||
if (a_IsLastValue)
|
||||
{
|
||||
LOGERROR("ERROR: FurnaceRecipe, syntax error" );
|
||||
End = a_Text.find_first_not_of(a_Delimiter, a_Begin);
|
||||
}
|
||||
LOG("Loaded " SIZE_T_FMT " furnace recipes and " SIZE_T_FMT " fuels", m_pState->Recipes.size(), m_pState->Fuel.size());
|
||||
else
|
||||
{
|
||||
End = a_Text.find_first_of(a_Delimiter, a_Begin);
|
||||
if (End == AString::npos)
|
||||
{
|
||||
PrintParseError(a_Line, a_Begin, a_Delimiter);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// stoi won't throw an exception if the string is alphanumeric, we should check for this
|
||||
if (!DoesStringContainOnlyNumbers(a_Text.substr(a_Begin, End - a_Begin)))
|
||||
{
|
||||
PrintParseError(a_Line, a_Begin, "number");
|
||||
return false;
|
||||
}
|
||||
a_Value = atoi(a_Text.substr(a_Begin, End - a_Begin).c_str());
|
||||
|
||||
a_Begin = End + 1; // Jump over delimiter
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cFurnaceRecipe::ReadOptionalNumbers(AString::size_type & a_Begin, const AString & a_DelimiterOne, const AString & a_DelimiterTwo, const AString & a_Text, unsigned int a_Line, int & a_ValueOne, int & a_ValueTwo, bool a_IsLastValue)
|
||||
{
|
||||
// TODO: replace atoi with std::stoi
|
||||
AString::size_type End, Begin = a_Begin;
|
||||
|
||||
End = a_Text.find_first_of(a_DelimiterOne, Begin);
|
||||
if (End != AString::npos)
|
||||
{
|
||||
if (DoesStringContainOnlyNumbers(a_Text.substr(Begin, End - Begin)))
|
||||
{
|
||||
a_ValueOne = std::atoi(a_Text.substr(Begin, End - Begin).c_str());
|
||||
Begin = End + 1;
|
||||
|
||||
if (a_IsLastValue)
|
||||
{
|
||||
End = a_Text.find_first_not_of(a_DelimiterTwo, Begin);
|
||||
}
|
||||
else
|
||||
{
|
||||
End = a_Text.find_first_of(a_DelimiterTwo, Begin);
|
||||
if (End == AString::npos)
|
||||
{
|
||||
PrintParseError(a_Line, Begin, a_DelimiterTwo);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// stoi won't throw an exception if the string is alphanumeric, we should check for this
|
||||
if (!DoesStringContainOnlyNumbers(a_Text.substr(Begin, End - Begin)))
|
||||
{
|
||||
PrintParseError(a_Line, Begin, "number");
|
||||
return false;
|
||||
}
|
||||
a_ValueTwo = atoi(a_Text.substr(Begin, End - Begin).c_str());
|
||||
|
||||
a_Begin = End + 1; // Jump over delimiter
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ReadMandatoryNumber(a_Begin, a_DelimiterTwo, a_Text, a_Line, a_ValueOne, a_IsLastValue);
|
||||
}
|
||||
}
|
||||
|
||||
return ReadMandatoryNumber(a_Begin, a_DelimiterTwo, a_Text, a_Line, a_ValueOne, a_IsLastValue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cFurnaceRecipe::DoesStringContainOnlyNumbers(const AString & a_String)
|
||||
{
|
||||
// TODO: replace this with std::all_of(a_String.begin(), a_String.end(), isdigit)
|
||||
return (a_String.find_first_not_of("0123456789") == AString::npos);
|
||||
}
|
||||
|
||||
|
||||
@ -187,7 +268,9 @@ void cFurnaceRecipe::ClearRecipes(void)
|
||||
{
|
||||
Recipe R = *itr;
|
||||
delete R.In;
|
||||
R.In = NULL;
|
||||
delete R.Out;
|
||||
R.Out = NULL;
|
||||
}
|
||||
m_pState->Recipes.clear();
|
||||
|
||||
@ -195,6 +278,7 @@ void cFurnaceRecipe::ClearRecipes(void)
|
||||
{
|
||||
Fuel F = *itr;
|
||||
delete F.In;
|
||||
F.In = NULL;
|
||||
}
|
||||
m_pState->Fuel.clear();
|
||||
}
|
||||
|
@ -41,6 +41,36 @@ public:
|
||||
private:
|
||||
void ClearRecipes(void);
|
||||
|
||||
/** Parses the fuel contained in the line, adds it to m_pState's fuels.
|
||||
Logs a warning to the console on input error. */
|
||||
void AddFuelFromLine(const AString & a_Line, int a_LineNum);
|
||||
|
||||
/** Parses the recipe contained in the line, adds it to m_pState's recipes.
|
||||
Logs a warning to the console on input error. */
|
||||
void AddRecipeFromLine(const AString & a_Line, int a_LineNum);
|
||||
|
||||
/** Calls LOGWARN with the line, position, and error */
|
||||
static void PrintParseError(unsigned int a_Line, size_t a_Position, const AString & a_CharactersMissing);
|
||||
|
||||
/** Reads a number from a string given, starting at a given position and ending at a delimiter given
|
||||
Updates beginning position to the delimiter found + 1, and updates the value to the one read
|
||||
If it encounters a substring that is not fully numeric, it will call SetParseError() and return false; the caller should abort processing
|
||||
Otherwise, the function will return true
|
||||
*/
|
||||
static bool ReadMandatoryNumber(AString::size_type & a_Begin, const AString & a_Delimiter, const AString & a_Text, unsigned int a_Line, int & a_Value, bool a_IsLastValue = false);
|
||||
|
||||
/** Reads two numbers from a string given, starting at a given position and ending at the first delimiter given, then again (with an updated position) until the second delimiter given
|
||||
Updates beginning position to the second delimiter found + 1, and updates the values to the ones read
|
||||
If it encounters a substring that is not fully numeric whilst reading the second value, it will call SetParseError() and return false; the caller should abort processing
|
||||
If this happens whilst reading the first value, it will call ReadMandatoryNumber() with the appropriate position, as this may legitimately occur with the optional value and AString::find_first_of finding the incorrect delimiter. It will return the result of ReadMandatoryNumber()
|
||||
True will be returned definitively for an optional value that is valid
|
||||
*/
|
||||
static bool ReadOptionalNumbers(AString::size_type & a_Begin, const AString & a_DelimiterOne, const AString & a_DelimiterTwo, const AString & a_Text, unsigned int a_Line, int & a_ValueOne, int & a_ValueTwo, bool a_IsLastValue = false);
|
||||
|
||||
/** Uses std::all_of to determine if a string contains only digits */
|
||||
static bool DoesStringContainOnlyNumbers(const AString & a_String);
|
||||
|
||||
|
||||
struct sFurnaceRecipeState;
|
||||
sFurnaceRecipeState * m_pState;
|
||||
};
|
||||
|
@ -135,7 +135,9 @@ cBioGenCache::cBioGenCache(cBiomeGen * a_BioGenToCache, int a_CacheSize) :
|
||||
cBioGenCache::~cBioGenCache()
|
||||
{
|
||||
delete[] m_CacheData;
|
||||
m_CacheData = NULL;
|
||||
delete[] m_CacheOrder;
|
||||
m_CacheOrder = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -745,7 +747,12 @@ cBioGenTwoLevel::cBioGenTwoLevel(int a_Seed) :
|
||||
m_VoronoiSmall(a_Seed + 2000),
|
||||
m_DistortX(a_Seed + 3000),
|
||||
m_DistortZ(a_Seed + 4000),
|
||||
m_Noise(a_Seed + 5000)
|
||||
m_Noise1(a_Seed + 5001),
|
||||
m_Noise2(a_Seed + 5002),
|
||||
m_Noise3(a_Seed + 5003),
|
||||
m_Noise4(a_Seed + 5004),
|
||||
m_Noise5(a_Seed + 5005),
|
||||
m_Noise6(a_Seed + 5006)
|
||||
{
|
||||
}
|
||||
|
||||
@ -767,12 +774,12 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap
|
||||
int BlockZ = BaseZ + z * 4;
|
||||
float BlockXF = (float)(16 * BlockX) / 128;
|
||||
float BlockZF = (float)(16 * BlockZ) / 128;
|
||||
double NoiseX = m_Noise.CubicNoise3D(BlockXF / 16, BlockZF / 16, 1000);
|
||||
NoiseX += 0.5 * m_Noise.CubicNoise3D(BlockXF / 8, BlockZF / 8, 2000);
|
||||
NoiseX += 0.08 * m_Noise.CubicNoise3D(BlockXF, BlockZF, 3000);
|
||||
double NoiseZ = m_Noise.CubicNoise3D(BlockXF / 16, BlockZF / 16, 4000);
|
||||
NoiseZ += 0.5 * m_Noise.CubicNoise3D(BlockXF / 8, BlockZF / 8, 5000);
|
||||
NoiseZ += 0.08 * m_Noise.CubicNoise3D(BlockXF, BlockZF, 6000);
|
||||
double NoiseX = m_Noise1.CubicNoise2D(BlockXF / 16, BlockZF / 16);
|
||||
NoiseX += 0.5 * m_Noise2.CubicNoise2D(BlockXF / 8, BlockZF / 8);
|
||||
NoiseX += 0.08 * m_Noise3.CubicNoise2D(BlockXF, BlockZF);
|
||||
double NoiseZ = m_Noise4.CubicNoise2D(BlockXF / 16, BlockZF / 16);
|
||||
NoiseZ += 0.5 * m_Noise5.CubicNoise2D(BlockXF / 8, BlockZF / 8);
|
||||
NoiseZ += 0.08 * m_Noise6.CubicNoise2D(BlockXF, BlockZF);
|
||||
|
||||
DistortX[4 * x][4 * z] = BlockX + (int)(64 * NoiseX);
|
||||
DistortZ[4 * x][4 * z] = BlockZ + (int)(64 * NoiseZ);
|
||||
@ -786,8 +793,8 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap
|
||||
{
|
||||
for (int x = 0; x < cChunkDef::Width; x++)
|
||||
{
|
||||
int BiomeGroup = m_VoronoiLarge.GetValueAt(DistortX[x][z], DistortZ[x][z]) / 7;
|
||||
int MinDist1, MinDist2;
|
||||
int BiomeGroup = m_VoronoiLarge.GetValueAt(DistortX[x][z], DistortZ[x][z], MinDist1, MinDist2) / 7;
|
||||
int BiomeIdx = m_VoronoiSmall.GetValueAt(DistortX[x][z], DistortZ[x][z], MinDist1, MinDist2) / 11;
|
||||
cChunkDef::SetBiome(a_BiomeMap, x, z, SelectBiome(BiomeGroup, BiomeIdx, (MinDist1 < MinDist2 / 4) ? 0 : 1));
|
||||
}
|
||||
|
@ -261,7 +261,12 @@ protected:
|
||||
/// The noise used to distort the inupt Z coord
|
||||
cPerlinNoise m_DistortZ;
|
||||
|
||||
cNoise m_Noise;
|
||||
cNoise m_Noise1;
|
||||
cNoise m_Noise2;
|
||||
cNoise m_Noise3;
|
||||
cNoise m_Noise4;
|
||||
cNoise m_Noise5;
|
||||
cNoise m_Noise6;
|
||||
|
||||
|
||||
// cBiomeGen overrides:
|
||||
|
@ -672,7 +672,9 @@ cCompoGenCache::cCompoGenCache(cTerrainCompositionGen & a_Underlying, int a_Cach
|
||||
cCompoGenCache::~cCompoGenCache()
|
||||
{
|
||||
delete[] m_CacheData;
|
||||
m_CacheData = NULL;
|
||||
delete[] m_CacheOrder;
|
||||
m_CacheOrder = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "POCPieceGenerator.h"
|
||||
#include "RainbowRoadsGen.h"
|
||||
#include "Ravines.h"
|
||||
#include "TestRailsGen.h"
|
||||
#include "UnderwaterBaseGen.h"
|
||||
#include "VillageGen.h"
|
||||
|
||||
@ -414,6 +415,10 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
|
||||
{
|
||||
m_FinishGens.push_back(new cFinishGenSprinkleFoliage(Seed));
|
||||
}
|
||||
else if (NoCaseCompare(*itr, "TestRails") == 0)
|
||||
{
|
||||
m_FinishGens.push_back(new cTestRailsGen(Seed, 100, 1, 7, 50));
|
||||
}
|
||||
else if (NoCaseCompare(*itr, "Trees") == 0)
|
||||
{
|
||||
m_FinishGens.push_back(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen));
|
||||
|
@ -88,8 +88,8 @@ void cGridStructGen::GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructur
|
||||
for (cStructurePtrs::iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end;)
|
||||
{
|
||||
if (
|
||||
((*itr)->m_OriginX >= MinX) && ((*itr)->m_OriginX < MaxX) &&
|
||||
((*itr)->m_OriginZ >= MinZ) && ((*itr)->m_OriginZ < MaxZ)
|
||||
((*itr)->m_GridX >= MinX) && ((*itr)->m_GridX < MaxX) &&
|
||||
((*itr)->m_GridZ >= MinZ) && ((*itr)->m_GridZ < MaxZ)
|
||||
)
|
||||
{
|
||||
// want
|
||||
|
@ -142,7 +142,9 @@ cHeiGenCache::cHeiGenCache(cTerrainHeightGen & a_HeiGenToCache, int a_CacheSize)
|
||||
cHeiGenCache::~cHeiGenCache()
|
||||
{
|
||||
delete[] m_CacheData;
|
||||
m_CacheData = NULL;
|
||||
delete[] m_CacheOrder;
|
||||
m_CacheOrder = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -211,6 +211,17 @@ void cPrefab::Draw(cChunkDesc & a_Dest, const Vector3i & a_Placement, int a_NumR
|
||||
int ChunkStartZ = a_Dest.GetChunkZ() * cChunkDef::Width;
|
||||
Placement.Move(-ChunkStartX, 0, -ChunkStartZ);
|
||||
const cBlockArea & Image = m_BlockArea[a_NumRotations];
|
||||
|
||||
// If the placement is outside this chunk, bail out:
|
||||
if (
|
||||
(Placement.x > cChunkDef::Width) || (Placement.x + Image.GetSizeX() < 0) ||
|
||||
(Placement.z > cChunkDef::Width) || (Placement.z + Image.GetSizeZ() < 0)
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Write the image:
|
||||
a_Dest.WriteBlockArea(Image, Placement.x, Placement.y, Placement.z, m_MergeStrategy);
|
||||
|
||||
// If requested, draw the floor (from the bottom of the prefab down to the nearest non-air)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -129,6 +129,176 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] =
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Farm:
|
||||
// The data has been exported from the gallery Plains, area index 166, ID 554, created by Aloe_vera
|
||||
{
|
||||
// Size:
|
||||
11, 7, 13, // SizeX = 11, SizeY = 7, SizeZ = 13
|
||||
|
||||
// Hitbox (relative to bounding box):
|
||||
0, 0, 0, // MinX, MinY, MinZ
|
||||
10, 6, 12, // MaxX, MaxY, MaxZ
|
||||
|
||||
// Block definitions:
|
||||
".: 0: 0\n" /* air */
|
||||
"a: 3: 0\n" /* dirt */
|
||||
"b: 60: 7\n" /* tilleddirt */
|
||||
"c: 8: 0\n" /* water */
|
||||
"d: 43: 0\n" /* doubleslab */
|
||||
"e: 44: 0\n" /* step */
|
||||
"f: 59: 7\n" /* crops */
|
||||
"g: 83: 0\n" /* reedblock */
|
||||
"h:113: 0\n" /* netherbrickfence */
|
||||
"m: 19: 0\n" /* sponge */,
|
||||
|
||||
// Block data:
|
||||
// Level 0
|
||||
/* z\x* 1 */
|
||||
/* * 01234567890 */
|
||||
/* 0 */ "mmmmmmmmmmm"
|
||||
/* 1 */ "maaaaaaaaam"
|
||||
/* 2 */ "maaaaaaaaam"
|
||||
/* 3 */ "maaaaaaaaam"
|
||||
/* 4 */ "maaaaaaaaam"
|
||||
/* 5 */ "maaaaaaaaam"
|
||||
/* 6 */ "maaaaaaaaam"
|
||||
/* 7 */ "maaaaaaaaam"
|
||||
/* 8 */ "maaaaaaaaam"
|
||||
/* 9 */ "maaaaaaaaam"
|
||||
/* 10 */ "maaaaaaaaam"
|
||||
/* 11 */ "maaaaaaaaam"
|
||||
/* 12 */ "mmmmmmmmmmm"
|
||||
|
||||
// Level 1
|
||||
/* z\x* 1 */
|
||||
/* * 01234567890 */
|
||||
/* 0 */ "mmmmmmmmmmm"
|
||||
/* 1 */ "maaaaaaaaam"
|
||||
/* 2 */ "mabbbbbbbam"
|
||||
/* 3 */ "mabbbbbbbam"
|
||||
/* 4 */ "mabbbbbbbam"
|
||||
/* 5 */ "mabbbbbbbam"
|
||||
/* 6 */ "mabcccccaam"
|
||||
/* 7 */ "mabbbbbbbam"
|
||||
/* 8 */ "mabbbbbbbam"
|
||||
/* 9 */ "mabbbbbbbam"
|
||||
/* 10 */ "mabbbbbbbam"
|
||||
/* 11 */ "maaaaaaaaam"
|
||||
/* 12 */ "mmmmmmmmmmm"
|
||||
|
||||
// Level 2
|
||||
/* z\x* 1 */
|
||||
/* * 01234567890 */
|
||||
/* 0 */ "..........."
|
||||
/* 1 */ ".deeeeeeed."
|
||||
/* 2 */ ".efffffffe."
|
||||
/* 3 */ ".efffffffe."
|
||||
/* 4 */ ".efffffffe."
|
||||
/* 5 */ ".efgggggfe."
|
||||
/* 6 */ ".eg.....ge."
|
||||
/* 7 */ ".efgggggfe."
|
||||
/* 8 */ ".efffffffe."
|
||||
/* 9 */ ".efffffffe."
|
||||
/* 10 */ ".efffffffe."
|
||||
/* 11 */ ".deeeeeeed."
|
||||
/* 12 */ "..........."
|
||||
|
||||
// Level 3
|
||||
/* z\x* 1 */
|
||||
/* * 01234567890 */
|
||||
/* 0 */ "..........."
|
||||
/* 1 */ ".h.......h."
|
||||
/* 2 */ "..........."
|
||||
/* 3 */ "..........."
|
||||
/* 4 */ "..........."
|
||||
/* 5 */ "...ggggg..."
|
||||
/* 6 */ "..g.....g.."
|
||||
/* 7 */ "...ggggg..."
|
||||
/* 8 */ "..........."
|
||||
/* 9 */ "..........."
|
||||
/* 10 */ "..........."
|
||||
/* 11 */ ".h.......h."
|
||||
/* 12 */ "..........."
|
||||
|
||||
// Level 4
|
||||
/* z\x* 1 */
|
||||
/* * 01234567890 */
|
||||
/* 0 */ "..........."
|
||||
/* 1 */ ".h.......h."
|
||||
/* 2 */ "..........."
|
||||
/* 3 */ "..........."
|
||||
/* 4 */ "..........."
|
||||
/* 5 */ "...ggggg..."
|
||||
/* 6 */ "..g.....g.."
|
||||
/* 7 */ "...ggggg..."
|
||||
/* 8 */ "..........."
|
||||
/* 9 */ "..........."
|
||||
/* 10 */ "..........."
|
||||
/* 11 */ ".h.......h."
|
||||
/* 12 */ "..........."
|
||||
|
||||
// Level 5
|
||||
/* z\x* 1 */
|
||||
/* * 01234567890 */
|
||||
/* 0 */ "..........."
|
||||
/* 1 */ ".h.......h."
|
||||
/* 2 */ "..........."
|
||||
/* 3 */ "..........."
|
||||
/* 4 */ "..........."
|
||||
/* 5 */ "..........."
|
||||
/* 6 */ "..........."
|
||||
/* 7 */ "..........."
|
||||
/* 8 */ "..........."
|
||||
/* 9 */ "..........."
|
||||
/* 10 */ "..........."
|
||||
/* 11 */ ".h.......h."
|
||||
/* 12 */ "..........."
|
||||
|
||||
// Level 6
|
||||
/* z\x* 1 */
|
||||
/* * 01234567890 */
|
||||
/* 0 */ ".h.......h."
|
||||
/* 1 */ "hhh.....hhh"
|
||||
/* 2 */ ".h.......h."
|
||||
/* 3 */ "..........."
|
||||
/* 4 */ "..........."
|
||||
/* 5 */ "..........."
|
||||
/* 6 */ "..........."
|
||||
/* 7 */ "..........."
|
||||
/* 8 */ "..........."
|
||||
/* 9 */ "..........."
|
||||
/* 10 */ ".h.......h."
|
||||
/* 11 */ "hhh.....hhh"
|
||||
/* 12 */ ".h.......h.",
|
||||
|
||||
// Connectors:
|
||||
"-1: 10, 2, 6: 5\n" /* Type -1, direction X+ */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
|
||||
// Merge strategy:
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
|
||||
// DepthWeight:
|
||||
"",
|
||||
|
||||
// AddWeightIfSame:
|
||||
0,
|
||||
|
||||
// MoveToGround:
|
||||
true,
|
||||
}, // Farm
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Forge:
|
||||
// The data has been exported from the gallery Plains, area index 79, ID 145, created by Aloe_vera
|
||||
@ -2025,12 +2195,12 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] =
|
||||
|
||||
// Level 1
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "bbbbbbb"
|
||||
/* 1 */ "bbbbbbb"
|
||||
/* 2 */ "bbbbbbb"
|
||||
/* 3 */ "bbbabbb"
|
||||
/* 4 */ "bbbbbbb"
|
||||
/* 5 */ "bbbbbbb"
|
||||
/* 0 */ "bmmmmmm"
|
||||
/* 1 */ "bmmmmmm"
|
||||
/* 2 */ "bmmmmmm"
|
||||
/* 3 */ "bmmmmmm"
|
||||
/* 4 */ "bmmmmmm"
|
||||
/* 5 */ "bmmmmmm"
|
||||
/* 6 */ "bbbbbbb"
|
||||
|
||||
// Level 2
|
||||
@ -3005,159 +3175,157 @@ const cPrefab::sDef g_JapaneseVillageStartingPrefabs[] =
|
||||
"a: 1: 0\n" /* stone */
|
||||
"b: 4: 0\n" /* cobblestone */
|
||||
"c: 8: 0\n" /* water */
|
||||
"d: 3: 0\n" /* dirt */
|
||||
"e: 2: 0\n" /* grass */
|
||||
"f: 13: 0\n" /* gravel */
|
||||
"g: 67: 1\n" /* stairs */
|
||||
"h: 67: 2\n" /* stairs */
|
||||
"i: 67: 0\n" /* stairs */
|
||||
"j: 67: 3\n" /* stairs */
|
||||
"k: 85: 0\n" /* fence */
|
||||
"l: 44: 8\n" /* step */
|
||||
"m: 19: 0\n" /* sponge */
|
||||
"n: 44: 0\n" /* step */
|
||||
"o: 43: 0\n" /* doubleslab */,
|
||||
"d: 13: 0\n" /* gravel */
|
||||
"e: 67: 1\n" /* stairs */
|
||||
"f: 67: 2\n" /* stairs */
|
||||
"g: 67: 0\n" /* stairs */
|
||||
"h: 67: 3\n" /* stairs */
|
||||
"i: 85: 0\n" /* fence */
|
||||
"j: 44: 8\n" /* step */
|
||||
"k: 44: 0\n" /* step */
|
||||
"l: 43: 0\n" /* doubleslab */
|
||||
"m: 19: 0\n" /* sponge */,
|
||||
|
||||
// Block data:
|
||||
// Level 0
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "aaaaaaa"
|
||||
/* 1 */ "aaaaaaa"
|
||||
/* 2 */ "aaaaaaa"
|
||||
/* 3 */ "aaaaaaa"
|
||||
/* 4 */ "aaaaaaa"
|
||||
/* 5 */ "aaaaaaa"
|
||||
/* 6 */ "aaaaaaa"
|
||||
/* 0 */ "mmmmmmm"
|
||||
/* 1 */ "maaaaam"
|
||||
/* 2 */ "maaaaam"
|
||||
/* 3 */ "maaaaam"
|
||||
/* 4 */ "maaaaam"
|
||||
/* 5 */ "maaaaam"
|
||||
/* 6 */ "mmmmmmm"
|
||||
|
||||
// Level 1
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "aaaaaaa"
|
||||
/* 1 */ "abbbbba"
|
||||
/* 2 */ "abcc.ba"
|
||||
/* 3 */ "abcccba"
|
||||
/* 4 */ "abcccba"
|
||||
/* 5 */ "abbbbba"
|
||||
/* 6 */ "aaaaaaa"
|
||||
/* 0 */ "mmmmmmm"
|
||||
/* 1 */ "mbbbbbm"
|
||||
/* 2 */ "mbcc.bm"
|
||||
/* 3 */ "mbcccbm"
|
||||
/* 4 */ "mbcccbm"
|
||||
/* 5 */ "mbbbbbm"
|
||||
/* 6 */ "mmmmmmm"
|
||||
|
||||
// Level 2
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "aaaaaaa"
|
||||
/* 1 */ "abbbbba"
|
||||
/* 2 */ "abcccba"
|
||||
/* 3 */ "abcccba"
|
||||
/* 4 */ "abcccba"
|
||||
/* 5 */ "abbbbba"
|
||||
/* 6 */ "aaaaaaa"
|
||||
/* 0 */ "mmmmmmm"
|
||||
/* 1 */ "mbbbbbm"
|
||||
/* 2 */ "mbcccbm"
|
||||
/* 3 */ "mbcccbm"
|
||||
/* 4 */ "mbcccbm"
|
||||
/* 5 */ "mbbbbbm"
|
||||
/* 6 */ "mmmmmmm"
|
||||
|
||||
// Level 3
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "aaaaaaa"
|
||||
/* 1 */ "abbbbba"
|
||||
/* 2 */ "abcccba"
|
||||
/* 3 */ "abcccba"
|
||||
/* 4 */ "abcccba"
|
||||
/* 5 */ "abbbbba"
|
||||
/* 6 */ "aaaaaaa"
|
||||
/* 0 */ "mmmmmmm"
|
||||
/* 1 */ "mbbbbbm"
|
||||
/* 2 */ "mbcccbm"
|
||||
/* 3 */ "mbcccbm"
|
||||
/* 4 */ "mbcccbm"
|
||||
/* 5 */ "mbbbbbm"
|
||||
/* 6 */ "mmmmmmm"
|
||||
|
||||
// Level 4
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "aaaaaaa"
|
||||
/* 1 */ "abbbbba"
|
||||
/* 2 */ "abcccba"
|
||||
/* 3 */ "abcccba"
|
||||
/* 4 */ "abcccba"
|
||||
/* 5 */ "abbbbba"
|
||||
/* 6 */ "aaaaaaa"
|
||||
/* 0 */ "mmmmmmm"
|
||||
/* 1 */ "mbbbbbm"
|
||||
/* 2 */ "mbcccbm"
|
||||
/* 3 */ "mbcccbm"
|
||||
/* 4 */ "mbcccbm"
|
||||
/* 5 */ "mbbbbbm"
|
||||
/* 6 */ "mmmmmmm"
|
||||
|
||||
// Level 5
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "ddddddd"
|
||||
/* 1 */ "dbbbbbd"
|
||||
/* 2 */ "dbcccbd"
|
||||
/* 3 */ "dbcccbd"
|
||||
/* 4 */ "dbcccbd"
|
||||
/* 5 */ "dbbbbbd"
|
||||
/* 6 */ "ddddddd"
|
||||
/* 0 */ "mmmmmmm"
|
||||
/* 1 */ "mbbbbbm"
|
||||
/* 2 */ "mbcccbm"
|
||||
/* 3 */ "mbcccbm"
|
||||
/* 4 */ "mbcccbm"
|
||||
/* 5 */ "mbbbbbm"
|
||||
/* 6 */ "mmmmmmm"
|
||||
|
||||
// Level 6
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "ddddddd"
|
||||
/* 1 */ "dbbbbbd"
|
||||
/* 2 */ "dbcccbd"
|
||||
/* 3 */ "dbcccbd"
|
||||
/* 4 */ "dbcccbd"
|
||||
/* 5 */ "dbbbbbd"
|
||||
/* 6 */ "ddddddd"
|
||||
/* 0 */ "mmmmmmm"
|
||||
/* 1 */ "mbbbbbm"
|
||||
/* 2 */ "mbcccbm"
|
||||
/* 3 */ "mbcccbm"
|
||||
/* 4 */ "mbcccbm"
|
||||
/* 5 */ "mbbbbbm"
|
||||
/* 6 */ "mmmmmmm"
|
||||
|
||||
// Level 7
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "ddddddd"
|
||||
/* 1 */ "dbbbbbd"
|
||||
/* 2 */ "dbcccbd"
|
||||
/* 3 */ "dbcccbd"
|
||||
/* 4 */ "dbcccbd"
|
||||
/* 5 */ "dbbbbbd"
|
||||
/* 6 */ "ddddddd"
|
||||
/* 0 */ "mmbbbmm"
|
||||
/* 1 */ "mbbbbbm"
|
||||
/* 2 */ "bbcccbb"
|
||||
/* 3 */ "bbcccbb"
|
||||
/* 4 */ "bbcccbb"
|
||||
/* 5 */ "mbbbbbm"
|
||||
/* 6 */ "mmbbbmm"
|
||||
|
||||
// Level 8
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "eefffee"
|
||||
/* 1 */ "ebbbbbe"
|
||||
/* 2 */ "fbcccbf"
|
||||
/* 3 */ "fbcccbf"
|
||||
/* 4 */ "fbcccbf"
|
||||
/* 5 */ "ebbbbbe"
|
||||
/* 6 */ "eefffee"
|
||||
/* 0 */ "mmdddmm"
|
||||
/* 1 */ "mbbbbbm"
|
||||
/* 2 */ "dbcccbd"
|
||||
/* 3 */ "dbcccbd"
|
||||
/* 4 */ "dbcccbd"
|
||||
/* 5 */ "mbbbbbm"
|
||||
/* 6 */ "mmdddmm"
|
||||
|
||||
// Level 9
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "......."
|
||||
/* 1 */ ".bghib."
|
||||
/* 2 */ ".j...j."
|
||||
/* 3 */ ".i...g."
|
||||
/* 4 */ ".h...h."
|
||||
/* 5 */ ".bgjib."
|
||||
/* 6 */ "......."
|
||||
/* 0 */ "mm...mm"
|
||||
/* 1 */ "mbefgbm"
|
||||
/* 2 */ ".h...h."
|
||||
/* 3 */ ".g...e."
|
||||
/* 4 */ ".f...f."
|
||||
/* 5 */ "mbehgbm"
|
||||
/* 6 */ "mm...mm"
|
||||
|
||||
// Level 10
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "......."
|
||||
/* 1 */ ".k...k."
|
||||
/* 0 */ "mm...mm"
|
||||
/* 1 */ "mi...im"
|
||||
/* 2 */ "......."
|
||||
/* 3 */ "......."
|
||||
/* 4 */ "......."
|
||||
/* 5 */ ".k...k."
|
||||
/* 6 */ "......."
|
||||
/* 5 */ "mi...im"
|
||||
/* 6 */ "mm...mm"
|
||||
|
||||
// Level 11
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "......."
|
||||
/* 1 */ ".k...k."
|
||||
/* 0 */ "mm...mm"
|
||||
/* 1 */ "mi...im"
|
||||
/* 2 */ "......."
|
||||
/* 3 */ "......."
|
||||
/* 4 */ "......."
|
||||
/* 5 */ ".k...k."
|
||||
/* 6 */ "......."
|
||||
/* 5 */ "mi...im"
|
||||
/* 6 */ "mm...mm"
|
||||
|
||||
// Level 12
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ ".lnnnl."
|
||||
/* 1 */ "loooool"
|
||||
/* 2 */ "nooooon"
|
||||
/* 3 */ "nooooon"
|
||||
/* 4 */ "nooooon"
|
||||
/* 5 */ "loooool"
|
||||
/* 6 */ ".lnnnl."
|
||||
/* 0 */ "mjkkkjm"
|
||||
/* 1 */ "jlllllj"
|
||||
/* 2 */ "klllllk"
|
||||
/* 3 */ "klllllk"
|
||||
/* 4 */ "klllllk"
|
||||
/* 5 */ "jlllllj"
|
||||
/* 6 */ "mjkkkjm"
|
||||
|
||||
// Level 13
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "n.....n"
|
||||
/* 0 */ "k.....k"
|
||||
/* 1 */ "......."
|
||||
/* 2 */ "..nnn.."
|
||||
/* 3 */ "..non.."
|
||||
/* 4 */ "..nnn.."
|
||||
/* 2 */ "..kkk.."
|
||||
/* 3 */ "..klk.."
|
||||
/* 4 */ "..kkk.."
|
||||
/* 5 */ "......."
|
||||
/* 6 */ "n.....n",
|
||||
/* 6 */ "k.....k",
|
||||
|
||||
// Connectors:
|
||||
"2: 0, 9, 3: 4\n" /* Type 2, direction X- */
|
||||
|
@ -356,35 +356,36 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
"e: 8: 0\n" /* water */
|
||||
"f: 50: 5\n" /* torch */
|
||||
"g: 59: 7\n" /* crops */
|
||||
"h:111: 0\n" /* lilypad */
|
||||
"m: 19: 0\n" /* sponge */,
|
||||
|
||||
// Block data:
|
||||
// Level 0
|
||||
/* z\x* 11111 */
|
||||
/* * 012345678901234 */
|
||||
/* 0 */ "aaaaaaaaaaaaaaa"
|
||||
/* 0 */ "aaaaaaabaaaaaaa"
|
||||
/* 1 */ "aaaaaaaaaaaaaaa"
|
||||
/* 2 */ "aaaaaaaaaaaaaaa"
|
||||
/* 3 */ "aaaaaaaaaaaaaaa"
|
||||
/* 4 */ "aaaaaaaaaaaaaaa"
|
||||
/* 5 */ "aaaaaaaaaaaaaaa"
|
||||
/* 6 */ "aaaaaaaaaaaaaaa"
|
||||
/* 7 */ "aaaaaaaaaaaaaaa"
|
||||
/* 8 */ "aaaaaaaaaaaaaaa"
|
||||
|
||||
// Level 1
|
||||
/* z\x* 11111 */
|
||||
/* * 012345678901234 */
|
||||
/* 0 */ "aaaaaaabaaaaaaa"
|
||||
/* 1 */ "aaaaaaabaaaaaaa"
|
||||
/* 2 */ "aaaaaaabaaaaaaa"
|
||||
/* 3 */ "aaaaaaabaaaaaaa"
|
||||
/* 4 */ "aaaaaaabaaaaaaa"
|
||||
/* 5 */ "aaaaaaabaaaaaaa"
|
||||
/* 6 */ "aaaaaaabaaaaaaa"
|
||||
/* 7 */ "aaaaaaabaaaaaaa"
|
||||
/* 8 */ "aaaaaaabaaaaaaa"
|
||||
|
||||
// Level 1
|
||||
/* z\x* 11111 */
|
||||
/* * 012345678901234 */
|
||||
/* 0 */ "aaaaaaamaaaaaaa"
|
||||
/* 1 */ "aaaaaaamaaaaaaa"
|
||||
/* 2 */ "aaaaaaamaaaaaaa"
|
||||
/* 3 */ "aaaaaaamaaaaaaa"
|
||||
/* 4 */ "aaaaaaamaaaaaaa"
|
||||
/* 5 */ "aaaaaaamaaaaaaa"
|
||||
/* 6 */ "aaaaaaamaaaaaaa"
|
||||
/* 7 */ "aaaaaaamaaaaaaa"
|
||||
/* 8 */ "aaaaaaamaaaaaaa"
|
||||
|
||||
// Level 2
|
||||
/* z\x* 11111 */
|
||||
/* * 012345678901234 */
|
||||
@ -407,7 +408,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 3 */ ".g.......gg.gg."
|
||||
/* 4 */ ".gg..g...gg.gg."
|
||||
/* 5 */ ".gg..g...gg.gg."
|
||||
/* 6 */ "..g..g...gg.gg."
|
||||
/* 6 */ "..g..g...gghgg."
|
||||
/* 7 */ "..g.g....gg.gg."
|
||||
/* 8 */ "f.....f.f.....f"
|
||||
|
||||
@ -509,12 +510,12 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
"d: 67: 1\n" /* stairs */
|
||||
"e: 17: 0\n" /* tree */
|
||||
"f: 5: 0\n" /* wood */
|
||||
"g: 64: 6\n" /* wooddoorblock */
|
||||
"g: 64: 2\n" /* wooddoorblock */
|
||||
"h: 10: 0\n" /* lava */
|
||||
"i: 54: 2\n" /* chest */
|
||||
"j: 61: 2\n" /* furnace */
|
||||
"k:102: 0\n" /* glasspane */
|
||||
"l: 64:12\n" /* wooddoorblock */
|
||||
"l: 64: 8\n" /* wooddoorblock */
|
||||
"m: 19: 0\n" /* sponge */
|
||||
"n:139: 0\n" /* cobblestonewall */
|
||||
"o:101: 0\n" /* ironbars */
|
||||
@ -2544,7 +2545,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
20,
|
||||
|
||||
// DepthWeight:
|
||||
"",
|
||||
@ -2746,8 +2747,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
"d: 67: 1\n" /* stairs */
|
||||
"e: 17: 0\n" /* tree */
|
||||
"f: 5: 0\n" /* wood */
|
||||
"g: 64: 7\n" /* wooddoorblock */
|
||||
"h: 64:12\n" /* wooddoorblock */
|
||||
"g: 64: 3\n" /* wooddoorblock */
|
||||
"h: 64: 8\n" /* wooddoorblock */
|
||||
"i:102: 0\n" /* glasspane */
|
||||
"j: 53: 2\n" /* woodstairs */
|
||||
"k: 53: 7\n" /* woodstairs */
|
||||
@ -3000,9 +3001,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
"d: 67: 1\n" /* stairs */
|
||||
"e: 17: 0\n" /* tree */
|
||||
"f: 5: 0\n" /* wood */
|
||||
"g: 64: 7\n" /* wooddoorblock */
|
||||
"g: 64: 3\n" /* wooddoorblock */
|
||||
"h:102: 0\n" /* glasspane */
|
||||
"i: 64:12\n" /* wooddoorblock */
|
||||
"i: 64: 8\n" /* wooddoorblock */
|
||||
"j: 53: 2\n" /* woodstairs */
|
||||
"k: 53: 7\n" /* woodstairs */
|
||||
"l: 50: 3\n" /* torch */
|
||||
@ -3141,31 +3142,32 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
"k: 85: 0\n" /* fence */
|
||||
"l: 53: 0\n" /* woodstairs */
|
||||
"m: 19: 0\n" /* sponge */
|
||||
"n: 64: 6\n" /* wooddoorblock */
|
||||
"n: 64: 2\n" /* wooddoorblock */
|
||||
"o: 64: 4\n" /* wooddoorblock */
|
||||
"p:102: 0\n" /* glasspane */
|
||||
"q: 72: 0\n" /* woodplate */
|
||||
"r: 64:12\n" /* wooddoorblock */
|
||||
"s: 53: 5\n" /* woodstairs */
|
||||
"t: 53: 4\n" /* woodstairs */
|
||||
"u: 50: 1\n" /* torch */
|
||||
"v: 50: 2\n" /* torch */,
|
||||
"r: 64: 8\n" /* wooddoorblock */
|
||||
"s: 64:12\n" /* wooddoorblock */
|
||||
"t: 53: 5\n" /* woodstairs */
|
||||
"u: 53: 4\n" /* woodstairs */
|
||||
"v: 50: 1\n" /* torch */
|
||||
"w: 50: 2\n" /* torch */,
|
||||
|
||||
// Block data:
|
||||
// Level 0
|
||||
/* z\x* */
|
||||
/* * 0123456789 */
|
||||
/* 0 */ ".........."
|
||||
/* 1 */ ".aaaaa...."
|
||||
/* 2 */ ".aaaaa...."
|
||||
/* 3 */ ".aaaaabbbb"
|
||||
/* 0 */ "mmmmmmmmmm"
|
||||
/* 1 */ "maaaaammmm"
|
||||
/* 2 */ "maaaaammmm"
|
||||
/* 3 */ "maaaaabbbb"
|
||||
/* 4 */ "aaaaaabbbb"
|
||||
/* 5 */ "aaaaaabbbb"
|
||||
/* 6 */ "aaaaaabbbb"
|
||||
/* 7 */ ".aaaaabbbb"
|
||||
/* 8 */ ".aaaaabbbb"
|
||||
/* 9 */ ".aaaaa...."
|
||||
/* 10 */ ".........."
|
||||
/* 7 */ "maaaaabbbb"
|
||||
/* 8 */ "maaaaabbbb"
|
||||
/* 9 */ "maaaaammmm"
|
||||
/* 10 */ "mmmmmmmmmm"
|
||||
|
||||
// Level 1
|
||||
/* z\x* */
|
||||
@ -3205,7 +3207,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 2 */ ".p.q.pmmmm"
|
||||
/* 3 */ ".p...p...."
|
||||
/* 4 */ ".c...c...."
|
||||
/* 5 */ ".r...r...."
|
||||
/* 5 */ ".r...s...."
|
||||
/* 6 */ ".c...c...."
|
||||
/* 7 */ ".p...p...."
|
||||
/* 8 */ ".p...p...."
|
||||
@ -3215,47 +3217,47 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
// Level 4
|
||||
/* z\x* */
|
||||
/* * 0123456789 */
|
||||
/* 0 */ "ls...tjmmm"
|
||||
/* 0 */ "lt...ujmmm"
|
||||
/* 1 */ "licccijmmm"
|
||||
/* 2 */ "lc...cjmmm"
|
||||
/* 3 */ "lc...cj..."
|
||||
/* 4 */ "lcu.vcj..."
|
||||
/* 4 */ "lcv.wcj..."
|
||||
/* 5 */ "lc...cj..."
|
||||
/* 6 */ "lcu.vcj..."
|
||||
/* 6 */ "lcv.wcj..."
|
||||
/* 7 */ "lc...cj..."
|
||||
/* 8 */ "lc...cj..."
|
||||
/* 9 */ "licccijmmm"
|
||||
/* 10 */ "ls...tjmmm"
|
||||
/* 10 */ "lt...ujmmm"
|
||||
|
||||
// Level 5
|
||||
/* z\x* */
|
||||
/* * 0123456789 */
|
||||
/* 0 */ "mls.tjmmmm"
|
||||
/* 1 */ "mlcccjmmmm"
|
||||
/* 2 */ "mlc.cjmmmm"
|
||||
/* 3 */ "mlc.cjm..."
|
||||
/* 4 */ "mlc.cjm..."
|
||||
/* 5 */ "mlc.cjm..."
|
||||
/* 6 */ "mlc.cjm..."
|
||||
/* 7 */ "mlc.cjm..."
|
||||
/* 8 */ "mlc.cjm..."
|
||||
/* 9 */ "mlcccjmmmm"
|
||||
/* 10 */ "mls.tjmmmm"
|
||||
/* 0 */ ".lt.uj.mmm"
|
||||
/* 1 */ ".lcccj.mmm"
|
||||
/* 2 */ ".lc.cj.mmm"
|
||||
/* 3 */ ".lc.cj...."
|
||||
/* 4 */ ".lc.cj...."
|
||||
/* 5 */ ".lc.cj...."
|
||||
/* 6 */ ".lc.cj...."
|
||||
/* 7 */ ".lc.cj...."
|
||||
/* 8 */ ".lc.cj...."
|
||||
/* 9 */ ".lcccj.mmm"
|
||||
/* 10 */ ".lt.uj.mmm"
|
||||
|
||||
// Level 6
|
||||
/* z\x* */
|
||||
/* * 0123456789 */
|
||||
/* 0 */ "mmlcjmmmmm"
|
||||
/* 1 */ "mmlcjmmmmm"
|
||||
/* 2 */ "mmlcjmmmmm"
|
||||
/* 3 */ "mmlcjmm..."
|
||||
/* 4 */ "mmlcjmm..."
|
||||
/* 5 */ "mmlcjmm..."
|
||||
/* 6 */ "mmlcjmm..."
|
||||
/* 7 */ "mmlcjmm..."
|
||||
/* 8 */ "mmlcjmm..."
|
||||
/* 9 */ "mmlcjmmmmm"
|
||||
/* 10 */ "mmlcjmmmmm",
|
||||
/* 0 */ "..lcj..mmm"
|
||||
/* 1 */ "..lcj..mmm"
|
||||
/* 2 */ "..lcj..mmm"
|
||||
/* 3 */ "..lcj....."
|
||||
/* 4 */ "..lcj....."
|
||||
/* 5 */ "..lcj....."
|
||||
/* 6 */ "..lcj....."
|
||||
/* 7 */ "..lcj....."
|
||||
/* 8 */ "..lcj....."
|
||||
/* 9 */ "..lcj..mmm"
|
||||
/* 10 */ "..lcj..mmm",
|
||||
|
||||
// Connectors:
|
||||
"-1: 0, 1, 5: 4\n" /* Type -1, direction X- */,
|
||||
@ -3626,7 +3628,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
// Level 0
|
||||
/* z\x* 1 */
|
||||
/* * 01234567890 */
|
||||
/* 0 */ "aaabbbbaaaa"
|
||||
/* 0 */ "aaaabbbaaaa"
|
||||
/* 1 */ "abbbbbbbbba"
|
||||
/* 2 */ "abbbbbbbbba"
|
||||
/* 3 */ "abbbbbbbbba"
|
||||
@ -4509,10 +4511,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 4 */ ".aaaaaaaaa."
|
||||
/* 5 */ ".aaaaaaaaa."
|
||||
/* 6 */ ".....aaaaa."
|
||||
/* 7 */ ".....aaaaa."
|
||||
/* 8 */ ".....aaaaa."
|
||||
/* 9 */ ".....aaaaa."
|
||||
/* 10 */ "..........."
|
||||
/* 7 */ "mmmm.aaaaa."
|
||||
/* 8 */ "mmmm.aaaaa."
|
||||
/* 9 */ "mmmm.aaaaa."
|
||||
/* 10 */ "mmmm......."
|
||||
|
||||
// Level 2
|
||||
/* z\x* 1 */
|
||||
@ -4524,10 +4526,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 4 */ ".f.......f."
|
||||
/* 5 */ ".efffe...f."
|
||||
/* 6 */ ".....f...f."
|
||||
/* 7 */ ".....f...f."
|
||||
/* 8 */ ".....f...f."
|
||||
/* 9 */ ".....efffe."
|
||||
/* 10 */ "..........."
|
||||
/* 7 */ "mmmm.f...f."
|
||||
/* 8 */ "mmmm.f...f."
|
||||
/* 9 */ "mmmm.efffe."
|
||||
/* 10 */ "mmmm......."
|
||||
|
||||
// Level 3
|
||||
/* z\x* 1 */
|
||||
@ -4539,10 +4541,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 4 */ ".h.......h."
|
||||
/* 5 */ ".ehhhe...f."
|
||||
/* 6 */ ".....h...h."
|
||||
/* 7 */ ".....h...h."
|
||||
/* 8 */ ".....h...h."
|
||||
/* 9 */ ".....ehhhe."
|
||||
/* 10 */ "..........."
|
||||
/* 7 */ "mmmm.h...h."
|
||||
/* 8 */ "mmmm.h...h."
|
||||
/* 9 */ "mmmm.ehhhe."
|
||||
/* 10 */ "mmmm......."
|
||||
|
||||
// Level 4
|
||||
/* z\x* 1 */
|
||||
@ -4554,10 +4556,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 4 */ ".f...o...fl"
|
||||
/* 5 */ "pfffffq.rfl"
|
||||
/* 6 */ "sssssf...fl"
|
||||
/* 7 */ "....tf...fl"
|
||||
/* 8 */ "....tf...fl"
|
||||
/* 9 */ "....tfffffl"
|
||||
/* 10 */ "....tu...vl"
|
||||
/* 7 */ "mmmmtf...fl"
|
||||
/* 8 */ "mmmmtf...fl"
|
||||
/* 9 */ "mmmmtfffffl"
|
||||
/* 10 */ "mmmmtu...vl"
|
||||
|
||||
// Level 5
|
||||
/* z\x* 1 */
|
||||
@ -4569,10 +4571,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 4 */ "pffffff.fl."
|
||||
/* 5 */ "ssssssf.fl."
|
||||
/* 6 */ ".....tf.fl."
|
||||
/* 7 */ ".....tf.fl."
|
||||
/* 8 */ ".....tf.fl."
|
||||
/* 9 */ ".....tfffl."
|
||||
/* 10 */ ".....tu.vl."
|
||||
/* 7 */ "mmmm.tf.fl."
|
||||
/* 8 */ "mmmm.tf.fl."
|
||||
/* 9 */ "mmmm.tfffl."
|
||||
/* 10 */ "mmmm.tu.vl."
|
||||
|
||||
// Level 6
|
||||
/* z\x* 1 */
|
||||
@ -4584,10 +4586,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 4 */ "sssssstfl.."
|
||||
/* 5 */ "......tfl.."
|
||||
/* 6 */ "......tfl.."
|
||||
/* 7 */ "......tfl.."
|
||||
/* 8 */ "......tfl.."
|
||||
/* 9 */ "......tfl.."
|
||||
/* 10 */ "......tfl..",
|
||||
/* 7 */ "mmmm..tfl.."
|
||||
/* 8 */ "mmmm..tfl.."
|
||||
/* 9 */ "mmmm..tfl.."
|
||||
/* 10 */ "mmmm..tfl..",
|
||||
|
||||
// Connectors:
|
||||
"-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */,
|
||||
@ -4837,9 +4839,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
|
||||
// Level 1
|
||||
/* z\x* 012345678 */
|
||||
/* 0 */ "........."
|
||||
/* 1 */ "........."
|
||||
/* 2 */ "........."
|
||||
/* 0 */ "mmmmmmm.."
|
||||
/* 1 */ "mmmmmmm.."
|
||||
/* 2 */ "mmmmmmm.."
|
||||
/* 3 */ "........."
|
||||
/* 4 */ ".aaaaa..."
|
||||
/* 5 */ ".aaaaab.."
|
||||
@ -4847,15 +4849,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 7 */ ".aaaaad.."
|
||||
/* 8 */ ".aaaaa..."
|
||||
/* 9 */ "........."
|
||||
/* 10 */ "........."
|
||||
/* 11 */ "........."
|
||||
/* 12 */ "........."
|
||||
/* 10 */ "mmmmmmm.."
|
||||
/* 11 */ "mmmmmmm.."
|
||||
/* 12 */ "mmmmmmm.."
|
||||
|
||||
// Level 2
|
||||
/* z\x* 012345678 */
|
||||
/* 0 */ "........."
|
||||
/* 1 */ "........."
|
||||
/* 2 */ "........."
|
||||
/* 0 */ "mmmmmmm.."
|
||||
/* 1 */ "mmmmmmm.."
|
||||
/* 2 */ "mmmmmmm.."
|
||||
/* 3 */ "........."
|
||||
/* 4 */ ".efffe..."
|
||||
/* 5 */ ".f...f..."
|
||||
@ -4863,15 +4865,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 7 */ ".f...f..."
|
||||
/* 8 */ ".efffe..."
|
||||
/* 9 */ "........."
|
||||
/* 10 */ "........."
|
||||
/* 11 */ "........."
|
||||
/* 12 */ "........."
|
||||
/* 10 */ "mmmmmmm.."
|
||||
/* 11 */ "mmmmmmm.."
|
||||
/* 12 */ "mmmmmmm.."
|
||||
|
||||
// Level 3
|
||||
/* z\x* 012345678 */
|
||||
/* 0 */ "........."
|
||||
/* 1 */ "........."
|
||||
/* 2 */ "........."
|
||||
/* 0 */ "mmmmmmm.."
|
||||
/* 1 */ "mmmmmmm.."
|
||||
/* 2 */ "mmmmmmm.."
|
||||
/* 3 */ "........."
|
||||
/* 4 */ ".ejjje..."
|
||||
/* 5 */ ".j...f..."
|
||||
@ -4879,15 +4881,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 7 */ ".j...f..."
|
||||
/* 8 */ ".ejjje..."
|
||||
/* 9 */ "........."
|
||||
/* 10 */ "........."
|
||||
/* 11 */ "........."
|
||||
/* 12 */ "........."
|
||||
/* 10 */ "mmmmmmm.."
|
||||
/* 11 */ "mmmmmmm.."
|
||||
/* 12 */ "mmmmmmm.."
|
||||
|
||||
// Level 4
|
||||
/* z\x* 012345678 */
|
||||
/* 0 */ "........."
|
||||
/* 1 */ "........."
|
||||
/* 2 */ "........."
|
||||
/* 0 */ "mmmmmmm.."
|
||||
/* 1 */ "mmmmmmm.."
|
||||
/* 2 */ "mmmmmmm.."
|
||||
/* 3 */ "........."
|
||||
/* 4 */ ".efffe..."
|
||||
/* 5 */ ".f..nf..."
|
||||
@ -4895,15 +4897,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 7 */ ".f..nf..k"
|
||||
/* 8 */ ".efffe..o"
|
||||
/* 9 */ "........."
|
||||
/* 10 */ "........."
|
||||
/* 11 */ "........."
|
||||
/* 12 */ "........."
|
||||
/* 10 */ "mmmmmmm.."
|
||||
/* 11 */ "mmmmmmm.."
|
||||
/* 12 */ "mmmmmmm.."
|
||||
|
||||
// Level 5
|
||||
/* z\x* 012345678 */
|
||||
/* 0 */ "........."
|
||||
/* 1 */ "........."
|
||||
/* 2 */ "........."
|
||||
/* 0 */ "mmmmmmm.."
|
||||
/* 1 */ "mmmmmmm.."
|
||||
/* 2 */ "mmmmmmm.."
|
||||
/* 3 */ "........."
|
||||
/* 4 */ ".epppe..."
|
||||
/* 5 */ ".q...q..."
|
||||
@ -4911,15 +4913,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 7 */ ".q...q..k"
|
||||
/* 8 */ ".epppe..o"
|
||||
/* 9 */ "........."
|
||||
/* 10 */ "........."
|
||||
/* 11 */ "........."
|
||||
/* 12 */ "........."
|
||||
/* 10 */ "mmmmmmm.."
|
||||
/* 11 */ "mmmmmmm.."
|
||||
/* 12 */ "mmmmmmm.."
|
||||
|
||||
// Level 6
|
||||
/* z\x* 012345678 */
|
||||
/* 0 */ "........."
|
||||
/* 1 */ "........."
|
||||
/* 2 */ "........."
|
||||
/* 0 */ "mmmmmmm.."
|
||||
/* 1 */ "mmmmmmm.."
|
||||
/* 2 */ "mmmmmmm.."
|
||||
/* 3 */ "........."
|
||||
/* 4 */ ".efffe..."
|
||||
/* 5 */ ".f...f..."
|
||||
@ -4927,15 +4929,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 7 */ ".f...f..o"
|
||||
/* 8 */ ".efffe..o"
|
||||
/* 9 */ "........."
|
||||
/* 10 */ "........."
|
||||
/* 11 */ "........."
|
||||
/* 12 */ "........."
|
||||
/* 10 */ "mmmmmmm.."
|
||||
/* 11 */ "mmmmmmm.."
|
||||
/* 12 */ "mmmmmmm.."
|
||||
|
||||
// Level 7
|
||||
/* z\x* 012345678 */
|
||||
/* 0 */ "........."
|
||||
/* 1 */ "........."
|
||||
/* 2 */ "........."
|
||||
/* 0 */ "mmmmmmm.."
|
||||
/* 1 */ "mmmmmmm.."
|
||||
/* 2 */ "mmmmmmm.."
|
||||
/* 3 */ "........."
|
||||
/* 4 */ ".ejjje..."
|
||||
/* 5 */ ".j...j..."
|
||||
@ -4943,15 +4945,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 7 */ ".j...j..o"
|
||||
/* 8 */ ".ejjje..."
|
||||
/* 9 */ "........."
|
||||
/* 10 */ "........."
|
||||
/* 11 */ "........."
|
||||
/* 12 */ "........."
|
||||
/* 10 */ "mmmmmmm.."
|
||||
/* 11 */ "mmmmmmm.."
|
||||
/* 12 */ "mmmmmmm.."
|
||||
|
||||
// Level 8
|
||||
/* z\x* 012345678 */
|
||||
/* 0 */ "........o"
|
||||
/* 1 */ "........o"
|
||||
/* 2 */ "........o"
|
||||
/* 0 */ "mmmmmmm.o"
|
||||
/* 1 */ "mmmmmmm.o"
|
||||
/* 2 */ "mmmmmmm.o"
|
||||
/* 3 */ "........."
|
||||
/* 4 */ ".efffe..."
|
||||
/* 5 */ ".f...f..k"
|
||||
@ -4959,15 +4961,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 7 */ ".f...f..o"
|
||||
/* 8 */ ".efffe..."
|
||||
/* 9 */ "........."
|
||||
/* 10 */ "........."
|
||||
/* 11 */ "........."
|
||||
/* 12 */ "........."
|
||||
/* 10 */ "mmmmmmm.."
|
||||
/* 11 */ "mmmmmmm.."
|
||||
/* 12 */ "mmmmmmm.."
|
||||
|
||||
// Level 9
|
||||
/* z\x* 012345678 */
|
||||
/* 0 */ "........k"
|
||||
/* 1 */ "........k"
|
||||
/* 2 */ "........o"
|
||||
/* 0 */ "mmmmmmm.k"
|
||||
/* 1 */ "mmmmmmm.k"
|
||||
/* 2 */ "mmmmmmm.o"
|
||||
/* 3 */ "........o"
|
||||
/* 4 */ ".epppe..o"
|
||||
/* 5 */ ".q...q..k"
|
||||
@ -4975,15 +4977,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 7 */ ".q...q..k"
|
||||
/* 8 */ ".epppe..k"
|
||||
/* 9 */ "........."
|
||||
/* 10 */ "........."
|
||||
/* 11 */ "........."
|
||||
/* 12 */ "........."
|
||||
/* 10 */ "mmmmmmm.."
|
||||
/* 11 */ "mmmmmmm.."
|
||||
/* 12 */ "mmmmmmm.."
|
||||
|
||||
// Level 10
|
||||
/* z\x* 012345678 */
|
||||
/* 0 */ "........."
|
||||
/* 1 */ "........."
|
||||
/* 2 */ "........k"
|
||||
/* 0 */ "mmmmmmm.."
|
||||
/* 1 */ "mmmmmmm.."
|
||||
/* 2 */ "mmmmmmm.k"
|
||||
/* 3 */ "rrrrrrr.k"
|
||||
/* 4 */ "sfffffs.o"
|
||||
/* 5 */ ".f...f..o"
|
||||
@ -4991,15 +4993,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 7 */ ".f...f..o"
|
||||
/* 8 */ "tffffft.o"
|
||||
/* 9 */ "uuuuuuu.k"
|
||||
/* 10 */ "........k"
|
||||
/* 11 */ "........."
|
||||
/* 12 */ "........."
|
||||
/* 10 */ "mmmmmmm.k"
|
||||
/* 11 */ "mmmmmmm.."
|
||||
/* 12 */ "mmmmmmm.."
|
||||
|
||||
// Level 11
|
||||
/* z\x* 012345678 */
|
||||
/* 0 */ "........."
|
||||
/* 1 */ "........."
|
||||
/* 2 */ "........."
|
||||
/* 0 */ "mmmmmmm.."
|
||||
/* 1 */ "mmmmmmm.."
|
||||
/* 2 */ "mmmmmmm.."
|
||||
/* 3 */ "........."
|
||||
/* 4 */ "rrrrrrr.k"
|
||||
/* 5 */ "sfffffs.k"
|
||||
@ -5007,15 +5009,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 7 */ "tffffft.k"
|
||||
/* 8 */ "uuuuuuu.o"
|
||||
/* 9 */ "........o"
|
||||
/* 10 */ "........o"
|
||||
/* 11 */ "........k"
|
||||
/* 12 */ "........k"
|
||||
/* 10 */ "mmmmmmm.o"
|
||||
/* 11 */ "mmmmmmm.k"
|
||||
/* 12 */ "mmmmmmm.k"
|
||||
|
||||
// Level 12
|
||||
/* z\x* 012345678 */
|
||||
/* 0 */ "........."
|
||||
/* 1 */ "........."
|
||||
/* 2 */ "........."
|
||||
/* 0 */ "mmmmmmm.."
|
||||
/* 1 */ "mmmmmmm.."
|
||||
/* 2 */ "mmmmmmm.."
|
||||
/* 3 */ "........."
|
||||
/* 4 */ "........."
|
||||
/* 5 */ "rrrrrrr.o"
|
||||
@ -5023,15 +5025,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 7 */ "uuuuuuu.k"
|
||||
/* 8 */ "........."
|
||||
/* 9 */ "........."
|
||||
/* 10 */ "........o"
|
||||
/* 11 */ "........o"
|
||||
/* 12 */ "........o"
|
||||
/* 10 */ "mmmmmmm.o"
|
||||
/* 11 */ "mmmmmmm.o"
|
||||
/* 12 */ "mmmmmmm.o"
|
||||
|
||||
// Level 13
|
||||
/* z\x* 012345678 */
|
||||
/* 0 */ "........."
|
||||
/* 1 */ "........."
|
||||
/* 2 */ "........."
|
||||
/* 0 */ "mmmmmmm.."
|
||||
/* 1 */ "mmmmmmm.."
|
||||
/* 2 */ "mmmmmmm.."
|
||||
/* 3 */ "........."
|
||||
/* 4 */ "........."
|
||||
/* 5 */ "........o"
|
||||
@ -5039,15 +5041,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 7 */ "........."
|
||||
/* 8 */ "........."
|
||||
/* 9 */ "........."
|
||||
/* 10 */ "........."
|
||||
/* 11 */ "........."
|
||||
/* 12 */ "........."
|
||||
/* 10 */ "mmmmmmm.."
|
||||
/* 11 */ "mmmmmmm.."
|
||||
/* 12 */ "mmmmmmm.."
|
||||
|
||||
// Level 14
|
||||
/* z\x* 012345678 */
|
||||
/* 0 */ "........."
|
||||
/* 1 */ "........."
|
||||
/* 2 */ "........."
|
||||
/* 0 */ "mmmmmmm.."
|
||||
/* 1 */ "mmmmmmm.."
|
||||
/* 2 */ "mmmmmmm.."
|
||||
/* 3 */ "........."
|
||||
/* 4 */ "........o"
|
||||
/* 5 */ "........o"
|
||||
@ -5055,15 +5057,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 7 */ "........."
|
||||
/* 8 */ "........."
|
||||
/* 9 */ "........."
|
||||
/* 10 */ "........."
|
||||
/* 11 */ "........."
|
||||
/* 12 */ "........."
|
||||
/* 10 */ "mmmmmmm.."
|
||||
/* 11 */ "mmmmmmm.."
|
||||
/* 12 */ "mmmmmmm.."
|
||||
|
||||
// Level 15
|
||||
/* z\x* 012345678 */
|
||||
/* 0 */ "........."
|
||||
/* 1 */ "........."
|
||||
/* 2 */ "........."
|
||||
/* 0 */ "mmmmmmm.."
|
||||
/* 1 */ "mmmmmmm.."
|
||||
/* 2 */ "mmmmmmm.."
|
||||
/* 3 */ "........."
|
||||
/* 4 */ "........o"
|
||||
/* 5 */ "........k"
|
||||
@ -5071,15 +5073,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 7 */ "........."
|
||||
/* 8 */ "........."
|
||||
/* 9 */ "........."
|
||||
/* 10 */ "........."
|
||||
/* 11 */ "........."
|
||||
/* 12 */ "........."
|
||||
/* 10 */ "mmmmmmm.."
|
||||
/* 11 */ "mmmmmmm.."
|
||||
/* 12 */ "mmmmmmm.."
|
||||
|
||||
// Level 16
|
||||
/* z\x* 012345678 */
|
||||
/* 0 */ "........."
|
||||
/* 1 */ "........."
|
||||
/* 2 */ "........."
|
||||
/* 0 */ "mmmmmmm.."
|
||||
/* 1 */ "mmmmmmm.."
|
||||
/* 2 */ "mmmmmmm.."
|
||||
/* 3 */ "........."
|
||||
/* 4 */ "........o"
|
||||
/* 5 */ "........k"
|
||||
@ -5087,9 +5089,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
|
||||
/* 7 */ "........."
|
||||
/* 8 */ "........."
|
||||
/* 9 */ "........."
|
||||
/* 10 */ "........."
|
||||
/* 11 */ "........."
|
||||
/* 12 */ ".........",
|
||||
/* 10 */ "mmmmmmm.."
|
||||
/* 11 */ "mmmmmmm.."
|
||||
/* 12 */ "mmmmmmm..",
|
||||
|
||||
// Connectors:
|
||||
"-1: 8, 1, 6: 5\n" /* Type -1, direction X+ */,
|
||||
@ -5472,13 +5474,15 @@ const cPrefab::sDef g_PlainsVillageStartingPrefabs[] =
|
||||
"l: 66: 7\n" /* tracks */
|
||||
"m: 19: 0\n" /* sponge */
|
||||
"n: 50: 2\n" /* torch */
|
||||
"o: 2: 0\n" /* grass */
|
||||
"p: 53: 2\n" /* woodstairs */
|
||||
"q: 77: 1\n" /* stonebutton */
|
||||
"r: 27: 0\n" /* poweredrail */
|
||||
"s: 53: 7\n" /* woodstairs */
|
||||
"t: 53: 6\n" /* woodstairs */
|
||||
"u: 53: 3\n" /* woodstairs */,
|
||||
"o: 4: 0\n" /* cobblestone */
|
||||
"p: 2: 0\n" /* grass */
|
||||
"q: 13: 0\n" /* gravel */
|
||||
"r: 53: 2\n" /* woodstairs */
|
||||
"s: 77: 1\n" /* stonebutton */
|
||||
"t: 27: 0\n" /* poweredrail */
|
||||
"u: 53: 7\n" /* woodstairs */
|
||||
"v: 53: 6\n" /* woodstairs */
|
||||
"w: 53: 3\n" /* woodstairs */,
|
||||
|
||||
// Block data:
|
||||
// Level 0
|
||||
@ -5783,28 +5787,28 @@ const cPrefab::sDef g_PlainsVillageStartingPrefabs[] =
|
||||
|
||||
// Level 30
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "mmmmmmm"
|
||||
/* 0 */ "mmooomm"
|
||||
/* 1 */ "mmmammm"
|
||||
/* 2 */ "mm...mm"
|
||||
/* 3 */ "ma..aam"
|
||||
/* 4 */ "mmfgamm"
|
||||
/* 2 */ "om...mo"
|
||||
/* 3 */ "oa..aao"
|
||||
/* 4 */ "omfgamo"
|
||||
/* 5 */ "mmmammm"
|
||||
/* 6 */ "mmmmmmm"
|
||||
/* 6 */ "mmooomm"
|
||||
|
||||
// Level 31
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "ooomooo"
|
||||
/* 1 */ "oaaaaao"
|
||||
/* 2 */ "oa.aaao"
|
||||
/* 3 */ "oa..iao"
|
||||
/* 4 */ "oa..jao"
|
||||
/* 5 */ "oaaaaao"
|
||||
/* 6 */ "ooooooo"
|
||||
/* 0 */ "ppqqqpp"
|
||||
/* 1 */ "paaaaap"
|
||||
/* 2 */ "qa.aaaq"
|
||||
/* 3 */ "qa..iaq"
|
||||
/* 4 */ "qa..jaq"
|
||||
/* 5 */ "paaaaap"
|
||||
/* 6 */ "ppqqqpp"
|
||||
|
||||
// Level 32
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "...p..."
|
||||
/* 1 */ ".aqrba."
|
||||
/* 0 */ "...r..."
|
||||
/* 1 */ ".astba."
|
||||
/* 2 */ "...fl.."
|
||||
/* 3 */ "......."
|
||||
/* 4 */ "......."
|
||||
@ -5833,31 +5837,31 @@ const cPrefab::sDef g_PlainsVillageStartingPrefabs[] =
|
||||
|
||||
// Level 35
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "ppppppp"
|
||||
/* 1 */ "saaaaas"
|
||||
/* 0 */ "rrrrrrr"
|
||||
/* 1 */ "uaaaaau"
|
||||
/* 2 */ ".a...a."
|
||||
/* 3 */ ".a...a."
|
||||
/* 4 */ ".a...a."
|
||||
/* 5 */ "taaaaat"
|
||||
/* 6 */ "uuuuuuu"
|
||||
/* 5 */ "vaaaaav"
|
||||
/* 6 */ "wwwwwww"
|
||||
|
||||
// Level 36
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "......."
|
||||
/* 1 */ "ppppppp"
|
||||
/* 2 */ "saaaaas"
|
||||
/* 1 */ "rrrrrrr"
|
||||
/* 2 */ "uaaaaau"
|
||||
/* 3 */ ".aaaaa."
|
||||
/* 4 */ "taaaaat"
|
||||
/* 5 */ "uuuuuuu"
|
||||
/* 4 */ "vaaaaav"
|
||||
/* 5 */ "wwwwwww"
|
||||
/* 6 */ "......."
|
||||
|
||||
// Level 37
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "......."
|
||||
/* 1 */ "......."
|
||||
/* 2 */ "ppppppp"
|
||||
/* 2 */ "rrrrrrr"
|
||||
/* 3 */ "aaaaaaa"
|
||||
/* 4 */ "uuuuuuu"
|
||||
/* 4 */ "wwwwwww"
|
||||
/* 5 */ "......."
|
||||
/* 6 */ ".......",
|
||||
|
||||
|
@ -23,8 +23,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
|
||||
12, 6, 10, // SizeX = 12, SizeY = 6, SizeZ = 10
|
||||
|
||||
// Hitbox (relative to bounding box):
|
||||
0, 0, 0, // MinX, MinY, MinZ
|
||||
11, 5, 9, // MaxX, MaxY, MaxZ
|
||||
-1, 0, 0, // MinX, MinY, MinZ
|
||||
12, 5, 10, // MaxX, MaxY, MaxZ
|
||||
|
||||
// Block definitions:
|
||||
".: 0: 0\n" /* air */
|
||||
@ -170,8 +170,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
|
||||
13, 6, 9, // SizeX = 13, SizeY = 6, SizeZ = 9
|
||||
|
||||
// Hitbox (relative to bounding box):
|
||||
0, 0, 0, // MinX, MinY, MinZ
|
||||
12, 5, 8, // MaxX, MaxY, MaxZ
|
||||
-1, 0, 0, // MinX, MinY, MinZ
|
||||
13, 5, 9, // MaxX, MaxY, MaxZ
|
||||
|
||||
// Block definitions:
|
||||
".: 0: 0\n" /* air */
|
||||
@ -309,8 +309,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
|
||||
7, 6, 6, // SizeX = 7, SizeY = 6, SizeZ = 6
|
||||
|
||||
// Hitbox (relative to bounding box):
|
||||
0, 0, 0, // MinX, MinY, MinZ
|
||||
6, 5, 5, // MaxX, MaxY, MaxZ
|
||||
-1, 0, 0, // MinX, MinY, MinZ
|
||||
7, 5, 6, // MaxX, MaxY, MaxZ
|
||||
|
||||
// Block definitions:
|
||||
".: 0: 0\n" /* air */
|
||||
@ -420,8 +420,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
|
||||
7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7
|
||||
|
||||
// Hitbox (relative to bounding box):
|
||||
0, 0, 0, // MinX, MinY, MinZ
|
||||
6, 5, 6, // MaxX, MaxY, MaxZ
|
||||
-1, 0, 0, // MinX, MinY, MinZ
|
||||
7, 5, 7, // MaxX, MaxY, MaxZ
|
||||
|
||||
// Block definitions:
|
||||
".: 0: 0\n" /* air */
|
||||
@ -538,8 +538,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
|
||||
9, 6, 7, // SizeX = 9, SizeY = 6, SizeZ = 7
|
||||
|
||||
// Hitbox (relative to bounding box):
|
||||
0, 0, 0, // MinX, MinY, MinZ
|
||||
8, 5, 6, // MaxX, MaxY, MaxZ
|
||||
-1, 0, 0, // MinX, MinY, MinZ
|
||||
9, 5, 7, // MaxX, MaxY, MaxZ
|
||||
|
||||
// Block definitions:
|
||||
".: 0: 0\n" /* air */
|
||||
@ -656,8 +656,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
|
||||
10, 6, 7, // SizeX = 10, SizeY = 6, SizeZ = 7
|
||||
|
||||
// Hitbox (relative to bounding box):
|
||||
0, 0, 0, // MinX, MinY, MinZ
|
||||
9, 5, 6, // MaxX, MaxY, MaxZ
|
||||
-1, 0, 0, // MinX, MinY, MinZ
|
||||
10, 5, 7, // MaxX, MaxY, MaxZ
|
||||
|
||||
// Block definitions:
|
||||
".: 0: 0\n" /* air */
|
||||
@ -780,8 +780,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
|
||||
10, 6, 9, // SizeX = 10, SizeY = 6, SizeZ = 9
|
||||
|
||||
// Hitbox (relative to bounding box):
|
||||
0, 0, 0, // MinX, MinY, MinZ
|
||||
9, 5, 8, // MaxX, MaxY, MaxZ
|
||||
-1, 0, 0, // MinX, MinY, MinZ
|
||||
10, 5, 9, // MaxX, MaxY, MaxZ
|
||||
|
||||
// Block definitions:
|
||||
".: 0: 0\n" /* air */
|
||||
@ -918,8 +918,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
|
||||
11, 6, 9, // SizeX = 11, SizeY = 6, SizeZ = 9
|
||||
|
||||
// Hitbox (relative to bounding box):
|
||||
0, 0, 0, // MinX, MinY, MinZ
|
||||
10, 5, 8, // MaxX, MaxY, MaxZ
|
||||
-1, 0, 0, // MinX, MinY, MinZ
|
||||
11, 5, 9, // MaxX, MaxY, MaxZ
|
||||
|
||||
// Block definitions:
|
||||
".: 0: 0\n" /* air */
|
||||
@ -1054,18 +1054,18 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
|
||||
// The data has been exported from the gallery Desert, area index 53, ID 345, created by jakibaki
|
||||
{
|
||||
// Size:
|
||||
15, 5, 14, // SizeX = 15, SizeY = 5, SizeZ = 14
|
||||
15, 6, 14, // SizeX = 15, SizeY = 6, SizeZ = 14
|
||||
|
||||
// Hitbox (relative to bounding box):
|
||||
0, 0, 0, // MinX, MinY, MinZ
|
||||
14, 4, 13, // MaxX, MaxY, MaxZ
|
||||
-1, 0, 0, // MinX, MinY, MinZ
|
||||
15, 5, 14, // MaxX, MaxY, MaxZ
|
||||
|
||||
// Block definitions:
|
||||
".: 0: 0\n" /* air */
|
||||
"a:128: 0\n" /* sandstonestairs */
|
||||
"b:128: 2\n" /* sandstonestairs */
|
||||
"c:128: 1\n" /* sandstonestairs */
|
||||
"d: 24: 0\n" /* sandstone */
|
||||
"a: 24: 0\n" /* sandstone */
|
||||
"b:128: 0\n" /* sandstonestairs */
|
||||
"c:128: 2\n" /* sandstonestairs */
|
||||
"d:128: 1\n" /* sandstonestairs */
|
||||
"e: 43: 1\n" /* doubleslab */
|
||||
"f: 64: 7\n" /* wooddoorblock */
|
||||
"g:171: 0\n" /* carpet */
|
||||
@ -1088,43 +1088,61 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
|
||||
// Level 0
|
||||
/* z\x* 11111 */
|
||||
/* * 012345678901234 */
|
||||
/* 0 */ "...abc........."
|
||||
/* 1 */ ".ddddddddddddd."
|
||||
/* 2 */ ".ddddddddddddd."
|
||||
/* 3 */ ".ddddddddddddd."
|
||||
/* 4 */ ".ddddddddddddd."
|
||||
/* 5 */ ".ddddddddddded."
|
||||
/* 6 */ ".ddddddddddddd."
|
||||
/* 7 */ ".ddddddddddddd."
|
||||
/* 8 */ ".......deddddd."
|
||||
/* 9 */ "mmmmmm.ddddddd."
|
||||
/* 10 */ "mmmmmm.ddddddd."
|
||||
/* 11 */ "mmmmmm.ddddddd."
|
||||
/* 12 */ "mmmmmm.ddddddd."
|
||||
/* 13 */ "..............."
|
||||
/* 0 */ "mmmaaammmmmmmmm"
|
||||
/* 1 */ "maaaaaaaaaaaaam"
|
||||
/* 2 */ "maaaaaaaaaaaaam"
|
||||
/* 3 */ "maaaaaaaaaaaaam"
|
||||
/* 4 */ "maaaaaaaaaaaaam"
|
||||
/* 5 */ "maaaaaaaaaaaaam"
|
||||
/* 6 */ "maaaaaaaaaaaaam"
|
||||
/* 7 */ "maaaaaaaaaaaaam"
|
||||
/* 8 */ "mmmmmmmaaaaaaam"
|
||||
/* 9 */ "mmmmmmmaaaaaaam"
|
||||
/* 10 */ "mmmmmmmaaaaaaam"
|
||||
/* 11 */ "mmmmmmmaaaaaaam"
|
||||
/* 12 */ "mmmmmmmaaaaaaam"
|
||||
/* 13 */ "mmmmmmmmmmmmmmm"
|
||||
|
||||
// Level 1
|
||||
/* z\x* 11111 */
|
||||
/* * 012345678901234 */
|
||||
/* 0 */ "..............."
|
||||
/* 1 */ ".dddfddddddddd."
|
||||
/* 2 */ ".dgghhhhhhhhgd."
|
||||
/* 3 */ ".dghiiiiiiiihd."
|
||||
/* 4 */ ".dghiggggggihd."
|
||||
/* 5 */ ".dghiiiiiigihd."
|
||||
/* 6 */ ".dgghhhhhigihd."
|
||||
/* 7 */ ".dddddddhigihd."
|
||||
/* 8 */ ".......dhigihd."
|
||||
/* 9 */ "mmmmmm.dhiiihd."
|
||||
/* 10 */ "mmmmmm.dghhhgd."
|
||||
/* 11 */ "mmmmmm.dggggjd."
|
||||
/* 12 */ "mmmmmm.ddddddd."
|
||||
/* 0 */ "...bcd........."
|
||||
/* 1 */ ".aaaaaaaaaaaaa."
|
||||
/* 2 */ ".aaaaaaaaaaaaa."
|
||||
/* 3 */ ".aaaaaaaaaaaaa."
|
||||
/* 4 */ ".aaaaaaaaaaaaa."
|
||||
/* 5 */ ".aaaaaaaaaaaea."
|
||||
/* 6 */ ".aaaaaaaaaaaaa."
|
||||
/* 7 */ ".aaaaaaaaaaaaa."
|
||||
/* 8 */ ".......aeaaaaa."
|
||||
/* 9 */ "mmmmmm.aaaaaaa."
|
||||
/* 10 */ "mmmmmm.aaaaaaa."
|
||||
/* 11 */ "mmmmmm.aaaaaaa."
|
||||
/* 12 */ "mmmmmm.aaaaaaa."
|
||||
/* 13 */ "..............."
|
||||
|
||||
// Level 2
|
||||
/* z\x* 11111 */
|
||||
/* * 012345678901234 */
|
||||
/* 0 */ "..............."
|
||||
/* 1 */ ".aaafaaaaaaaaa."
|
||||
/* 2 */ ".agghhhhhhhhga."
|
||||
/* 3 */ ".aghiiiiiiiiha."
|
||||
/* 4 */ ".aghiggggggiha."
|
||||
/* 5 */ ".aghiiiiiigiha."
|
||||
/* 6 */ ".agghhhhhigiha."
|
||||
/* 7 */ ".aaaaaaahigiha."
|
||||
/* 8 */ ".......ahigiha."
|
||||
/* 9 */ "mmmmmm.ahiiiha."
|
||||
/* 10 */ "mmmmmm.aghhhga."
|
||||
/* 11 */ "mmmmmm.aggggja."
|
||||
/* 12 */ "mmmmmm.aaaaaaa."
|
||||
/* 13 */ "..............."
|
||||
|
||||
// Level 3
|
||||
/* z\x* 11111 */
|
||||
/* * 012345678901234 */
|
||||
/* 0 */ "..............."
|
||||
/* 1 */ ".kkklkkkk.kkkk."
|
||||
/* 2 */ ".k...........k."
|
||||
/* 3 */ ".k...........k."
|
||||
@ -1139,44 +1157,44 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
|
||||
/* 12 */ "mmmmmm.kkk.kkk."
|
||||
/* 13 */ "..............."
|
||||
|
||||
// Level 3
|
||||
/* z\x* 11111 */
|
||||
/* * 012345678901234 */
|
||||
/* 0 */ "..............."
|
||||
/* 1 */ ".ddddddddddddd."
|
||||
/* 2 */ ".d......n....d."
|
||||
/* 3 */ ".d...........d."
|
||||
/* 4 */ ".do..........d."
|
||||
/* 5 */ ".d...........d."
|
||||
/* 6 */ ".d..........pd."
|
||||
/* 7 */ ".ddddddd.....d."
|
||||
/* 8 */ ".......d.....d."
|
||||
/* 9 */ "mmmmmm.d.....d."
|
||||
/* 10 */ "mmmmmm.d.....d."
|
||||
/* 11 */ "mmmmmm.d..q..d."
|
||||
/* 12 */ "mmmmmm.ddddddd."
|
||||
/* 13 */ "..............."
|
||||
|
||||
// Level 4
|
||||
/* z\x* 11111 */
|
||||
/* * 012345678901234 */
|
||||
/* 0 */ "..............."
|
||||
/* 1 */ ".aaaaaaaaaaaaa."
|
||||
/* 2 */ ".a......n....a."
|
||||
/* 3 */ ".a...........a."
|
||||
/* 4 */ ".ao..........a."
|
||||
/* 5 */ ".a...........a."
|
||||
/* 6 */ ".a..........pa."
|
||||
/* 7 */ ".aaaaaaa.....a."
|
||||
/* 8 */ ".......a.....a."
|
||||
/* 9 */ "mmmmmm.a.....a."
|
||||
/* 10 */ "mmmmmm.a.....a."
|
||||
/* 11 */ "mmmmmm.a..q..a."
|
||||
/* 12 */ "mmmmmm.aaaaaaa."
|
||||
/* 13 */ "..............."
|
||||
|
||||
// Level 5
|
||||
/* z\x* 11111 */
|
||||
/* * 012345678901234 */
|
||||
/* 0 */ "rrrrrrrrrrrrrrs"
|
||||
/* 1 */ "tddddddddddddds"
|
||||
/* 2 */ "tddddddddddddds"
|
||||
/* 3 */ "tddddddddddddds"
|
||||
/* 4 */ "tddddddddddddds"
|
||||
/* 5 */ "tddddddddddddds"
|
||||
/* 6 */ "tddddddddddddds"
|
||||
/* 7 */ "tddddddddddddds"
|
||||
/* 8 */ "tuuuuutddddddds"
|
||||
/* 9 */ "mmmmmmtddddddds"
|
||||
/* 10 */ "mmmmmmtddddddds"
|
||||
/* 11 */ "mmmmmmtddddddds"
|
||||
/* 12 */ "mmmmmmtddddddds"
|
||||
/* 1 */ "taaaaaaaaaaaaas"
|
||||
/* 2 */ "taaaaaaaaaaaaas"
|
||||
/* 3 */ "taaaaaaaaaaaaas"
|
||||
/* 4 */ "taaaaaaaaaaaaas"
|
||||
/* 5 */ "taaaaaaaaaaaaas"
|
||||
/* 6 */ "taaaaaaaaaaaaas"
|
||||
/* 7 */ "taaaaaaaaaaaaas"
|
||||
/* 8 */ "tuuuuutaaaaaaas"
|
||||
/* 9 */ "mmmmmmtaaaaaaas"
|
||||
/* 10 */ "mmmmmmtaaaaaaas"
|
||||
/* 11 */ "mmmmmmtaaaaaaas"
|
||||
/* 12 */ "mmmmmmtaaaaaaas"
|
||||
/* 13 */ "......tuuuuuuuu",
|
||||
|
||||
// Connectors:
|
||||
"-1: 4, 0, 0: 2\n" /* Type -1, direction Z- */,
|
||||
"-1: 4, 1, 0: 2\n" /* Type -1, direction Z- */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
@ -1210,8 +1228,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
|
||||
7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7
|
||||
|
||||
// Hitbox (relative to bounding box):
|
||||
0, 0, 0, // MinX, MinY, MinZ
|
||||
6, 5, 6, // MaxX, MaxY, MaxZ
|
||||
-1, 0, 0, // MinX, MinY, MinZ
|
||||
7, 5, 7, // MaxX, MaxY, MaxZ
|
||||
|
||||
// Block definitions:
|
||||
".: 0: 0\n" /* air */
|
||||
@ -1320,8 +1338,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
|
||||
14, 4, 16, // SizeX = 14, SizeY = 4, SizeZ = 16
|
||||
|
||||
// Hitbox (relative to bounding box):
|
||||
0, 0, 0, // MinX, MinY, MinZ
|
||||
13, 3, 15, // MaxX, MaxY, MaxZ
|
||||
-1, 0, 0, // MinX, MinY, MinZ
|
||||
14, 3, 16, // MaxX, MaxY, MaxZ
|
||||
|
||||
// Block definitions:
|
||||
".: 0: 0\n" /* air */
|
||||
|
File diff suppressed because it is too large
Load Diff
484
src/Generating/Prefabs/TestRailsPrefabs.cpp
Normal file
484
src/Generating/Prefabs/TestRailsPrefabs.cpp
Normal file
@ -0,0 +1,484 @@
|
||||
|
||||
// TestRailsPrefabs.cpp
|
||||
|
||||
// Defines the prefabs in the group TestRails
|
||||
|
||||
// NOTE: This file has been generated automatically by GalExport!
|
||||
// Any manual changes will be overwritten by the next automatic export!
|
||||
|
||||
#include "Globals.h"
|
||||
#include "TestRailsPrefabs.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const cPrefab::sDef g_TestRailsPrefabs[] =
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ActivatorRail:
|
||||
// The data has been exported from the gallery Plains, area index 251, ID 746, created by Aloe_vera
|
||||
{
|
||||
// Size:
|
||||
7, 3, 7, // SizeX = 7, SizeY = 3, SizeZ = 7
|
||||
|
||||
// Hitbox (relative to bounding box):
|
||||
0, 0, 0, // MinX, MinY, MinZ
|
||||
6, 2, 6, // MaxX, MaxY, MaxZ
|
||||
|
||||
// Block definitions:
|
||||
".: 0: 0\n" /* air */
|
||||
"a: 1: 0\n" /* stone */
|
||||
"b: 5: 0\n" /* wood */
|
||||
"c:157: 0\n" /* activatorrail */
|
||||
"d:157: 2\n" /* activatorrail */
|
||||
"e:157: 3\n" /* activatorrail */
|
||||
"f:157: 5\n" /* activatorrail */
|
||||
"g: 50: 5\n" /* torch */
|
||||
"h:157: 4\n" /* activatorrail */
|
||||
"i:157: 1\n" /* activatorrail */
|
||||
"m: 19: 0\n" /* sponge */,
|
||||
|
||||
// Block data:
|
||||
// Level 0
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "aaab..."
|
||||
/* 1 */ "abbbbb."
|
||||
/* 2 */ "abbb.b."
|
||||
/* 3 */ "bbbb.bb"
|
||||
/* 4 */ ".b...b."
|
||||
/* 5 */ ".bbbbb."
|
||||
/* 6 */ "...b..."
|
||||
|
||||
// Level 1
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "......."
|
||||
/* 1 */ ".cdbec."
|
||||
/* 2 */ ".fg..f."
|
||||
/* 3 */ ".b.g.b."
|
||||
/* 4 */ ".h...h."
|
||||
/* 5 */ ".cdbec."
|
||||
/* 6 */ "......."
|
||||
|
||||
// Level 2
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "......."
|
||||
/* 1 */ "...i..."
|
||||
/* 2 */ "......."
|
||||
/* 3 */ ".c...c."
|
||||
/* 4 */ "......."
|
||||
/* 5 */ "...i..."
|
||||
/* 6 */ ".......",
|
||||
|
||||
// Connectors:
|
||||
"1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
|
||||
"-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */
|
||||
"1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */
|
||||
"-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */
|
||||
"1: 0, 1, 3: 4\n" /* Type 1, direction X- */
|
||||
"-1: 0, 1, 3: 4\n" /* Type -1, direction X- */
|
||||
"1: 3, 1, 0: 2\n" /* Type 1, direction Z- */
|
||||
"-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
|
||||
// Merge strategy:
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
|
||||
// DepthWeight:
|
||||
"",
|
||||
|
||||
// AddWeightIfSame:
|
||||
0,
|
||||
|
||||
// MoveToGround:
|
||||
false,
|
||||
}, // ActivatorRail
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// DetectorRail:
|
||||
// The data has been exported from the gallery Plains, area index 250, ID 745, created by Aloe_vera
|
||||
{
|
||||
// Size:
|
||||
7, 3, 7, // SizeX = 7, SizeY = 3, SizeZ = 7
|
||||
|
||||
// Hitbox (relative to bounding box):
|
||||
0, 0, 0, // MinX, MinY, MinZ
|
||||
6, 2, 6, // MaxX, MaxY, MaxZ
|
||||
|
||||
// Block definitions:
|
||||
".: 0: 0\n" /* air */
|
||||
"a: 1: 0\n" /* stone */
|
||||
"b: 5: 0\n" /* wood */
|
||||
"c: 28: 0\n" /* detectorrail */
|
||||
"d: 28: 2\n" /* detectorrail */
|
||||
"e: 28: 3\n" /* detectorrail */
|
||||
"f: 28: 5\n" /* detectorrail */
|
||||
"g: 50: 5\n" /* torch */
|
||||
"h: 28: 4\n" /* detectorrail */
|
||||
"i: 28: 1\n" /* detectorrail */
|
||||
"m: 19: 0\n" /* sponge */,
|
||||
|
||||
// Block data:
|
||||
// Level 0
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "aaab..."
|
||||
/* 1 */ "abbbbb."
|
||||
/* 2 */ "abbb.b."
|
||||
/* 3 */ "bbbb.bb"
|
||||
/* 4 */ ".b...b."
|
||||
/* 5 */ ".bbbbb."
|
||||
/* 6 */ "...b..."
|
||||
|
||||
// Level 1
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "......."
|
||||
/* 1 */ ".cdbec."
|
||||
/* 2 */ ".fg..f."
|
||||
/* 3 */ ".b.g.b."
|
||||
/* 4 */ ".h...h."
|
||||
/* 5 */ ".cdbec."
|
||||
/* 6 */ "......."
|
||||
|
||||
// Level 2
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "......."
|
||||
/* 1 */ "...i..."
|
||||
/* 2 */ "......."
|
||||
/* 3 */ ".c...c."
|
||||
/* 4 */ "......."
|
||||
/* 5 */ "...i..."
|
||||
/* 6 */ ".......",
|
||||
|
||||
// Connectors:
|
||||
"1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
|
||||
"-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */
|
||||
"1: 3, 1, 0: 2\n" /* Type 1, direction Z- */
|
||||
"-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */
|
||||
"1: 0, 1, 3: 4\n" /* Type 1, direction X- */
|
||||
"-1: 0, 1, 3: 4\n" /* Type -1, direction X- */
|
||||
"1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */
|
||||
"-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
|
||||
// Merge strategy:
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
|
||||
// DepthWeight:
|
||||
"",
|
||||
|
||||
// AddWeightIfSame:
|
||||
0,
|
||||
|
||||
// MoveToGround:
|
||||
false,
|
||||
}, // DetectorRail
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PowerRail:
|
||||
// The data has been exported from the gallery Plains, area index 248, ID 743, created by Aloe_vera
|
||||
{
|
||||
// Size:
|
||||
7, 3, 7, // SizeX = 7, SizeY = 3, SizeZ = 7
|
||||
|
||||
// Hitbox (relative to bounding box):
|
||||
0, 0, 0, // MinX, MinY, MinZ
|
||||
6, 2, 6, // MaxX, MaxY, MaxZ
|
||||
|
||||
// Block definitions:
|
||||
".: 0: 0\n" /* air */
|
||||
"a: 1: 0\n" /* stone */
|
||||
"b: 5: 0\n" /* wood */
|
||||
"c: 27: 0\n" /* poweredrail */
|
||||
"d: 27: 2\n" /* poweredrail */
|
||||
"e: 27: 3\n" /* poweredrail */
|
||||
"f: 27: 5\n" /* poweredrail */
|
||||
"g: 50: 5\n" /* torch */
|
||||
"h: 27: 4\n" /* poweredrail */
|
||||
"i: 27: 1\n" /* poweredrail */
|
||||
"m: 19: 0\n" /* sponge */,
|
||||
|
||||
// Block data:
|
||||
// Level 0
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "aaab..."
|
||||
/* 1 */ "abbbbb."
|
||||
/* 2 */ "abbb.b."
|
||||
/* 3 */ "bbbb.bb"
|
||||
/* 4 */ ".b...b."
|
||||
/* 5 */ ".bbbbb."
|
||||
/* 6 */ "...b..."
|
||||
|
||||
// Level 1
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "......."
|
||||
/* 1 */ ".cdbec."
|
||||
/* 2 */ ".fg..f."
|
||||
/* 3 */ ".b.g.b."
|
||||
/* 4 */ ".h...h."
|
||||
/* 5 */ ".cdbec."
|
||||
/* 6 */ "......."
|
||||
|
||||
// Level 2
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "......."
|
||||
/* 1 */ "...i..."
|
||||
/* 2 */ "......."
|
||||
/* 3 */ ".c...c."
|
||||
/* 4 */ "......."
|
||||
/* 5 */ "...i..."
|
||||
/* 6 */ ".......",
|
||||
|
||||
// Connectors:
|
||||
"1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
|
||||
"-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */
|
||||
"1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */
|
||||
"-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */
|
||||
"1: 0, 1, 3: 4\n" /* Type 1, direction X- */
|
||||
"-1: 0, 1, 3: 4\n" /* Type -1, direction X- */
|
||||
"1: 3, 1, 0: 2\n" /* Type 1, direction Z- */
|
||||
"-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */
|
||||
"1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
|
||||
"-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
|
||||
// Merge strategy:
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
|
||||
// DepthWeight:
|
||||
"",
|
||||
|
||||
// AddWeightIfSame:
|
||||
0,
|
||||
|
||||
// MoveToGround:
|
||||
false,
|
||||
}, // PowerRail
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RegularRail:
|
||||
// The data has been exported from the gallery Plains, area index 247, ID 742, created by Aloe_vera
|
||||
{
|
||||
// Size:
|
||||
7, 3, 7, // SizeX = 7, SizeY = 3, SizeZ = 7
|
||||
|
||||
// Hitbox (relative to bounding box):
|
||||
0, 0, 0, // MinX, MinY, MinZ
|
||||
6, 2, 6, // MaxX, MaxY, MaxZ
|
||||
|
||||
// Block definitions:
|
||||
".: 0: 0\n" /* air */
|
||||
"a: 1: 0\n" /* stone */
|
||||
"b: 5: 0\n" /* wood */
|
||||
"c: 66: 6\n" /* tracks */
|
||||
"d: 66: 2\n" /* tracks */
|
||||
"e: 66: 3\n" /* tracks */
|
||||
"f: 66: 7\n" /* tracks */
|
||||
"g: 66: 5\n" /* tracks */
|
||||
"h: 50: 5\n" /* torch */
|
||||
"i: 66: 4\n" /* tracks */
|
||||
"j: 66: 9\n" /* tracks */
|
||||
"k: 66: 8\n" /* tracks */
|
||||
"l: 66: 1\n" /* tracks */
|
||||
"m: 19: 0\n" /* sponge */
|
||||
"n: 66: 0\n" /* tracks */,
|
||||
|
||||
// Block data:
|
||||
// Level 0
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "aaab..."
|
||||
/* 1 */ "abbbbb."
|
||||
/* 2 */ "abbb.b."
|
||||
/* 3 */ "bbbb.bb"
|
||||
/* 4 */ ".b...b."
|
||||
/* 5 */ ".bbbbb."
|
||||
/* 6 */ "...b..."
|
||||
|
||||
// Level 1
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "......."
|
||||
/* 1 */ ".cdbef."
|
||||
/* 2 */ ".gh..g."
|
||||
/* 3 */ ".b.h.b."
|
||||
/* 4 */ ".i...i."
|
||||
/* 5 */ ".jdbek."
|
||||
/* 6 */ "......."
|
||||
|
||||
// Level 2
|
||||
/* z\x* 0123456 */
|
||||
/* 0 */ "......."
|
||||
/* 1 */ "...l..."
|
||||
/* 2 */ "......."
|
||||
/* 3 */ ".n...n."
|
||||
/* 4 */ "......."
|
||||
/* 5 */ "...l..."
|
||||
/* 6 */ ".......",
|
||||
|
||||
// Connectors:
|
||||
"1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
|
||||
"-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */
|
||||
"1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */
|
||||
"-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */
|
||||
"1: 0, 1, 3: 4\n" /* Type 1, direction X- */
|
||||
"-1: 0, 1, 3: 4\n" /* Type -1, direction X- */
|
||||
"1: 3, 1, 0: 2\n" /* Type 1, direction Z- */
|
||||
"-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
|
||||
// Merge strategy:
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
|
||||
// DepthWeight:
|
||||
"",
|
||||
|
||||
// AddWeightIfSame:
|
||||
0,
|
||||
|
||||
// MoveToGround:
|
||||
false,
|
||||
}, // RegularRail
|
||||
}; // g_TestRailsPrefabs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const cPrefab::sDef g_TestRailsStartingPrefabs[] =
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CentralPiece:
|
||||
// The data has been exported from the gallery Plains, area index 249, ID 744, created by Aloe_vera
|
||||
{
|
||||
// Size:
|
||||
6, 3, 6, // SizeX = 6, SizeY = 3, SizeZ = 6
|
||||
|
||||
// Hitbox (relative to bounding box):
|
||||
0, 0, 0, // MinX, MinY, MinZ
|
||||
5, 2, 5, // MaxX, MaxY, MaxZ
|
||||
|
||||
// Block definitions:
|
||||
".: 0: 0\n" /* air */
|
||||
"a: 1: 0\n" /* stone */
|
||||
"b: 5: 0\n" /* wood */
|
||||
"c: 66: 6\n" /* tracks */
|
||||
"d: 66: 2\n" /* tracks */
|
||||
"e: 66: 3\n" /* tracks */
|
||||
"f: 66: 7\n" /* tracks */
|
||||
"g: 66: 5\n" /* tracks */
|
||||
"h: 50: 5\n" /* torch */
|
||||
"i: 66: 4\n" /* tracks */
|
||||
"j: 66: 9\n" /* tracks */
|
||||
"k: 66: 8\n" /* tracks */
|
||||
"l: 66: 1\n" /* tracks */
|
||||
"m: 19: 0\n" /* sponge */
|
||||
"n: 66: 0\n" /* tracks */,
|
||||
|
||||
// Block data:
|
||||
// Level 0
|
||||
/* z\x* 012345 */
|
||||
/* 0 */ "aaab.."
|
||||
/* 1 */ "abbbbb"
|
||||
/* 2 */ "abbb.b"
|
||||
/* 3 */ "bbbb.b"
|
||||
/* 4 */ ".b...b"
|
||||
/* 5 */ ".bbbbb"
|
||||
|
||||
// Level 1
|
||||
/* z\x* 012345 */
|
||||
/* 0 */ "......"
|
||||
/* 1 */ ".cdbef"
|
||||
/* 2 */ ".gh..g"
|
||||
/* 3 */ ".b.h.b"
|
||||
/* 4 */ ".i...i"
|
||||
/* 5 */ ".jdbek"
|
||||
|
||||
// Level 2
|
||||
/* z\x* 012345 */
|
||||
/* 0 */ "......"
|
||||
/* 1 */ "...l.."
|
||||
/* 2 */ "......"
|
||||
/* 3 */ ".n...n"
|
||||
/* 4 */ "......"
|
||||
/* 5 */ "...l..",
|
||||
|
||||
// Connectors:
|
||||
"1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */
|
||||
"1: 0, 1, 3: 4\n" /* Type 1, direction X- */
|
||||
"-1: 0, 1, 3: 4\n" /* Type -1, direction X- */
|
||||
"-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */
|
||||
"1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
|
||||
"-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */
|
||||
"1: 3, 1, 0: 2\n" /* Type 1, direction Z- */
|
||||
"-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
|
||||
// Merge strategy:
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
|
||||
// DepthWeight:
|
||||
"",
|
||||
|
||||
// AddWeightIfSame:
|
||||
0,
|
||||
|
||||
// MoveToGround:
|
||||
false,
|
||||
}, // CentralPiece
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// The prefab counts:
|
||||
|
||||
const size_t g_TestRailsPrefabsCount = ARRAYCOUNT(g_TestRailsPrefabs);
|
||||
|
||||
const size_t g_TestRailsStartingPrefabsCount = ARRAYCOUNT(g_TestRailsStartingPrefabs);
|
||||
|
15
src/Generating/Prefabs/TestRailsPrefabs.h
Normal file
15
src/Generating/Prefabs/TestRailsPrefabs.h
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
// TestRailsPrefabs.h
|
||||
|
||||
// Declares the prefabs in the group TestRails
|
||||
|
||||
#include "../Prefab.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern const cPrefab::sDef g_TestRailsPrefabs[];
|
||||
extern const cPrefab::sDef g_TestRailsStartingPrefabs[];
|
||||
extern const size_t g_TestRailsPrefabsCount;
|
||||
extern const size_t g_TestRailsStartingPrefabsCount;
|
@ -366,7 +366,7 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] =
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
200,
|
||||
|
||||
// DepthWeight:
|
||||
"",
|
||||
|
116
src/Generating/TestRailsGen.cpp
Normal file
116
src/Generating/TestRailsGen.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
|
||||
// TestRailsGen.cpp
|
||||
|
||||
// Implements the cTestRailsGen class representing the testing rails generator
|
||||
|
||||
#include "Globals.h"
|
||||
#include "TestRailsGen.h"
|
||||
#include "Prefabs/TestRailsPrefabs.h"
|
||||
#include "PieceGenerator.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static cPrefabPiecePool g_TestRails(g_TestRailsPrefabs, g_TestRailsPrefabsCount, g_TestRailsStartingPrefabs, g_TestRailsStartingPrefabsCount);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cTestRailsGen::cTestRails:
|
||||
|
||||
class cTestRailsGen::cTestRails :
|
||||
public cGridStructGen::cStructure
|
||||
{
|
||||
typedef cGridStructGen::cStructure super;
|
||||
|
||||
public:
|
||||
cTestRails(
|
||||
int a_Seed,
|
||||
int a_GridX, int a_GridZ,
|
||||
int a_OriginX, int a_OriginZ,
|
||||
int a_MaxDepth,
|
||||
int a_MaxSize
|
||||
) :
|
||||
super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
|
||||
m_Seed(a_Seed),
|
||||
m_Noise(a_Seed),
|
||||
m_MaxSize(a_MaxSize),
|
||||
m_Borders(a_OriginX - a_MaxSize, 0, a_OriginZ - a_MaxSize, a_OriginX + a_MaxSize, 255, a_OriginZ + a_MaxSize)
|
||||
{
|
||||
// Generate the pieces for this test:
|
||||
cBFSPieceGenerator pg(g_TestRails, a_Seed);
|
||||
pg.PlacePieces(a_OriginX, 150, a_OriginZ, a_MaxDepth, m_Pieces);
|
||||
if (m_Pieces.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
~cTestRails()
|
||||
{
|
||||
cPieceGenerator::FreePieces(m_Pieces);
|
||||
}
|
||||
|
||||
protected:
|
||||
/** Seed for the random functions */
|
||||
int m_Seed;
|
||||
|
||||
/** The noise used as a pseudo-random generator */
|
||||
cNoise m_Noise;
|
||||
|
||||
/** Maximum size, in X/Z blocks, of the structure (radius from the origin) */
|
||||
int m_MaxSize;
|
||||
|
||||
/** Borders of the structure - no item may reach out of this cuboid. */
|
||||
cCuboid m_Borders;
|
||||
|
||||
/** The rails pieces, placed by the generator. */
|
||||
cPlacedPieces m_Pieces;
|
||||
|
||||
|
||||
// cGridStructGen::cStructure overrides:
|
||||
virtual void DrawIntoChunk(cChunkDesc & a_Chunk) override
|
||||
{
|
||||
for (cPlacedPieces::iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr)
|
||||
{
|
||||
cPrefab & Prefab = (cPrefab &)((*itr)->GetPiece());
|
||||
Prefab.Draw(a_Chunk, *itr);
|
||||
} // for itr - m_PlacedPieces[]
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cTestRailsGen:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cTestRailsGen::cTestRailsGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize) :
|
||||
super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxSize, a_MaxSize, 100),
|
||||
m_Noise(a_Seed + 1000),
|
||||
m_MaxDepth(a_MaxDepth),
|
||||
m_MaxSize(a_MaxSize)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cGridStructGen::cStructurePtr cTestRailsGen::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
|
||||
{
|
||||
// Create a base based on the chosen prefabs:
|
||||
return cStructurePtr(new cTestRails(m_Seed, a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
47
src/Generating/TestRailsGen.h
Normal file
47
src/Generating/TestRailsGen.h
Normal file
@ -0,0 +1,47 @@
|
||||
|
||||
// TestRailsGen.h
|
||||
|
||||
// Declares the cTestRailsGen class representing the testing rails generator
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GridStructGen.h"
|
||||
#include "PrefabPiecePool.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cTestRailsGen :
|
||||
public cGridStructGen
|
||||
{
|
||||
typedef cGridStructGen super;
|
||||
|
||||
public:
|
||||
cTestRailsGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize);
|
||||
|
||||
protected:
|
||||
class cTestRails; // fwd: TestRailsGen.cpp
|
||||
|
||||
|
||||
/** The noise used for generating random numbers */
|
||||
cNoise m_Noise;
|
||||
|
||||
/** Maximum depth of the generator tree*/
|
||||
int m_MaxDepth;
|
||||
|
||||
/** Maximum size, in X/Z blocks, of the base (radius from the origin) */
|
||||
int m_MaxSize;
|
||||
|
||||
|
||||
// cGridStructGen overrides:
|
||||
virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -71,9 +71,24 @@
|
||||
|
||||
#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__))
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user