Merge branch 'master' into LuaProxy
This commit is contained in:
commit
9d843405b2
1
.gitignore
vendored
1
.gitignore
vendored
@ -26,6 +26,7 @@ cloc.xsl
|
||||
## Eclipse
|
||||
.cproject
|
||||
.project
|
||||
*.cbp
|
||||
|
||||
# world inside source
|
||||
ChunkWorx.ini
|
||||
|
@ -62,7 +62,6 @@ 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/)
|
||||
|
@ -26,10 +26,17 @@ endmacro()
|
||||
|
||||
|
||||
macro(set_flags)
|
||||
# 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_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/lib/cmake-coverage/")
|
||||
include(CodeCoverage)
|
||||
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,12 +70,16 @@ macro(set_flags)
|
||||
|
||||
else()
|
||||
# Let gcc / clang know that we're compiling a multi-threaded app:
|
||||
add_flags_cxx("-pthread")
|
||||
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")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
|
||||
set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -std=c++11")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")
|
||||
endif()
|
||||
|
||||
# We use a signed char (fixes #640 on RasPi)
|
||||
|
@ -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)
|
||||
|
@ -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
|
@ -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)
|
||||
|
@ -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"
|
||||
@ -2001,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;
|
||||
}
|
||||
|
||||
|
@ -8,13 +8,6 @@
|
||||
|
||||
|
||||
|
||||
cBlockInfo cBlockInfo::ms_Info[256];
|
||||
static bool g_IsBlockInfoInitialized = false;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBlockInfo::cBlockInfo()
|
||||
: m_LightValue(0x00)
|
||||
, m_SpreadLightFalloff(0x0f)
|
||||
@ -42,12 +35,17 @@ cBlockInfo::~cBlockInfo()
|
||||
|
||||
|
||||
|
||||
/** 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)
|
||||
{
|
||||
if (!g_IsBlockInfoInitialized)
|
||||
static cBlockInfo ms_Info[256];
|
||||
static bool IsBlockInfoInitialized = false;
|
||||
if (!IsBlockInfoInitialized)
|
||||
{
|
||||
cBlockInfo::Initialize();
|
||||
g_IsBlockInfoInitialized = true;
|
||||
cBlockInfo::Initialize(ms_Info);
|
||||
IsBlockInfoInitialized = true;
|
||||
}
|
||||
return ms_Info[a_Type];
|
||||
}
|
||||
@ -56,399 +54,408 @@ 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_PISTON_EXTENSION ].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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -102,7 +102,7 @@ public:
|
||||
AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true);
|
||||
BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn);
|
||||
|
||||
return (a_RelY > 0) && (cBlockInfo::IsSolid(BlockIsOn));
|
||||
return (a_RelY > 0) && (cBlockInfo::FullyOccupiesVoxel(BlockIsOn));
|
||||
}
|
||||
} ;
|
||||
|
||||
|
@ -65,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"
|
||||
@ -291,6 +293,8 @@ 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); // TODO: This needs a special handler
|
||||
case E_BLOCK_WATER: return new cBlockFluidHandler (a_BlockType);
|
||||
|
@ -22,7 +22,7 @@ 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.GetBroadcastManager().BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f);
|
||||
}
|
||||
|
||||
@ -104,7 +104,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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -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)
|
||||
@ -119,7 +119,8 @@ if (NOT MSVC)
|
||||
|
||||
# lib dependencies are not included
|
||||
|
||||
|
||||
include_directories ("${CMAKE_CURRENT_SOURCE_DIR}/../lib/polarssl/include")
|
||||
|
||||
#add cpp files here
|
||||
add_library(Bindings
|
||||
Bindings/Bindings
|
||||
@ -134,7 +135,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 +261,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)
|
||||
|
@ -2701,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 )
|
||||
{
|
||||
@ -2709,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"
|
||||
|
||||
|
||||
|
||||
@ -239,18 +239,16 @@ AString cClientHandle::GenerateOfflineUUID(const AString & a_Username)
|
||||
// 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
|
||||
|
||||
// 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;
|
||||
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]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -365,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;
|
||||
@ -1085,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;
|
||||
}
|
||||
@ -2077,9 +2073,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);
|
||||
}
|
||||
|
||||
|
||||
@ -2401,9 +2397,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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -123,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);
|
||||
@ -156,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);
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "Player.h"
|
||||
#include "ArrowEntity.h"
|
||||
#include "../Chunk.h"
|
||||
#include "FastRandom.h"
|
||||
|
||||
|
||||
|
||||
@ -24,9 +25,9 @@ cArrowEntity::cArrowEntity(cEntity * a_Creator, double a_X, double a_Y, double a
|
||||
SetYawFromSpeed();
|
||||
SetPitchFromSpeed();
|
||||
LOGD("Created arrow %d with speed {%.02f, %.02f, %.02f} and rot {%.02f, %.02f}",
|
||||
m_UniqueID, GetSpeedX(), GetSpeedY(), GetSpeedZ(),
|
||||
GetYaw(), GetPitch()
|
||||
);
|
||||
m_UniqueID, GetSpeedX(), GetSpeedY(), GetSpeedZ(),
|
||||
GetYaw(), GetPitch()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -109,7 +114,14 @@ 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));
|
||||
m_World->BroadcastSoundEffect(
|
||||
"random.successful_hit",
|
||||
(int)std::floor(GetPosX() * 8.0),
|
||||
(int)std::floor(GetPosY() * 8.0),
|
||||
(int)std::floor(GetPosZ() * 8.0),
|
||||
0.5f,
|
||||
0.75f + ((float)((GetUniqueID() * 23) % 32)) / 64.0f
|
||||
);
|
||||
|
||||
Destroy();
|
||||
}
|
||||
@ -120,16 +132,33 @@ 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))
|
||||
{
|
||||
int NumAdded = a_Dest->GetInventory().AddItem(E_ITEM_ARROW);
|
||||
if (NumAdded > 0) // Only play effects if there was space in inventory
|
||||
// Do not add the arrow to the inventory when the player is in creative:
|
||||
if (!a_Dest->IsGameModeCreative())
|
||||
{
|
||||
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;
|
||||
int NumAdded = a_Dest->GetInventory().AddItem(E_ITEM_ARROW);
|
||||
if (NumAdded == 0)
|
||||
{
|
||||
// No space in the inventory
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: BroadcastCollectPickup needs a cPickup, which we don't have
|
||||
// m_World->BroadcastCollectPickup(*this, *a_Dest);
|
||||
|
||||
m_bIsCollected = true;
|
||||
|
||||
cFastRandom Random;
|
||||
m_World->BroadcastSoundEffect(
|
||||
"random.pop",
|
||||
(int)std::floor(GetPosX() * 8.0),
|
||||
(int)std::floor(GetPosY() * 8),
|
||||
(int)std::floor(GetPosZ() * 8),
|
||||
0.2F,
|
||||
((Random.NextFloat(1.0F) - Random.NextFloat(1.0F)) * 0.7F + 1.0F) * 2.0F
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1090,7 +1090,10 @@ void cEntity::HandleAir(void)
|
||||
|
||||
if (IsSubmerged())
|
||||
{
|
||||
SetSpeedY(1); // Float in the water
|
||||
if (!IsPlayer()) // Players control themselves
|
||||
{
|
||||
SetSpeedY(1); // Float in the water
|
||||
}
|
||||
|
||||
// Either reduce air level or damage player
|
||||
if (m_AirLevel < 1)
|
||||
|
@ -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()))
|
||||
{
|
||||
m_Pickup->GetItem().AddCount(((cPickup *)a_Entity)->GetItem().m_ItemCount);
|
||||
a_Entity->Destroy();
|
||||
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)
|
||||
{
|
||||
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
|
||||
@ -206,7 +227,7 @@ bool cPickup::CollectedBy(cPlayer * a_Dest)
|
||||
m_World->BroadcastCollectPickup(*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"
|
||||
@ -412,6 +412,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);
|
||||
}
|
||||
|
||||
|
||||
@ -424,6 +425,8 @@ int cPlayer::FinishChargingBow(void)
|
||||
int res = m_BowCharge;
|
||||
m_IsChargingBow = false;
|
||||
m_BowCharge = 0;
|
||||
m_World->BroadcastEntityMetadata(*this, m_ClientHandle);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -436,6 +439,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);
|
||||
}
|
||||
|
||||
|
||||
@ -972,7 +976,7 @@ void cPlayer::Respawn(void)
|
||||
m_LifetimeTotalXp = 0;
|
||||
// ToDo: send score to client? How?
|
||||
|
||||
m_ClientHandle->SendRespawn(*m_World);
|
||||
m_ClientHandle->SendRespawn(*m_World, true);
|
||||
|
||||
// Extinguish the fire:
|
||||
StopBurning();
|
||||
@ -1909,7 +1913,7 @@ 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);
|
||||
|
@ -404,7 +404,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);
|
||||
|
||||
|
@ -5,7 +5,8 @@
|
||||
#include "Item.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#define FURNACE_RECIPE_FILE "furnace.txt"
|
||||
|
||||
|
||||
|
||||
@ -54,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;
|
||||
}
|
||||
|
||||
unsigned int LineNum = 0;
|
||||
AString ParsingLine;
|
||||
|
||||
while (std::getline(f, ParsingLine))
|
||||
{
|
||||
LineNum++;
|
||||
ParsingLine.erase(std::remove_if(ParsingLine.begin(), ParsingLine.end(), isspace), ParsingLine.end()); // Remove ALL whitespace from the line
|
||||
if (ParsingLine.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (ParsingLine[0])
|
||||
{
|
||||
case '#':
|
||||
{
|
||||
// Comment
|
||||
break;
|
||||
}
|
||||
|
||||
case '!':
|
||||
{
|
||||
AddFuelFromLine(ParsingLine, LineNum);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
AddRecipeFromLine(ParsingLine, LineNum);
|
||||
break;
|
||||
}
|
||||
} // switch (ParsingLine[0])
|
||||
} // while (getline(ParsingLine))
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// TODO: Replace this messy parse with a high-level-structured one (ReadLine / ProcessLine)
|
||||
bool bSyntaxError = false;
|
||||
while (f.good())
|
||||
// Add to fuel list:
|
||||
Fuel F;
|
||||
F.In = new cItem((ENUM_ITEM_ID)IItemID, (char)IItemCount, (short)IItemHealth);
|
||||
F.BurnTime = IBurnTime;
|
||||
m_pState->Fuel.push_back(F);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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;
|
||||
AString::size_type BeginPos = 0; // Begin at start of line
|
||||
|
||||
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
|
||||
)
|
||||
{
|
||||
char c;
|
||||
return;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// comments
|
||||
f >> c;
|
||||
f.unget();
|
||||
if( c == '#' )
|
||||
// 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 = 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)
|
||||
{
|
||||
End = a_Text.find_first_not_of(a_Delimiter, a_Begin);
|
||||
}
|
||||
else
|
||||
{
|
||||
End = a_Text.find_first_of(a_Delimiter, a_Begin);
|
||||
if (End == AString::npos)
|
||||
{
|
||||
while( f.good() && c != '\n' )
|
||||
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)
|
||||
{
|
||||
f.get( c );
|
||||
End = a_Text.find_first_not_of(a_DelimiterTwo, Begin);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Line breaks
|
||||
f.get( c );
|
||||
while( f.good() && ( c == '\n' || c == '\r' ) ) { f.get( c ); }
|
||||
if (f.eof())
|
||||
{
|
||||
break;
|
||||
}
|
||||
f.unget();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Check for fuel
|
||||
f >> c;
|
||||
if( c == '!' ) // It's fuel :)
|
||||
{
|
||||
// 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;
|
||||
End = a_Text.find_first_of(a_DelimiterTwo, Begin);
|
||||
if (End == AString::npos)
|
||||
{
|
||||
PrintParseError(a_Line, Begin, a_DelimiterTwo);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Burn time
|
||||
int BurnTime;
|
||||
f >> c; if( c != '=' ) { bSyntaxError = true; break; }
|
||||
f >> BurnTime;
|
||||
// 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());
|
||||
|
||||
// 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;
|
||||
a_Begin = End + 1; // Jump over delimiter
|
||||
return true;
|
||||
}
|
||||
f.unget();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// 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;
|
||||
return ReadMandatoryNumber(a_Begin, a_DelimiterTwo, a_Text, a_Line, a_ValueOne, a_IsLastValue);
|
||||
}
|
||||
|
||||
int CookTime;
|
||||
f >> c; if( c != '@' ) { bSyntaxError = true; break; }
|
||||
f >> CookTime;
|
||||
|
||||
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;
|
||||
|
||||
// Optional health
|
||||
f >> c;
|
||||
if( c != ':' )
|
||||
f.unget();
|
||||
else
|
||||
{
|
||||
f >> OItemHealth;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
LOGERROR("ERROR: FurnaceRecipe, syntax error" );
|
||||
}
|
||||
LOG("Loaded " SIZE_T_FMT " furnace recipes and " SIZE_T_FMT " fuels", m_pState->Recipes.size(), m_pState->Fuel.size());
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -71,9 +71,24 @@
|
||||
|
||||
#define FORMATSTRING(formatIndex, va_argsIndex) __attribute__((format (printf, formatIndex, va_argsIndex)))
|
||||
|
||||
#define SIZE_T_FMT "%zu"
|
||||
#define SIZE_T_FMT_PRECISION(x) "%" #x "zu"
|
||||
#define SIZE_T_FMT_HEX "%zx"
|
||||
#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__))
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#include "Item.h"
|
||||
|
@ -46,20 +46,17 @@ public:
|
||||
{
|
||||
// Actual shot - produce the arrow with speed based on the ticks that the bow was charged
|
||||
ASSERT(a_Player != NULL);
|
||||
|
||||
|
||||
int BowCharge = a_Player->FinishChargingBow();
|
||||
double Force = (double)BowCharge / 20;
|
||||
Force = (Force * Force + 2 * Force) / 3; // This formula is used by the 1.6.2 client
|
||||
double Force = (double)BowCharge / 20.0;
|
||||
Force = (Force * Force + 2.0 * Force) / 3.0; // This formula is used by the 1.6.2 client
|
||||
if (Force < 0.1)
|
||||
{
|
||||
// Too little force, ignore the shot
|
||||
return;
|
||||
}
|
||||
if (Force > 1)
|
||||
{
|
||||
Force = 1;
|
||||
}
|
||||
|
||||
Force = std::max(Force, 1.0);
|
||||
|
||||
// Create the arrow entity:
|
||||
cArrowEntity * Arrow = new cArrowEntity(*a_Player, Force * 2);
|
||||
if (Arrow == NULL)
|
||||
@ -72,8 +69,16 @@ public:
|
||||
Arrow = NULL;
|
||||
return;
|
||||
}
|
||||
a_Player->GetWorld()->BroadcastSpawnEntity(*Arrow);
|
||||
a_Player->GetWorld()->BroadcastSoundEffect("random.bow", (int)a_Player->GetPosX() * 8, (int)a_Player->GetPosY() * 8, (int)a_Player->GetPosZ() * 8, 0.5, (float)Force);
|
||||
|
||||
cFastRandom Random;
|
||||
a_Player->GetWorld()->BroadcastSoundEffect(
|
||||
"random.bow",
|
||||
(int)std::floor(a_Player->GetPosX() * 8.0),
|
||||
(int)std::floor(a_Player->GetPosY() * 8.0),
|
||||
(int)std::floor(a_Player->GetPosZ() * 8.0),
|
||||
1.0F,
|
||||
1.0F / (Random.NextFloat(1.0F) * 0.4F + 1.2F) + (float)Force * 0.5F
|
||||
);
|
||||
|
||||
if (!a_Player->IsGameModeCreative())
|
||||
{
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "ItemSign.h"
|
||||
#include "ItemMobHead.h"
|
||||
#include "ItemSpawnEgg.h"
|
||||
#include "ItemString.h"
|
||||
#include "ItemSugarcane.h"
|
||||
#include "ItemSword.h"
|
||||
|
||||
@ -129,6 +130,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType)
|
||||
case E_ITEM_HEAD: return new cItemMobHeadHandler(a_ItemType);
|
||||
case E_ITEM_SNOWBALL: return new cItemSnowballHandler();
|
||||
case E_ITEM_SPAWN_EGG: return new cItemSpawnEggHandler(a_ItemType);
|
||||
case E_ITEM_STRING: return new cItemStringHandler(a_ItemType);
|
||||
case E_ITEM_SUGARCANE: return new cItemSugarcaneHandler(a_ItemType);
|
||||
|
||||
case E_ITEM_WOODEN_HOE:
|
||||
|
39
src/Items/ItemString.h
Normal file
39
src/Items/ItemString.h
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ItemHandler.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cItemStringHandler :
|
||||
public cItemHandler
|
||||
{
|
||||
public:
|
||||
cItemStringHandler(int a_ItemType) :
|
||||
cItemHandler(a_ItemType)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool IsPlaceable(void) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool GetPlacementBlockTypeMeta(
|
||||
cWorld * a_World, 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 = E_BLOCK_TRIPWIRE;
|
||||
a_BlockMeta = 0;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -78,3 +78,23 @@ void cPig::OnRightClicked(cPlayer & a_Player)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPig::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
{
|
||||
super::Tick(a_Dt, a_Chunk);
|
||||
|
||||
// If the attachee player is holding a carrot-on-stick, let them drive this pig:
|
||||
if (m_bIsSaddled && (m_Attachee != NULL))
|
||||
{
|
||||
if (m_Attachee->IsPlayer() && (m_Attachee->GetEquippedWeapon().m_ItemType == E_ITEM_CARROT_ON_STICK))
|
||||
{
|
||||
MoveToPosition((m_Attachee->GetPosition()) + (m_Attachee->GetLookVector()*10));
|
||||
m_bMovingToDestination = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -19,6 +19,7 @@ public:
|
||||
|
||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
|
||||
virtual void OnRightClicked(cPlayer & a_Player) override;
|
||||
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||
|
||||
virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_CARROT); }
|
||||
|
||||
|
@ -7,6 +7,9 @@
|
||||
|
||||
#include "File.h"
|
||||
#include <fstream>
|
||||
#ifdef _WIN32
|
||||
#include <share.h> // for _SH_DENYWRITE
|
||||
#endif // _WIN32
|
||||
|
||||
|
||||
|
||||
|
@ -64,7 +64,7 @@ public:
|
||||
virtual void SendChat (const AString & a_Message) = 0;
|
||||
virtual void SendChat (const cCompositeChat & a_Message) = 0;
|
||||
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) = 0;
|
||||
virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) = 0;
|
||||
virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) = 0;
|
||||
virtual void SendDestroyEntity (const cEntity & a_Entity) = 0;
|
||||
virtual void SendDisconnect (const AString & a_Reason) = 0;
|
||||
virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) = 0; ///< Request the client to open up the sign editor for the sign (1.6+)
|
||||
@ -100,7 +100,7 @@ public:
|
||||
virtual void SendPlayerSpawn (const cPlayer & a_Player) = 0;
|
||||
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) = 0;
|
||||
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) = 0;
|
||||
virtual void SendRespawn (const cWorld & a_World) = 0;
|
||||
virtual void SendRespawn (const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks = false) = 0;
|
||||
virtual void SendExperience (void) = 0;
|
||||
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) = 0;
|
||||
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) = 0;
|
||||
|
@ -274,11 +274,11 @@ void cProtocol125::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerialize
|
||||
|
||||
|
||||
|
||||
void cProtocol125::SendCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player)
|
||||
void cProtocol125::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player)
|
||||
{
|
||||
cCSLock Lock(m_CSPacket);
|
||||
WriteByte(PACKET_COLLECT_PICKUP);
|
||||
WriteInt (a_Pickup.GetUniqueID());
|
||||
WriteInt (a_Entity.GetUniqueID());
|
||||
WriteInt (a_Player.GetUniqueID());
|
||||
Flush();
|
||||
}
|
||||
@ -833,12 +833,12 @@ void cProtocol125::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Effect
|
||||
|
||||
|
||||
|
||||
void cProtocol125::SendRespawn(const cWorld & a_World)
|
||||
void cProtocol125::SendRespawn(const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks)
|
||||
{
|
||||
cCSLock Lock(m_CSPacket);
|
||||
if (m_LastSentDimension == a_World.GetDimension())
|
||||
if ((m_LastSentDimension == a_World.GetDimension()) && !a_ShouldIgnoreDimensionChecks)
|
||||
{
|
||||
// Must not send a respawn for the world with the same dimension, the client goes cuckoo if we do
|
||||
// Must not send a respawn for the world with the same dimension, the client goes cuckoo if we do (unless we are respawning from death)
|
||||
return;
|
||||
}
|
||||
cPlayer * Player = m_Client->GetPlayer();
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
virtual void SendChat (const AString & a_Message) override;
|
||||
virtual void SendChat (const cCompositeChat & a_Message) override;
|
||||
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
|
||||
virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override;
|
||||
virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override;
|
||||
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
|
||||
virtual void SendDisconnect (const AString & a_Reason) override;
|
||||
virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+)
|
||||
@ -72,7 +72,7 @@ public:
|
||||
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
|
||||
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
|
||||
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
|
||||
virtual void SendRespawn (const cWorld & a_World) override;
|
||||
virtual void SendRespawn (const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks = false) override;
|
||||
virtual void SendExperience (void) override;
|
||||
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;
|
||||
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override;
|
||||
|
@ -188,19 +188,19 @@ void cProtocol132::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerialize
|
||||
|
||||
|
||||
|
||||
void cProtocol132::SendCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player)
|
||||
void cProtocol132::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player)
|
||||
{
|
||||
cCSLock Lock(m_CSPacket);
|
||||
WriteByte(PACKET_COLLECT_PICKUP);
|
||||
WriteInt (a_Pickup.GetUniqueID());
|
||||
WriteInt (a_Entity.GetUniqueID());
|
||||
WriteInt (a_Player.GetUniqueID());
|
||||
Flush();
|
||||
|
||||
// Also send the "pop" sound effect with a somewhat random pitch (fast-random using EntityID ;)
|
||||
SendSoundEffect(
|
||||
"random.pop",
|
||||
(int)(a_Pickup.GetPosX() * 8), (int)(a_Pickup.GetPosY() * 8), (int)(a_Pickup.GetPosZ() * 8),
|
||||
0.5, (float)(0.75 + ((float)((a_Pickup.GetUniqueID() * 23) % 32)) / 64)
|
||||
(int)(a_Entity.GetPosX() * 8), (int)(a_Entity.GetPosY() * 8), (int)(a_Entity.GetPosZ() * 8),
|
||||
0.5, (float)(0.75 + ((float)((a_Entity.GetUniqueID() * 23) % 32)) / 64)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ public:
|
||||
virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override;
|
||||
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
|
||||
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
|
||||
virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override;
|
||||
virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override;
|
||||
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
|
||||
virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override;
|
||||
virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override;
|
||||
|
@ -158,10 +158,10 @@ void cProtocol161::SendPlayerMaxSpeed(void)
|
||||
|
||||
|
||||
|
||||
void cProtocol161::SendRespawn(const cWorld & a_World)
|
||||
void cProtocol161::SendRespawn(const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks)
|
||||
{
|
||||
// Besides sending the respawn, we need to also send the player max speed, otherwise the client reverts to super-fast
|
||||
super::SendRespawn(a_World);
|
||||
super::SendRespawn(a_World, a_ShouldIgnoreDimensionChecks);
|
||||
SendPlayerMaxSpeed();
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ protected:
|
||||
virtual void SendGameMode (eGameMode a_GameMode) override;
|
||||
virtual void SendHealth (void) override;
|
||||
virtual void SendPlayerMaxSpeed(void) override;
|
||||
virtual void SendRespawn (const cWorld & a_World) override;
|
||||
virtual void SendRespawn (const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks = false) override;
|
||||
virtual void SendWindowOpen (const cWindow & a_Window) override;
|
||||
|
||||
virtual int ParseEntityAction (void) override;
|
||||
|
@ -351,12 +351,12 @@ void cProtocol172::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerialize
|
||||
|
||||
|
||||
|
||||
void cProtocol172::SendCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player)
|
||||
void cProtocol172::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
cPacketizer Pkt(*this, 0x0d); // Collect Item packet
|
||||
Pkt.WriteInt(a_Pickup.GetUniqueID());
|
||||
Pkt.WriteInt(a_Entity.GetUniqueID());
|
||||
Pkt.WriteInt(a_Player.GetUniqueID());
|
||||
}
|
||||
|
||||
@ -986,11 +986,11 @@ void cProtocol172::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Effect
|
||||
|
||||
|
||||
|
||||
void cProtocol172::SendRespawn(const cWorld & a_World)
|
||||
void cProtocol172::SendRespawn(const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks)
|
||||
{
|
||||
if (m_LastSentDimension == a_World.GetDimension())
|
||||
if ((m_LastSentDimension == a_World.GetDimension()) && !a_ShouldIgnoreDimensionChecks)
|
||||
{
|
||||
// Must not send a respawn for the world with the same dimension, the client goes cuckoo if we do
|
||||
// Must not send a respawn for the world with the same dimension, the client goes cuckoo if we do (unless we are respawning from death)
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1221,10 +1221,9 @@ void cProtocol172::SendStatistics(const cStatManager & a_Manager)
|
||||
cPacketizer Pkt(*this, 0x37);
|
||||
Pkt.WriteVarInt(statCount); // TODO 2014-05-11 xdot: Optimization: Send "dirty" statistics only
|
||||
|
||||
for (unsigned int i = 0; i < (unsigned int)statCount; ++i)
|
||||
for (size_t i = 0; i < (size_t)statCount; ++i)
|
||||
{
|
||||
StatValue Value = a_Manager.GetValue((eStatistic) i);
|
||||
|
||||
const AString & StatName = cStatInfo::GetName((eStatistic) i);
|
||||
|
||||
Pkt.WriteString(StatName);
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
virtual void SendChat (const AString & a_Message) override;
|
||||
virtual void SendChat (const cCompositeChat & a_Message) override;
|
||||
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
|
||||
virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override;
|
||||
virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override;
|
||||
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
|
||||
virtual void SendDisconnect (const AString & a_Reason) override;
|
||||
virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+)
|
||||
@ -104,7 +104,7 @@ public:
|
||||
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
|
||||
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
|
||||
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
|
||||
virtual void SendRespawn (const cWorld & a_World) override;
|
||||
virtual void SendRespawn (const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks = false) override;
|
||||
virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; // a_Src coords are Block * 8
|
||||
virtual void SendExperience (void) override;
|
||||
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;
|
||||
|
@ -181,10 +181,10 @@ void cProtocolRecognizer::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSe
|
||||
|
||||
|
||||
|
||||
void cProtocolRecognizer::SendCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player)
|
||||
void cProtocolRecognizer::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player)
|
||||
{
|
||||
ASSERT(m_Protocol != NULL);
|
||||
m_Protocol->SendCollectPickup(a_Pickup, a_Player);
|
||||
m_Protocol->SendCollectEntity(a_Entity, a_Player);
|
||||
}
|
||||
|
||||
|
||||
@ -556,10 +556,10 @@ void cProtocolRecognizer::SendRemoveEntityEffect(const cEntity & a_Entity, int a
|
||||
|
||||
|
||||
|
||||
void cProtocolRecognizer::SendRespawn(const cWorld & a_World)
|
||||
void cProtocolRecognizer::SendRespawn(const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks)
|
||||
{
|
||||
ASSERT(m_Protocol != NULL);
|
||||
m_Protocol->SendRespawn(a_World);
|
||||
m_Protocol->SendRespawn(a_World, a_ShouldIgnoreDimensionChecks);
|
||||
}
|
||||
|
||||
|
||||
|
@ -71,7 +71,7 @@ public:
|
||||
virtual void SendChat (const AString & a_Message) override;
|
||||
virtual void SendChat (const cCompositeChat & a_Message) override;
|
||||
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
|
||||
virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override;
|
||||
virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override;
|
||||
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
|
||||
virtual void SendDisconnect (const AString & a_Reason) override;
|
||||
virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+)
|
||||
@ -107,7 +107,7 @@ public:
|
||||
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
|
||||
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
|
||||
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
|
||||
virtual void SendRespawn (const cWorld & a_World) override;
|
||||
virtual void SendRespawn (const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks = false) override;
|
||||
virtual void SendExperience (void) override;
|
||||
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;
|
||||
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override;
|
||||
|
@ -217,14 +217,20 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i
|
||||
{
|
||||
ASSERT(a_NewMeta <= 8); // Invalid meta values
|
||||
ASSERT(a_NewMeta > 0); // Source blocks aren't spread
|
||||
|
||||
BLOCKTYPE BlockType;
|
||||
NIBBLETYPE BlockMeta;
|
||||
if (!a_NearChunk->UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ, BlockType, BlockMeta))
|
||||
|
||||
a_NearChunk = a_NearChunk->GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ);
|
||||
if ((a_NearChunk == NULL) || (!a_NearChunk->IsValid()))
|
||||
{
|
||||
// Chunk not available
|
||||
return;
|
||||
}
|
||||
|
||||
const int BlockX = a_NearChunk->GetPosX() * cChunkDef::Width + a_RelX;
|
||||
const int BlockZ = a_NearChunk->GetPosZ() * cChunkDef::Width + a_RelZ;
|
||||
|
||||
BLOCKTYPE BlockType;
|
||||
NIBBLETYPE BlockMeta;
|
||||
a_NearChunk->GetBlockTypeMeta(a_RelX, a_RelY, a_RelZ, BlockType, BlockMeta);
|
||||
|
||||
if (IsAllowedBlock(BlockType))
|
||||
{
|
||||
@ -246,15 +252,9 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i
|
||||
a_RelX, a_RelY, a_RelZ,
|
||||
ItemTypeToString(NewBlock).c_str()
|
||||
);
|
||||
a_NearChunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, NewBlock, 0);
|
||||
a_NearChunk->SetBlock(a_RelX, a_RelY, a_RelZ, NewBlock, 0);
|
||||
|
||||
int BaseX = a_NearChunk->GetPosX() * cChunkDef::Width;
|
||||
int BaseZ = a_NearChunk->GetPosZ() * cChunkDef::Width;
|
||||
|
||||
BaseX += a_RelX;
|
||||
BaseZ += a_RelZ;
|
||||
|
||||
a_NearChunk->BroadcastSoundEffect("random.fizz", BaseX * 8, a_RelY * 8, BaseZ * 8, 0.5f, 1.5f);
|
||||
a_NearChunk->BroadcastSoundEffect("random.fizz", BlockX * 8, a_RelY * 8, BlockZ * 8, 0.5f, 1.5f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -267,15 +267,9 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i
|
||||
FLOG(" Water flowing into lava, turning lava at rel {%d, %d, %d} into %s",
|
||||
a_RelX, a_RelY, a_RelZ, ItemTypeToString(NewBlock).c_str()
|
||||
);
|
||||
a_NearChunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, NewBlock, 0);
|
||||
a_NearChunk->SetBlock(a_RelX, a_RelY, a_RelZ, NewBlock, 0);
|
||||
|
||||
int BaseX = a_NearChunk->GetPosX() * cChunkDef::Width;
|
||||
int BaseZ = a_NearChunk->GetPosZ() * cChunkDef::Width;
|
||||
|
||||
BaseX += a_RelX;
|
||||
BaseZ += a_RelZ;
|
||||
|
||||
a_NearChunk->BroadcastSoundEffect("random.fizz", BaseX * 8, a_RelY * 8, BaseZ * 8, 0.5f, 1.5f);
|
||||
a_NearChunk->BroadcastSoundEffect("random.fizz", BlockX * 8, a_RelY * 8, BlockZ * 8, 0.5f, 1.5f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -303,21 +297,17 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i
|
||||
m_World,
|
||||
PluginInterface,
|
||||
NULL,
|
||||
a_NearChunk->GetPosX() * cChunkDef::Width + a_RelX,
|
||||
BlockX,
|
||||
a_RelY,
|
||||
a_NearChunk->GetPosZ() * cChunkDef::Width + a_RelZ
|
||||
BlockZ
|
||||
);
|
||||
}
|
||||
} // if (CanWashAway)
|
||||
|
||||
|
||||
// Spread:
|
||||
FLOG(" Spreading to {%d, %d, %d} with meta %d",
|
||||
a_NearChunk->GetPosX() * cChunkDef::Width + a_RelX,
|
||||
a_RelY,
|
||||
a_NearChunk->GetPosZ() * cChunkDef::Width + a_RelZ,
|
||||
a_NewMeta
|
||||
);
|
||||
a_NearChunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, m_FluidBlock, a_NewMeta);
|
||||
FLOG(" Spreading to {%d, %d, %d} with meta %d", BlockX, a_RelY, BlockZ, a_NewMeta);
|
||||
a_NearChunk->SetBlock(a_RelX, a_RelY, a_RelZ, m_FluidBlock, a_NewMeta);
|
||||
m_World.GetSimulatorManager()->WakeUp(BlockX, a_RelY, BlockZ, a_NearChunk);
|
||||
|
||||
HardenBlock(a_NearChunk, a_RelX, a_RelY, a_RelZ, m_FluidBlock, a_NewMeta);
|
||||
}
|
||||
@ -409,13 +399,13 @@ bool cFloodyFluidSimulator::HardenBlock(cChunk * a_Chunk, int a_RelX, int a_RelY
|
||||
if (a_Meta == 0)
|
||||
{
|
||||
// Source lava block
|
||||
a_Chunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_OBSIDIAN, 0);
|
||||
a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_OBSIDIAN, 0);
|
||||
return true;
|
||||
}
|
||||
// Ignore last lava level
|
||||
else if (a_Meta <= 4)
|
||||
{
|
||||
a_Chunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_COBBLESTONE, 0);
|
||||
a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_COBBLESTONE, 0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#include "IncrementalRedstoneSimulator.h"
|
||||
#include "BoundingBox.h"
|
||||
#include "../BlockEntities/DropSpenserEntity.h"
|
||||
#include "../BlockEntities/NoteEntity.h"
|
||||
#include "../BlockEntities/CommandBlockEntity.h"
|
||||
@ -12,10 +13,13 @@
|
||||
#include "../Blocks/BlockButton.h"
|
||||
#include "../Blocks/BlockLever.h"
|
||||
#include "../Blocks/BlockPiston.h"
|
||||
#include "../Blocks/BlockTripwireHook.h"
|
||||
|
||||
#define WAKE_SIMULATOR_IF_DIRTY(a_Chunk, a_BlockX, a_BlockY, a_BlockZ) if (a_Chunk->IsRedstoneDirty()) WakeUp(a_BlockX, a_BlockY, a_BlockZ, a_Chunk);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulator(cWorld & a_World) :
|
||||
super(a_World),
|
||||
@ -99,10 +103,11 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
|
||||
// Changeable sources
|
||||
((Block == E_BLOCK_REDSTONE_WIRE) && (Meta == 0)) ||
|
||||
((Block == E_BLOCK_LEVER) && !IsLeverOn(Meta)) ||
|
||||
((Block == E_BLOCK_DETECTOR_RAIL) && (Meta & 0x08) == 0) ||
|
||||
((Block == E_BLOCK_DETECTOR_RAIL) && ((Meta & 0x08) == 0)) ||
|
||||
(((Block == E_BLOCK_STONE_BUTTON) || (Block == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(Meta))) ||
|
||||
(((Block == E_BLOCK_STONE_PRESSURE_PLATE) || (Block == E_BLOCK_WOODEN_PRESSURE_PLATE)) && (Meta == 0)) ||
|
||||
(((Block == E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE) || (Block == E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE)) && (Meta == 0))
|
||||
(((Block == E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE) || (Block == E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE)) && (Meta == 0)) ||
|
||||
((Block == E_BLOCK_TRIPWIRE_HOOK) && ((Meta & 0x08) == 0))
|
||||
)
|
||||
{
|
||||
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
|
||||
@ -289,6 +294,9 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int
|
||||
switch (dataitr->Data)
|
||||
{
|
||||
case E_BLOCK_DAYLIGHT_SENSOR: HandleDaylightSensor(dataitr->x, dataitr->y, dataitr->z); break;
|
||||
case E_BLOCK_TRIPWIRE: HandleTripwire(dataitr->x, dataitr->y, dataitr->z); break;
|
||||
case E_BLOCK_TRIPWIRE_HOOK: HandleTripwireHook(dataitr->x, dataitr->y, dataitr->z); break;
|
||||
|
||||
case E_BLOCK_WOODEN_PRESSURE_PLATE:
|
||||
case E_BLOCK_STONE_PRESSURE_PLATE:
|
||||
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE:
|
||||
@ -1120,7 +1128,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
|
||||
case E_BLOCK_STONE_PRESSURE_PLATE:
|
||||
{
|
||||
// MCS feature - stone pressure plates can only be triggered by players :D
|
||||
cPlayer * a_Player = m_World.FindClosestPlayer(Vector3f(BlockX + 0.5f, (float)a_RelBlockY, BlockZ + 0.5f), 0.7f, false);
|
||||
cPlayer * a_Player = m_World.FindClosestPlayer(Vector3f(BlockX + 0.5f, (float)a_RelBlockY, BlockZ + 0.5f), 0.5f, false);
|
||||
|
||||
if (a_Player != NULL)
|
||||
{
|
||||
@ -1131,7 +1139,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
|
||||
else
|
||||
{
|
||||
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x0);
|
||||
m_World.WakeUpSimulators(BlockX, a_RelBlockY, BlockZ);
|
||||
WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1155,7 +1163,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
|
||||
Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f);
|
||||
double Distance = (EntityPos - BlockPos).Length();
|
||||
|
||||
if (Distance <= 0.7)
|
||||
if (Distance <= 0.5)
|
||||
{
|
||||
m_NumberOfEntities++;
|
||||
}
|
||||
@ -1177,7 +1185,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
|
||||
};
|
||||
|
||||
cPressurePlateCallback PressurePlateCallback(BlockX, a_RelBlockY, BlockZ);
|
||||
m_World.ForEachEntity(PressurePlateCallback);
|
||||
m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), PressurePlateCallback);
|
||||
|
||||
unsigned char Power;
|
||||
NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
|
||||
@ -1198,7 +1206,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
|
||||
m_Chunk->BroadcastSoundEffect("random.click", (int)((BlockX + 0.5) * 8.0), (int)((a_RelBlockY + 0.1) * 8.0), (int)((BlockZ + 0.5) * 8.0), 0.3F, 0.6F);
|
||||
}
|
||||
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED);
|
||||
m_World.WakeUpSimulators(BlockX, a_RelBlockY, BlockZ);
|
||||
WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -1223,7 +1231,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
|
||||
Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f);
|
||||
double Distance = (EntityPos - BlockPos).Length();
|
||||
|
||||
if (Distance <= 0.7)
|
||||
if (Distance <= 0.5)
|
||||
{
|
||||
m_NumberOfEntities++;
|
||||
}
|
||||
@ -1232,7 +1240,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
|
||||
|
||||
bool GetPowerLevel(unsigned char & a_PowerLevel) const
|
||||
{
|
||||
a_PowerLevel = std::min((int)ceil(m_NumberOfEntities / (float)10), MAX_POWER_LEVEL);
|
||||
a_PowerLevel = std::min((int)ceil(m_NumberOfEntities / 10.f), MAX_POWER_LEVEL);
|
||||
return (a_PowerLevel > 0);
|
||||
}
|
||||
|
||||
@ -1245,7 +1253,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
|
||||
};
|
||||
|
||||
cPressurePlateCallback PressurePlateCallback(BlockX, a_RelBlockY, BlockZ);
|
||||
m_World.ForEachEntity(PressurePlateCallback);
|
||||
m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), PressurePlateCallback);
|
||||
|
||||
unsigned char Power;
|
||||
NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
|
||||
@ -1266,7 +1274,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
|
||||
m_Chunk->BroadcastSoundEffect("random.click", (int)((BlockX + 0.5) * 8.0), (int)((a_RelBlockY + 0.1) * 8.0), (int)((BlockZ + 0.5) * 8.0), 0.3F, 0.6F);
|
||||
}
|
||||
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED);
|
||||
m_World.WakeUpSimulators(BlockX, a_RelBlockY, BlockZ);
|
||||
WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -1291,7 +1299,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
|
||||
Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f);
|
||||
double Distance = (EntityPos - BlockPos).Length();
|
||||
|
||||
if (Distance <= 0.7)
|
||||
if (Distance <= 0.5)
|
||||
{
|
||||
m_FoundEntity = true;
|
||||
return true; // Break out, we only need to know for plates that at least one entity is on top
|
||||
@ -1313,7 +1321,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
|
||||
} ;
|
||||
|
||||
cPressurePlateCallback PressurePlateCallback(BlockX, a_RelBlockY, BlockZ);
|
||||
m_World.ForEachEntity(PressurePlateCallback);
|
||||
m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), PressurePlateCallback);
|
||||
|
||||
NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
|
||||
if (PressurePlateCallback.FoundEntity())
|
||||
@ -1333,7 +1341,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
|
||||
m_Chunk->BroadcastSoundEffect("random.click", (int)((BlockX + 0.5) * 8.0), (int)((a_RelBlockY + 0.1) * 8.0), (int)((BlockZ + 0.5) * 8.0), 0.3F, 0.6F);
|
||||
}
|
||||
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED);
|
||||
m_World.WakeUpSimulators(BlockX, a_RelBlockY, BlockZ);
|
||||
WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1349,6 +1357,131 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
|
||||
|
||||
|
||||
|
||||
void cIncrementalRedstoneSimulator::HandleTripwireHook(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
|
||||
{
|
||||
int BlockX = m_Chunk->GetPosX() * cChunkDef::Width + a_RelBlockX;
|
||||
int BlockZ = m_Chunk->GetPosZ() * cChunkDef::Width + a_RelBlockZ;
|
||||
int RelX = a_RelBlockX, RelZ = a_RelBlockZ;
|
||||
bool FoundActivated = false;
|
||||
eBlockFace FaceToGoTowards = cBlockTripwireHookHandler::MetadataToDirection(m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ));
|
||||
|
||||
for (int i = 0; i < 40; ++i) // Tripwires can be connected up to 40 blocks
|
||||
{
|
||||
BLOCKTYPE Type;
|
||||
NIBBLETYPE Meta;
|
||||
|
||||
AddFaceDirection(RelX, a_RelBlockY, RelZ, FaceToGoTowards);
|
||||
m_Chunk->UnboundedRelGetBlock(RelX, a_RelBlockY, RelZ, Type, Meta);
|
||||
|
||||
if (Type == E_BLOCK_TRIPWIRE)
|
||||
{
|
||||
if (Meta == 0x1)
|
||||
{
|
||||
FoundActivated = true;
|
||||
}
|
||||
}
|
||||
else if (Type == E_BLOCK_TRIPWIRE_HOOK)
|
||||
{
|
||||
if (ReverseBlockFace(cBlockTripwireHookHandler::MetadataToDirection(Meta)) == FaceToGoTowards)
|
||||
{
|
||||
// Other hook not facing in opposite direction
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Tripwire hook not connected at all, AND away all the power state bits
|
||||
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x3);
|
||||
WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Tripwire hook not connected at all, AND away all the power state bits
|
||||
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x3);
|
||||
WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (FoundActivated)
|
||||
{
|
||||
// Connected and activated, set the 3rd and 4th highest bits
|
||||
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) | 0xC);
|
||||
SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Connected but not activated, AND away the highest bit
|
||||
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, (m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x7) | 0x4);
|
||||
WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cIncrementalRedstoneSimulator::HandleTripwire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
|
||||
{
|
||||
int BlockX = m_Chunk->GetPosX() * cChunkDef::Width + a_RelBlockX;
|
||||
int BlockZ = m_Chunk->GetPosZ() * cChunkDef::Width + a_RelBlockZ;
|
||||
|
||||
class cTripwireCallback :
|
||||
public cEntityCallback
|
||||
{
|
||||
public:
|
||||
cTripwireCallback(int a_BlockX, int a_BlockY, int a_BlockZ) :
|
||||
m_FoundEntity(false),
|
||||
m_X(a_BlockX),
|
||||
m_Y(a_BlockY),
|
||||
m_Z(a_BlockZ)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool Item(cEntity * a_Entity) override
|
||||
{
|
||||
cBoundingBox bbWire(m_X, m_X + 1, m_Y, m_Y + 0.1, m_Z, m_Z + 1);
|
||||
cBoundingBox bbEntity(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight());
|
||||
|
||||
if (bbEntity.DoesIntersect(bbWire))
|
||||
{
|
||||
m_FoundEntity = true;
|
||||
return true; // One entity is sufficient to trigger the wire
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FoundEntity(void) const
|
||||
{
|
||||
return m_FoundEntity;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool m_FoundEntity;
|
||||
|
||||
int m_X;
|
||||
int m_Y;
|
||||
int m_Z;
|
||||
};
|
||||
|
||||
cTripwireCallback TripwireCallback(BlockX, a_RelBlockY, BlockZ);
|
||||
m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), TripwireCallback);
|
||||
|
||||
if (TripwireCallback.FoundEntity())
|
||||
{
|
||||
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cIncrementalRedstoneSimulator::AreCoordsDirectlyPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
|
||||
{
|
||||
int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
|
||||
|
@ -102,6 +102,11 @@ private:
|
||||
void HandleDaylightSensor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles pressure plates */
|
||||
void HandlePressurePlate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType);
|
||||
/** Handles tripwire hooks
|
||||
Performs correct meta and power setting for self by going in the direction it faces and looking for a continous line of tripwire bounded by another oppositely facing hook
|
||||
If this line is complete, it verifies that at least on wire reports an entity is on top (via its meta), and performs its task
|
||||
*/
|
||||
void HandleTripwireHook(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/* ==================== */
|
||||
|
||||
/* ====== CARRIERS ====== */
|
||||
@ -134,6 +139,8 @@ private:
|
||||
void HandleFenceGate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles noteblocks */
|
||||
void HandleNoteBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles tripwires */
|
||||
void HandleTripwire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/* ===================== */
|
||||
|
||||
/* ====== Helper functions ====== */
|
||||
@ -271,6 +278,7 @@ private:
|
||||
case E_BLOCK_TNT:
|
||||
case E_BLOCK_TRAPDOOR:
|
||||
case E_BLOCK_TRIPWIRE_HOOK:
|
||||
case E_BLOCK_TRIPWIRE:
|
||||
case E_BLOCK_WOODEN_BUTTON:
|
||||
case E_BLOCK_WOODEN_DOOR:
|
||||
case E_BLOCK_WOODEN_PRESSURE_PLATE:
|
||||
|
@ -1877,9 +1877,18 @@ void cWorld::BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastCollectEntity(a_Entity, a_Player, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastCollectPickup(a_Pickup, a_Player, a_Exclude);
|
||||
m_ChunkMap->BroadcastCollectEntity(a_Pickup, a_Player, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
@ -206,6 +206,7 @@ public:
|
||||
// tolua_end
|
||||
|
||||
void BroadcastChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastCollectEntity (const cEntity & a_Pickup, 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);
|
||||
|
@ -345,6 +345,7 @@ void cNBTChunkSerializer::AddBasicEntity(cEntity * a_Entity, const AString & a_C
|
||||
m_Writer.AddDouble("", a_Entity->GetYaw());
|
||||
m_Writer.AddDouble("", a_Entity->GetPitch());
|
||||
m_Writer.EndList();
|
||||
m_Writer.AddShort("Health", a_Entity->GetHealth());
|
||||
}
|
||||
|
||||
|
||||
@ -575,7 +576,6 @@ void cNBTChunkSerializer::AddPickupEntity(cPickup * a_Pickup)
|
||||
m_Writer.BeginCompound("");
|
||||
AddBasicEntity(a_Pickup, "Item");
|
||||
AddItem(a_Pickup->GetItem(), -1, "Item");
|
||||
m_Writer.AddShort("Health", (Int16)(unsigned char)a_Pickup->GetHealth());
|
||||
m_Writer.AddShort("Age", (Int16)a_Pickup->GetAge());
|
||||
m_Writer.EndCompound();
|
||||
}
|
||||
@ -678,7 +678,6 @@ void cNBTChunkSerializer::AddExpOrbEntity(cExpOrb * a_ExpOrb)
|
||||
{
|
||||
m_Writer.BeginCompound("");
|
||||
AddBasicEntity(a_ExpOrb, "XPOrb");
|
||||
m_Writer.AddShort("Health", (Int16)(unsigned char)a_ExpOrb->GetHealth());
|
||||
m_Writer.AddShort("Age", (Int16)a_ExpOrb->GetAge());
|
||||
m_Writer.AddShort("Value", (Int16)a_ExpOrb->GetReward());
|
||||
m_Writer.EndCompound();
|
||||
|
@ -1461,13 +1461,6 @@ void cWSSAnvil::LoadPickupFromNBT(cEntityList & a_Entities, const cParsedNBT & a
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Load health:
|
||||
int Health = a_NBT.FindChildByName(a_TagIdx, "Health");
|
||||
if (Health > 0)
|
||||
{
|
||||
Pickup->SetHealth((int) (a_NBT.GetShort(Health) & 0xFF));
|
||||
}
|
||||
|
||||
// Load age:
|
||||
int Age = a_NBT.FindChildByName(a_TagIdx, "Age");
|
||||
@ -1513,13 +1506,6 @@ void cWSSAnvil::LoadExpOrbFromNBT(cEntityList & a_Entities, const cParsedNBT & a
|
||||
return;
|
||||
}
|
||||
|
||||
// Load Health:
|
||||
int Health = a_NBT.FindChildByName(a_TagIdx, "Health");
|
||||
if (Health > 0)
|
||||
{
|
||||
ExpOrb->SetHealth((int) (a_NBT.GetShort(Health) & 0xFF));
|
||||
}
|
||||
|
||||
// Load Age:
|
||||
int Age = a_NBT.FindChildByName(a_TagIdx, "Age");
|
||||
if (Age > 0)
|
||||
@ -2437,6 +2423,13 @@ bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_N
|
||||
}
|
||||
a_Entity.SetYaw(Rotation[0]);
|
||||
a_Entity.SetRoll(Rotation[1]);
|
||||
|
||||
// Load health:
|
||||
int Health = a_NBT.FindChildByName(a_TagIdx, "Health");
|
||||
if (Health > 0)
|
||||
{
|
||||
a_Entity.SetHealth(a_NBT.GetShort(Health));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user